diff --git a/package.json b/package.json index 187e20b..4237267 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "@logseq/libs": "^0.0.1-alpha.26", "eslint-plugin-react-hooks": "^4.2.0", + "fast-deep-equal": "^3.1.3", "immer": "^9.0.5", "keyboardjs": "^2.6.4", "react": "^17.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9894540..c8c8959 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,6 +15,7 @@ specifiers: eslint: ^7.32.0 eslint-plugin-react: ^7.25.1 eslint-plugin-react-hooks: ^4.2.0 + fast-deep-equal: ^3.1.3 immer: ^9.0.5 keyboardjs: ^2.6.4 react: ^17.0.2 @@ -28,6 +29,7 @@ specifiers: dependencies: '@logseq/libs': 0.0.1-alpha.26 eslint-plugin-react-hooks: 4.2.0_eslint@7.32.0 + fast-deep-equal: 3.1.3 immer: 9.0.5 keyboardjs: 2.6.4 react: 17.0.2 diff --git a/src/PageTabs.tsx b/src/PageTabs.tsx index 9df2d52..e844829 100644 --- a/src/PageTabs.tsx +++ b/src/PageTabs.tsx @@ -16,7 +16,7 @@ import { mainContainerScroll, useAdaptMainUIStyle, useEventCallback, - useOpeningPageTabs, + useStoreTabs, useScrollWidth, } from "./utils"; @@ -263,7 +263,7 @@ const sortTabs = (tabs: ITabInfo[]) => { }; export function PageTabs(): JSX.Element { - const [tabs, setTabs] = useOpeningPageTabs(); + const [tabs, setTabs] = useStoreTabs(); const [activePage, setActivePage] = useActivePage(tabs); const currActivePageRef = React.useRef(); diff --git a/src/utils.ts b/src/utils.ts index 4e91c90..979c975 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { PageEntity } from "@logseq/libs/dist/LSPlugin"; import React, { useState } from "react"; +import isEqual from 'fast-deep-equal'; import { - useDeepCompareEffect, useHoverDirty, - useMountedState, + useMountedState } from "react-use"; import { version } from "../package.json"; import { ITabInfo } from "./types"; @@ -48,7 +48,7 @@ export const useThemeMode = () => { (top!.document .querySelector("html") ?.getAttribute("data-theme") as typeof mode) ?? - (matchMedia("prefers-color-scheme: dark").matches ? "dark" : "light") + (matchMedia("prefers-color-scheme: dark").matches ? "dark" : "light") ); return logseq.App.onThemeModeChanged((s) => { if (isMounted()) { @@ -94,10 +94,12 @@ export async function getSourcePage( export const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); -const KEY_ID = "logseq-opening-page-tabs:" + version; +function getKeyId(graph: string) { + return "logseq-plugin-tabs:" + version + "/" + graph; +} -const readFromLocalStorage = () => { - const str = localStorage.getItem(KEY_ID); +const readFromLocalStorage = (graph: string): ITabInfo[] | null => { + const str = localStorage.getItem(getKeyId(graph)); if (str) { try { return JSON.parse(str); @@ -105,25 +107,47 @@ const readFromLocalStorage = () => { // no ops } } - return []; + return null; }; -const persistToLocalStorage = (tabs: ITabInfo[]) => { - localStorage.setItem(KEY_ID, JSON.stringify(tabs)); +const persistToLocalStorage = (tabs: ITabInfo[], graph: string) => { + localStorage.setItem(getKeyId(graph), JSON.stringify(tabs)); }; -export function useOpeningPageTabs() { - const [tabs, setTabs] = React.useState(readFromLocalStorage()); +function useCurrentGraph() { + const [graph, setGraph] = useState(null); + const reset = async () => { + const g = await logseq.App.getCurrentGraph(); + setGraph(g?.path ?? null); + }; + React.useEffect(() => { + reset(); + return logseq.App.onCurrentGraphChanged(() => { + reset(); + }); + }, []); + return graph; +} - useDeepCompareEffect(() => { - persistToLocalStorage(tabs); - }, [tabs]); +export function useStoreTabs() { + const [tabs, setTabs] = React.useState([]); + const currentGraph = useCurrentGraph(); React.useEffect(() => { - return logseq.App.onCurrentGraphChanged(() => setTabs([])); - }, []); + if (currentGraph) { + const tabs = readFromLocalStorage(currentGraph); + setTabs(tabs ?? []); + } + }, [currentGraph]); + + const userSetTabs = (newTabs: ITabInfo[]) => { + if (currentGraph && !isEqual(tabs, newTabs)) { + persistToLocalStorage(newTabs, currentGraph); + return setTabs(newTabs); + } + }; - return [tabs, setTabs] as const; + return [tabs, userSetTabs] as const; } export function useAdaptMainUIStyle(show: boolean, tabsWidth?: number | null) {