/** * WorkspaceScreen — Screen-Wrapper fuer den Workspace-Canvas. * * 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) * * Ersetzt den bisherigen Chat-Tab: die ChatScreen lebt als Kachel im Canvas, * bleibt aber genau eine Instanz. */ import React, { useEffect, useMemo, useState } from 'react'; import projectFocus, { FocusSnapshot } from '../services/projectFocus'; 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'; const WorkspaceScreen: React.FC = () => { const [mode, setMode] = useState(viewMode.get()); const [focus, setFocus] = useState(projectFocus.get()); const [hasCode, setHasCode] = useState(false); const [hasDesktop, setHasDesktop] = useState(false); useEffect(() => viewMode.subscribe(setMode), []); useEffect(() => projectFocus.subscribe(setFocus), []); const pid = focus.focusedProjectId; const kind = projectFocus.getProjectKind(pid); // Code-Signal: hat der Spiegel schon Dateien fuer dieses Projekt? useEffect(() => { setHasCode(codeFile.getFiles(pid).length > 0); return codeFile.subscribe((u) => { if ((u.projectId || '') === (pid || '')) setHasCode(true); }); }, [pid]); // Desktop-Signal + einmaliger Check beim Betreten eines Code-Projekts. useEffect(() => { setHasDesktop(desktop.getStatus().available); const unsub = desktop.subscribeStatus((s) => setHasDesktop(s.available)); if (kind === 'code') desktop.requestCheck(pid); 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>; }, [pid, focus.projectNameById, isCode, hasCode, hasDesktop]); // Kompakt-Ansicht: klassischer Vollbild-Chat, exakt wie vor dem Umbau. if (mode === 'compact') { return ; } // Cockpit: zoombarer Kachel-Desktop. return ; }; export default WorkspaceScreen;