| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | import { autoAnimate } from "@formkit/auto-animate"; | 1 | import { autoAnimate } from "@formkit/auto-animate"; |
| 2 | import { useAtomValue } from "@effect/atom-react"; | 2 | import { useAtomValue } from "@effect/atom-react"; |
| | 3 | import * as Schema from "effect/Schema"; |
| 3 | import { | 4 | import { |
| 4 | DndContext, | 5 | DndContext, |
| 5 | PointerSensor, | 6 | PointerSensor, |
| ... | @@ -100,6 +101,7 @@ import { openCommandPalette } from "../commandPaletteBus"; | ... | @@ -100,6 +101,7 @@ import { openCommandPalette } from "../commandPaletteBus"; |
| 100 | import { startNewThreadFromContext } from "../lib/chatThreadActions"; | 101 | import { startNewThreadFromContext } from "../lib/chatThreadActions"; |
| 101 | import { useClientSettings } from "../hooks/useSettings"; | 102 | import { useClientSettings } from "../hooks/useSettings"; |
| 102 | import { useCopyToClipboard } from "../hooks/useCopyToClipboard"; | 103 | import { useCopyToClipboard } from "../hooks/useCopyToClipboard"; |
| | 104 | import { useLocalStorage } from "../hooks/useLocalStorage"; |
| 103 | import { useNowMinute } from "../hooks/useNowMinute"; | 105 | import { useNowMinute } from "../hooks/useNowMinute"; |
| 104 | import { useEnvironments, usePrimaryEnvironmentId } from "../state/environments"; | 106 | import { useEnvironments, usePrimaryEnvironmentId } from "../state/environments"; |
| 105 | import { useProjects, useThreadShells } from "../state/entities"; | 107 | import { useProjects, useThreadShells } from "../state/entities"; |
| ... | @@ -176,6 +178,9 @@ import { | ... | @@ -176,6 +178,9 @@ import { |
| 176 | // stays behind an explicit Show more. | 178 | // stays behind an explicit Show more. |
| 177 | const SETTLED_TAIL_INITIAL_COUNT = 10; | 179 | const SETTLED_TAIL_INITIAL_COUNT = 10; |
| 178 | const SETTLED_TAIL_PAGE_COUNT = 25; | 180 | const SETTLED_TAIL_PAGE_COUNT = 25; |
| | 181 | // Keep the v2 key so existing preferences survive the v2-to-default rename. |
| | 182 | const SETTLED_SHELF_EXPANDED_KEY = "t3code:sidebar-v2:settled-expanded"; |
| | 183 | const SNOOZED_SHELF_EXPANDED_KEY = "t3code:sidebar-v2:snoozed-expanded"; |
| 179 | | 184 | |
| 180 | function compactSidebarTimeLabel(label: string): string { | 185 | function compactSidebarTimeLabel(label: string): string { |
| 181 | if (label === "just now") return "now"; | 186 | if (label === "just now") return "now"; |
| ... | @@ -2044,8 +2049,15 @@ export default function Sidebar() { | ... | @@ -2044,8 +2049,15 @@ export default function Sidebar() { |
| 2044 | () => setSettledVisibleCount((count) => count + SETTLED_TAIL_PAGE_COUNT), | 2049 | () => setSettledVisibleCount((count) => count + SETTLED_TAIL_PAGE_COUNT), |
| 2045 | [], | 2050 | [], |
| 2046 | ); | 2051 | ); |
| 2047 | const [settledShelfExpanded, setSettledShelfExpanded] = useState(true); | 2052 | const [settledShelfExpanded, setSettledShelfExpanded] = useLocalStorage( |
| 2048 | const toggleSettledShelf = useCallback(() => setSettledShelfExpanded((value) => !value), []); | 2053 | SETTLED_SHELF_EXPANDED_KEY, |
| | 2054 | true, |
| | 2055 | Schema.Boolean, |
| | 2056 | ); |
| | 2057 | const toggleSettledShelf = useCallback( |
| | 2058 | () => setSettledShelfExpanded((value) => !value), |
| | 2059 | [setSettledShelfExpanded], |
| | 2060 | ); |
| 2049 | const renderedSettledThreads = useMemo(() => { | 2061 | const renderedSettledThreads = useMemo(() => { |
| 2050 | if (settledShelfExpanded) return visibleSettledThreads; | 2062 | if (settledShelfExpanded) return visibleSettledThreads; |
| 2051 | if (routeThreadKey === null) return []; | 2063 | if (routeThreadKey === null) return []; |
| ... | @@ -2059,8 +2071,15 @@ export default function Sidebar() { | ... | @@ -2059,8 +2071,15 @@ export default function Sidebar() { |
| 2059 | // The snoozed shelf is collapsed by default: out of the way, never gone. | 2071 | // The snoozed shelf is collapsed by default: out of the way, never gone. |
| 2060 | // Collapsed threads don't render (and so don't participate in jump | 2072 | // Collapsed threads don't render (and so don't participate in jump |
| 2061 | // shortcuts or multi-select), matching the settled tail's paging model. | 2073 | // shortcuts or multi-select), matching the settled tail's paging model. |
| 2062 | const [snoozedShelfExpanded, setSnoozedShelfExpanded] = useState(false); | 2074 | const [snoozedShelfExpanded, setSnoozedShelfExpanded] = useLocalStorage( |
| 2063 | const toggleSnoozedShelf = useCallback(() => setSnoozedShelfExpanded((value) => !value), []); | 2075 | SNOOZED_SHELF_EXPANDED_KEY, |
| | 2076 | false, |
| | 2077 | Schema.Boolean, |
| | 2078 | ); |
| | 2079 | const toggleSnoozedShelf = useCallback( |
| | 2080 | () => setSnoozedShelfExpanded((value) => !value), |
| | 2081 | [setSnoozedShelfExpanded], |
| | 2082 | ); |
| 2064 | const visibleSnoozedThreads = useMemo(() => { | 2083 | const visibleSnoozedThreads = useMemo(() => { |
| 2065 | if (snoozedShelfExpanded) return snoozedThreads; | 2084 | if (snoozedShelfExpanded) return snoozedThreads; |
| 2066 | // The open thread must never vanish behind the collapsed shelf: a | 2085 | // The open thread must never vanish behind the collapsed shelf: a |