feat/ 添加app-expo三种环境切换,待测试 调整tts
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
import { Image } from 'expo-image';
|
||||
import { useLocalSearchParams } from 'expo-router';
|
||||
import { Mic, Pause, Play, PlusCircle, Type, X } from 'lucide-react-native';
|
||||
import {
|
||||
Mic,
|
||||
Pause,
|
||||
Play,
|
||||
PlusCircle,
|
||||
Type,
|
||||
Volume2,
|
||||
X,
|
||||
} from 'lucide-react-native';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
Alert,
|
||||
@@ -23,6 +31,7 @@ import { useThemeColors } from '@/hooks/use-theme-colors';
|
||||
import { useMessages, useRealtimeSession } from '@/features/conversation/hooks';
|
||||
import type { MessageItem } from '@/features/conversation/types';
|
||||
import { audioFocus } from '@/core/audio/audio-focus';
|
||||
import { usePlayer } from '@/features/voice/hooks/use-player';
|
||||
import { useRecorder } from '@/features/voice/hooks/use-recorder';
|
||||
import { useAudioPlayer, useAudioPlayerStatus } from 'expo-audio';
|
||||
|
||||
@@ -543,10 +552,12 @@ export default function ConversationScreen() {
|
||||
const { t } = useTranslation('conversation');
|
||||
const { t: tApp } = useTranslation('app');
|
||||
const { data: messages } = useMessages(id);
|
||||
const { enqueueTtsAudio, status: playerStatus } = usePlayer();
|
||||
const { connectionState, streamingMessage, sendText, sendVoiceMessage } =
|
||||
useRealtimeSession({
|
||||
conversationId: id,
|
||||
conversationId: id ?? '',
|
||||
enabled: !!id,
|
||||
onTtsAudio: enqueueTtsAudio,
|
||||
});
|
||||
|
||||
const handleRecordingComplete = useCallback(
|
||||
@@ -606,6 +617,14 @@ export default function ConversationScreen() {
|
||||
title={
|
||||
<View style={styles.headerTitleBlock}>
|
||||
<Text style={styles.headerTitle}>{tApp('name')}</Text>
|
||||
{playerStatus === 'playing' && (
|
||||
<Icon
|
||||
as={Volume2}
|
||||
size={18}
|
||||
color={CHAT_COLORS.primary}
|
||||
style={{ marginRight: 6 }}
|
||||
/>
|
||||
)}
|
||||
<View
|
||||
style={[
|
||||
styles.statusBadge,
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
const DEV_API_URL = 'http://127.0.0.1:8000';
|
||||
const DEV_WS_URL = 'ws://127.0.0.1:8000';
|
||||
|
||||
const PROD_API_URL = 'https://lifecho.worldsplats.com';
|
||||
const PROD_WS_URL = 'wss://lifecho.worldsplats.com';
|
||||
|
||||
const useProdServer = process.env.EXPO_PUBLIC_USE_PROD_SERVER === 'true';
|
||||
|
||||
export const config = {
|
||||
apiBaseUrl: useProdServer ? PROD_API_URL : DEV_API_URL,
|
||||
wsBaseUrl: useProdServer ? PROD_WS_URL : DEV_WS_URL,
|
||||
apiBaseUrl: process.env.EXPO_PUBLIC_API_URL ?? 'http://192.168.10.178:8000',
|
||||
wsBaseUrl: process.env.EXPO_PUBLIC_WS_URL ?? 'ws://192.168.10.178:8000',
|
||||
isDebugMode: __DEV__,
|
||||
|
||||
api: {
|
||||
|
||||
@@ -112,6 +112,7 @@ export function useEndConversation() {
|
||||
interface UseRealtimeSessionOptions {
|
||||
conversationId: string;
|
||||
enabled?: boolean;
|
||||
onTtsAudio?: (audioBase64: string) => void;
|
||||
}
|
||||
|
||||
const MIN_RECORDING_DURATION_SEC = 1;
|
||||
@@ -136,6 +137,7 @@ interface RealtimeSessionState {
|
||||
export function useRealtimeSession({
|
||||
conversationId,
|
||||
enabled = true,
|
||||
onTtsAudio,
|
||||
}: UseRealtimeSessionOptions): RealtimeSessionState {
|
||||
const queryClient = useQueryClient();
|
||||
const sessionRef = useRef<RealtimeSession | null>(null);
|
||||
@@ -168,6 +170,7 @@ export function useRealtimeSession({
|
||||
conversationId,
|
||||
queryClient,
|
||||
onStreamingText: handleStreamingText,
|
||||
onTtsAudio,
|
||||
onError: handleError,
|
||||
onStateChange: setConnectionState,
|
||||
});
|
||||
@@ -181,7 +184,7 @@ export function useRealtimeSession({
|
||||
setConnectionState('disconnected');
|
||||
setStreamingMessage(null);
|
||||
};
|
||||
}, [conversationId, enabled, queryClient, handleStreamingText, handleError]);
|
||||
}, [conversationId, enabled, queryClient, handleStreamingText, handleError, onTtsAudio]);
|
||||
|
||||
const sendText = useCallback(
|
||||
(text: string) => {
|
||||
|
||||
@@ -18,6 +18,7 @@ interface RealtimeSessionOptions {
|
||||
conversationId: string;
|
||||
queryClient: QueryClient;
|
||||
onStreamingText?: StreamingTextCallback;
|
||||
onTtsAudio?: (audioBase64: string) => void;
|
||||
onError?: ErrorCallback;
|
||||
onStateChange?: WsStateListener;
|
||||
}
|
||||
@@ -38,6 +39,7 @@ export class RealtimeSession {
|
||||
private conversationId: string;
|
||||
private queryClient: QueryClient;
|
||||
private onStreamingText?: StreamingTextCallback;
|
||||
private onTtsAudio?: (audioBase64: string) => void;
|
||||
private onError?: ErrorCallback;
|
||||
private unsubEvent: (() => void) | null = null;
|
||||
private unsubState: (() => void) | null = null;
|
||||
@@ -49,6 +51,7 @@ export class RealtimeSession {
|
||||
this.conversationId = options.conversationId;
|
||||
this.queryClient = options.queryClient;
|
||||
this.onStreamingText = options.onStreamingText;
|
||||
this.onTtsAudio = options.onTtsAudio;
|
||||
this.onError = options.onError;
|
||||
|
||||
this.unsubEvent = this.client.onEvent(this.handleEvent);
|
||||
@@ -117,6 +120,11 @@ export class RealtimeSession {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.kind === 'tts_audio_received') {
|
||||
this.onTtsAudio?.(event.audioBase64);
|
||||
return;
|
||||
}
|
||||
|
||||
handleWsEvent(this.queryClient, event);
|
||||
|
||||
if (event.kind === 'session_error') {
|
||||
|
||||
Reference in New Issue
Block a user