Spaces:
Running
Running
Download src/store/useLibraryStore.ts from mrfakename/flow: direct link, hf CLI and curl.
- Browser
- Download file 3.06 kB
-
https://huggingface.co/spaces/mrfakename/flow/resolve/main/src/store/useLibraryStore.ts
- Command line
-
hf download hf://spaces/mrfakename/flow/src/store/useLibraryStore.ts
-
curl -L -o useLibraryStore.ts https://huggingface.co/spaces/mrfakename/flow/resolve/main/src/store/useLibraryStore.ts
3.06 kB
| import { create } from "zustand"; | |
| import { prefs } from "../lib/prefs"; | |
| const KEY = "gr-canvas-library"; | |
| interface LibraryState { | |
| /** Def types pinned to the top of the library, in display order. */ | |
| pinned: string[]; | |
| /** Def types hidden from the library. */ | |
| hidden: string[]; | |
| /** Collapsed section keys. */ | |
| collapsed: string[]; | |
| showHidden: boolean; | |
| /** Whether the full node tree is unfolded under the favourites in the sidebar. */ | |
| allOpen: boolean; | |
| setAllOpen: (v: boolean) => void; | |
| pin: (type: string) => void; | |
| unpin: (type: string) => void; | |
| movePinned: (type: string, toIndex: number) => void; | |
| hide: (type: string) => void; | |
| unhide: (type: string) => void; | |
| toggleSection: (key: string) => void; | |
| setShowHidden: (v: boolean) => void; | |
| /** Drops prefs for defs that no longer exist (e.g. a removed Space). */ | |
| forget: (predicate: (type: string) => boolean) => void; | |
| reset: () => void; | |
| } | |
| /** First visit: a couple of favourites so the sidebar is not empty. */ | |
| const DEFAULT_PINNED = ["in:text", "in:image"]; | |
| function load(): Pick<LibraryState, "pinned" | "hidden" | "collapsed" | "allOpen"> { | |
| try { | |
| const raw = prefs.get(KEY); | |
| if (raw) { | |
| const p = JSON.parse(raw); | |
| return { pinned: p.pinned ?? [], hidden: p.hidden ?? [], collapsed: p.collapsed ?? [], allOpen: !!p.allOpen }; | |
| } | |
| } catch { | |
| /* ignore */ | |
| } | |
| return { pinned: DEFAULT_PINNED, hidden: [], collapsed: [], allOpen: false }; | |
| } | |
| const without = (xs: string[], x: string) => xs.filter((y) => y !== x); | |
| export const useLibraryStore = create<LibraryState>((set) => ({ | |
| ...load(), | |
| showHidden: false, | |
| setAllOpen: (allOpen) => set({ allOpen }), | |
| pin: (t) => set((s) => ({ pinned: [...without(s.pinned, t), t], hidden: without(s.hidden, t) })), | |
| unpin: (t) => set((s) => ({ pinned: without(s.pinned, t) })), | |
| movePinned: (t, to) => | |
| set((s) => { | |
| const from = s.pinned.indexOf(t); | |
| if (from < 0) return {}; | |
| const next = without(s.pinned, t); | |
| next.splice(Math.max(0, Math.min(to > from ? to - 1 : to, next.length)), 0, t); | |
| return { pinned: next }; | |
| }), | |
| hide: (t) => set((s) => ({ hidden: [...without(s.hidden, t), t], pinned: without(s.pinned, t) })), | |
| unhide: (t) => set((s) => ({ hidden: without(s.hidden, t) })), | |
| toggleSection: (k) => set((s) => ({ collapsed: s.collapsed.includes(k) ? without(s.collapsed, k) : [...s.collapsed, k] })), | |
| setShowHidden: (v) => set({ showHidden: v }), | |
| forget: (pred) => set((s) => ({ pinned: s.pinned.filter((t) => !pred(t)), hidden: s.hidden.filter((t) => !pred(t)) })), | |
| reset: () => set({ pinned: [], hidden: [], collapsed: [] }), | |
| })); | |
| /** Re-reads prefs (after state.json was loaded). */ | |
| export const rehydrateLibrary = () => useLibraryStore.setState(load()); | |
| useLibraryStore.subscribe((s) => { | |
| try { | |
| prefs.set(KEY, JSON.stringify({ pinned: s.pinned, hidden: s.hidden, collapsed: s.collapsed, allOpen: s.allOpen })); | |
| } catch { | |
| /* ignore */ | |
| } | |
| }); | |
| export const isPinned = (t: string) => useLibraryStore.getState().pinned.includes(t); | |