refactor(workbench): drop per-card height and free-form resize

Height was practically unused — most WorkbenchSceneApp rows had
heightPx: undefined and scrolled internally, and the few explicit
values nobody ever revisited were just noise in the sync ledger.
Same goes for pixel-precise drag: users would produce widths like
823px and then never touch them again. Both paths come out in
favour of a fixed set of five width presets (next commit) that
guarantee cards sit on sensible sizes without a decision per card.

- types/workbench-scenes: heightPx removed from WorkbenchSceneApp
- page-carousel/types: heightPx removed from CarouselPage
- stores/workbench-scenes: resizeApp(appId, widthPx) loses its
  height param; patchScene allowlist no longer lists heightPx.
  Existing Dexie rows with heightPx set simply stop being read
  — the field ages out the next time the row is written.
- PageCarousel: placeholder renders width-only; comment updated
- AppPage: heightPx prop + onResize height param gone
- +page.svelte: carouselPages no longer carries heightPx, handler
  signature narrowed to (id, widthPx)

This commit removes the data; the next commit rewires PageShell's
UI so the drag handle is replaced by the five-preset picker.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-15 20:37:03 +02:00
parent bc77b36234
commit 681136266b
6 changed files with 14 additions and 25 deletions

View file

@ -119,9 +119,7 @@
{:else}
<div
class="page-placeholder"
style="width: {p.widthPx ?? defaultWidth}px;{p.heightPx
? ` height: ${p.heightPx}px;`
: ''}"
style="width: {p.widthPx ?? defaultWidth}px;"
aria-hidden="true"
></div>
{/if}
@ -179,11 +177,12 @@
align-items: center;
}
/* Sized stand-in for a not-yet-mounted card. Matches the card's
widthPx/heightPx so scroll position and the surrounding flex
layout stay stable while the IntersectionObserver decides which
cards to mount. Falls back to 60vh height when heightPx is
absent (the same minimum the empty state uses), which keeps the
track from collapsing on initial paint. */
widthPx so scroll position and the surrounding flex layout stay
stable while the IntersectionObserver decides which cards to
mount. Height falls back to 60vh (the same minimum the empty
state uses), which keeps the track from collapsing on initial
paint. Card bodies scroll internally — per-card heights were
dropped in favour of a single viewport-height policy. */
.page-placeholder {
min-height: 60vh;
border-radius: 1.25rem;

View file

@ -4,7 +4,6 @@ export interface CarouselPage {
id: string;
maximized?: boolean;
widthPx: number;
heightPx?: number;
title: string;
color: string;
icon?: Component;

View file

@ -15,11 +15,10 @@
interface Props {
appId: string;
widthPx: number;
heightPx?: number;
maximized?: boolean;
onClose: () => void;
onMaximize?: () => void;
onResize?: (widthPx: number, heightPx?: number) => void;
onResize?: (widthPx: number) => void;
onMoveLeft?: () => void;
onMoveRight?: () => void;
onContextMenu?: (e: MouseEvent) => void;
@ -28,7 +27,6 @@
let {
appId,
widthPx,
heightPx,
maximized = false,
onClose,
onMaximize,
@ -296,7 +294,6 @@
<!-- Base: PageShell with list view (always visible) -->
<PageShell
{widthPx}
{heightPx}
{maximized}
title={appName}
titleHref={`/${appId}`}

View file

@ -296,12 +296,8 @@ export const workbenchScenesStore = {
);
},
async resizeApp(appId: string, widthPx: number, heightPx?: number) {
await patchActiveScene((apps) =>
apps.map((a) =>
a.appId === appId ? { ...a, widthPx, ...(heightPx !== undefined ? { heightPx } : {}) } : a
)
);
async resizeApp(appId: string, widthPx: number) {
await patchActiveScene((apps) => apps.map((a) => (a.appId === appId ? { ...a, widthPx } : a)));
},
async moveAppLeft(appId: string) {

View file

@ -17,8 +17,8 @@ import type { WallpaperConfig } from '@mana/shared-theme';
export interface WorkbenchSceneApp {
appId: string;
maximized?: boolean;
/** Width preset in pixels. See PAGE_WIDTH_PRESETS for allowed values. */
widthPx?: number;
heightPx?: number;
}
/** A user-defined named layout of the workbench. */

View file

@ -106,7 +106,6 @@
id: a.appId,
maximized: a.maximized,
widthPx: a.widthPx ?? DEFAULT_WIDTH,
heightPx: a.heightPx,
title: appTitles.get(a.appId) ?? a.appId,
color: entry?.color ?? '#6B7280',
icon: entry?.icon,
@ -192,8 +191,8 @@
function handleMaximizeApp(id: string) {
workbenchScenesStore.toggleMaximizeApp(id);
}
function handleResize(id: string, widthPx: number, heightPx?: number) {
workbenchScenesStore.resizeApp(id, widthPx, heightPx);
function handleResize(id: string, widthPx: number) {
workbenchScenesStore.resizeApp(id, widthPx);
}
function handleMoveLeft(id: string) {
workbenchScenesStore.moveAppLeft(id);
@ -329,11 +328,10 @@
<AppPage
appId={p.id}
widthPx={p.widthPx}
heightPx={p.heightPx}
maximized={p.maximized}
onClose={() => handleRemoveApp(p.id)}
onMaximize={() => handleMaximizeApp(p.id)}
onResize={(w, h) => handleResize(p.id, w, h)}
onResize={(w) => handleResize(p.id, w)}
onMoveLeft={idx > 0 ? () => handleMoveLeft(p.id) : undefined}
onMoveRight={idx < openApps.length - 1 ? () => handleMoveRight(p.id) : undefined}
onContextMenu={(e) => handleCardContextMenu(e, p.id, idx)}