web(realtime): refresh chat info panel on chat updates
Some checks are pending
CI / test (push) Has started running
Some checks are pending
CI / test (push) Has started running
This commit is contained in:
@@ -107,6 +107,49 @@ export function ChatInfoPanel({ chatId, open, onClose }: Props) {
|
||||
setMemberUsers(byId);
|
||||
}
|
||||
|
||||
async function refreshPanelData(targetChatId: number, withLoading = false) {
|
||||
if (withLoading) {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
setAttachmentsLoading(true);
|
||||
}
|
||||
try {
|
||||
const detail = await getChatDetail(targetChatId);
|
||||
setChat(detail);
|
||||
setTitleDraft((prev) => (prev.trim() ? prev : (detail.title ?? "")));
|
||||
const notificationSettings = await getChatNotificationSettings(targetChatId);
|
||||
setMuted(notificationSettings.muted);
|
||||
if (detail.type === "private" && !detail.is_saved && detail.counterpart_user_id) {
|
||||
try {
|
||||
const counterpart = await getUserById(detail.counterpart_user_id);
|
||||
setCounterpartProfile(counterpart);
|
||||
const blocked = await listBlockedUsers();
|
||||
setCounterpartBlocked(blocked.some((u) => u.id === detail.counterpart_user_id));
|
||||
} catch {
|
||||
setCounterpartProfile(null);
|
||||
setCounterpartBlocked(false);
|
||||
}
|
||||
} else {
|
||||
setCounterpartProfile(null);
|
||||
setCounterpartBlocked(false);
|
||||
}
|
||||
await refreshMembers(targetChatId);
|
||||
const chatAttachments = await getChatAttachments(targetChatId, 120);
|
||||
const messages = await getRecentMessagesForLinks(targetChatId);
|
||||
setAttachments(chatAttachments);
|
||||
setLinkItems(extractLinkItems(messages));
|
||||
} catch {
|
||||
if (withLoading) {
|
||||
setError("Failed to load chat info");
|
||||
}
|
||||
} finally {
|
||||
if (withLoading) {
|
||||
setLoading(false);
|
||||
setAttachmentsLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jumpToMessage(messageId: number) {
|
||||
if (!chatId) {
|
||||
return;
|
||||
@@ -140,53 +183,10 @@ export function ChatInfoPanel({ chatId, open, onClose }: Props) {
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
setAttachmentsLoading(true);
|
||||
void (async () => {
|
||||
try {
|
||||
const detail = await getChatDetail(chatId);
|
||||
if (cancelled) return;
|
||||
setChat(detail);
|
||||
setTitleDraft(detail.title ?? "");
|
||||
const notificationSettings = await getChatNotificationSettings(chatId);
|
||||
if (!cancelled) {
|
||||
setMuted(notificationSettings.muted);
|
||||
}
|
||||
if (detail.type === "private" && !detail.is_saved && detail.counterpart_user_id) {
|
||||
try {
|
||||
const counterpart = await getUserById(detail.counterpart_user_id);
|
||||
if (!cancelled) {
|
||||
setCounterpartProfile(counterpart);
|
||||
}
|
||||
const blocked = await listBlockedUsers();
|
||||
if (!cancelled) {
|
||||
setCounterpartBlocked(blocked.some((u) => u.id === detail.counterpart_user_id));
|
||||
}
|
||||
} catch {
|
||||
if (!cancelled) {
|
||||
setCounterpartProfile(null);
|
||||
setCounterpartBlocked(false);
|
||||
}
|
||||
}
|
||||
} else if (!cancelled) {
|
||||
setCounterpartProfile(null);
|
||||
setCounterpartBlocked(false);
|
||||
}
|
||||
await refreshMembers(chatId);
|
||||
const chatAttachments = await getChatAttachments(chatId, 120);
|
||||
const messages = await getRecentMessagesForLinks(chatId);
|
||||
if (!cancelled) {
|
||||
setAttachments(chatAttachments);
|
||||
setLinkItems(extractLinkItems(messages));
|
||||
}
|
||||
} catch {
|
||||
if (!cancelled) setError("Failed to load chat info");
|
||||
} finally {
|
||||
if (!cancelled) {
|
||||
setLoading(false);
|
||||
setAttachmentsLoading(false);
|
||||
}
|
||||
await refreshPanelData(chatId, true);
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
@@ -205,6 +205,22 @@ export function ChatInfoPanel({ chatId, open, onClose }: Props) {
|
||||
setSearchResults([]);
|
||||
}, [chatId, open]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || !chatId) {
|
||||
return;
|
||||
}
|
||||
const onRealtimeChatUpdated = (event: Event) => {
|
||||
const realtimeEvent = event as CustomEvent<{ chatId?: number }>;
|
||||
const updatedChatId = Number(realtimeEvent.detail?.chatId);
|
||||
if (!Number.isFinite(updatedChatId) || updatedChatId !== chatId) {
|
||||
return;
|
||||
}
|
||||
void refreshPanelData(chatId, false);
|
||||
};
|
||||
window.addEventListener("bm:chat-updated", onRealtimeChatUpdated);
|
||||
return () => window.removeEventListener("bm:chat-updated", onRealtimeChatUpdated);
|
||||
}, [open, chatId]);
|
||||
|
||||
useEffect(() => {
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === "Escape") {
|
||||
|
||||
@@ -133,6 +133,7 @@ export function useRealtime() {
|
||||
if (event.event === "chat_updated") {
|
||||
const chatId = Number(event.payload.chat_id);
|
||||
if (Number.isFinite(chatId)) {
|
||||
window.dispatchEvent(new CustomEvent("bm:chat-updated", { detail: { chatId } }));
|
||||
scheduleReloadChats();
|
||||
if (chatStore.activeChatId === chatId || (chatStore.messagesByChat[chatId]?.length ?? 0) > 0) {
|
||||
void chatStore.loadMessages(chatId);
|
||||
|
||||
Reference in New Issue
Block a user