/** * WorkspaceDock — die Taskleiste unten (Daumenzone). Ein Tap wechselt sofort * das Panel; ein animierter Indikator gleitet unter das aktive Icon. Kleine * Aktivitaets-Punkte (Badges) zeigen z.B. „Desktop verbunden" / „Code da". * * Das ist der Kern des Workbench-Gefuehls: Desktop-Umfang, aber Handy-schnell * per Daumen erreichbar — statt einer Zoom-Landkarte. */ import React, { useState } from 'react'; import { LayoutChangeEvent, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { TileId, TILE_META } from './layout'; interface Props { panels: TileId[]; active: TileId; badges?: Partial>; // TileId → Punkt-Farbe (undefined = kein Punkt) onSelect: (id: TileId) => void; } const WorkspaceDock: React.FC = ({ panels, active, badges, onSelect }) => { const insets = useSafeAreaInsets(); const [rowW, setRowW] = useState(0); const n = Math.max(1, panels.length); const idx = Math.max(0, panels.indexOf(active)); const slot = rowW / n; const onLayout = (e: LayoutChangeEvent) => setRowW(e.nativeEvent.layout.width); const indicatorStyle = useAnimatedStyle(() => ({ width: slot, transform: [{ translateX: withTiming(slot * idx, { duration: 200 }) }], })); return ( {rowW > 0 && } {panels.map((id) => { const meta = TILE_META[id]; const isActive = id === active; const badge = badges?.[id]; return ( onSelect(id)} activeOpacity={0.7} > {meta.icon} {!!badge && } {meta.title} ); })} ); }; const styles = StyleSheet.create({ dock: { backgroundColor: '#0B0B18', borderTopWidth: 1, borderTopColor: '#1E1E2E', }, row: { flexDirection: 'row', height: 58, position: 'relative', }, indicator: { position: 'absolute', top: 0, height: 3, backgroundColor: '#0096FF', borderBottomLeftRadius: 3, borderBottomRightRadius: 3, }, item: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 2, }, icon: { fontSize: 22, opacity: 0.55 }, iconActive: { opacity: 1 }, label: { color: '#6A6A85', fontSize: 10, fontWeight: '600' }, labelActive: { color: '#0096FF' }, badge: { position: 'absolute', top: -2, right: -6, width: 8, height: 8, borderRadius: 4, borderWidth: 1, borderColor: '#0B0B18', }, }); export default WorkspaceDock;