summaryrefslogtreecommitdiffhomepage
path: root/src/features/workspaces/logic/view-model.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-09-07 16:12:58 +0900
committerAdam Malczewski <[email protected]>2026-09-07 16:12:58 +0900
commit83fb6e3ce7f80a9c287764df26b6245e0945a941 (patch)
treeafe8a0046b40a45a85f3bc56a4bcd4c93a6f36c7 /src/features/workspaces/logic/view-model.ts
parent754450b539818f9ad94c9586888973b0edd74b68 (diff)
downloaddispatch-web-83fb6e3ce7f80a9c287764df26b6245e0945a941.tar.gz
dispatch-web-83fb6e3ce7f80a9c287764df26b6245e0945a941.zip
feat(workspaces): rework tile-grid visuals — Start-screen polish
The home canvas now reads as a real Windows 8 Start screen instead of a cramped, edge-hugging list: - Geometry: the wide unit is DERIVED from the canvas height (4 rows fill it: unit=height/5 clamped to 112-184px, gap=unit/9, margin=unit/3 clamped 24-64px) — tiles are no longer tiny, and the tile field always carries a proportional outer margin (never compressed against the left edge). Tall mode keeps fluid columns with a taller 148px row + 12px gap. - Tiles take a per-workspace SATURATED tone (new pure tileTone(id): FNV-1a hash → one of the six theme-semantic colors) with tone-content text — the Win8 colored-tile identity. Starred is now a ★ badge (a tile keeps its own color), not a gray-tint override. - The tile face is the Win8 layout: small uppercase slug caption at the top, a bold span-aware title (lg → 3xl across 1×1 → 4×2), and a single-line stat row pinned to the bottom (count compacts to 'conv.' on 1×1 tiles, truncation-safe so narrow tiles never clip). - Selection is a high-contrast offset ring (visible on any tile color); tiles lift on hover; the pan arrow is a solid elevated circle. - Header gains a 'WORKSPACES' kicker; empty/loading states are centered and styled for the Start-screen canvas. Persisted data (order + spans only) and all interaction semantics (drag/FLIP, long-press, action bar, resize picker, create popover) are untouched. Tests: geometry derivation/clamping, tileTone determinism, wide-vs-compact count label — 1664 green.
Diffstat (limited to 'src/features/workspaces/logic/view-model.ts')
-rw-r--r--src/features/workspaces/logic/view-model.ts34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/features/workspaces/logic/view-model.ts b/src/features/workspaces/logic/view-model.ts
index b994b7c..0b9f239 100644
--- a/src/features/workspaces/logic/view-model.ts
+++ b/src/features/workspaces/logic/view-model.ts
@@ -6,6 +6,40 @@ import type { WorkspaceEntry } from "@dispatch/wire";
import type { Route } from "./route";
/**
+ * A home tile's color tone. Windows 8's Start screen gave every tile its own
+ * saturated color; here the tile's workspace id DETERMINISTICALLY picks one of
+ * the theme's six semantic tones, so the same workspace keeps its color across
+ * sessions and themes (the tone name maps to a DaisyUI color, which adapts to
+ * the active theme). Starred stays a separate visual concern (a badge), NOT a
+ * tone — any tile may be starred regardless of its color.
+ */
+export type TileTone = "primary" | "secondary" | "accent" | "info" | "success" | "warning";
+
+/** The tones a tile may take, in hash order. */
+const TILE_TONES: readonly TileTone[] = [
+ "primary",
+ "secondary",
+ "accent",
+ "info",
+ "success",
+ "warning",
+];
+
+/**
+ * Map a workspace id to its tile tone. Deterministic (FNV-1a hash of the id)
+ * and uniformly distributed across the six tones — pure: id in, tone out.
+ */
+export function tileTone(id: string): TileTone {
+ let hash = 0x811c9dc5;
+ for (let index = 0; index < id.length; index++) {
+ hash ^= id.charCodeAt(index);
+ // FNV prime (16777619), kept in 32-bit unsigned range.
+ hash = Math.imul(hash, 0x01000193) >>> 0;
+ }
+ return TILE_TONES[hash % TILE_TONES.length] ?? "primary";
+}
+
+/**
* The browser tab / page (`document.title`) text for a route. The home route
* (`/`) is "Dispatch"; a workspace route (`/<id>`) is "Dispatch: {title}",
* using the workspace's display title and falling back to the URL slug (`id`)