feat(chat): add presence metadata and improve web chat core
Some checks failed
CI / test (push) Failing after 22s
Some checks failed
CI / test (push) Failing after 22s
- add user last_seen_at with alembic migration and persist on realtime disconnect - extend chat serialization with private online/last_seen, group members/online, channel subscribers - add Redis batch presence lookup helper - update web chat list/header to display status counters and last-seen labels - improve delivery receipt handling using last_delivered/last_read boundaries - include chat info panel and related API/type updates
This commit is contained in:
@@ -23,6 +23,12 @@ interface ChatState {
|
||||
confirmMessageByClientId: (chatId: number, clientMessageId: string, message: Message) => void;
|
||||
removeOptimisticMessage: (chatId: number, clientMessageId: string) => void;
|
||||
setMessageDeliveryStatus: (chatId: number, messageId: number, status: DeliveryStatus) => void;
|
||||
setMessageDeliveryStatusUpTo: (
|
||||
chatId: number,
|
||||
maxMessageId: number,
|
||||
status: DeliveryStatus,
|
||||
senderId: number
|
||||
) => void;
|
||||
removeMessage: (chatId: number, messageId: number) => void;
|
||||
restoreMessages: (chatId: number, messages: Message[]) => void;
|
||||
clearChatMessages: (chatId: number) => void;
|
||||
@@ -151,6 +157,31 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
||||
messagesByChat: { ...state.messagesByChat, [chatId]: next }
|
||||
}));
|
||||
},
|
||||
setMessageDeliveryStatusUpTo: (chatId, maxMessageId, status, senderId) => {
|
||||
const old = get().messagesByChat[chatId] ?? [];
|
||||
if (!old.length) {
|
||||
return;
|
||||
}
|
||||
const order: Record<DeliveryStatus, number> = { sending: 1, sent: 2, delivered: 3, read: 4 };
|
||||
let changed = false;
|
||||
const next = old.map((message) => {
|
||||
if (message.sender_id !== senderId || message.id <= 0 || message.id > maxMessageId) {
|
||||
return message;
|
||||
}
|
||||
const currentStatus = message.delivery_status ?? "sent";
|
||||
if (order[status] <= order[currentStatus]) {
|
||||
return message;
|
||||
}
|
||||
changed = true;
|
||||
return { ...message, delivery_status: status, is_pending: false };
|
||||
});
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
set((state) => ({
|
||||
messagesByChat: { ...state.messagesByChat, [chatId]: next }
|
||||
}));
|
||||
},
|
||||
removeMessage: (chatId, messageId) => {
|
||||
const old = get().messagesByChat[chatId] ?? [];
|
||||
set((state) => ({
|
||||
|
||||
Reference in New Issue
Block a user