feat(app): Workbench-Dock statt Zoom-Landkarte + bedienbare VNC-Konsole (0.2.2.0)

Cockpit neu gedacht — das Pinch-Zoom-Landkarten-Konzept war auf 5 Zoll fummelig:
- WorkspaceDeck + WorkspaceDock: Taskleiste unten (Chat · Code · Desktop),
  Ein-Tap-Panelwechsel im Daumenbereich, animierter Indikator, Aktivitaets-
  Badges (Code blau / Desktop gruen), Safe-Area, blendet bei offener Tastatur
  aus. Panels bildschirmfuellend + immer gemountet (kein Remount).
- noVNC bedienbar: novncHtml bekommt Tastatur-Bridge (verstecktes Input-Feld →
  rfb.sendKey inkl. Enter/Backspace/Pfeile), Strg-Alt-Entf, Fit↔1:1. VncTile
  zeigt eine Steuerungs-Leiste (⌨ / Strg+Alt+Entf / ⤢).
- Entfernt: WorkspaceCanvas, Tile, PreviewTile, CockpitOverviewButton,
  cockpitNav (Pinch-Canvas + Uebersichts-Button obsolet). layout.ts auf
  Panel-Metadaten geschlankt. Header nur noch mit Kompakt/Cockpit-Umschalter.

tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 21:44:32 +02:00
co-authored by Claude Opus 4.8
parent 7d46d8e531
commit 0110526622
14 changed files with 317 additions and 551 deletions
-43
View File
@@ -1,43 +0,0 @@
/**
* cockpitNav — kleine Brücke zwischen WorkspaceCanvas (Fokus-Zustand) und dem
* Navigations-Header, damit der „⤢ Übersicht"-Button im Header sitzen kann
* (kollidiert dort mit nichts im Chat) statt im überfüllten Chat-Inhalt.
*
* Der Canvas meldet, ob gerade eine Kachel fokussiert ist, und registriert eine
* Aktion zum Zurück-zur-Übersicht. Der Header abonniert den Zustand und ruft die
* Aktion. Muster wie services/rvs.ts (Singleton).
*/
type Sub = (focused: boolean) => void;
class CockpitNav {
private focused = false;
private overviewHandler: (() => void) | null = null;
private subs: Sub[] = [];
isFocused(): boolean { return this.focused; }
setFocused(f: boolean): void {
if (this.focused === f) return;
this.focused = f;
this.subs.forEach((cb) => cb(f));
}
/** Canvas registriert seine „zur Übersicht"-Aktion (null beim Unmount). */
registerOverview(fn: (() => void) | null): void {
this.overviewHandler = fn;
}
requestOverview(): void {
this.overviewHandler?.();
}
subscribe(cb: Sub): () => void {
this.subs.push(cb);
cb(this.focused);
return () => { this.subs = this.subs.filter((s) => s !== cb); };
}
}
const cockpitNav = new CockpitNav();
export default cockpitNav;