Files
backspace/packages/web/src/stores/activityStore.ts
T
Jannis Braun 9705304be9 feat(activity): fan out activity updates to all connected instances
Switch pushActivities and setShowActivity from wsSend (home-only) to
wsSendAll (all instances). Add myActivities cache for re-push on late
connections.
2026-03-24 21:55:45 +01:00

83 lines
2.3 KiB
TypeScript

import { create } from 'zustand';
import type { Activity } from '@backspace/shared';
import { wsSendAll } from '../hooks/useWebSocket';
let pushTimer: ReturnType<typeof setTimeout> | null = null;
interface ActivityState {
userActivities: Map<string, Activity[]>;
showActivity: boolean;
myActivities: Activity[] | null;
setUserActivities: (userId: string, activities: Activity[]) => void;
clearUserActivities: (userId: string) => void;
initActivities: (activityMap: Record<string, Activity[]>) => void;
setShowActivity: (show: boolean) => void;
pushActivities: (activities: Activity[]) => void;
reset: () => void;
}
export const useActivityStore = create<ActivityState>((set, get) => ({
userActivities: new Map(),
showActivity: true,
myActivities: null,
setUserActivities: (userId, activities) => {
set((state) => {
const next = new Map(state.userActivities);
if (activities.length === 0) {
next.delete(userId);
} else {
next.set(userId, activities);
}
return { userActivities: next };
});
},
clearUserActivities: (userId) => {
set((state) => {
const next = new Map(state.userActivities);
next.delete(userId);
return { userActivities: next };
});
},
initActivities: (activityMap) => {
set((state) => {
const next = new Map(state.userActivities);
for (const [userId, activities] of Object.entries(activityMap)) {
if (activities.length > 0) {
next.set(userId, activities);
} else {
next.delete(userId);
}
}
return { userActivities: next };
});
},
setShowActivity: (show) => {
set({ showActivity: show });
if (!show) {
if (pushTimer) { clearTimeout(pushTimer); pushTimer = null; }
wsSendAll({ type: 'activity_update', activities: [] });
set({ myActivities: null });
}
},
pushActivities: (activities) => {
if (!get().showActivity) return;
set({ myActivities: activities });
if (pushTimer) clearTimeout(pushTimer);
pushTimer = setTimeout(() => {
wsSendAll({ type: 'activity_update', activities });
pushTimer = null;
}, 5000);
},
reset: () => {
if (pushTimer) { clearTimeout(pushTimer); pushTimer = null; }
set({ userActivities: new Map(), showActivity: true, myActivities: null });
},
}));