New sidebar and folder view (#263)

This commit is contained in:
Gregory Schier
2025-10-15 13:46:57 -07:00
committed by GitHub
parent 19c1efc73e
commit 267cd079ad
80 changed files with 2974 additions and 1450 deletions

View File

@@ -1,43 +1,29 @@
import { keyValuesAtom } from '@yaakapp-internal/models';
import { useCallback, useEffect, useState } from 'react';
import { atom, useAtomValue } from 'jotai';
import { useCallback } from 'react';
import { atomWithKVStorage } from '../lib/atoms/atomWithKVStorage';
import { jotaiStore } from '../lib/jotai';
import { setKeyValue } from '../lib/keyValueStore';
import { activeWorkspaceIdAtom } from './useActiveWorkspace';
import { getKeyValue } from './useKeyValue';
function kvKey(workspaceId: string | null) {
return ['sidebar_collapsed', workspaceId ?? 'n/a'];
}
export function useSidebarItemCollapsed(itemId: string) {
const [isCollapsed, setIsCollapsed] = useState<boolean>(
getSidebarCollapsedMap()[itemId] === true,
);
useEffect(
() =>
jotaiStore.sub(keyValuesAtom, () => {
setIsCollapsed(getSidebarCollapsedMap()[itemId] === true);
}),
[itemId],
);
export const sidebarCollapsedAtom = atom((get) => {
const workspaceId = get(activeWorkspaceIdAtom);
return atomWithKVStorage<Record<string, boolean>>(kvKey(workspaceId), {});
});
const toggle = useCallback(() => {
setKeyValue({
key: kvKey(jotaiStore.get(activeWorkspaceIdAtom)),
namespace: 'no_sync',
value: { ...getSidebarCollapsedMap(), [itemId]: !isCollapsed },
}).catch(console.error);
}, [isCollapsed, itemId]);
export function useSidebarItemCollapsed(itemId: string) {
const map = useAtomValue(useAtomValue(sidebarCollapsedAtom));
const isCollapsed = map[itemId] === true;
const toggle = useCallback(() => toggleSidebarItemCollapsed(itemId), [itemId]);
return [isCollapsed, toggle] as const;
}
export function getSidebarCollapsedMap() {
const value = getKeyValue<Record<string, boolean>>({
key: kvKey(jotaiStore.get(activeWorkspaceIdAtom)),
fallback: {},
namespace: 'no_sync',
export function toggleSidebarItemCollapsed(itemId: string) {
jotaiStore.set(jotaiStore.get(sidebarCollapsedAtom), (prev) => {
return { ...prev, [itemId]: !prev[itemId] };
});
return value;
}