diff --git a/studio/frontend/src/app/provider.tsx b/studio/frontend/src/app/provider.tsx index 6f3c7618be..4bd348effc 100644 --- a/studio/frontend/src/app/provider.tsx +++ b/studio/frontend/src/app/provider.tsx @@ -48,11 +48,10 @@ async function applyAppWindowLayout(isCurrent: WindowLayoutGuard): Promise const win = getCurrentWindow(); // Decide first-launch vs restore from the on-disk state file BEFORE touching the - // window. Probing the window itself after restoreStateCurrent is unreliable: - // on GTK, set_size against a hidden window is deferred until show(), so - // innerSize() reads a stale value and any baseline fallback would overwrite the - // queued restore. On macOS the same probe works, hence the inconsistency - // between previous iterations of this code. + // window. Probing the window after restoreStateCurrent is unreliable: on GTK, + // set_size on a hidden window is deferred until show(), so innerSize() reads a + // stale value and a baseline fallback would overwrite the queued restore. On + // macOS the same probe works, hence the inconsistency between prior iterations. const hasSavedState = await invoke("has_saved_window_state"); if (!isCurrent()) return; @@ -60,9 +59,8 @@ async function applyAppWindowLayout(isCurrent: WindowLayoutGuard): Promise if (!isCurrent()) return; if (hasSavedState) { - // Subsequent launch: the plugin handles size, position, and maximized, - // with built-in off-screen protection (monitor-intersection check) for - // positions saved on a now-disconnected display. + // Subsequent launch: plugin restores size/position/maximized, with built-in + // off-screen protection for positions saved on a now-disconnected display. await restoreStateCurrent( StateFlags.SIZE | StateFlags.POSITION | StateFlags.MAXIMIZED, ); @@ -87,8 +85,8 @@ async function applyAppWindowLayout(isCurrent: WindowLayoutGuard): Promise if (!isCurrent()) return; await win.show(); if (!isCurrent()) return; - // Apply constraints after restore/show. Setting constraints before plugin restore - // can emit a Resized event and overwrite the plugin's cached saved size. + // Apply constraints after restore/show: doing so before plugin restore can emit + // a Resized event and overwrite the plugin's cached saved size. await win.setSizeConstraints({ minWidth: MIN_WINDOW_WIDTH, minHeight: MIN_WINDOW_HEIGHT }); } diff --git a/studio/frontend/src/app/routes/__root.tsx b/studio/frontend/src/app/routes/__root.tsx index da74a9e8a7..200200d190 100644 --- a/studio/frontend/src/app/routes/__root.tsx +++ b/studio/frontend/src/app/routes/__root.tsx @@ -55,8 +55,8 @@ function isChatOnlyAllowed(pathname: string): boolean { export const Route = createRootRoute({ beforeLoad: async ({ location }) => { - // Ensure platform info is fetched before checking chat-only guard. - // fetchDeviceType caches after first call, so subsequent navigations are instant. + // Fetch platform info before the chat-only guard. fetchDeviceType caches, + // so later navigations are instant. await fetchDeviceType(); const chatOnly = usePlatformStore.getState().isChatOnly(); if (chatOnly && !isChatOnlyAllowed(location.pathname)) { diff --git a/studio/frontend/src/app/routes/settings.tsx b/studio/frontend/src/app/routes/settings.tsx index fa97a450f7..84650bdb8b 100644 --- a/studio/frontend/src/app/routes/settings.tsx +++ b/studio/frontend/src/app/routes/settings.tsx @@ -7,10 +7,10 @@ import { useSettingsDialogStore } from "@/features/settings"; import { requireAuth } from "../auth-guards"; import { Route as rootRoute } from "./__root"; -// /settings is a deep link to the modal. Open it, then redirect home. -// Tab title is driven by useSettingsDialogStore in __root.tsx since the -// redirect means /settings never stays matched; staticData is just a -// safety net if beforeLoad ever stops throwing. +// /settings deep-links the modal: open it, then redirect home. Tab title is +// driven by useSettingsDialogStore in __root.tsx since the redirect means +// /settings never stays matched; staticData is a safety net if beforeLoad +// ever stops throwing. export const Route = createRoute({ getParentRoute: () => rootRoute, path: "/settings", diff --git a/studio/frontend/src/components/app-sidebar.tsx b/studio/frontend/src/components/app-sidebar.tsx index 941c2e8a74..8d56d90f98 100644 --- a/studio/frontend/src/components/app-sidebar.tsx +++ b/studio/frontend/src/components/app-sidebar.tsx @@ -138,11 +138,8 @@ function getTourId(pathname: string): string | null { return null; } -// Hugeicons' TestTube01Icon ships with two interior bubbles (paths #4 -// and #5 of the 5-path definition). Slicing to the first three paths -// keeps the test-tube outline + horizontal cap + liquid line, dropping -// the bubbles. The original export stays untouched, and HugeiconsIcon -// renders this trimmed array exactly the same way. +// TestTube01Icon's last 2 paths are interior bubbles; slice to the first +// 3 (outline + cap + liquid line) to drop them. Original export untouched. const TestTubeOutlineIcon = TestTube01Icon.slice( 0, 3, @@ -261,11 +258,11 @@ export function AppSidebar() { const scrollRef = useRef(null); const [scrolled, setScrolled] = useState(false); - // Bottom fade hides at the very bottom (and for short, non-scrolling lists) - // so the last row isn't washed out - Gemini-style. + // Bottom fade hides at the very bottom / for short lists so the last row + // isn't washed out (Gemini-style). const [canScrollDown, setCanScrollDown] = useState(false); - // Driven only from onScroll + a content-change effect below. Deliberately NO - // ResizeObserver: its callback-driven setState created a render loop (React + // Driven only from onScroll + a content-change effect below. No + // ResizeObserver: its callback-driven setState caused a render loop (React // #185). Both setters bail out when unchanged, so neither path can loop. const syncScrollState = (el: HTMLDivElement) => { const nextScrolled = el.scrollTop > 0; @@ -311,10 +308,9 @@ export function AppSidebar() { const selectedHistoryRunId = useTrainingRuntimeStore((s) => s.selectedHistoryRunId); const setSelectedHistoryRunId = useTrainingRuntimeStore((s) => s.setSelectedHistoryRunId); - // Recompute the bottom-fade state on mount and whenever the list height can - // change (items load, sections collapse/expand, route switches the visible - // list) - onScroll never fires for short, non-scrolling lists. Guarded - // setState below means this can't loop even if a dep is a fresh reference. + // Recompute bottom-fade on mount and whenever list height can change + // (items load, sections toggle, route switch) - onScroll never fires for + // short, non-scrolling lists. Guarded setState below can't loop. useEffect(() => { const el = scrollRef.current; if (!el) return; @@ -761,9 +757,8 @@ export function AppSidebar() { label={t("shell.navigation.search")} active={false} onClick={() => { - // Search is read-only over chat history and never runs - // inference, so it stays available while training (unlike - // New chat, which is gated on `chatDisabled`). + // Search is read-only and never runs inference, so it stays + // available while training (unlike New chat, gated on chatDisabled). useChatSearchStore.getState().open(); closeMobileIfOpen(); }} @@ -796,8 +791,7 @@ export function AppSidebar() { closeMobileIfOpen(); }} /> - {/* Train has its own labelled section when expanded; surface it as - a plain icon here only while the sidebar is collapsed. */} + {/* Train has a labelled section when expanded; plain icon here only when collapsed. */} {runItems.map((run) => { - // An explicit sidebar selection wins. Otherwise highlight - // the active job only while the "Current Run" tab is the - // view - that covers a live run (it auto-switches there) and - // a just-finished/errored run you're still viewing, while - // keeping the Configure tab unhighlighted even though - // `activeJobId` stays pinned to the last job. + // Explicit selection wins. Otherwise highlight the active + // job only while the "Current Run" tab is the view, keeping + // the Configure tab unhighlighted even though activeJobId + // stays pinned to the last job. const isActiveRun = selectedHistoryRunId != null ? run.id === selectedHistoryRunId @@ -988,10 +980,9 @@ export function AppSidebar() { - {/* Fade above the profile box, shown only while there's more list below - the fold; at the very bottom (or for short lists) it fades out so the - last row shows fully (Gemini-style). `right-2` keeps it clear of the - 8px scrollbar gutter so the scrollbar isn't faded out. */} + {/* Fade above the profile box, shown only when there's more list below + the fold; at the bottom (or short lists) it fades so the last row + shows fully (Gemini-style). right-2 keeps it clear of the 8px scrollbar gutter. */}