History

Optimize sidebar sorting and favicon reuse

- Avoid cloning thread arrays before sorting - Cache loaded project favicons across sidebar renders - Update sidebar sort labels for clearer wording

Julius Marminge committed 7 months ago

Commit d9ef0ca1 parent eac49092 files · +15 −10Browse files

Unified · Split

2 files
  1. apps/web/src/components/Sidebar.logic.ts +1 −1
  2. apps/web/src/components/Sidebar.tsx +14 −9
apps/web/src/components/Sidebar.logic.ts+1−1
@@ -224,7 +224,7 @@ export function getThreadSortTimestamp( · 223 unmodified lines
224224 export function sortThreadsForSidebar<
225225 T extends Pick<Thread, "id" | "createdAt" | "updatedAt" | "messages">,
226226 >(threads: readonly T[], sortOrder: SidebarThreadSortOrder): T[] {
227− return [...threads].toSorted((left, right) => {
227+ return threads.toSorted((left, right) => {
228228 const byTimestamp =
229229 getThreadSortTimestamp(right, sortOrder) - getThreadSortTimestamp(left, sortOrder);
230230 if (byTimestamp !== 0) return byTimestamp;
apps/web/src/components/Sidebar.tsx+14−9
@@ -105,17 +105,18 @@ const EMPTY_KEYBINDINGS: ResolvedKeybindingsConfig = []; · 104 unmodified lines
105105 const THREAD_PREVIEW_LIMIT = 6;
106106 const SIDEBAR_SORT_LABELS: Record<SidebarProjectSortOrder, string> = {
107107 updated_at: "Last user message",
108− created_at: "Created",
108+ created_at: "Created at",
109109 manual: "Manual",
110110 };
111111 const SIDEBAR_THREAD_SORT_LABELS: Record<SidebarThreadSortOrder, string> = {
112112 updated_at: "Last user message",
113− created_at: "Created",
113+ created_at: "Created at",
114114 };
115115 const SIDEBAR_LIST_ANIMATION_OPTIONS = {
116116 duration: 180,
117117 easing: "ease-out",
118118 } as const;
119+const loadedProjectFaviconSrcs = new Set<string>();
119120
120121 function formatRelativeTime(iso: string): string {
121122 const diff = Date.now() - new Date(iso).getTime();
@@ -226,9 +227,10 @@ function getServerHttpOrigin(): string { · 104 unmodified lines
226227 const serverHttpOrigin = getServerHttpOrigin();
227228
228229 function ProjectFavicon({ cwd }: { cwd: string }) {
229− const [status, setStatus] = useState<"loading" | "loaded" | "error">("loading");
230−
231230 const src = `${serverHttpOrigin}/api/project-favicon?cwd=${encodeURIComponent(cwd)}`;
231+ const [status, setStatus] = useState<"loading" | "loaded" | "error">(() =>
232+ loadedProjectFaviconSrcs.has(src) ? "loaded" : "loading",
233+ );
232234
233235 if (status === "error") {
234236 return <FolderIcon className="size-3.5 shrink-0 text-muted-foreground/50" />;
@@ -239,7 +241,10 @@ function ProjectFavicon({ cwd }: { cwd: string }) { · 4 unmodified lines
239241 src={src}
240242 alt=""
241243 className={`size-3.5 shrink-0 rounded-sm object-contain ${status === "loading" ? "hidden" : ""}`}
242− onLoad={() => setStatus("loaded")}
244+ onLoad={() => {
245+ loadedProjectFaviconSrcs.add(src);
246+ setStatus("loaded");
247+ }}
243248 onError={() => setStatus("error")}
244249 />
245250 );
@@ -275,7 +280,7 @@ function ProjectSortMenu({ · 29 unmodified lines
275280 </Tooltip>
276281 <MenuPopup align="end" side="bottom" className="min-w-44">
277282 <MenuGroup>
278− <div className="px-2 py-1 text-[11px] font-medium text-muted-foreground">
283+ <div className="px-2 py-1 sm:text-xs font-medium text-muted-foreground">
279284 Sort projects
280285 </div>
281286 <MenuRadioGroup
@@ -286,7 +291,7 @@ function ProjectSortMenu({ · 4 unmodified lines
286291 >
287292 {(Object.entries(SIDEBAR_SORT_LABELS) as Array<[SidebarProjectSortOrder, string]>).map(
288293 ([value, label]) => (
289− <MenuRadioItem key={value} value={value} className="min-h-7 py-1 text-xs">
294+ <MenuRadioItem key={value} value={value} className="min-h-7 py-1 sm:text-xs">
290295 {label}
291296 </MenuRadioItem>
292297 ),
@@ -294,7 +299,7 @@ function ProjectSortMenu({ · 1 unmodified line
294299 </MenuRadioGroup>
295300 </MenuGroup>
296301 <MenuGroup>
297− <div className="px-2 pt-2 pb-1 text-[11px] font-medium text-muted-foreground">
302+ <div className="px-2 pt-2 pb-1 sm:text-xs font-medium text-muted-foreground">
298303 Sort threads
299304 </div>
300305 <MenuRadioGroup
@@ -306,7 +311,7 @@ function ProjectSortMenu({ · 5 unmodified lines
306311 {(
307312 Object.entries(SIDEBAR_THREAD_SORT_LABELS) as Array<[SidebarThreadSortOrder, string]>
308313 ).map(([value, label]) => (
309− <MenuRadioItem key={value} value={value} className="min-h-7 py-1 text-xs">
314+ <MenuRadioItem key={value} value={value} className="min-h-7 py-1 sm:text-xs">
310315 {label}
311316 </MenuRadioItem>
312317 ))}