v3: added a chatbox
Some checks failed
Build and Publish Docker Image / build-and-push (push) Has been cancelled
Some checks failed
Build and Publish Docker Image / build-and-push (push) Has been cancelled
This commit is contained in:
@@ -2,6 +2,7 @@ import { randomBytes, scryptSync } from "node:crypto";
|
||||
import { DatabaseSync, type SQLOutputValue } from "node:sqlite";
|
||||
import {
|
||||
type Category,
|
||||
type ChatMessage,
|
||||
type Comment,
|
||||
Dump,
|
||||
isRole,
|
||||
@@ -304,6 +305,43 @@ export function commentRowToApi(row: CommentRow): Comment {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ChatMessageRow {
|
||||
id: string;
|
||||
user_id: string;
|
||||
body: string;
|
||||
created_at: string;
|
||||
updated_at: string | null;
|
||||
author_username: string;
|
||||
author_avatar_mime: string | null;
|
||||
[key: string]: SQLOutputValue;
|
||||
}
|
||||
|
||||
export function isChatMessageRow(obj: unknown): obj is ChatMessageRow {
|
||||
return !!obj && typeof obj === "object" &&
|
||||
"id" in obj && typeof obj.id === "string" &&
|
||||
"user_id" in obj && typeof obj.user_id === "string" &&
|
||||
"body" in obj && typeof obj.body === "string" &&
|
||||
"created_at" in obj && typeof obj.created_at === "string" &&
|
||||
"updated_at" in obj &&
|
||||
(typeof obj.updated_at === "string" || obj.updated_at === null) &&
|
||||
"author_username" in obj && typeof obj.author_username === "string" &&
|
||||
"author_avatar_mime" in obj &&
|
||||
(typeof obj.author_avatar_mime === "string" ||
|
||||
obj.author_avatar_mime === null);
|
||||
}
|
||||
|
||||
export function chatMessageRowToApi(row: ChatMessageRow): ChatMessage {
|
||||
return {
|
||||
id: row.id,
|
||||
userId: row.user_id,
|
||||
body: row.body,
|
||||
createdAt: new Date(row.created_at),
|
||||
updatedAt: row.updated_at ? new Date(row.updated_at) : undefined,
|
||||
authorUsername: row.author_username,
|
||||
authorAvatarMime: row.author_avatar_mime ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export interface PlaylistRow {
|
||||
id: string;
|
||||
user_id: string;
|
||||
|
||||
@@ -309,6 +309,25 @@ export interface CreateCommentRequest {
|
||||
parentId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat
|
||||
*/
|
||||
|
||||
export interface ChatMessage {
|
||||
id: string;
|
||||
userId: string;
|
||||
body: string;
|
||||
createdAt: Date;
|
||||
updatedAt?: Date;
|
||||
authorUsername: string;
|
||||
authorAvatarMime?: string;
|
||||
}
|
||||
|
||||
/** Wire format — createdAt arrives as an ISO string over JSON. */
|
||||
export type RawChatMessage = Omit<ChatMessage, "createdAt"> & {
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export function isCreateCommentRequest(
|
||||
obj: unknown,
|
||||
): obj is CreateCommentRequest {
|
||||
@@ -532,13 +551,40 @@ export interface CommentLikeRemoveMessage {
|
||||
commentId: string;
|
||||
}
|
||||
|
||||
export interface ChatSendMessage {
|
||||
type: "chat_send";
|
||||
body: string;
|
||||
}
|
||||
|
||||
// Tells the server whether this client currently has the chatbox open, so that
|
||||
// mention notifications can be skipped for users who are already reading chat.
|
||||
export interface ChatFocusMessage {
|
||||
type: "chat_focus";
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
export interface ChatEditMessage {
|
||||
type: "chat_edit";
|
||||
id: string;
|
||||
body: string;
|
||||
}
|
||||
|
||||
export interface ChatDeleteMessage {
|
||||
type: "chat_delete";
|
||||
id: string;
|
||||
}
|
||||
|
||||
export type ClientToServerMessage =
|
||||
| PingMessage
|
||||
| PongMessage
|
||||
| VoteCastMessage
|
||||
| VoteRemoveMessage
|
||||
| CommentLikeCastMessage
|
||||
| CommentLikeRemoveMessage;
|
||||
| CommentLikeRemoveMessage
|
||||
| ChatSendMessage
|
||||
| ChatFocusMessage
|
||||
| ChatEditMessage
|
||||
| ChatDeleteMessage;
|
||||
|
||||
// ── Server → Client ──────────────────────────────────────────────────────────
|
||||
|
||||
@@ -669,6 +715,21 @@ export interface ForceLogoutMessage {
|
||||
type: "force_logout";
|
||||
}
|
||||
|
||||
export interface ChatMessageMessage {
|
||||
type: "chat_message";
|
||||
message: ChatMessage;
|
||||
}
|
||||
|
||||
export interface ChatMessageUpdatedMessage {
|
||||
type: "chat_message_updated";
|
||||
message: ChatMessage;
|
||||
}
|
||||
|
||||
export interface ChatMessageDeletedMessage {
|
||||
type: "chat_message_deleted";
|
||||
id: string;
|
||||
}
|
||||
|
||||
export type ServerToClientMessage =
|
||||
| PingMessage
|
||||
| WelcomeMessage
|
||||
@@ -690,7 +751,10 @@ export type ServerToClientMessage =
|
||||
| CommentDeletedMessage
|
||||
| NotificationCreatedMessage
|
||||
| ErrorMessage
|
||||
| ForceLogoutMessage;
|
||||
| ForceLogoutMessage
|
||||
| ChatMessageMessage
|
||||
| ChatMessageUpdatedMessage
|
||||
| ChatMessageDeletedMessage;
|
||||
|
||||
/**
|
||||
* Follows
|
||||
@@ -751,7 +815,7 @@ export interface DumpUpvotedData {
|
||||
export interface UserMentionedData {
|
||||
mentionerId: string;
|
||||
mentionerUsername: string;
|
||||
contextType: "comment" | "dump" | "playlist";
|
||||
contextType: "comment" | "dump" | "playlist" | "chat";
|
||||
contextId: string;
|
||||
contextTitle: string;
|
||||
dumpId?: string;
|
||||
|
||||
Reference in New Issue
Block a user