diff --git a/src/comps/FavList.tsx b/src/comps/FavList.tsx index 1ef3651..064db14 100644 --- a/src/comps/FavList.tsx +++ b/src/comps/FavList.tsx @@ -15,16 +15,18 @@ export default function FavList({ items, arrowContainer, name, + readKeys, }: { items: any[] arrowContainer: HTMLElement name: string + readKeys?: Set }) { const [expanded, setExpanded] = useState(false) useEffect(() => { ;(async () => { - setExpanded(await readRootExpansionState(name)) + setExpanded(await readRootExpansionState(name, readKeys)) })() }, [name]) @@ -41,7 +43,12 @@ export default function FavList({ , arrowContainer, )} - + ) } @@ -50,10 +57,12 @@ function SubList({ items, shown, storageKey, + readKeys, }: { items: any[] shown: boolean storageKey: string + readKeys?: Set }) { const [childrenData, setChildrenData] = useState(null) const expansionState = useRef>() @@ -65,7 +74,7 @@ function SubList({ useEffect(() => { if (shown && childrenData == null) { ;(async () => { - expansionState.current = await readExpansionState(storageKey) + expansionState.current = await readExpansionState(storageKey, readKeys) const data: any = {} for (const item of items) { if (item.filters) { @@ -191,6 +200,7 @@ function SubList({ items={data.items} shown={data.expanded} storageKey={`${storageKey}-${displayName}`} + readKeys={readKeys} /> )} diff --git a/src/libs/storage.ts b/src/libs/storage.ts index 9965020..c1c2ddf 100644 --- a/src/libs/storage.ts +++ b/src/libs/storage.ts @@ -1,14 +1,18 @@ const storage = logseq.Assets.makeSandboxStorage() -export async function readExpansionState(key: string) { +export async function readExpansionState(key: string, readKeys?: Set) { + readKeys?.add(key) key = `expansion-${key}.json` - const str = (await storage.hasItem(key)) - ? (await storage.getItem(key))! - : "{}" + const hasItem = await storage.hasItem(key) + const str = hasItem ? (await storage.getItem(key))! : "{}" return JSON.parse(str) as Record } -export async function readRootExpansionState(key: string) { +export async function readRootExpansionState( + key: string, + readKeys?: Set, +) { + readKeys?.add(`_${key}`) key = `expansion-_${key}.json` if (await storage.hasItem(key)) { return JSON.parse((await storage.getItem(key))!) as boolean @@ -29,3 +33,17 @@ export async function writeExpansionState( key = `expansion-${key}.json` await storage.setItem(key, JSON.stringify(value)) } + +export async function allExpansionKeys() { + const keys = await storage.allKeys() + return keys + .filter((key) => key.startsWith("expansion-")) + .map((key) => + key.substring("expansion-".length, key.length - ".json".length), + ) +} + +export async function removeExpansionState(key: string) { + key = `expansion-${key}.json` + await storage.removeItem(key) +} diff --git a/src/plugin.tsx b/src/plugin.tsx index bf858d9..279cdea 100644 --- a/src/plugin.tsx +++ b/src/plugin.tsx @@ -3,9 +3,12 @@ import { setup, t } from "logseq-l10n" import { render } from "preact" import { throttle } from "rambdax" import FavList from "./comps/FavList" +import { allExpansionKeys, removeExpansionState } from "./libs/storage" import { hash, queryForSubItems, setLanguage, waitForEl } from "./libs/utils" import zhCN from "./translations/zh-CN.json" +const CLEAN_WAIT = 3000 + let dragHandle: HTMLElement | null = null async function main() { @@ -82,7 +85,17 @@ async function main() { const graphOff = logseq.App.onCurrentGraphChanged(adjustLeftBarWidth) await waitForEl("#left-sidebar .favorite-item", 1000) - await processFavorites() + + const readKeys = new Set() + await processFavorites(readKeys) + setTimeout(async () => { + const keys = await allExpansionKeys() + const notReadKeys = keys.filter((key) => !readKeys.has(key)) + for (const key of notReadKeys) { + await removeExpansionState(key) + } + }, CLEAN_WAIT) + await adjustLeftBarWidth() logseq.provideUI({ @@ -184,19 +197,23 @@ function provideStyles() { }) } -async function processFavorites() { +async function processFavorites(readKeys?: Set) { const favorites = parent.document.querySelectorAll( `#left-sidebar .favorite-item`, ) for (const fav of favorites) { const items = await queryForSubItems(fav.dataset.ref!) if (items?.length > 0) { - injectList(fav, items) + injectList(fav, items, readKeys) } } } -async function injectList(el: HTMLElement, items: any[]) { +async function injectList( + el: HTMLElement, + items: any[], + readKeys?: Set, +) { const key = `kef-ft-f-${await hash(el.dataset.ref!)}` const arrowContainer = el.querySelector("a")! @@ -214,7 +231,7 @@ async function injectList(el: HTMLElement, items: any[]) { } setTimeout(() => { - renderList(key, items, arrowContainer, el.dataset.ref!) + renderList(key, items, arrowContainer, el.dataset.ref!, readKeys) }, 0) } @@ -223,10 +240,16 @@ function renderList( items: any[], arrowContainer: HTMLElement, name: string, + readKeys?: Set, ) { const el = parent.document.getElementById(key)! render( - , + , el, ) }