feat: record expansion state
This commit is contained in:
parent
b13fcf9742
commit
cfc98167a7
@ -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",
|
||||||
|
|||||||
@ -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
31
src/libs/storage.ts
Normal 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))
|
||||||
|
}
|
||||||
@ -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) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user