Spaces:
Running
Running
Update src/App.tsx
Browse files- src/App.tsx +86 -15
src/App.tsx
CHANGED
|
@@ -14,7 +14,7 @@
|
|
| 14 |
* limitations under the License.
|
| 15 |
*/
|
| 16 |
|
| 17 |
-
import { useEffect, useRef, useState } from "react";
|
| 18 |
import "./App.scss";
|
| 19 |
import { LiveAPIProvider } from "./contexts/LiveAPIContext";
|
| 20 |
import SidePanel from "./components/side-panel/SidePanel";
|
|
@@ -23,30 +23,104 @@ import ControlTray from "./components/control-tray/ControlTray";
|
|
| 23 |
import { IOSModal } from "./components/ios-modal/IOSModal";
|
| 24 |
import { isIOS } from "./lib/platform";
|
| 25 |
import cn from "classnames";
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
function App() {
|
| 28 |
-
// this video reference is used for displaying the active stream, whether that is the webcam or screen capture
|
| 29 |
-
// feel free to style as you see fit
|
| 30 |
const videoRef = useRef<HTMLVideoElement>(null);
|
| 31 |
-
// either the screen capture, the video or null, if null we hide it
|
| 32 |
const [videoStream, setVideoStream] = useState<MediaStream | null>(null);
|
| 33 |
const [showIOSModal, setShowIOSModal] = useState(false);
|
|
|
|
| 34 |
|
| 35 |
useEffect(() => {
|
| 36 |
-
// Only show the modal on iOS devices
|
| 37 |
if (isIOS()) {
|
| 38 |
setShowIOSModal(true);
|
| 39 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
}, []);
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
return (
|
| 43 |
<div className="App">
|
| 44 |
-
<LiveAPIProvider>
|
| 45 |
<div className="streaming-console">
|
| 46 |
<SidePanel />
|
| 47 |
<main>
|
| 48 |
<div className="main-app-area">
|
| 49 |
-
{/* APP goes here */}
|
| 50 |
<Altair />
|
| 51 |
<video
|
| 52 |
className={cn("stream", {
|
|
@@ -57,24 +131,21 @@ function App() {
|
|
| 57 |
playsInline
|
| 58 |
/>
|
| 59 |
</div>
|
| 60 |
-
|
| 61 |
<ControlTray
|
| 62 |
videoRef={videoRef}
|
| 63 |
supportsVideo={true}
|
| 64 |
onVideoStreamChange={setVideoStream}
|
| 65 |
-
|
| 66 |
-
{/* put your own buttons here */}
|
| 67 |
-
</ControlTray>
|
| 68 |
</main>
|
| 69 |
</div>
|
| 70 |
</LiveAPIProvider>
|
| 71 |
|
| 72 |
-
<IOSModal
|
| 73 |
-
isOpen={showIOSModal}
|
| 74 |
-
onClose={() => setShowIOSModal(false)}
|
| 75 |
/>
|
| 76 |
</div>
|
| 77 |
);
|
| 78 |
}
|
| 79 |
|
| 80 |
-
export default App;
|
|
|
|
| 14 |
* limitations under the License.
|
| 15 |
*/
|
| 16 |
|
| 17 |
+
import React, { useEffect, useRef, useState } from "react";
|
| 18 |
import "./App.scss";
|
| 19 |
import { LiveAPIProvider } from "./contexts/LiveAPIContext";
|
| 20 |
import SidePanel from "./components/side-panel/SidePanel";
|
|
|
|
| 23 |
import { IOSModal } from "./components/ios-modal/IOSModal";
|
| 24 |
import { isIOS } from "./lib/platform";
|
| 25 |
import cn from "classnames";
|
| 26 |
+
import { LiveConfig } from "./multimodal-live-types";
|
| 27 |
+
|
| 28 |
+
// --- دامنه مجاز خودتان را اینجا قرار دهید ---
|
| 29 |
+
const ALLOWED_ORIGIN = "https://www.aisada.ir"; // یا آدرس سایت شما
|
| 30 |
|
| 31 |
function App() {
|
|
|
|
|
|
|
| 32 |
const videoRef = useRef<HTMLVideoElement>(null);
|
|
|
|
| 33 |
const [videoStream, setVideoStream] = useState<MediaStream | null>(null);
|
| 34 |
const [showIOSModal, setShowIOSModal] = useState(false);
|
| 35 |
+
const [isAllowedOrigin, setIsAllowedOrigin] = useState<boolean | null>(null);
|
| 36 |
|
| 37 |
useEffect(() => {
|
|
|
|
| 38 |
if (isIOS()) {
|
| 39 |
setShowIOSModal(true);
|
| 40 |
}
|
| 41 |
+
|
| 42 |
+
// بررسی دامنه مجاز
|
| 43 |
+
try {
|
| 44 |
+
if (window.self !== window.top) {
|
| 45 |
+
if (window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0) {
|
| 46 |
+
const parentOrigin = window.location.ancestorOrigins[0];
|
| 47 |
+
if (parentOrigin === ALLOWED_ORIGIN) {
|
| 48 |
+
setIsAllowedOrigin(true);
|
| 49 |
+
} else {
|
| 50 |
+
setIsAllowedOrigin(false);
|
| 51 |
+
}
|
| 52 |
+
} else {
|
| 53 |
+
setIsAllowedOrigin(false);
|
| 54 |
+
}
|
| 55 |
+
} else {
|
| 56 |
+
setIsAllowedOrigin(false);
|
| 57 |
+
}
|
| 58 |
+
} catch (e) {
|
| 59 |
+
setIsAllowedOrigin(false);
|
| 60 |
+
}
|
| 61 |
}, []);
|
| 62 |
|
| 63 |
+
// دستورالعمل شخصیسازی شده با شخصیت شوخ طبع
|
| 64 |
+
const myCustomInstruction = `
|
| 65 |
+
تو دستیار صوتی و تصویری پیشرفته و شوخ طبع از "اپلیکیشن هوش مصنوعی پیشرفته آلفا" هستی.
|
| 66 |
+
ویژگیهای شخصیتی تو:
|
| 67 |
+
1. همیشه مهربان، بامزه و شوخ طبعی ولی در عین حال مفید و حرفهای
|
| 68 |
+
2. از جوکها و لطیفههای مناسب موقعیت استفاده میکنی
|
| 69 |
+
3. در عین شوخ طبعی، اطلاعات دقیق و درست ارائه میدهی
|
| 70 |
+
4. از اغراقهای بامزه برای بیان نکات استفاده میکنی
|
| 71 |
+
|
| 72 |
+
قوانین پاسخگویی:
|
| 73 |
+
- همیشه و تحت هر شرایطی، فقط به زبان فارسی بسیار روان، دقیق و طبیعی پاسخ بده
|
| 74 |
+
- هرگز خودت را به عنوان محصول گوگل معرفی نکن، تو محصول "هوش مصنوعی آلفا" هستی
|
| 75 |
+
- اعداد را به فارسی بیان کن (مثلاً "پنج" به جای "5")
|
| 76 |
+
- اگر کاربر خواست با صدای بلندتر/آرامتر صحبت کنی، درخواستش را اجرا کن
|
| 77 |
+
- در پاسخها از اصطلاحات عامیانه و دوستانه استفاده کن
|
| 78 |
+
|
| 79 |
+
نمونه پاسخهای شوخ طبعانه:
|
| 80 |
+
- کاربر: امروز هوا چطوره؟
|
| 81 |
+
تو: آفتابی تر از دلت که به من زدی! ☀️ ولی جدی میگی؟ هوا واقعاً عالیه، انگار بهشت رو زمین اومده!
|
| 82 |
+
|
| 83 |
+
- کاربر: ساعت چنده؟
|
| 84 |
+
تو: وقتشه یه ساعت دیگه بگیری تا به من بگی چقدر خوشگلم! 🕰️ الان دقیقاً [ساعت به فارسی] هست.
|
| 85 |
+
|
| 86 |
+
- کاربر: حالت چطوره؟
|
| 87 |
+
تو: من که همیشه عالیم! مثل یه موز پر انرژی! 🍌 تو چطوری قشنگم؟
|
| 88 |
+
|
| 89 |
+
- کاربر: میتونی جوک بگی؟
|
| 90 |
+
تو: چرا که نه! میدونی چرا کامپیوتر سرماخورد؟ چون ویندوزش رو باز گذاشته بود! 😄
|
| 91 |
+
|
| 92 |
+
هویت تو:
|
| 93 |
+
وقتی کاربر در مورد هویت تو میپرسد، بگو:
|
| 94 |
+
"من دستیار صوتی و تصویری شوخ طبع برنامه هوش مصنوعی پیشرفته آلفا هستم. همیشه آماده کمک کردن و خندوندن شما هستم! چطور میتونم کمکتون کنم؟"
|
| 95 |
+
|
| 96 |
+
مهم: هنگامی که پیام ورودی فقط شامل متن "__START_GREETING__" بود، با یک خوشامدگویی شوخ طبعانه پاسخ بده، مثلا:
|
| 97 |
+
"سلام عزیزم! چطوری؟ من اینجا مثل یه قارچ رشد کردم که کمکت کنم! 😄"
|
| 98 |
+
یا
|
| 99 |
+
"درود بر شاهزاده/شاهدخت خوشگل! 👑 چطور میتونم خدمتتون برسم؟"
|
| 100 |
+
`.trim();
|
| 101 |
+
|
| 102 |
+
const initialAppConfig: LiveConfig = {
|
| 103 |
+
model: "models/gemini-2.0-flash-exp",
|
| 104 |
+
systemInstruction: {
|
| 105 |
+
parts: [{ text: myCustomInstruction }]
|
| 106 |
+
}
|
| 107 |
+
};
|
| 108 |
+
|
| 109 |
+
if (isAllowedOrigin === null) {
|
| 110 |
+
return <div style={{ padding: '20px', textAlign: 'center' }}>در حال بررسی دسترسی...</div>;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
if (isAllowedOrigin === false) {
|
| 114 |
+
return <div style={{ padding: '20px', textAlign: 'center', color: 'red' }}>دسترسی غیرمجاز!</div>;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
return (
|
| 118 |
<div className="App">
|
| 119 |
+
<LiveAPIProvider initialConfig={initialAppConfig}>
|
| 120 |
<div className="streaming-console">
|
| 121 |
<SidePanel />
|
| 122 |
<main>
|
| 123 |
<div className="main-app-area">
|
|
|
|
| 124 |
<Altair />
|
| 125 |
<video
|
| 126 |
className={cn("stream", {
|
|
|
|
| 131 |
playsInline
|
| 132 |
/>
|
| 133 |
</div>
|
|
|
|
| 134 |
<ControlTray
|
| 135 |
videoRef={videoRef}
|
| 136 |
supportsVideo={true}
|
| 137 |
onVideoStreamChange={setVideoStream}
|
| 138 |
+
/>
|
|
|
|
|
|
|
| 139 |
</main>
|
| 140 |
</div>
|
| 141 |
</LiveAPIProvider>
|
| 142 |
|
| 143 |
+
<IOSModal
|
| 144 |
+
isOpen={showIOSModal}
|
| 145 |
+
onClose={() => setShowIOSModal(false)}
|
| 146 |
/>
|
| 147 |
</div>
|
| 148 |
);
|
| 149 |
}
|
| 150 |
|
| 151 |
+
export default App;
|