Ezmary commited on
Commit
844f21c
·
verified ·
1 Parent(s): ad5b828

Update src/contexts/AppContext.tsx

Browse files
Files changed (1) hide show
  1. src/contexts/AppContext.tsx +33 -24
src/contexts/AppContext.tsx CHANGED
@@ -1,9 +1,11 @@
1
- // src/contexts/AppContext.tsx (نسخه نهایی با قابلیت شناسایی نام در همه شخصیت‌ها)
2
  import React, { createContext, FC, ReactNode, useContext, useEffect, useState, useCallback } from "react";
3
  import { useLiveAPI, type UseLiveAPIResults } from "../hooks/use-live-api";
4
  import { LiveConfig } from "../multimodal-live-types";
 
5
 
6
  const LS_SELECTED_PERSONALITY = 'app_selected_personality';
 
7
  const LS_CUSTOM_NAME = 'app_custom_name';
8
  const LS_CUSTOM_INSTRUCTIONS = 'app_custom_instructions';
9
 
@@ -12,7 +14,9 @@ export type PersonalityInstructions = Partial<Record<PersonalityType, string>>;
12
 
13
  interface AppContextType extends UseLiveAPIResults {
14
  selectedPersonality: PersonalityType;
 
15
  changePersonality: (personality: PersonalityType, customDetails?: { name: string, instructions: string }) => void;
 
16
  personalityInstructions: PersonalityInstructions;
17
  customUserName: string;
18
  customInstructions: string;
@@ -29,49 +33,44 @@ export const AppProvider: FC<{ children: ReactNode; initialConfig?: LiveConfig;
29
  const liveAPI = useLiveAPI({ url });
30
 
31
  const [selectedPersonality, setSelectedPersonality] = useState<PersonalityType>(() => (localStorage.getItem(LS_SELECTED_PERSONALITY) as PersonalityType) || 'default');
 
32
  const [customUserName, setCustomUserName] = useState<string>(() => localStorage.getItem(LS_CUSTOM_NAME) || '');
33
  const [customInstructions, setCustomInstructions] = useState<string>(() => localStorage.getItem(LS_CUSTOM_INSTRUCTIONS) || '');
34
  const [isRestarting, setIsRestarting] = useState(false);
35
 
36
  useEffect(() => {
37
- // ✅ START: منطق جدید و بهبود یافته برای ساخت دستورالعمل نهایی
38
-
39
- // بخش اول: دستورالعمل پایه و جهانی
40
  let instructionParts = [BASE_INSTRUCTION];
41
-
42
- // بخش دوم: اضافه کردن نام کاربر (اگر وجود داشته باشد) برای همه شخصیت‌ها
43
  if (customUserName) {
44
  instructionParts.push(`نام کاربر ${customUserName} است. او را با نامش صدا بزن.`);
45
  }
46
-
47
- // بخش سوم: اضافه کردن دستورالعمل مخصوص شخصیت انتخاب شده
48
  if (selectedPersonality === 'custom') {
49
- // اگر شخصیت اختصاصی بود، از دستورات کاربر استفاده کن
50
- if (customInstructions) {
51
- instructionParts.push(customInstructions);
52
- }
53
  } else {
54
- // برای سایر شخصیت‌ها، از دستورالعمل‌های تعریف شده استفاده کن
55
  const personalityPrompt = personalityInstructions[selectedPersonality];
56
- if (personalityPrompt) {
57
- instructionParts.push(personalityPrompt);
58
- }
59
  }
60
-
61
- // تمام بخش‌ها را با دو خط جدید از هم جدا می‌کنیم تا برای مدل خوانا باشد
62
  const finalInstruction = instructionParts.join('\n\n');
63
 
64
- // ✅ END: پایان منطق جدید
65
-
66
  const newConfig: LiveConfig = {
67
- model: initialConfig?.model || "gemini-2.5-flash-preview-native-audio-dialog",
 
68
  tools: [{ googleSearch: {} }],
69
- generationConfig: { responseModalities: "audio" },
 
 
 
 
 
 
 
 
 
 
70
  systemInstruction: { parts: [{ text: finalInstruction.trim() }] },
71
  };
72
  liveAPI.setConfig(newConfig);
73
 
74
- }, [selectedPersonality, customUserName, customInstructions, personalityInstructions, liveAPI.setConfig, initialConfig]);
75
 
76
  useEffect(() => {
77
  if (isRestarting && !liveAPI.connected) {
@@ -87,10 +86,18 @@ export const AppProvider: FC<{ children: ReactNode; initialConfig?: LiveConfig;
87
  setCustomUserName(customDetails.name);
88
  setCustomInstructions(customDetails.instructions);
89
  }
90
-
91
  localStorage.setItem(LS_SELECTED_PERSONALITY, newPersonality);
92
  setSelectedPersonality(newPersonality);
 
 
 
 
 
93
 
 
 
 
 
94
  if (liveAPI.connected) {
95
  setIsRestarting(true);
96
  liveAPI.disconnect();
@@ -100,7 +107,9 @@ export const AppProvider: FC<{ children: ReactNode; initialConfig?: LiveConfig;
100
  const contextValue: AppContextType = {
101
  ...liveAPI,
102
  selectedPersonality,
 
103
  changePersonality,
 
104
  personalityInstructions,
105
  customUserName,
106
  customInstructions,
 
1
+ // src/contexts/AppContext.tsx (نسخه نهایی با قابلیت انتخاب گوینده)
2
  import React, { createContext, FC, ReactNode, useContext, useEffect, useState, useCallback } from "react";
3
  import { useLiveAPI, type UseLiveAPIResults } from "../hooks/use-live-api";
4
  import { LiveConfig } from "../multimodal-live-types";
5
+ import { speakers } from '../data/speakers'; // <-- ایمپورت داده‌های گویندگان
6
 
7
  const LS_SELECTED_PERSONALITY = 'app_selected_personality';
8
+ const LS_SELECTED_VOICE = 'app_selected_voice'; // <-- کلید جدید برای ذخیره گوینده
9
  const LS_CUSTOM_NAME = 'app_custom_name';
10
  const LS_CUSTOM_INSTRUCTIONS = 'app_custom_instructions';
11
 
 
14
 
15
  interface AppContextType extends UseLiveAPIResults {
16
  selectedPersonality: PersonalityType;
17
+ selectedVoice: string;
18
  changePersonality: (personality: PersonalityType, customDetails?: { name: string, instructions: string }) => void;
19
+ changeVoice: (voiceId: string) => void;
20
  personalityInstructions: PersonalityInstructions;
21
  customUserName: string;
22
  customInstructions: string;
 
33
  const liveAPI = useLiveAPI({ url });
34
 
35
  const [selectedPersonality, setSelectedPersonality] = useState<PersonalityType>(() => (localStorage.getItem(LS_SELECTED_PERSONALITY) as PersonalityType) || 'default');
36
+ const [selectedVoice, setSelectedVoice] = useState<string>(() => localStorage.getItem(LS_SELECTED_VOICE) || speakers[0].id); // <-- State برای گوینده
37
  const [customUserName, setCustomUserName] = useState<string>(() => localStorage.getItem(LS_CUSTOM_NAME) || '');
38
  const [customInstructions, setCustomInstructions] = useState<string>(() => localStorage.getItem(LS_CUSTOM_INSTRUCTIONS) || '');
39
  const [isRestarting, setIsRestarting] = useState(false);
40
 
41
  useEffect(() => {
 
 
 
42
  let instructionParts = [BASE_INSTRUCTION];
 
 
43
  if (customUserName) {
44
  instructionParts.push(`نام کاربر ${customUserName} است. او را با نامش صدا بزن.`);
45
  }
 
 
46
  if (selectedPersonality === 'custom') {
47
+ if (customInstructions) instructionParts.push(customInstructions);
 
 
 
48
  } else {
 
49
  const personalityPrompt = personalityInstructions[selectedPersonality];
50
+ if (personalityPrompt) instructionParts.push(personalityPrompt);
 
 
51
  }
 
 
52
  const finalInstruction = instructionParts.join('\n\n');
53
 
 
 
54
  const newConfig: LiveConfig = {
55
+ // تغییر ۱: استفاده از مدل جدید
56
+ model: "models/gemini-2.5-flash-preview-native-audio-dialog",
57
  tools: [{ googleSearch: {} }],
58
+ // تغییر ۲: اضافه کردن تنظیمات صدا و گوینده
59
+ generationConfig: {
60
+ responseModalities: "audio",
61
+ speechConfig: {
62
+ voiceConfig: {
63
+ prebuiltVoiceConfig: {
64
+ voiceName: selectedVoice,
65
+ },
66
+ },
67
+ },
68
+ },
69
  systemInstruction: { parts: [{ text: finalInstruction.trim() }] },
70
  };
71
  liveAPI.setConfig(newConfig);
72
 
73
+ }, [selectedPersonality, selectedVoice, customUserName, customInstructions, personalityInstructions, liveAPI.setConfig, initialConfig]);
74
 
75
  useEffect(() => {
76
  if (isRestarting && !liveAPI.connected) {
 
86
  setCustomUserName(customDetails.name);
87
  setCustomInstructions(customDetails.instructions);
88
  }
 
89
  localStorage.setItem(LS_SELECTED_PERSONALITY, newPersonality);
90
  setSelectedPersonality(newPersonality);
91
+ if (liveAPI.connected) {
92
+ setIsRestarting(true);
93
+ liveAPI.disconnect();
94
+ }
95
+ }, [liveAPI.connected, liveAPI.disconnect]);
96
 
97
+ // ✅ تغییر ۳: تابع جدید برای تغییر گوینده
98
+ const changeVoice = useCallback((voiceId: string) => {
99
+ localStorage.setItem(LS_SELECTED_VOICE, voiceId);
100
+ setSelectedVoice(voiceId);
101
  if (liveAPI.connected) {
102
  setIsRestarting(true);
103
  liveAPI.disconnect();
 
107
  const contextValue: AppContextType = {
108
  ...liveAPI,
109
  selectedPersonality,
110
+ selectedVoice,
111
  changePersonality,
112
+ changeVoice,
113
  personalityInstructions,
114
  customUserName,
115
  customInstructions,