feat(ui): SOS-Page LLM/TTS-Toggles raus + DemographicsAccordion FieldRow flex fix
- urge.tsx: TtsProviderToggle + LlmProviderToggle entfernt (Testing durch); Core-Logic (useTtsProvider, currentLlmProvider, BenchSession) bleibt für spätere Debug-Page intakt - DemographicsAccordion FieldRow: flex:1 auf Label-Text, kein flexShrink- Wrapper mehr nötig; Label+Input wrappen nicht mehr auf schmalen Devices Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
def21a220d
commit
e9a9bd8880
@ -30,9 +30,7 @@ import { CHIP_SETS, BREATH_PHASES, type ChipSet } from '../lib/sosConstants';
|
|||||||
import { parseLyraResponse, detectEmotion, type LyraEmotion, type ChipSpec } from '../lib/lyraResponse';
|
import { parseLyraResponse, detectEmotion, type LyraEmotion, type ChipSpec } from '../lib/lyraResponse';
|
||||||
import { streamSosLyra } from '../lib/sosStream';
|
import { streamSosLyra } from '../lib/sosStream';
|
||||||
import { SosTtsQueue } from '../lib/sosTtsQueue';
|
import { SosTtsQueue } from '../lib/sosTtsQueue';
|
||||||
import { endpointForProvider, useTtsProvider, currentProvider, type TtsProvider } from '../lib/ttsProvider';
|
import { endpointForProvider, useTtsProvider, currentProvider } from '../lib/ttsProvider';
|
||||||
import { TtsProviderToggle } from '../components/urge/TtsProviderToggle';
|
|
||||||
import { LlmProviderToggle } from '../components/urge/LlmProviderToggle';
|
|
||||||
import { currentLlmProvider } from '../lib/llmProvider';
|
import { currentLlmProvider } from '../lib/llmProvider';
|
||||||
import { BenchSession } from '../lib/sosTtsBenchmark';
|
import { BenchSession } from '../lib/sosTtsBenchmark';
|
||||||
|
|
||||||
@ -101,14 +99,13 @@ export default function SOSScreen() {
|
|||||||
|
|
||||||
useEffect(() => { soundEnabledRef.current = soundEnabled; }, [soundEnabled]);
|
useEffect(() => { soundEnabledRef.current = soundEnabled; }, [soundEnabled]);
|
||||||
|
|
||||||
// Aktueller TTS-Provider — currentProvider() liest immer den frischen Wert,
|
// ttsProvider state: Änderungen invalidieren den Atemübungs-Audio-Cache unten.
|
||||||
// ttsProvider state ist nur für UI-Re-Renders + cache-invalidation hier.
|
|
||||||
const [ttsProvider] = useTtsProvider();
|
const [ttsProvider] = useTtsProvider();
|
||||||
|
|
||||||
// Pre-cache der Atemübungs-Voice-Cues (Einatmen / Halten / Ausatmen).
|
// Pre-cache der Atemübungs-Voice-Cues (Einatmen / Halten / Ausatmen).
|
||||||
// Bei Phase-Wechsel im BreathingDrawer kommt das Audio sofort statt mit
|
// Bei Phase-Wechsel im BreathingDrawer kommt das Audio sofort statt mit
|
||||||
// ~600ms TTS-Roundtrip — so bleibt Voice synchron mit der Pulse-Animation.
|
// ~600ms TTS-Roundtrip — so bleibt Voice synchron mit der Pulse-Animation.
|
||||||
// Cache wird invalidiert wenn User den TTS-Provider wechselt.
|
// Cache wird invalidiert wenn der TTS-Provider wechselt.
|
||||||
const breathAudioCacheRef = useRef<Map<string, string>>(new Map());
|
const breathAudioCacheRef = useRef<Map<string, string>>(new Map());
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
breathAudioCacheRef.current.clear();
|
breathAudioCacheRef.current.clear();
|
||||||
@ -240,7 +237,6 @@ export default function SOSScreen() {
|
|||||||
const session = (await supabase.auth.getSession()).data.session;
|
const session = (await supabase.auth.getSession()).data.session;
|
||||||
if (controller.signal.aborted) return null;
|
if (controller.signal.aborted) return null;
|
||||||
const apiBase = Constants.expoConfig?.extra?.apiUrl as string;
|
const apiBase = Constants.expoConfig?.extra?.apiUrl as string;
|
||||||
// Endpoint folgt User-Provider-Toggle (TtsProviderToggle im SOS-Header).
|
|
||||||
const endpoint = endpointForProvider(currentProvider());
|
const endpoint = endpointForProvider(currentProvider());
|
||||||
const isGoogleCloud = endpoint.endsWith('/speak-google');
|
const isGoogleCloud = endpoint.endsWith('/speak-google');
|
||||||
const ttsRes = await fetch(`${apiBase}${endpoint}`, {
|
const ttsRes = await fetch(`${apiBase}${endpoint}`, {
|
||||||
@ -1125,11 +1121,6 @@ export default function SOSScreen() {
|
|||||||
</Pressable>
|
</Pressable>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={[st.ttsToggleBar, { top: topBarHeight - 36 }]} pointerEvents="box-none">
|
|
||||||
<TtsProviderToggle />
|
|
||||||
<LlmProviderToggle />
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{playingGame ? (
|
{playingGame ? (
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
<GameHeader game={playingGame} emotion={emotion} onBack={handleGameAbandon} />
|
<GameHeader game={playingGame} emotion={emotion} onBack={handleGameAbandon} />
|
||||||
@ -1298,7 +1289,6 @@ const st = StyleSheet.create({
|
|||||||
container: { flex: 1, backgroundColor: '#ffffff' },
|
container: { flex: 1, backgroundColor: '#ffffff' },
|
||||||
topBar: { position: 'absolute', left: 0, right: 0, zIndex: 10, flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'space-between', paddingHorizontal: 12 },
|
topBar: { position: 'absolute', left: 0, right: 0, zIndex: 10, flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'space-between', paddingHorizontal: 12 },
|
||||||
topBarBackdrop: { position: 'absolute', top: 0, left: 0, right: 0, zIndex: 9, backgroundColor: '#ffffff' },
|
topBarBackdrop: { position: 'absolute', top: 0, left: 0, right: 0, zIndex: 9, backgroundColor: '#ffffff' },
|
||||||
ttsToggleBar: { position: "absolute", left: 0, right: 0, zIndex: 11, alignItems: "center" },
|
|
||||||
actionBtn: { width: 40, height: 40, borderRadius: 20, backgroundColor: 'rgba(255,255,255,0.92)', alignItems: 'center', justifyContent: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.08, shadowRadius: 6, elevation: 4 },
|
actionBtn: { width: 40, height: 40, borderRadius: 20, backgroundColor: 'rgba(255,255,255,0.92)', alignItems: 'center', justifyContent: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.08, shadowRadius: 6, elevation: 4 },
|
||||||
avatarCenter: { flex: 1, alignItems: 'center', gap: 4 },
|
avatarCenter: { flex: 1, alignItems: 'center', gap: 4 },
|
||||||
avatarMeta: { alignItems: 'center', gap: 2 },
|
avatarMeta: { alignItems: 'center', gap: 2 },
|
||||||
|
|||||||
@ -454,6 +454,7 @@ function FieldRow({
|
|||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
|
flex: 1,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: colors.text,
|
color: colors.text,
|
||||||
fontFamily: 'Nunito_600SemiBold',
|
fontFamily: 'Nunito_600SemiBold',
|
||||||
@ -461,7 +462,7 @@ function FieldRow({
|
|||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</Text>
|
</Text>
|
||||||
<View style={{ flexShrink: 1 }}>{children}</View>
|
{children}
|
||||||
</View>
|
</View>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user