fix(web): persistent WS connection, auto-refetch on ready, and direct selector binding with scroll fix

This commit is contained in:
2026-07-27 09:09:27 -04:00
parent 86717a2867
commit a54a67e41b
4 changed files with 19 additions and 14 deletions
+4 -3
View File
@@ -288,9 +288,7 @@ export function ChatArea() {
const activeChannelId = rawActiveChannelId ? rawActiveChannelId.toLowerCase() : null;
const channelsByServer = useChannelStore((s) => s.channelsByServer);
const activeServerId = useServerStore((s) => s.activeServerId);
const messages = useMessageStore(
useCallback((s) => (activeChannelId ? s.messagesByChannel[activeChannelId] || [] : []), [activeChannelId])
);
const messages = useMessageStore((s) => (activeChannelId ? s.messagesByChannel[activeChannelId] || [] : []));
const isLoading = useMessageStore((s) => s.isLoading);
const isLoadingOlder = useMessageStore((s) => s.isLoadingOlder);
const hasMore = useMessageStore((s) => activeChannelId ? s.hasMoreByChannel[activeChannelId] !== false : true);
@@ -461,6 +459,9 @@ export function ChatArea() {
}, [activeChannelId, isLoadingOlder, hasMore, fetchOlderMessages]);
useEffect(() => {
if (scrollContainerRef.current) {
scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight;
}
bottomRef.current?.scrollIntoView({ behavior: "auto" });
}, [messages]);
+9 -6
View File
@@ -176,9 +176,14 @@ export function DMChat() {
const id = rawId ? rawId.toLowerCase() : undefined;
const conversation = conversations.find((c) => c.id.toLowerCase() === id);
const hasMore = useConversationStore((s) => id ? s.hasMoreByConversation[id] !== false : true);
const messages = useConversationStore(
useCallback((s) => (id ? s.messagesByConversation[id] || [] : []), [id])
);
const messages = useConversationStore((s) => (id ? s.messagesByConversation[id] || [] : []));
useEffect(() => {
if (scrollContainerRef.current) {
scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight;
}
bottomRef.current?.scrollIntoView({ behavior: "auto" });
}, [messages]);
const handleAddReaction = useCallback(async (messageId: string, emoji: string) => {
if (!id) return;
@@ -216,9 +221,7 @@ export function DMChat() {
}
}, [id, setActive, fetchMessages]);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "auto" });
}, [messages]);
useEffect(() => {
if (!id || messages.length === 0 || isLoading) return;
+2 -5
View File
@@ -35,8 +35,6 @@ export function Layout() {
const user = useAuthStore((state) => state.user);
const logout = useAuthStore((state) => state.logout);
const updateProfile = useAuthStore((state) => state.updateProfile);
const wsConnect = useWebSocketStore((s) => s.connect);
const wsDisconnect = useWebSocketStore((s) => s.disconnect);
const navigate = useNavigate();
const location = useLocation();
const [showStatusMenu, setShowStatusMenu] = useState(false);
@@ -63,9 +61,8 @@ export function Layout() {
}, [currentVoiceRoom]);
useEffect(() => {
wsConnect();
return () => { wsDisconnect(); };
}, [wsConnect, wsDisconnect]);
useWebSocketStore.getState().connect();
}, []);
useEffect(() => {
if (!isLoading && !isAuthenticated && location.pathname !== '/login') {
+4
View File
@@ -110,6 +110,10 @@ export const useWebSocketStore = create<WebSocketState>((set, get) => ({
if (data.type === 'ready') {
set({ connected: true });
reconnectDelay = 1000;
const activeChan = useChannelStore.getState().activeChannelId;
if (activeChan) useMessageStore.getState().fetchMessages(activeChan);
const activeConv = useConversationStore.getState().activeConversationId;
if (activeConv) useConversationStore.getState().fetchMessages(activeConv);
return;
}