Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/web/src/components/LegacySidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ export const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThr
<span
aria-label={threadEnvironmentLabel ?? "Remote"}
className="inline-flex items-center justify-center"
data-legacy-sidebar-unscaled-content
/>
}
>
Expand Down Expand Up @@ -886,6 +887,7 @@ export const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThr
className={`text-[10px] tabular-nums ${
isHighlighted ? "text-foreground" : "text-secondary-label"
}`}
data-legacy-sidebar-unscaled-content
>
{formatRelativeTimeLabel(
thread.latestUserMessageAt ?? thread.updatedAt ?? thread.createdAt,
Expand Down Expand Up @@ -2292,7 +2294,7 @@ const SidebarProjectItem = memo(function SidebarProjectItem(props: SidebarProjec
>
<span className="absolute inset-0 flex items-center justify-center transition-opacity duration-150 group-hover/project-header:opacity-0">
<span
data-legacy-sidebar-unscaled-icon
data-legacy-sidebar-unscaled-content
className={`size-[9px] rounded-full ${projectStatus.dotClass} ${
projectStatus.pulse ? "animate-status-pulse" : ""
}`}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/ThreadStatusIndicators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export function ThreadStatusLabel({
}
>
<span
data-legacy-sidebar-unscaled-icon
data-legacy-sidebar-unscaled-content
className={`size-[9px] rounded-full ${status.dotClass} ${
status.pulse ? "animate-status-pulse" : ""
}`}
Expand All @@ -388,7 +388,7 @@ export function ThreadStatusLabel({
}
>
<span
data-legacy-sidebar-unscaled-icon
data-legacy-sidebar-unscaled-content
className={`h-1.5 w-1.5 rounded-full ${status.dotClass} ${
status.pulse ? "animate-status-pulse" : ""
}`}
Expand Down
12 changes: 6 additions & 6 deletions apps/web/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -488,17 +488,17 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
}

/* The original compact-sidebar patch changed row geometry and typography but
left favicons, action glyphs, and status glyphs at their stock dimensions.
left favicons, action/status glyphs, and thread metadata at stock dimensions.
Each scaled legacy-sidebar surface publishes the reciprocal of its row zoom
so icon descendants retain that behavior. */
so selected descendants retain that behavior. */
[data-legacy-sidebar-scale] :is(svg, img),
[data-legacy-sidebar-scale] [data-legacy-sidebar-unscaled-icon] {
zoom: var(--legacy-sidebar-icon-zoom);
[data-legacy-sidebar-scale] [data-legacy-sidebar-unscaled-content] {
zoom: var(--legacy-sidebar-content-zoom);
}

/* An explicitly unscaled icon container already supplies the reciprocal zoom;
/* An explicitly unscaled content container already supplies the reciprocal zoom;
do not apply it a second time to a nested SVG or image. */
[data-legacy-sidebar-scale] [data-legacy-sidebar-unscaled-icon] :is(svg, img) {
[data-legacy-sidebar-scale] [data-legacy-sidebar-unscaled-content] :is(svg, img) {
zoom: 1;
}

Expand Down
8 changes: 4 additions & 4 deletions apps/web/src/legacySidebarScale.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ describe("legacySidebarScaleStyle", () => {
it("leaves the stock sidebar geometry unchanged at 100%", () => {
expect(legacySidebarScaleStyle(100)).toEqual({
zoom: 1,
"--legacy-sidebar-icon-zoom": 1,
"--legacy-sidebar-content-zoom": 1,
});
});

it("renders the reference profile at 75% while keeping icons at stock size", () => {
it("renders the reference profile at 75% while keeping selected content at stock size", () => {
const style = legacySidebarScaleStyle(75);

expect(style.zoom).toBe(0.75);
expect(style["--legacy-sidebar-icon-zoom"]).toBeCloseTo(4 / 3);
expect(style["--legacy-sidebar-content-zoom"]).toBeCloseTo(4 / 3);
});

it("renders the minimum 50% scale", () => {
expect(legacySidebarScaleStyle(50)).toEqual({
zoom: 0.5,
"--legacy-sidebar-icon-zoom": 2,
"--legacy-sidebar-content-zoom": 2,
});
});
});
8 changes: 4 additions & 4 deletions apps/web/src/legacySidebarScale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import type { CSSProperties } from "react";
import type { LegacySidebarScale } from "@t3tools/contracts/settings";

type LegacySidebarScaleStyle = CSSProperties & {
"--legacy-sidebar-icon-zoom": number;
"--legacy-sidebar-content-zoom": number;
};

/**
* Scale the legacy project tree while preserving its layout and scroll bounds.
* CSS zoom participates in layout, so no inverse dimensions are needed. Icons
* use the reciprocal factor inside this surface to retain their stock size.
* CSS zoom participates in layout, so no inverse dimensions are needed. Selected
* content uses the reciprocal factor inside this surface to retain its stock size.
* Electron's window zoom is applied outside this element and composes with
* both factors.
*/
export function legacySidebarScaleStyle(scale: LegacySidebarScale): LegacySidebarScaleStyle {
const ratio = scale / 100;
return {
zoom: ratio,
"--legacy-sidebar-icon-zoom": 1 / ratio,
"--legacy-sidebar-content-zoom": 1 / ratio,
};
}
36 changes: 21 additions & 15 deletions docs/lastcode/legacy-sidebar-scaling-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ not affect the current sidebar or the mobile client.
- Use a range slider with whole-number values from 50% through 100%, a live numeric
output, and an explicitly labeled 75% reference tick.
- Treat the percentage as a geometric scale for project and thread row layout and
typography. Keep project favicons and action/status icons at their stock visual
size, matching the original console patch.
typography. Keep project favicons, action/status icons, remote cloud indicators,
and relative timestamps at their stock visual size, matching the original console
patch.
- Keep the LastCode header, Search field, Projects heading, drafts, status notices,
and footer at standard size. Apply layout-aware CSS zoom to each project header
and thread list while leaving sortable project containers unscaled, so the
Expand All @@ -41,11 +42,12 @@ not affect the current sidebar or the mobile client.
reset action, and client-settings update path. Reuse the existing settings-slider
styling and persistence rather than adding LastCode-specific IPC or storage.
3. Apply a layout-aware scaling surface to each rendered project header and thread
list. Derive its CSS zoom and reciprocal icon zoom from the persisted percentage
with a pure helper that can be tested independently. Keep the sortable project
item outside that surface so drag transforms use unscaled coordinates, and do not
place the header, Search field, Projects heading, drafts, notices, or footer
inside it.
list. Derive its CSS zoom and reciprocal content zoom from the persisted percentage
with a pure helper that can be tested independently. Apply reciprocal zoom to
favicons, action/status glyphs, remote cloud metadata, and relative timestamps.
Keep the sortable project item outside that surface so drag transforms use
unscaled coordinates, and do not place the header, Search field, Projects heading,
drafts, notices, or footer inside it.
4. Add focused tests for schema defaults and bounds, scale-style geometry, settings
search routing, and desktop client-settings persistence fixtures.
5. Update this plan with implementation and validation results before handoff.
Expand Down Expand Up @@ -82,8 +84,9 @@ not affect the current sidebar or the mobile client.
reset behavior, and a visible 75% reference tick.
- The setting affects only the legacy sidebar and updates it without an app restart.
- At 75%, legacy project and thread row layout and typography render at 0.75 scale
while project favicons, action/status icons, the header, Search field, Projects
heading, drafts, notices, and footer remain at standard size.
while project favicons, action/status icons, remote cloud indicators, relative
timestamps, the header, Search field, Projects heading, drafts, notices, and footer
remain at standard size.
- Electron's View zoom commands remain implemented solely by the existing main-window
zoom path and continue to compose with the sidebar scale.

Expand All @@ -102,9 +105,12 @@ The core feature shipped through LastCode PR #32:
merge commit `36d6ddef7`. The normal nightly mechanism published
`lastcode/revision/v0.0.34-nightly.20260817.1120.1` for installation.
- Follow-up QA on that revision found that the original console patch also kept
favicons and action/status icons at stock size. The follow-up branch publishes a
reciprocal icon zoom for SVG and image glyphs and explicitly unscales non-SVG
status dots while row geometry, action containers, and typography remain compact.
- Follow-up focused validation passes seven scale/status tests, the web typecheck,
the web production build, formatting, and `git diff --check`. Integrated nightly
QA and publication of the follow-up remain pending.
favicons and action/status icons at stock size. PR #35 added reciprocal zoom for
SVG and image glyphs and explicitly unscaled non-SVG status dots while row geometry,
action containers, and typography remain compact. Guarded merge commit `444dd7027`
was published as `lastcode/revision/v0.0.34-nightly.20260817.1120.4`.
- Subsequent QA found that the remote cloud metadata footprint and relative timestamp
still inherited the row scale. The content marker now covers those elements as well
as non-SVG status dots, while nested SVGs avoid double compensation. Focused scale
and status-indicator tests, the web typecheck, the production web build, formatting,
and diff checks pass for this follow-up.
10 changes: 5 additions & 5 deletions docs/user/thread-sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Open **Settings -> LastCode** and adjust **Scale legacy sidebar** from 50% throu
mark is labeled as a useful compact reference point. The default is 100%, and your selection is
stored locally and retained when LastCode restarts.

This setting compacts project headings and thread rows while keeping project favicons and action
or status icons at their standard size. The LastCode header, Search field, Projects heading,
drafts, status notices, and footer also stay at their standard size. On desktop, **View -> Actual
Size**, **Zoom In**, and **Zoom Out** continue to zoom the whole application and compose with the
legacy sidebar scale.
This setting compacts project headings and thread rows while keeping project favicons, action or
status icons, remote cloud indicators, and relative timestamps at their standard size. The
LastCode header, Search field, Projects heading, drafts, status notices, and footer also stay at
their standard size. On desktop, **View -> Actual Size**, **Zoom In**, and **Zoom Out** continue to
zoom the whole application and compose with the legacy sidebar scale.