Ezmary commited on
Commit
cb7916c
·
verified ·
1 Parent(s): 8b4e354

Update src/components/control-tray/ControlTray.tsx

Browse files
src/components/control-tray/ControlTray.tsx CHANGED
@@ -18,7 +18,7 @@ import { AudioRecorder } from "../../lib/audio-recorder";
18
  // آیکون توقف (Pause) - برای زمانی که میکروفون فعال است
19
  const SvgPauseIcon = () => <svg width="37" height="37" viewBox="0 0 37 37" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.9872 29.6198V8.28342C15.9872 6.25781 15.132 5.44757 12.9713 5.44757H7.52469C5.36404 5.44757 4.50879 6.25781 4.50879 8.28342V29.6198C4.50879 31.6454 5.36404 32.4556 7.52469 32.4556H12.9713C15.132 32.4556 15.9872 31.6454 15.9872 29.6198Z" fill="#BE123C"/><path opacity="0.4" d="M31.5175 29.6198V8.28342C31.5175 6.25781 30.6622 5.44757 28.5016 5.44757H23.055C20.9093 5.44757 20.0391 6.25781 20.0391 8.28342V29.6198C20.0391 31.6454 20.8943 32.4556 23.055 32.4556H28.5016C30.6622 32.4556 31.5175 31.6454 31.5175 29.6198Z" fill="#BE123C"/></svg>;
20
 
21
- // آیکون دوربین
22
  const SvgCameraIcon = () => <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path opacity="0.4" d="M21.8118 5.52235H11.9265C6.29183 5.52235 4.10059 7.7136 4.10059 13.3482V26.5286C4.10059 30.318 6.16002 34.3545 11.9265 34.3545H21.8118C27.4464 34.3545 29.6376 32.1633 29.6376 26.5286V13.3482C29.6376 7.7136 27.4464 5.52235 21.8118 5.52235Z" fill="#2252A0"/><path d="M19.3406 18.9169C21.0512 18.9169 22.438 17.5302 22.438 15.8195C22.438 14.1089 21.0512 12.7222 19.3406 12.7222C17.6299 12.7222 16.2432 14.1089 16.2432 15.8195C16.2432 17.5302 17.6299 18.9169 19.3406 18.9169Z" fill="#2252A0"/><path d="M36.0629 10.3332C35.3874 9.98721 33.9705 9.5918 32.0429 10.9428L29.6045 12.6562C29.621 12.8869 29.6374 13.1011 29.6374 13.3482V26.5286C29.6374 26.7758 29.6045 26.9899 29.6045 27.2206L32.0429 28.934C33.0643 29.659 33.954 29.8896 34.6625 29.8896C35.2721 29.8896 35.7499 29.7249 36.0629 29.5601C36.7384 29.2141 37.8752 28.275 37.8752 25.919V13.9743C37.8752 11.6183 36.7384 10.6792 36.0629 10.3332Z" fill="#2252A0"/></svg>;
23
 
24
  // آیکون توقف دوربین
@@ -36,7 +36,7 @@ export type ControlTrayProps = {
36
  isAppCamActive: boolean;
37
  onAppCamToggle: (active: boolean) => void;
38
  createLogoFunction: (isMini: boolean, isActive: boolean, type?: 'human' | 'ai', forFooter?: boolean) => ReactNode;
39
- ReferenceMicrophoneIcon: () => JSX.Element; // آیکون میکروفون از App.tsx
40
  };
41
 
42
  const ControlTray: React.FC<ControlTrayProps> = ({
@@ -48,7 +48,7 @@ const ControlTray: React.FC<ControlTrayProps> = ({
48
  isAppCamActive,
49
  onAppCamToggle,
50
  createLogoFunction,
51
- ReferenceMicrophoneIcon, // دریافت آیکون صحیح
52
  }) => {
53
  const { client, connected, connect } = useLiveAPIContext();
54
  const [audioRecorder] = useState(() => new AudioRecorder());
@@ -129,7 +129,6 @@ const ControlTray: React.FC<ControlTrayProps> = ({
129
  }
130
  }, [activeLocalVideoStream, videoRef]);
131
 
132
-
133
  const ensureConnectedAndReady = async (): Promise<boolean> => {
134
  if (!connected) {
135
  try { await connect(); return true; }
@@ -168,7 +167,7 @@ const ControlTray: React.FC<ControlTrayProps> = ({
168
  if (isSwitchingCamera) return;
169
  const newCamState = !isAppCamActive;
170
 
171
- if (newCamState) {
172
  if (!(await ensureConnectedAndReady())) {
173
  onAppCamToggle(false);
174
  return;
@@ -177,12 +176,11 @@ const ControlTray: React.FC<ControlTrayProps> = ({
177
  onAppMicToggle(true);
178
  }
179
  onAppCamToggle(true);
180
- } else {
181
  onAppCamToggle(false);
182
  }
183
  };
184
 
185
-
186
  const handleSwitchCamera = async () => {
187
  if (!isAppCamActive || !activeLocalVideoStream || isSwitchingCamera) return;
188
  setIsSwitchingCamera(true);
@@ -203,32 +201,31 @@ const ControlTray: React.FC<ControlTrayProps> = ({
203
  } finally { setIsSwitchingCamera(false); }
204
  };
205
 
206
- // چیدمان و کلاس‌ها بر اساس HTML مرجع (میکروفون چپ، دوربین راست)
207
  return (
208
  <footer id="footer-controls" className="footer-controls-html-like">
209
  <canvas style={{ display: "none" }} ref={renderCanvasRef} />
210
 
211
- {/* Mic Button (Left in HTML) */}
212
  <div
213
- id="mic-button" // ID از HTML
214
- className="control-button mic-button-color" // کلاس‌ها از HTML
215
  onClick={handleMicToggle}
216
  >
217
  {isAppMicActive ? <SvgPauseIcon /> : <ReferenceMicrophoneIcon />}
218
  </div>
219
 
220
- {/* Small Logo Container - Visible when Cam is Active (and Mic is also implicitly active as per logic) */}
221
- {isAppCamActive && ( // شرط نمایش لوگوی کوچک: فقط وقتی دوربین فعال است
222
  <div id="small-logo-footer-container" className="small-logo-footer-html-like">
223
  {createLogoFunction(true, true, 'human', true)}
224
  </div>
225
  )}
226
 
227
- {/* Cam Button Wrapper (Right in HTML) */}
228
  <div id="cam-button-wrapper" className="control-button-wrapper cam-wrapper-html-like">
229
  <div
230
- id="cam-button" // ID از HTML
231
- className="control-button cam-button-color" // کلاس‌ها از HTML
232
  onClick={handleCamToggle}
233
  >
234
  {isAppCamActive ? <SvgStopCamIcon /> : <SvgCameraIcon />}
@@ -240,7 +237,7 @@ const ControlTray: React.FC<ControlTrayProps> = ({
240
  <button
241
  id="switch-camera-button"
242
  aria-label="Switch Camera"
243
- className="switch-camera-button-content group" // کلاس از HTML
244
  onClick={handleSwitchCamera}
245
  disabled={!isAppCamActive || isSwitchingCamera}
246
  >
 
18
  // آیکون توقف (Pause) - برای زمانی که میکروفون فعال است
19
  const SvgPauseIcon = () => <svg width="37" height="37" viewBox="0 0 37 37" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.9872 29.6198V8.28342C15.9872 6.25781 15.132 5.44757 12.9713 5.44757H7.52469C5.36404 5.44757 4.50879 6.25781 4.50879 8.28342V29.6198C4.50879 31.6454 5.36404 32.4556 7.52469 32.4556H12.9713C15.132 32.4556 15.9872 31.6454 15.9872 29.6198Z" fill="#BE123C"/><path opacity="0.4" d="M31.5175 29.6198V8.28342C31.5175 6.25781 30.6622 5.44757 28.5016 5.44757H23.055C20.9093 5.44757 20.0391 6.25781 20.0391 8.28342V29.6198C20.0391 31.6454 20.8943 32.4556 23.055 32.4556H28.5016C30.6622 32.4556 31.5175 31.6454 31.5175 29.6198Z" fill="#BE123C"/></svg>;
20
 
21
+ // آیکون دوربین - برای زمانی که دوربین غیرفعال است
22
  const SvgCameraIcon = () => <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path opacity="0.4" d="M21.8118 5.52235H11.9265C6.29183 5.52235 4.10059 7.7136 4.10059 13.3482V26.5286C4.10059 30.318 6.16002 34.3545 11.9265 34.3545H21.8118C27.4464 34.3545 29.6376 32.1633 29.6376 26.5286V13.3482C29.6376 7.7136 27.4464 5.52235 21.8118 5.52235Z" fill="#2252A0"/><path d="M19.3406 18.9169C21.0512 18.9169 22.438 17.5302 22.438 15.8195C22.438 14.1089 21.0512 12.7222 19.3406 12.7222C17.6299 12.7222 16.2432 14.1089 16.2432 15.8195C16.2432 17.5302 17.6299 18.9169 19.3406 18.9169Z" fill="#2252A0"/><path d="M36.0629 10.3332C35.3874 9.98721 33.9705 9.5918 32.0429 10.9428L29.6045 12.6562C29.621 12.8869 29.6374 13.1011 29.6374 13.3482V26.5286C29.6374 26.7758 29.6045 26.9899 29.6045 27.2206L32.0429 28.934C33.0643 29.659 33.954 29.8896 34.6625 29.8896C35.2721 29.8896 35.7499 29.7249 36.0629 29.5601C36.7384 29.2141 37.8752 28.275 37.8752 25.919V13.9743C37.8752 11.6183 36.7384 10.6792 36.0629 10.3332Z" fill="#2252A0"/></svg>;
23
 
24
  // آیکون توقف دوربین
 
36
  isAppCamActive: boolean;
37
  onAppCamToggle: (active: boolean) => void;
38
  createLogoFunction: (isMini: boolean, isActive: boolean, type?: 'human' | 'ai', forFooter?: boolean) => ReactNode;
39
+ ReferenceMicrophoneIcon: () => JSX.Element;
40
  };
41
 
42
  const ControlTray: React.FC<ControlTrayProps> = ({
 
48
  isAppCamActive,
49
  onAppCamToggle,
50
  createLogoFunction,
51
+ ReferenceMicrophoneIcon,
52
  }) => {
53
  const { client, connected, connect } = useLiveAPIContext();
54
  const [audioRecorder] = useState(() => new AudioRecorder());
 
129
  }
130
  }, [activeLocalVideoStream, videoRef]);
131
 
 
132
  const ensureConnectedAndReady = async (): Promise<boolean> => {
133
  if (!connected) {
134
  try { await connect(); return true; }
 
167
  if (isSwitchingCamera) return;
168
  const newCamState = !isAppCamActive;
169
 
170
+ if (newCamState) { // Turning cam ON
171
  if (!(await ensureConnectedAndReady())) {
172
  onAppCamToggle(false);
173
  return;
 
176
  onAppMicToggle(true);
177
  }
178
  onAppCamToggle(true);
179
+ } else { // Turning cam OFF
180
  onAppCamToggle(false);
181
  }
182
  };
183
 
 
184
  const handleSwitchCamera = async () => {
185
  if (!isAppCamActive || !activeLocalVideoStream || isSwitchingCamera) return;
186
  setIsSwitchingCamera(true);
 
201
  } finally { setIsSwitchingCamera(false); }
202
  };
203
 
 
204
  return (
205
  <footer id="footer-controls" className="footer-controls-html-like">
206
  <canvas style={{ display: "none" }} ref={renderCanvasRef} />
207
 
208
+ {/* Mic Button (چپ در HTML) */}
209
  <div
210
+ id="mic-button"
211
+ className="control-button mic-button-color" // رنگ قرمز برای میکروفون
212
  onClick={handleMicToggle}
213
  >
214
  {isAppMicActive ? <SvgPauseIcon /> : <ReferenceMicrophoneIcon />}
215
  </div>
216
 
217
+ {/* لوگوی کوچک وسط - فقط زمانی که دوربین فعال است */}
218
+ {isAppCamActive && (
219
  <div id="small-logo-footer-container" className="small-logo-footer-html-like">
220
  {createLogoFunction(true, true, 'human', true)}
221
  </div>
222
  )}
223
 
224
+ {/* دکمه دوربین (راست در HTML) */}
225
  <div id="cam-button-wrapper" className="control-button-wrapper cam-wrapper-html-like">
226
  <div
227
+ id="cam-button"
228
+ className="control-button cam-button-color" // رنگ آبی برای دوربین
229
  onClick={handleCamToggle}
230
  >
231
  {isAppCamActive ? <SvgStopCamIcon /> : <SvgCameraIcon />}
 
237
  <button
238
  id="switch-camera-button"
239
  aria-label="Switch Camera"
240
+ className="switch-camera-button-content group"
241
  onClick={handleSwitchCamera}
242
  disabled={!isAppCamActive || isSwitchingCamera}
243
  >