fix(dm): add image paste support to DM chat and fix realtime DM updates

This commit is contained in:
2026-07-06 13:44:41 +00:00
parent 0c26e2402b
commit c2fb3165f4
3 changed files with 127 additions and 31 deletions
+49 -30
View File
@@ -6,7 +6,9 @@ import { usePresenceStore } from './presence.ts';
import { useTypingStore } from './typing.ts';
import { useVoiceStore } from './voice.ts';
import { useAuthStore } from './auth.ts';
import { useConversationStore } from './conversation.ts';
import type { Message } from './message.ts';
import type { ConversationMessage } from './conversation.ts';
import type { Channel } from './channel.ts';
import type { Server } from './server.ts';
import type { UserStatus } from './auth.ts';
@@ -47,11 +49,11 @@ function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null;
}
function extractIds(payload: UnknownPayload | undefined): { channel_id: string; message_id: string } | null {
if (!payload || typeof payload.channel_id !== 'string' || typeof payload.message_id !== 'string') {
return null;
}
return { channel_id: payload.channel_id, message_id: payload.message_id };
function extractIds(payload: UnknownPayload | undefined): { channel_id?: string; conversation_id?: string; message_id: string } | null {
if (!payload || typeof payload.message_id !== 'string') return null;
if (typeof payload.channel_id === 'string') return { channel_id: payload.channel_id, message_id: payload.message_id };
if (typeof payload.conversation_id === 'string') return { conversation_id: payload.conversation_id, message_id: payload.message_id };
return null;
}
export const useWebSocketStore = create<WebSocketState>((set, get) => ({
@@ -127,42 +129,59 @@ export const useWebSocketStore = create<WebSocketState>((set, get) => ({
switch (data.type) {
case 'MESSAGE_CREATE': {
if (isRecord(payload)) {
const msg = payload as unknown as Message;
addMessage(msg);
// Desktop notification
const currentUserId = useAuthStore.getState().user?.id;
if (msg.author_id !== currentUserId && !document.hasFocus()) {
// Update browser tab title
unreadCount++;
if (document.title.match(/^\(\d+\)\s/)) {
document.title = document.title.replace(/^\(\d+\)\s/, `(${unreadCount}) `);
} else {
document.title = `(${unreadCount}) ` + document.title;
}
if (payload.conversation_id) {
const msg = payload as unknown as ConversationMessage;
useConversationStore.getState().addMessage(msg);
} else {
const msg = payload as unknown as Message;
addMessage(msg);
// Desktop notification
const currentUserId = useAuthStore.getState().user?.id;
if (msg.author_id !== currentUserId && !document.hasFocus()) {
// Update browser tab title
unreadCount++;
if (document.title.match(/^\(\d+\)\s/)) {
document.title = document.title.replace(/^\(\d+\)\s/, `(${unreadCount}) `);
} else {
document.title = `(${unreadCount}) ` + document.title;
}
if (Notification.permission === 'granted') {
const title = msg.author_username ? `New message from ${msg.author_display_name || msg.author_username}` : 'New message';
const notification = new Notification(title, {
body: msg.content,
icon: '/icons/icon-192.png',
});
notification.onclick = () => {
window.focus();
notification.close();
};
if (Notification.permission === 'granted') {
const title = msg.author_username ? `New message from ${msg.author_display_name || msg.author_username}` : 'New message';
const notification = new Notification(title, {
body: msg.content,
icon: '/icons/icon-192.png',
});
notification.onclick = () => {
window.focus();
notification.close();
};
}
}
}
}
break;
}
case 'MESSAGE_UPDATE': {
if (isRecord(payload)) updateMessage(payload as unknown as Message);
if (isRecord(payload)) {
if (payload.conversation_id) {
useConversationStore.getState().updateMessage(payload as unknown as ConversationMessage);
} else {
updateMessage(payload as unknown as Message);
}
}
break;
}
case 'MESSAGE_DELETE': {
const ids = extractIds(payload);
if (ids) removeMessage(ids.channel_id, ids.message_id);
if (ids) {
if (ids.conversation_id) {
useConversationStore.getState().deleteMessage(ids.conversation_id, ids.message_id);
} else if (ids.channel_id) {
removeMessage(ids.channel_id, ids.message_id);
}
}
break;
}
case 'REACTION_ADD': {