36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
import { useCallback, useSyncExternalStore } from "react";
|
|
|
|
export type ViewMode = "split" | "unified";
|
|
|
|
const DIFF_VIEW_MODE_KEY = "diff-view-mode";
|
|
const DEFAULT_VIEW_MODE: ViewMode = "unified";
|
|
const VIEW_MODE_CHANGE_EVENT = "diff-view-mode-change";
|
|
|
|
function getStoredViewMode(): ViewMode {
|
|
if (typeof window === "undefined") return DEFAULT_VIEW_MODE;
|
|
const stored = localStorage.getItem(DIFF_VIEW_MODE_KEY);
|
|
return stored === "split" || stored === "unified" ? stored : DEFAULT_VIEW_MODE;
|
|
}
|
|
|
|
function setStoredViewMode(mode: ViewMode): void {
|
|
localStorage.setItem(DIFF_VIEW_MODE_KEY, mode);
|
|
window.dispatchEvent(new CustomEvent(VIEW_MODE_CHANGE_EVENT, { detail: mode }));
|
|
}
|
|
|
|
export function useGlobalViewMode(): [ViewMode, (mode: ViewMode) => void] {
|
|
const subscribe = useCallback((callback: () => void) => {
|
|
window.addEventListener(VIEW_MODE_CHANGE_EVENT, callback);
|
|
window.addEventListener("storage", callback);
|
|
return () => {
|
|
window.removeEventListener(VIEW_MODE_CHANGE_EVENT, callback);
|
|
window.removeEventListener("storage", callback);
|
|
};
|
|
}, []);
|
|
|
|
const getSnapshot = useCallback(() => getStoredViewMode(), []);
|
|
const getServerSnapshot = useCallback(() => DEFAULT_VIEW_MODE, []);
|
|
const viewMode = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
|
|
return [viewMode, setStoredViewMode];
|
|
}
|