[eric] canvas: fullscreen locks canvas panning (drag joined the wheel gate), thirds cut from the tile menus, Applications window gets always-on search + image-only tiles (screenshot > symbol > svg, letters never)

This commit is contained in:
ciregenz
2026-08-09 13:27:26 -07:00
parent 3c2aeb8fa7
commit d050517c4e
3 changed files with 18 additions and 9 deletions
@@ -3,13 +3,12 @@
export const ZONE_LABELS: Record<string, string> = {
fill: 'Fill', left: 'Left half', right: 'Right half', top: 'Top half', bottom: 'Bottom half',
tl: 'Top left', tr: 'Top right', bl: 'Bottom left', br: 'Bottom right',
t3l: 'Left third', t3c: 'Center third', t3r: 'Right third',
};
// The one grid every tiling surface renders: the green-dot hover menu and the right-click "Tile to
// zone" submenu both map this, so they can never drift apart on which zones exist.
// zone" submenu both map this, so they can never drift apart on which zones exist. Thirds were cut
// (Eric 2026-08-09): the geometry still restores an old t3* card fine, the menus just stop offering it.
export const TILE_GROUPS: { label: string; zones: string[] }[] = [
{ label: 'Fill and halves', zones: ['fill', 'left', 'right', 'top', 'bottom'] },
{ label: 'Quarters', zones: ['tl', 'tr', 'bl', 'br'] },
{ label: 'Thirds', zones: ['t3l', 't3c', 't3r'] },
];
@@ -19,10 +19,11 @@ function hueFor(name: string): number {
return h % 360;
}
// Every tile is a generated ICON (gradient + monogram): a screenshot crushed to 68px reads as mud,
// so the screenshot lives in the hover preview instead and the row stays dock-uniform.
// Never letters or numbers on a tile (Eric 2026-08-09): the app's own screenshot is the icon; an
// emoji glyph (a real symbol, not an initial) is the next-best mark; the generic app SVG closes.
function AppTile({ output }: { output: Output }): React.ReactElement {
const glyph = (output.icon || '').trim();
const glyphIsSymbol = glyph.length > 0 && glyph.length <= 3 && !/[a-z0-9]/i.test(glyph);
const h = hueFor(output.name || '?');
return (
<Box
@@ -34,14 +35,20 @@ function AppTile({ output }: { output: Output }): React.ReactElement {
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
overflow: 'hidden',
boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.14), 0 6px 18px rgba(0,0,0,0.32)',
background: `linear-gradient(160deg, hsl(${h}, 42%, 52%), hsl(${(h + 24) % 360}, 48%, 34%))`,
fontSize: glyph && glyph.length <= 3 ? '1.5rem' : '1.375rem',
fontWeight: 590,
fontSize: '1.5rem',
color: 'rgba(255,255,255,0.94)',
}}
>
{glyph && glyph.length <= 3 ? glyph : (output.name || '?').trim().charAt(0).toUpperCase()}
{output.thumbnail ? (
<Box component="img" src={output.thumbnail} alt="" sx={{ width: '100%', height: '100%', objectFit: 'cover' }} />
) : glyphIsSymbol ? (
glyph
) : (
<GridViewRoundedIcon sx={{ fontSize: 30, color: 'rgba(255,255,255,0.92)' }} />
)}
</Box>
);
}
@@ -126,7 +133,7 @@ function ApplicationsWindow({ outputs, onOpenApp, onClose }: ApplicationsWindowP
)}
</Box>
{Object.keys(outputs).length > 8 && (
{Object.keys(outputs).length > 0 && (
<Box
component="input"
autoFocus
@@ -514,6 +514,9 @@ export function useCanvasControls(
// tree, not the DOM: without this guard their clicks started a canvas pan and the preventDefault
// killed input focus (the "can't click into the Add-connector fields" bug).
if (e.currentTarget instanceof Node && e.target instanceof Node && !e.currentTarget.contains(e.target)) return;
// Fullscreen has no canvas nav, period (same rule the wheel handler enforces): a drag that
// slipped past the fullscreen surface panned the hidden canvas underneath it.
if (selectFullscreenCardId(store.getState())) return;
e.preventDefault();
cancelAnimation();
cancelInertia();