Corp/frontend/src/hooks/useMessagesWorkspaceMode.ts

61 lines
2.0 KiB
TypeScript

"use client";
import { useCallback, useSyncExternalStore } from "react";
import {
resolveMessagesWorkspaceMode,
type MessagesWorkspaceMode,
} from "@/lib/messages/workspace.js";
export type { MessagesWorkspaceMode } from "@/lib/messages/workspace.js";
const STORAGE_PREFIX = "messages.workspaceMode";
const LEGACY_FOCUS_PREFIX = "messages.desktopFocusMode";
const LEGACY_IMMERSIVE_PREFIX = "messages.desktopImmersiveMode";
const CHANGE_EVENT = "messages-workspace-mode-change";
function storageKey(prefix: string, userId: number): string {
return `${prefix}.${userId}`;
}
function readMode(userId: number): MessagesWorkspaceMode {
return resolveMessagesWorkspaceMode({
current: window.localStorage.getItem(storageKey(STORAGE_PREFIX, userId)),
legacyFocus: window.localStorage.getItem(storageKey(LEGACY_FOCUS_PREFIX, userId)),
legacyImmersive: window.localStorage.getItem(storageKey(LEGACY_IMMERSIVE_PREFIX, userId)),
});
}
export function useMessagesWorkspaceMode(userId?: number | null) {
const subscribe = useCallback((notify: () => void) => {
if (!userId) return () => undefined;
const key = storageKey(STORAGE_PREFIX, userId);
const handleStorage = (event: StorageEvent) => {
if (event.key === key) notify();
};
window.addEventListener("storage", handleStorage);
window.addEventListener(CHANGE_EVENT, notify);
return () => {
window.removeEventListener("storage", handleStorage);
window.removeEventListener(CHANGE_EVENT, notify);
};
}, [userId]);
const getSnapshot = useCallback((): MessagesWorkspaceMode =>
(userId ? readMode(userId) : "wide"),
[userId],
);
const mode = useSyncExternalStore<MessagesWorkspaceMode>(subscribe, getSnapshot, () => "wide");
const setMode = useCallback((next: MessagesWorkspaceMode) => {
if (!userId) return;
window.localStorage.setItem(storageKey(STORAGE_PREFIX, userId), next);
window.dispatchEvent(new Event(CHANGE_EVENT));
}, [userId]);
return [mode, setMode] as const;
}