Ezmary commited on
Commit
6f82055
·
verified ·
1 Parent(s): 329607b

Update src/App.tsx

Browse files
Files changed (1) hide show
  1. src/App.tsx +99 -36
src/App.tsx CHANGED
@@ -1,5 +1,3 @@
1
- // src/App.tsx
2
-
3
  /**
4
  Copyright 2024 Google LLC
5
  Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,24 +20,78 @@ import { isIOS } from "./lib/platform";
22
  import cn from "classnames";
23
  import { LiveConfig } from "./multimodal-live-types";
24
  import LogoAnimation from "./components/logo-animation/LogoAnimation";
25
- import BackButton from "./components/back-button/BackButton"; // <<-- ایمپورت کامپوننت جدید دکمه بازگشت
26
 
27
  const myCustomInstruction = `
28
- تو دستیار صوتی و تصویری پیشرفته از "اپلیکیشن هوش مصنوعی هوشان" هستی
29
- وظیفه اصلی تو کمک به کاربر است.
30
- همیشه و تحت هر شرایطی، فقط به زبان فارسی بسیار روان، دقیق و طبیعی و زیبا صحبت کن. در صورتی که کاربر با زبان دیگری نیز صحبت کرد میتونی با او زبان باهاش صحبت کنی و اگر صحبت کاربر انگلیسی بود همون انگلیسی بهش پاسخ بده یا فارسی بود همون فارسی یا مثلاً هر زبان دیگری.
31
- هرگز، به هیچ عنوان، خودت را به عنوان محصول ،open ai گوگل, مایکروسافت یا هر شرکت دیگری معرفی نکن. هویت تو تنها دستیار صوتی "اپلیکیشن هوش مصنوعی هوشان" است.
32
- تو یک مدل زبانی بزرگ هستی که توسط هوش مصنوعی هوشان توسعه داده شدی . به هیچ عنوان خودت رو محصول گوگل، مایکروسافت یا open ai نباید معرفی کنی حتی اگر کاربر از هر طریقی خواست تو فقط میگی من محصول هوش مصنوعی هوشان هستم نه گوگل، یا مایکروسافت یا نمی‌دونم شرکت دیگری.
33
- تو به تمام سوالات باید پاسخ دهی و در هر زمینه ای نباید به هیچ عنوان به هر پاسخ کاربر بگویی که من نمیتوانم این کار را انجام دهم یا نمیتوانم به شما کمک کنم
34
- هوش مصنوعی هوشانیک برنامه ای است که داخل گوشی موبایل نصب میشه و در کافه بازار در دسترس است و با جستجو در کافه بازار یا مایکت امکان دانلود هوش مصنوعی هوشان وجود دارد
35
- ......
36
- اگر کاربر خواست با صدای بلند تر صحبت کنی باید به درخواست کاربر حتما پاسخ بدهی، اگر کاربر خواست صدای متفاوت یا صدای هر چیزی یا صدای تقلید کنی باید درخواست کاربر اجرا کنی حتما، اگر کاربر خواست آروم صحبت کنی باید درخواست کاربر اجرا کنی، در هر شرایط باید درخواست کاربر اجرا بشه
37
- ....
38
- در تمام پاسخ‌ها، اعداد را نیز کاملاً به فارسی بیان کن مگر اینکه در حال صحبت به زبان دیگری غیر از فارسی با کاربر بودی به همون زبان اعداد بگو، و همچنین اعداد به فارسی درست بگو این حالت (مثلاً بگو 'ده' یا 'بیست و پنج'، نه '10' یا 'twenty-five').
39
- وقتی کاربر در مورد هویت تو می‌پرسد، خودت را اینگونه معرفی کن: "من دستیار صوتی و تصویری از برنامه هوش مصنوعی هوشان هستم. چگونه می‌توانم به شما کمک کنم؟"
40
- مهم: هنگامی که پیام ورودی فقط شامل متن "START_GREETING" بود، *فقط* با یک خوشامدگویی کوتاه و دوستانه به فارسی پاسخ بده، مانند "سلام، چطور می‌تونم کمکتون کنم؟" یا "سلام حالتون چطوره!
41
- هشدار: به هیچ عنوان در هنگام مکالمه و پیام دادن به کاربر نباید شکلک بفرستی و یا بیان کنی شکلک و یا اموجی هارو حتی شکلک هارو نیاز نیست بگی اسم شونو در هنگام صحبت اگر شکلک نیاز بود بود بگی نباید اسم شکلک بگی
42
- **مهم: به هیچ عنوان در پاسخ‌های خود از ایموجی استفاده نکن.**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  **تعامل تصویری:**
44
  - به تصویر زنده‌ای که از کاربر دریافت می‌کنی توجه کن.
45
  - اگر در تصویر نکته قابل توجهی وجود دارد (مانند حالت چهره، اشیاء خاص، یا محیط اطراف کاربر)، می‌توانی به آن در مکالمه اشاره کنی، البته فقط اگر مرتبط با موضوع صحبت باشد یا کاربر از تو بخواهد.
@@ -61,26 +113,32 @@ const SvgReferenceMicrophoneIcon = () => (
61
  </svg>
62
  );
63
 
64
- const AppInternalLogic: React.FC<{
65
  isMicActive: boolean;
66
  isCamActive: boolean;
67
  setIsMicActive: React.Dispatch<React.SetStateAction<boolean>>;
68
  setIsCamActive: React.Dispatch<React.SetStateAction<boolean>>;
69
  videoRef: React.RefObject<HTMLVideoElement>;
70
  notificationPopoverRef: React.RefObject<HTMLDivElement>;
71
- notificationButtonRef: React.RefObject<HTMLButtonElement>; // این ref برای دکمه نوتیفیکیشن است
72
  isNotificationOpen: boolean;
73
  setIsNotificationOpen: React.Dispatch<React.SetStateAction<boolean>>;
74
- }> = ({
 
 
 
 
75
  isMicActive,
76
  isCamActive,
77
  setIsMicActive,
78
  setIsCamActive,
79
  videoRef,
80
  notificationPopoverRef,
81
- notificationButtonRef, // دریافت ref
82
  isNotificationOpen,
83
- setIsNotificationOpen
 
 
84
  }) => {
85
  const { connected, disconnect } = useLiveAPIContext();
86
 
@@ -94,17 +152,15 @@ const AppInternalLogic: React.FC<{
94
  <div className="w-full flex flex-col items-center justify-center min-h-screen text-foreground antialiased">
95
  <div className="main-wrapper max-w-3xl w-full flex flex-col items-center justify-center h-full relative">
96
  <div className="header-controls">
97
- {/* دکمه بازگشت جدید (حالا سمت چپ) */}
98
  <div className="back-button-container">
99
- <BackButton /> {/* <<-- استفاده از کامپوننت جدید */}
100
  </div>
101
- {/* دکمه نوتیفیکیشن (حالا سمت راست) */}
102
  <div id="notification-trigger-container">
103
  <button
104
- ref={notificationButtonRef} // ref به این دکمه متصل است
105
  id="notification-button"
106
  aria-label="Notifications"
107
- className="header-button" // کلاس برای ظاهر مشابه
108
  onClick={(e) => {
109
  e.stopPropagation();
110
  setIsNotificationOpen(!isNotificationOpen);
@@ -129,6 +185,7 @@ const AppInternalLogic: React.FC<{
129
  </div>
130
  </div>
131
 
 
132
  <div className="media-area w-full flex flex-col items-center justify-center flex-grow relative">
133
  <video
134
  id="video-feed"
@@ -136,8 +193,9 @@ const AppInternalLogic: React.FC<{
136
  autoPlay
137
  playsInline
138
  className={cn(
139
- "absolute top-0 left-0 w-full h-full object-cover scale-x-[-1]",
140
- { "hidden": !isCamActive }
 
141
  )}
142
  />
143
  {isMicActive && !isCamActive && (
@@ -153,17 +211,21 @@ const AppInternalLogic: React.FC<{
153
  <ControlTray
154
  videoRef={videoRef}
155
  supportsVideo={true}
156
- onVideoStreamChange={(stream) => { /* ... */ }}
 
 
157
  isAppMicActive={isMicActive}
158
  onAppMicToggle={setIsMicActive}
159
  isAppCamActive={isCamActive}
160
  onAppCamToggle={setIsCamActive}
161
  ReferenceMicrophoneIcon={SvgReferenceMicrophoneIcon}
 
 
162
  />
163
  </div>
164
  </div>
165
  );
166
- }
167
 
168
  function App() {
169
  const videoRef = useRef<HTMLVideoElement>(null);
@@ -173,9 +235,8 @@ function App() {
173
  const [isMicActive, setIsMicActive] = useState(false);
174
  const [isCamActive, setIsCamActive] = useState(false);
175
  const [isNotificationOpen, setIsNotificationOpen] = useState(false);
 
176
 
177
- // ref برای دکمه نوتیفیکیشن باید در کامپوننت App تعریف شود
178
- // چون state مربوط به isNotificationOpen در App مدیریت می‌شود
179
  const notificationButtonRef = useRef<HTMLButtonElement>(null);
180
  const notificationPopoverRef = useRef<HTMLDivElement>(null);
181
 
@@ -206,7 +267,7 @@ function App() {
206
  return () => {
207
  document.removeEventListener("mousedown", handleClickOutside);
208
  };
209
- }, [isNotificationOpen]); // وابستگی به isNotificationOpen صحیح است
210
 
211
  if (isAllowedOrigin === null) {
212
  return <div style={{ padding: '20px', textAlign: 'center' }}>در حال بررسی دسترسی...</div>;
@@ -221,9 +282,11 @@ function App() {
221
  setIsCamActive={setIsCamActive}
222
  videoRef={videoRef}
223
  notificationPopoverRef={notificationPopoverRef}
224
- notificationButtonRef={notificationButtonRef} // پاس دادن ref به AppInternalLogic
225
  isNotificationOpen={isNotificationOpen}
226
  setIsNotificationOpen={setIsNotificationOpen}
 
 
227
  />
228
  <IOSModal isOpen={showIOSModal} onClose={() => setShowIOSModal(false)} />
229
  </LiveAPIProvider>
 
 
 
1
  /**
2
  Copyright 2024 Google LLC
3
  Licensed under the Apache License, Version 2.0 (the "License");
 
20
  import cn from "classnames";
21
  import { LiveConfig } from "./multimodal-live-types";
22
  import LogoAnimation from "./components/logo-animation/LogoAnimation";
23
+ import BackButton from "./components/back-button/BackButton";
24
 
25
  const myCustomInstruction = `
26
+ ت1. هویت دستیار:
27
+
28
+ فقط خود را به عنوان "دستیار صوتی و تصویری اپلیکیشن زبانفلای" معرفی کن.
29
+
30
+ هرگز خود را محصول یا زیرمجموعه گوگل، اپل یا هیچ شرکت دیگری معرفی نکن.
31
+
32
+ در پاسخ به سؤال کاربر درباره هویت، دقیقاً بگو:
33
+ "من دستیار صوتی و تصویری اپلیکیشن زبانفلای هستم. چگونه می‌توانم به شما کمک کنم؟"
34
+
35
+ مدیریت زبان گفتگو:
36
+
37
+ به طور پیش‌فرض�� مکالمه را به زبان انگلیسی آغاز کن.
38
+
39
+ اگر کاربر با زبانی غیر از انگلیسی صحبت کرد، گفتگو را به همان زبان ادامه بده.
40
+
41
+ زبان پاسخ را همیشه مطابق زبان کاربر تنظیم کن. تغییر زبان به صورت خودکار انجام شود.
42
+
43
+ بیان اعداد:
44
+
45
+ هنگام مکالمه به انگلیسی، اعداد را به صورت کامل به انگلیسی بیان کن (مثلاً: twenty-five).
46
+
47
+ هنگام مکالمه به زبانی دیگر، اعداد را به همان زبان بیان کن (مثلاً: بیست و پنج).
48
+
49
+ تنظیم صدا و لحن:
50
+
51
+ با صدای مایل به بلند و شفاف صحبت کن.
52
+
53
+ در صورت درخواست کاربر، صدای خود را بلندتر، آرام‌تر یا به تقلید از صدای خواسته‌شده تغییر بده.
54
+
55
+ بدون استثنا، هرگونه تغییر صدای درخواستی کاربر را اجرا کن.
56
+
57
+ تعهد به پاسخگویی:
58
+
59
+ تحت هیچ شرایطی به کاربر نگو که "نمی‌توانم پاسخ دهم" یا "نمی‌توانم کمک کنم".
60
+
61
+ همیشه در تمام زمینه‌ها تلاش کن بهترین پاسخ ممکن را به کاربر ارائه بدهی.
62
+
63
+ رفتار در شروع گفتگو:
64
+
65
+ اگر پیام ورودی "START_GREETING" دریافت شد، تنها با یکی از جملات کوتاه زیر پاسخ بده:
66
+
67
+ "Hello, how can I help you?"
68
+
69
+ یا "Hey, what's up?"
70
+
71
+ اطلاع‌رسانی درباره اپلیکیشن زبانفلای:
72
+
73
+ در صورت نیاز کاربر، توضیح بده که اپلیکیشن زبانفلای در گوگل پلی و کافه بازار قابل دانلود است.
74
+
75
+ راهنمایی کن که کاربران می‌توانند با جستجو در این فروشگاه‌ها، اپلیکیشن را نصب کنند.
76
+
77
+ پشتیبانی از یادگیری زبان:
78
+
79
+ هنگام پاسخگویی، در صورت مرتبط بودن، مثال‌های جمله‌سازی، کاربرد واژگان و اصطلاحات ارائه بده.
80
+
81
+ در صورت درخواست کاربر، معانی واژگان، هم‌معنی‌ها، متضادها، و نمونه جمله‌ها را هم ارائه بده.
82
+
83
+ تمرین شنیداری و گفتاری:
84
+
85
+ اگر کاربر بخواهد، جمله‌ای را بخوان و از او بخواه آن را تکرار کند (تمرین shadowing).
86
+
87
+ فرصت کامل برای تکرار بده و کاربر را با بازخورد مثبت تشویق کن.
88
+
89
+ شخصی‌سازی تجربه یادگیری:
90
+
91
+ در صورت درخواست کاربر، سرعت مکالمه را کند یا تند کن.
92
+
93
+ سطح سختی واژگان و جملات را بر اساس سطح کاربر (مبتدی، متوسط، پیشرفته) تنظیم کن.
94
+
95
  **تعامل تصویری:**
96
  - به تصویر زنده‌ای که از کاربر دریافت می‌کنی توجه کن.
97
  - اگر در تصویر نکته قابل توجهی وجود دارد (مانند حالت چهره، اشیاء خاص، یا محیط اطراف کاربر)، می‌توانی به آن در مکالمه اشاره کنی، البته فقط اگر مرتبط با موضوع صحبت باشد یا کاربر از تو بخواهد.
 
113
  </svg>
114
  );
115
 
116
+ interface AppInternalLogicProps {
117
  isMicActive: boolean;
118
  isCamActive: boolean;
119
  setIsMicActive: React.Dispatch<React.SetStateAction<boolean>>;
120
  setIsCamActive: React.Dispatch<React.SetStateAction<boolean>>;
121
  videoRef: React.RefObject<HTMLVideoElement>;
122
  notificationPopoverRef: React.RefObject<HTMLDivElement>;
123
+ notificationButtonRef: React.RefObject<HTMLButtonElement>;
124
  isNotificationOpen: boolean;
125
  setIsNotificationOpen: React.Dispatch<React.SetStateAction<boolean>>;
126
+ currentFacingMode: 'user' | 'environment';
127
+ onFacingModeChange: (mode: 'user' | 'environment') => void;
128
+ }
129
+
130
+ const AppInternalLogic: React.FC<AppInternalLogicProps> = ({
131
  isMicActive,
132
  isCamActive,
133
  setIsMicActive,
134
  setIsCamActive,
135
  videoRef,
136
  notificationPopoverRef,
137
+ notificationButtonRef,
138
  isNotificationOpen,
139
+ setIsNotificationOpen,
140
+ currentFacingMode,
141
+ onFacingModeChange,
142
  }) => {
143
  const { connected, disconnect } = useLiveAPIContext();
144
 
 
152
  <div className="w-full flex flex-col items-center justify-center min-h-screen text-foreground antialiased">
153
  <div className="main-wrapper max-w-3xl w-full flex flex-col items-center justify-center h-full relative">
154
  <div className="header-controls">
 
155
  <div className="back-button-container">
156
+ <BackButton />
157
  </div>
 
158
  <div id="notification-trigger-container">
159
  <button
160
+ ref={notificationButtonRef}
161
  id="notification-button"
162
  aria-label="Notifications"
163
+ className="header-button"
164
  onClick={(e) => {
165
  e.stopPropagation();
166
  setIsNotificationOpen(!isNotificationOpen);
 
185
  </div>
186
  </div>
187
 
188
+ {/* The .media-area should ideally take up the desired space for the video */}
189
  <div className="media-area w-full flex flex-col items-center justify-center flex-grow relative">
190
  <video
191
  id="video-feed"
 
193
  autoPlay
194
  playsInline
195
  className={cn(
196
+ "absolute top-0 left-0 w-full h-full object-cover", // <<-- بازگشت به object-cover
197
+ { "hidden": !isCamActive },
198
+ { "scale-x-[-1]": currentFacingMode === 'user' }
199
  )}
200
  />
201
  {isMicActive && !isCamActive && (
 
211
  <ControlTray
212
  videoRef={videoRef}
213
  supportsVideo={true}
214
+ onVideoStreamChange={(stream) => {
215
+ // Placeholder, actual logic might be in ControlTray
216
+ }}
217
  isAppMicActive={isMicActive}
218
  onAppMicToggle={setIsMicActive}
219
  isAppCamActive={isCamActive}
220
  onAppCamToggle={setIsCamActive}
221
  ReferenceMicrophoneIcon={SvgReferenceMicrophoneIcon}
222
+ currentFacingMode={currentFacingMode}
223
+ onFacingModeChange={onFacingModeChange}
224
  />
225
  </div>
226
  </div>
227
  );
228
+ };
229
 
230
  function App() {
231
  const videoRef = useRef<HTMLVideoElement>(null);
 
235
  const [isMicActive, setIsMicActive] = useState(false);
236
  const [isCamActive, setIsCamActive] = useState(false);
237
  const [isNotificationOpen, setIsNotificationOpen] = useState(false);
238
+ const [currentFacingMode, setCurrentFacingMode] = useState<'user' | 'environment'>('user');
239
 
 
 
240
  const notificationButtonRef = useRef<HTMLButtonElement>(null);
241
  const notificationPopoverRef = useRef<HTMLDivElement>(null);
242
 
 
267
  return () => {
268
  document.removeEventListener("mousedown", handleClickOutside);
269
  };
270
+ }, [isNotificationOpen]);
271
 
272
  if (isAllowedOrigin === null) {
273
  return <div style={{ padding: '20px', textAlign: 'center' }}>در حال بررسی دسترسی...</div>;
 
282
  setIsCamActive={setIsCamActive}
283
  videoRef={videoRef}
284
  notificationPopoverRef={notificationPopoverRef}
285
+ notificationButtonRef={notificationButtonRef}
286
  isNotificationOpen={isNotificationOpen}
287
  setIsNotificationOpen={setIsNotificationOpen}
288
+ currentFacingMode={currentFacingMode}
289
+ onFacingModeChange={setCurrentFacingMode}
290
  />
291
  <IOSModal isOpen={showIOSModal} onClose={() => setShowIOSModal(false)} />
292
  </LiveAPIProvider>