feat: record expansion state

This commit is contained in:
Seth 2023-10-30 17:12:16 +08:00
parent b13fcf9742
commit cfc98167a7
4 changed files with 86 additions and 10 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "logseq-plugin-favorite-tree", "name": "logseq-plugin-favorite-tree",
"version": "1.0.6", "version": "1.1.0",
"main": "dist/index.html", "main": "dist/index.html",
"logseq": { "logseq": {
"id": "_sethyuan-logseq-favorite-tree", "id": "_sethyuan-logseq-favorite-tree",

View File

@ -1,23 +1,38 @@
import { produce } from "immer" import { produce } from "immer"
import { createPortal } from "preact/compat" import { createPortal } from "preact/compat"
import { useEffect, useState } from "preact/hooks" import { useEffect, useRef, useState } from "preact/hooks"
import { cls } from "reactutils" import { cls } from "reactutils"
import {
readExpansionState,
readRootExpansionState,
writeExpansionState,
writeRootExpansionState,
} from "../libs/storage"
import { queryForSubItems } from "../libs/utils" import { queryForSubItems } from "../libs/utils"
import FavArrow from "./FavArrow" import FavArrow from "./FavArrow"
export default function FavList({ export default function FavList({
items, items,
arrowContainer, arrowContainer,
name,
}: { }: {
items: any[] items: any[]
arrowContainer: HTMLElement arrowContainer: HTMLElement
name: string
}) { }) {
const [expanded, setExpanded] = useState(false) const [expanded, setExpanded] = useState(false)
useEffect(() => {
;(async () => {
setExpanded(await readRootExpansionState(name))
})()
}, [name])
function toggleList(e: Event) { function toggleList(e: Event) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
setExpanded((v) => !v) setExpanded((v) => !v)
writeRootExpansionState(name, !expanded)
} }
return ( return (
@ -26,13 +41,22 @@ export default function FavList({
<FavArrow expanded={expanded} onToggle={toggleList} />, <FavArrow expanded={expanded} onToggle={toggleList} />,
arrowContainer, arrowContainer,
)} )}
<SubList items={items} shown={expanded} /> <SubList items={items} shown={expanded} storageKey={name} />
</> </>
) )
} }
function SubList({ items, shown }: { items: any[]; shown: boolean }) { function SubList({
items,
shown,
storageKey,
}: {
items: any[]
shown: boolean
storageKey: string
}) {
const [childrenData, setChildrenData] = useState<any>(null) const [childrenData, setChildrenData] = useState<any>(null)
const expansionState = useRef<Record<string, boolean>>()
useEffect(() => { useEffect(() => {
setChildrenData(null) setChildrenData(null)
@ -41,19 +65,23 @@ function SubList({ items, shown }: { items: any[]; shown: boolean }) {
useEffect(() => { useEffect(() => {
if (shown && childrenData == null) { if (shown && childrenData == null) {
;(async () => { ;(async () => {
expansionState.current = await readExpansionState(storageKey)
const data: any = {} const data: any = {}
for (const item of items) { for (const item of items) {
if (item.filters) { if (item.filters) {
if (item.subitems) { if (item.subitems) {
data[item.displayName] = { data[item.displayName] = {
expanded: false, expanded: !!expansionState.current[item.displayName],
items: Object.values(item.subitems), items: Object.values(item.subitems),
} }
} }
} else { } else {
const subitems = await queryForSubItems(item["original-name"]) const subitems = await queryForSubItems(item["original-name"])
if (subitems?.length > 0) { if (subitems?.length > 0) {
data[item.name] = { expanded: false, items: subitems } data[item.name] = {
expanded: !!expansionState.current[item.name],
items: subitems,
}
} }
} }
} }
@ -106,6 +134,11 @@ function SubList({ items, shown }: { items: any[]; shown: boolean }) {
draft[itemName].expanded = !draft[itemName].expanded draft[itemName].expanded = !draft[itemName].expanded
}) })
setChildrenData(newChildrenData) setChildrenData(newChildrenData)
if (expansionState.current) {
expansionState.current[itemName] = !childrenData[itemName].expanded
writeExpansionState(storageKey, expansionState.current)
}
} }
function preventSideEffect(e: Event) { function preventSideEffect(e: Event) {
@ -154,7 +187,11 @@ function SubList({ items, shown }: { items: any[]; shown: boolean }) {
)} )}
</div> </div>
{data?.items?.length > 0 && ( {data?.items?.length > 0 && (
<SubList items={data.items} shown={data.expanded} /> <SubList
items={data.items}
shown={data.expanded}
storageKey={`${storageKey}-${displayName}`}
/>
)} )}
</div> </div>
) )

31
src/libs/storage.ts Normal file
View File

@ -0,0 +1,31 @@
const storage = logseq.Assets.makeSandboxStorage()
export async function readExpansionState(key: string) {
key = `expansion-${key}.json`
const str = (await storage.hasItem(key))
? (await storage.getItem(key))!
: "{}"
return JSON.parse(str) as Record<string, boolean>
}
export async function readRootExpansionState(key: string) {
key = `expansion-_${key}.json`
if (await storage.hasItem(key)) {
return JSON.parse((await storage.getItem(key))!) as boolean
} else {
return false
}
}
export async function writeRootExpansionState(key: string, value: boolean) {
key = `expansion-_${key}.json`
await storage.setItem(key, `${value}`)
}
export async function writeExpansionState(
key: string,
value: Record<string, boolean>,
) {
key = `expansion-${key}.json`
await storage.setItem(key, JSON.stringify(value))
}

View File

@ -214,13 +214,21 @@ async function injectList(el: HTMLElement, items: any[]) {
} }
setTimeout(() => { setTimeout(() => {
renderList(key, items, arrowContainer) renderList(key, items, arrowContainer, el.dataset.ref!)
}, 0) }, 0)
} }
function renderList(key: string, items: any[], arrowContainer: HTMLElement) { function renderList(
key: string,
items: any[],
arrowContainer: HTMLElement,
name: string,
) {
const el = parent.document.getElementById(key)! const el = parent.document.getElementById(key)!
render(<FavList items={items} arrowContainer={arrowContainer} />, el) render(
<FavList items={items} arrowContainer={arrowContainer} name={name} />,
el,
)
} }
async function onTransaction({ blocks, txData, txMeta }: any) { async function onTransaction({ blocks, txData, txMeta }: any) {