feat: expansion state cleaning

This commit is contained in:
Seth 2023-10-31 13:43:39 +08:00
parent cfc98167a7
commit 784c8107e4
3 changed files with 65 additions and 14 deletions

View File

@ -15,16 +15,18 @@ export default function FavList({
items, items,
arrowContainer, arrowContainer,
name, name,
readKeys,
}: { }: {
items: any[] items: any[]
arrowContainer: HTMLElement arrowContainer: HTMLElement
name: string name: string
readKeys?: Set<string>
}) { }) {
const [expanded, setExpanded] = useState(false) const [expanded, setExpanded] = useState(false)
useEffect(() => { useEffect(() => {
;(async () => { ;(async () => {
setExpanded(await readRootExpansionState(name)) setExpanded(await readRootExpansionState(name, readKeys))
})() })()
}, [name]) }, [name])
@ -41,7 +43,12 @@ export default function FavList({
<FavArrow expanded={expanded} onToggle={toggleList} />, <FavArrow expanded={expanded} onToggle={toggleList} />,
arrowContainer, arrowContainer,
)} )}
<SubList items={items} shown={expanded} storageKey={name} /> <SubList
items={items}
shown={expanded}
storageKey={name}
readKeys={readKeys}
/>
</> </>
) )
} }
@ -50,10 +57,12 @@ function SubList({
items, items,
shown, shown,
storageKey, storageKey,
readKeys,
}: { }: {
items: any[] items: any[]
shown: boolean shown: boolean
storageKey: string storageKey: string
readKeys?: Set<string>
}) { }) {
const [childrenData, setChildrenData] = useState<any>(null) const [childrenData, setChildrenData] = useState<any>(null)
const expansionState = useRef<Record<string, boolean>>() const expansionState = useRef<Record<string, boolean>>()
@ -65,7 +74,7 @@ function SubList({
useEffect(() => { useEffect(() => {
if (shown && childrenData == null) { if (shown && childrenData == null) {
;(async () => { ;(async () => {
expansionState.current = await readExpansionState(storageKey) expansionState.current = await readExpansionState(storageKey, readKeys)
const data: any = {} const data: any = {}
for (const item of items) { for (const item of items) {
if (item.filters) { if (item.filters) {
@ -191,6 +200,7 @@ function SubList({
items={data.items} items={data.items}
shown={data.expanded} shown={data.expanded}
storageKey={`${storageKey}-${displayName}`} storageKey={`${storageKey}-${displayName}`}
readKeys={readKeys}
/> />
)} )}
</div> </div>

View File

@ -1,14 +1,18 @@
const storage = logseq.Assets.makeSandboxStorage() const storage = logseq.Assets.makeSandboxStorage()
export async function readExpansionState(key: string) { export async function readExpansionState(key: string, readKeys?: Set<string>) {
readKeys?.add(key)
key = `expansion-${key}.json` key = `expansion-${key}.json`
const str = (await storage.hasItem(key)) const hasItem = await storage.hasItem(key)
? (await storage.getItem(key))! const str = hasItem ? (await storage.getItem(key))! : "{}"
: "{}"
return JSON.parse(str) as Record<string, boolean> return JSON.parse(str) as Record<string, boolean>
} }
export async function readRootExpansionState(key: string) { export async function readRootExpansionState(
key: string,
readKeys?: Set<string>,
) {
readKeys?.add(`_${key}`)
key = `expansion-_${key}.json` key = `expansion-_${key}.json`
if (await storage.hasItem(key)) { if (await storage.hasItem(key)) {
return JSON.parse((await storage.getItem(key))!) as boolean return JSON.parse((await storage.getItem(key))!) as boolean
@ -29,3 +33,17 @@ export async function writeExpansionState(
key = `expansion-${key}.json` key = `expansion-${key}.json`
await storage.setItem(key, JSON.stringify(value)) 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)
}

View File

@ -3,9 +3,12 @@ import { setup, t } from "logseq-l10n"
import { render } from "preact" import { render } from "preact"
import { throttle } from "rambdax" import { throttle } from "rambdax"
import FavList from "./comps/FavList" import FavList from "./comps/FavList"
import { allExpansionKeys, removeExpansionState } from "./libs/storage"
import { hash, queryForSubItems, setLanguage, waitForEl } from "./libs/utils" import { hash, queryForSubItems, setLanguage, waitForEl } from "./libs/utils"
import zhCN from "./translations/zh-CN.json" import zhCN from "./translations/zh-CN.json"
const CLEAN_WAIT = 3000
let dragHandle: HTMLElement | null = null let dragHandle: HTMLElement | null = null
async function main() { async function main() {
@ -82,7 +85,17 @@ async function main() {
const graphOff = logseq.App.onCurrentGraphChanged(adjustLeftBarWidth) const graphOff = logseq.App.onCurrentGraphChanged(adjustLeftBarWidth)
await waitForEl("#left-sidebar .favorite-item", 1000) await waitForEl("#left-sidebar .favorite-item", 1000)
await processFavorites()
const readKeys = new Set<string>()
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() await adjustLeftBarWidth()
logseq.provideUI({ logseq.provideUI({
@ -184,19 +197,23 @@ function provideStyles() {
}) })
} }
async function processFavorites() { async function processFavorites(readKeys?: Set<string>) {
const favorites = parent.document.querySelectorAll<HTMLElement>( const favorites = parent.document.querySelectorAll<HTMLElement>(
`#left-sidebar .favorite-item`, `#left-sidebar .favorite-item`,
) )
for (const fav of favorites) { for (const fav of favorites) {
const items = await queryForSubItems(fav.dataset.ref!) const items = await queryForSubItems(fav.dataset.ref!)
if (items?.length > 0) { 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<string>,
) {
const key = `kef-ft-f-${await hash(el.dataset.ref!)}` const key = `kef-ft-f-${await hash(el.dataset.ref!)}`
const arrowContainer = el.querySelector("a")! const arrowContainer = el.querySelector("a")!
@ -214,7 +231,7 @@ async function injectList(el: HTMLElement, items: any[]) {
} }
setTimeout(() => { setTimeout(() => {
renderList(key, items, arrowContainer, el.dataset.ref!) renderList(key, items, arrowContainer, el.dataset.ref!, readKeys)
}, 0) }, 0)
} }
@ -223,10 +240,16 @@ function renderList(
items: any[], items: any[],
arrowContainer: HTMLElement, arrowContainer: HTMLElement,
name: string, name: string,
readKeys?: Set<string>,
) { ) {
const el = parent.document.getElementById(key)! const el = parent.document.getElementById(key)!
render( render(
<FavList items={items} arrowContainer={arrowContainer} name={name} />, <FavList
items={items}
arrowContainer={arrowContainer}
name={name}
readKeys={readKeys}
/>,
el, el,
) )
} }