diff --git a/android/src/screens/ChatScreen.tsx b/android/src/screens/ChatScreen.tsx index 89dc5ef..d51ba29 100644 --- a/android/src/screens/ChatScreen.tsx +++ b/android/src/screens/ChatScreen.tsx @@ -73,6 +73,9 @@ interface ChatMessage { /** Projekt-Zuordnung — leer = Hauptchat. Wird genutzt um Bubbles zu * Projekt-Bloecken zu gruppieren (auf/einklappbar). */ projectId?: string; + /** Welcher Backend die Antwort erzeugt hat: 'local' | 'claude' | 'fast-path'. + * Fuer den optionalen Quell-Badge (Einstellung aria_show_source, default aus). */ + answeredBy?: string; /** Bridge-Message-ID zur Zuordnung von TTS-Audio */ messageId?: string; /** Lokaler Pfad zur gecachten TTS-Audio-Datei (file://...) */ @@ -324,6 +327,8 @@ const ChatScreen: React.FC = () => { // App soll sie standardmaessig NICHT anzeigen — Stefan sieht sonst // jeden Hint mit. Toggle in Settings. const [showSystemHints, setShowSystemHints] = useState(false); + // Quell-Badge (local/claude/fast-path) an ARIA-Bubbles — pro Geraet, default AUS. + const [showSource, setShowSource] = useState(false); // Gerätelokale XTTS-Voice-Wahl (bevorzugt gegenueber dem globalen Default) const localXttsVoiceRef = useRef(''); // Geraetelokale TTS-Wiedergabegeschwindigkeit (speed-Param an F5-TTS) @@ -546,6 +551,8 @@ const ChatScreen: React.FC = () => { setGpsEnabled(gps === 'true'); const hints = await AsyncStorage.getItem('aria_show_hints'); setShowSystemHints(hints === 'true'); // default false + const src = await AsyncStorage.getItem('aria_show_source'); + setShowSource(src === 'true'); // default false (Mama sieht keine Badges) }; loadSettings(); const interval = setInterval(loadSettings, 2000); @@ -815,6 +822,7 @@ const ChatScreen: React.FC = () => { attachments: attachments.length ? attachments : undefined, backupTs: typeof m.ts === 'number' ? m.ts : undefined, projectId: typeof m.project_id === 'string' ? m.project_id : '', + answeredBy: typeof m.answeredBy === 'string' ? m.answeredBy : '', ...(cmid && { clientMsgId: cmid }), // Server-Bubble = vom Brain verarbeitet → 'delivered' (✓✓) ...(role === 'user' && cmid && { deliveryStatus: 'delivered' as const }), @@ -1151,6 +1159,7 @@ const ChatScreen: React.FC = () => { messageId: (message.payload.messageId as string) || undefined, backupTs: (message.payload.backupTs as number) || undefined, projectId: ((message.payload as any).projectId as string) || '', + answeredBy: ((message.payload as any).answeredBy as string) || '', }; // ARIA hat geantwortet → alle User-Bubbles davor als 'delivered' // markieren (WhatsApp-Doppelhaken ✓✓). Brain hat sie verarbeitet. @@ -2411,6 +2420,16 @@ const ChatScreen: React.FC = () => { ) : null} {time} + {!isUser && showSource && item.answeredBy ? (() => { + const ab = item.answeredBy as string; + const map: { [k: string]: { t: string; c: string } } = { + local: { t: '⚡ lokal', c: '#34C759' }, + claude: { t: 'Claude', c: '#0096FF' }, + 'fast-path': { t: '⚡ fast', c: '#AF7BFF' }, + }; + const b = map[ab] || { t: ab, c: '#8A8AA0' }; + return {b.t}; + })() : null} {item.text.length > 0 ? ( { const [bgGpsEnabled, setBgGpsEnabled] = useState(false); const [backgroundMode, setBackgroundMode] = useState(true); // Default an const [showSystemHints, setShowSystemHints] = useState(false); // Default aus + const [showSource, setShowSource] = useState(false); // Quell-Badge, Default aus const [scannerVisible, setScannerVisible] = useState(false); const [logTab, setLogTab] = useState('live'); const [logs, setLogs] = useState([]); @@ -261,6 +262,9 @@ const SettingsScreen: React.FC = () => { // Default ist aus — nur explicit 'true' aktiviert setShowSystemHints(saved === 'true'); }); + AsyncStorage.getItem('aria_show_source').then(saved => { + setShowSource(saved === 'true'); // Default aus + }); // gpsTrackingService status syncen + auf Aenderungen lauschen setGpsTracking(gpsTrackingService.isActive()); const offGps = gpsTrackingService.onChange(setGpsTracking); @@ -857,6 +861,11 @@ const SettingsScreen: React.FC = () => { AsyncStorage.setItem('aria_show_hints', String(value)).catch(() => {}); }, []); + const handleShowSourceToggle = useCallback((value: boolean) => { + setShowSource(value); + AsyncStorage.setItem('aria_show_source', String(value)).catch(() => {}); + }, []); + // --- XTTS Voice --- const selectVoice = useCallback((voiceName: string) => { @@ -1580,6 +1589,22 @@ const SettingsScreen: React.FC = () => { thumbColor={showSystemHints ? '#FFFFFF' : '#666680'} /> + + + Antwort-Quelle anzeigen + + Kleiner Badge an ARIAs Bubbles: ob die Antwort vom schnellen + lokalen Modell, von Claude oder per Direkt-Befehl kam. Nur fuer + dich interessant (Technik) — standardmaessig aus. + + + + {/* === Hintergrund-Modus === */}