feat(search): focus and highlight found message in chat

- store focused message id per chat
- scroll to target message and highlight it after search selection
- clear focus automatically after short timeout
This commit is contained in:
2026-03-08 02:53:03 +03:00
parent 874f9da12c
commit eef89983e0
3 changed files with 31 additions and 2 deletions

View File

@@ -12,6 +12,7 @@ interface ChatState {
typingByChat: Record<number, number[]>;
replyToByChat: Record<number, Message | null>;
unreadBoundaryByChat: Record<number, number>;
focusedMessageIdByChat: Record<number, number | null>;
loadChats: (query?: string) => Promise<void>;
setActiveChatId: (chatId: number | null) => void;
loadMessages: (chatId: number) => Promise<void>;
@@ -44,6 +45,7 @@ interface ChatState {
applyPresenceEvent: (chatId: number, userId: number, isOnline: boolean, lastSeenAt?: string) => void;
setDraft: (chatId: number, text: string) => void;
clearDraft: (chatId: number) => void;
setFocusedMessage: (chatId: number, messageId: number | null) => void;
}
export const useChatStore = create<ChatState>((set, get) => ({
@@ -56,6 +58,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
typingByChat: {},
replyToByChat: {},
unreadBoundaryByChat: {},
focusedMessageIdByChat: {},
loadChats: async (query) => {
const chats = await getChats(query);
const currentActive = get().activeChatId;
@@ -342,5 +345,12 @@ export const useChatStore = create<ChatState>((set, get) => ({
const next = { ...state.draftsByChat };
delete next[chatId];
return { draftsByChat: next };
})
}),
setFocusedMessage: (chatId, messageId) =>
set((state) => ({
focusedMessageIdByChat: {
...state.focusedMessageIdByChat,
[chatId]: messageId
}
}))
}));