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
+15 -26
View File
@@ -1,13 +1,11 @@
/**
* WorkspaceScreen — Screen-Wrapper fuer den Workspace-Canvas.
* WorkspaceScreen — Screen-Wrapper fuer die Workbench.
*
* Buendelt die Signale, die entscheiden welche Kacheln sichtbar sind:
* - projectFocus: aktives Projekt + dessen kind ('code'|'chat')
* - codeFile: kam schon eine Code-Datei rein? (Live-Reveal des Editors)
* - desktop: ist ein QEMU-Desktop verfuegbar? (Live-Reveal der VNC-Kachel)
* Kompakt-Modus → klassischer Vollbild-Chat (wie vor dem Umbau).
* Cockpit-Modus → Workbench mit Taskleisten-Dock: Chat · Code · Desktop.
*
* Ersetzt den bisherigen Chat-Tab: die ChatScreen lebt als Kachel im Canvas,
* bleibt aber genau eine Instanz.
* Aktivitaets-Badges am Dock: Editor blau, wenn schon Code-Dateien da sind;
* Desktop gruen, wenn eine VM verbunden ist.
*/
import React, { useEffect, useMemo, useState } from 'react';
@@ -16,8 +14,10 @@ import codeFile from '../services/codeFile';
import desktop from '../services/desktop';
import viewMode, { ViewModeValue } from '../services/viewMode';
import ChatScreen from '../screens/ChatScreen';
import { TileId, TILE_ORDER } from './layout';
import WorkspaceCanvas from './WorkspaceCanvas';
import { TileId } from './layout';
import WorkspaceDeck from './WorkspaceDeck';
const COCKPIT_PANELS: TileId[] = ['chat', 'editor', 'vnc'];
const WorkspaceScreen: React.FC = () => {
const [mode, setMode] = useState<ViewModeValue>(viewMode.get());
@@ -47,29 +47,18 @@ const WorkspaceScreen: React.FC = () => {
return unsub;
}, [pid, kind]);
// Im Cockpit immer alle Kacheln zeigen (Editor/Desktop/Vorschau als
// Platzhalter, bis ein Code-Projekt/VM aktiv ist) — sonst „fehlen" sie
// gefuehlt. isCode blendet nur die Untertitel-Info um.
const visibleTiles: TileId[] = TILE_ORDER;
const isCode = kind === 'code' || hasCode || hasDesktop;
const subtitles = useMemo(() => {
const fileCount = codeFile.getFiles(pid).length;
return {
chat: pid ? projectFocus.getProjectName(pid) : 'Hauptchat',
editor: isCode ? `${fileCount} Datei${fileCount === 1 ? '' : 'en'}` : 'kein Code-Projekt',
vnc: hasDesktop ? 'verbunden' : 'kein Desktop',
preview: undefined,
} as Partial<Record<TileId, string>>;
}, [pid, focus.projectNameById, isCode, hasCode, hasDesktop]);
const badges = useMemo(() => ({
editor: hasCode ? '#0096FF' : undefined,
vnc: hasDesktop ? '#34C759' : undefined,
} as Partial<Record<TileId, string>>), [hasCode, hasDesktop]);
// Kompakt-Ansicht: klassischer Vollbild-Chat, exakt wie vor dem Umbau.
if (mode === 'compact') {
return <ChatScreen />;
}
// Cockpit: zoombarer Kachel-Desktop.
return <WorkspaceCanvas projectId={pid} visibleTiles={visibleTiles} subtitles={subtitles} />;
// Cockpit: Workbench mit Dock.
return <WorkspaceDeck projectId={pid} panels={COCKPIT_PANELS} badges={badges} />;
};
export default WorkspaceScreen;