fix(app): Cockpit — alle Kacheln sichtbar + Uebersicht-Button in den Header

Zwei Nachbesserungen am Cockpit-Modus (noch Teil von 0.2.1.9):
- Im Cockpit werden IMMER alle vier Kacheln gezeigt (Chat/Editor/Desktop/
  Vorschau) statt erst bei Code-Projekten — Editor/Desktop/Vorschau als
  Platzhalter mit Status-Untertitel. Vorher wirkten sie "verschwunden".
- Der "⤢ Uebersicht"-Button hing im Chat genau ueber dem Abbrechen-Button der
  "ARIA denkt"-Leiste. Jetzt sitzt er im Navigations-Header links (nur sichtbar
  im Cockpit + Fokus), via neuem cockpitNav-Signal-Singleton. In-Content-Button
  entfernt.

tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 14:46:49 +02:00
co-authored by Claude Opus 4.8
parent 9950cdea87
commit b839b059d0
6 changed files with 122 additions and 31 deletions
+12 -21
View File
@@ -17,13 +17,14 @@
*/
import React, { useEffect, useMemo, useState } from 'react';
import { BackHandler, StyleSheet, Text, TouchableOpacity, useWindowDimensions, View } from 'react-native';
import { BackHandler, StyleSheet, Text, useWindowDimensions, View } from 'react-native';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import {
boundsOf, Camera, focusCamera, overviewCamera, TileId, TILE_RECTS, toLocal,
} from './layout';
import cockpitNav from '../services/cockpitNav';
import Tile from './Tile';
import { useWorkspaceLayout } from './useWorkspaceLayout';
import ChatTile from './tiles/ChatTile';
@@ -96,6 +97,14 @@ const WorkspaceCanvas: React.FC<Props> = ({ projectId, visibleTiles, subtitles }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [focusedTileId, visibleKey, vw, vh]);
// Fokus-Zustand + „zur Uebersicht"-Aktion an den Header (cockpitNav) melden,
// damit der Uebersicht-Button dort sitzt (kollidiert nicht mit dem Chat).
useEffect(() => {
cockpitNav.setFocused(focusedTileId != null);
cockpitNav.registerOverview(() => setFocusedTileId(null));
return () => { cockpitNav.registerOverview(null); cockpitNav.setFocused(false); };
}, [focusedTileId]);
// Hardware-Back: im Fokus → zurueck zur Uebersicht.
useEffect(() => {
const onBack = () => {
@@ -188,12 +197,8 @@ const WorkspaceCanvas: React.FC<Props> = ({ projectId, visibleTiles, subtitles }
))}
</View>
{/* Steuerung */}
{focusedTileId && (
<TouchableOpacity style={styles.overviewBtn} onPress={() => setFocusedTileId(null)} activeOpacity={0.8}>
<Text style={styles.overviewBtnText}> Übersicht</Text>
</TouchableOpacity>
)}
{/* Steuerung — der „⤢ Übersicht"-Button sitzt im Header (cockpitNav),
nicht hier im Chat-Inhalt. */}
{!focusedTileId && (
<View style={styles.hintBar} pointerEvents="none">
<Text style={styles.hintText}>Kachel antippen zum Öffnen · 2 Finger: zoomen & schieben</Text>
@@ -206,20 +211,6 @@ const WorkspaceCanvas: React.FC<Props> = ({ projectId, visibleTiles, subtitles }
const styles = StyleSheet.create({
root: { flex: 1, backgroundColor: '#0D0D1A' },
world: { position: 'absolute', left: 0, top: 0 },
// Unten rechts (ueber der Chat-Eingabezeile) — weg von ChatScreens Kopf-Icons.
overviewBtn: {
position: 'absolute',
bottom: 88,
right: 14,
backgroundColor: 'rgba(18,18,42,0.92)',
borderColor: '#0096FF',
borderWidth: 1,
borderRadius: 18,
paddingHorizontal: 14,
paddingVertical: 8,
elevation: 4,
},
overviewBtnText: { color: '#0096FF', fontSize: 14, fontWeight: '700' },
hintBar: {
position: 'absolute',
bottom: 16,
+15 -9
View File
@@ -16,7 +16,7 @@ import codeFile from '../services/codeFile';
import desktop from '../services/desktop';
import viewMode, { ViewModeValue } from '../services/viewMode';
import ChatScreen from '../screens/ChatScreen';
import { TileId, visibleTilesFor } from './layout';
import { TileId, TILE_ORDER } from './layout';
import WorkspaceCanvas from './WorkspaceCanvas';
const WorkspaceScreen: React.FC = () => {
@@ -47,15 +47,21 @@ const WorkspaceScreen: React.FC = () => {
return unsub;
}, [pid, kind]);
const visibleTiles: TileId[] = useMemo(
() => visibleTilesFor({ kind, hasCode, hasDesktop }),
[kind, hasCode, hasDesktop],
);
// 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(
() => ({ chat: pid ? projectFocus.getProjectName(pid) : 'Hauptchat' } as Partial<Record<TileId, string>>),
[pid, focus.projectNameById],
);
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]);
// Kompakt-Ansicht: klassischer Vollbild-Chat, exakt wie vor dem Umbau.
if (mode === 'compact') {