privateuserh commited on
Commit
f52dfb4
·
verified ·
1 Parent(s): 98d2e1a

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +1684 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Privaistrm Vbeta1 09
3
- emoji: 🏢
4
- colorFrom: gray
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: privaistrm-vbeta1-09
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: gray
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1684 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>StreamAI - Personalized Streaming Recommendations</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @keyframes float {
11
+ 0% { transform: translateY(0px); }
12
+ 50% { transform: translateY(-10px); }
13
+ 100% { transform: translateY(0px); }
14
+ }
15
+ .floating {
16
+ animation: float 6s ease-in-out infinite;
17
+ }
18
+ .gradient-bg {
19
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
20
+ }
21
+ .chat-bubble {
22
+ border-radius: 20px;
23
+ position: relative;
24
+ max-width: 80%;
25
+ }
26
+ .user-bubble {
27
+ background-color: #4f46e5;
28
+ color: white;
29
+ margin-left: auto;
30
+ border-bottom-right-radius: 5px;
31
+ }
32
+ .ai-bubble {
33
+ background-color: #f3f4f6;
34
+ color: #1f2937;
35
+ margin-right: auto;
36
+ border-bottom-left-radius: 5px;
37
+ }
38
+ .typing-indicator span {
39
+ display: inline-block;
40
+ width: 8px;
41
+ height: 8px;
42
+ border-radius: 50%;
43
+ background-color: #9ca3af;
44
+ margin: 0 2px;
45
+ }
46
+ .typing-indicator span:nth-child(1) {
47
+ animation: bounce 1s infinite;
48
+ }
49
+ .typing-indicator span:nth-child(2) {
50
+ animation: bounce 1s infinite 0.2s;
51
+ }
52
+ .typing-indicator span:nth-child(3) {
53
+ animation: bounce 1s infinite 0.4s;
54
+ }
55
+ @keyframes bounce {
56
+ 0%, 100% { transform: translateY(0); }
57
+ 50% { transform: translateY(-5px); }
58
+ }
59
+ .stream-card:hover {
60
+ transform: translateY(-5px);
61
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
62
+ }
63
+ .fade-in {
64
+ animation: fadeIn 0.5s ease-in;
65
+ }
66
+ @keyframes fadeIn {
67
+ from { opacity: 0; }
68
+ to { opacity: 1; }
69
+ }
70
+ .notification {
71
+ position: fixed;
72
+ bottom: 20px;
73
+ right: 20px;
74
+ background: #4f46e5;
75
+ color: white;
76
+ padding: 15px 25px;
77
+ border-radius: 8px;
78
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
79
+ transform: translateX(120%);
80
+ transition: transform 0.3s ease-out;
81
+ z-index: 1000;
82
+ }
83
+ .notification.show {
84
+ transform: translateX(0);
85
+ }
86
+ .production-button {
87
+ position: fixed;
88
+ bottom: 30px;
89
+ right: 30px;
90
+ width: 60px;
91
+ height: 60px;
92
+ border-radius: 50%;
93
+ background: linear-gradient(135deg, #ff5e62 0%, #ff9966 100%);
94
+ color: white;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ box-shadow: 0 10px 25px rgba(255, 94, 98, 0.3);
99
+ cursor: pointer;
100
+ z-index: 999;
101
+ transition: all 0.3s ease;
102
+ }
103
+ .production-button:hover {
104
+ transform: scale(1.1);
105
+ box-shadow: 0 15px 30px rgba(255, 94, 98, 0.4);
106
+ }
107
+ .production-panel {
108
+ position: fixed;
109
+ bottom: 110px;
110
+ right: 30px;
111
+ width: 350px;
112
+ background: white;
113
+ border-radius: 12px;
114
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
115
+ padding: 20px;
116
+ z-index: 998;
117
+ transform: translateY(20px);
118
+ opacity: 0;
119
+ pointer-events: none;
120
+ transition: all 0.3s ease;
121
+ }
122
+ .production-panel.open {
123
+ transform: translateY(0);
124
+ opacity: 1;
125
+ pointer-events: all;
126
+ }
127
+ .recording-indicator {
128
+ position: absolute;
129
+ top: -10px;
130
+ right: -10px;
131
+ width: 20px;
132
+ height: 20px;
133
+ border-radius: 50%;
134
+ background: #ff5e62;
135
+ animation: pulse 1.5s infinite;
136
+ }
137
+ @keyframes pulse {
138
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 94, 98, 0.7); }
139
+ 70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(255, 94, 98, 0); }
140
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 94, 98, 0); }
141
+ }
142
+ .clip-item {
143
+ display: flex;
144
+ align-items: center;
145
+ padding: 8px 0;
146
+ border-bottom: 1px solid #eee;
147
+ cursor: pointer;
148
+ }
149
+ .clip-item:hover {
150
+ background-color: #f9fafb;
151
+ }
152
+ .clip-item:last-child {
153
+ border-bottom: none;
154
+ }
155
+ .clip-preview {
156
+ width: 100%;
157
+ height: 180px;
158
+ background-color: #f3f4f6;
159
+ border-radius: 8px;
160
+ display: flex;
161
+ align-items: center;
162
+ justify-content: center;
163
+ margin-bottom: 15px;
164
+ position: relative;
165
+ overflow: hidden;
166
+ }
167
+ .clip-preview video {
168
+ width: 100%;
169
+ height: 100%;
170
+ object-fit: cover;
171
+ }
172
+ .clip-preview-placeholder {
173
+ text-align: center;
174
+ color: #6b7280;
175
+ }
176
+ .clip-preview-placeholder i {
177
+ font-size: 40px;
178
+ margin-bottom: 10px;
179
+ display: block;
180
+ }
181
+ .progress-bar {
182
+ height: 4px;
183
+ background-color: #e5e7eb;
184
+ border-radius: 2px;
185
+ overflow: hidden;
186
+ margin-top: 10px;
187
+ }
188
+ .progress-fill {
189
+ height: 100%;
190
+ background-color: #4f46e5;
191
+ width: 0%;
192
+ transition: width 0.3s ease;
193
+ }
194
+ .tab {
195
+ padding: 8px 16px;
196
+ border-radius: 20px;
197
+ font-size: 14px;
198
+ cursor: pointer;
199
+ margin-right: 8px;
200
+ }
201
+ .tab.active {
202
+ background-color: #4f46e5;
203
+ color: white;
204
+ }
205
+ .tab.inactive {
206
+ background-color: #f3f4f6;
207
+ color: #6b7280;
208
+ }
209
+ .rank-badge {
210
+ width: 20px;
211
+ height: 20px;
212
+ border-radius: 50%;
213
+ display: flex;
214
+ align-items: center;
215
+ justify-content: center;
216
+ font-size: 10px;
217
+ font-weight: bold;
218
+ margin-left: 8px;
219
+ }
220
+ .rank-1 {
221
+ background-color: #f59e0b;
222
+ color: white;
223
+ }
224
+ .rank-2 {
225
+ background-color: #6b7280;
226
+ color: white;
227
+ }
228
+ .rank-3 {
229
+ background-color: #92400e;
230
+ color: white;
231
+ }
232
+ .bluetooth-connected {
233
+ color: #3b82f6;
234
+ animation: pulse 2s infinite;
235
+ }
236
+ .bluetooth-disconnected {
237
+ color: #6b7280;
238
+ }
239
+ .user-tag {
240
+ background-color: #e5e7eb;
241
+ color: #4b5563;
242
+ padding: 2px 6px;
243
+ border-radius: 4px;
244
+ font-size: 10px;
245
+ margin-left: 4px;
246
+ }
247
+ .category-tag {
248
+ background-color: #dbeafe;
249
+ color: #1e40af;
250
+ padding: 2px 6px;
251
+ border-radius: 4px;
252
+ font-size: 10px;
253
+ margin-left: 4px;
254
+ }
255
+ </style>
256
+ </head>
257
+ <body class="bg-gray-100 font-sans">
258
+ <!-- Notification -->
259
+ <div id="notification" class="notification hidden">
260
+ <div class="flex items-center">
261
+ <i class="fas fa-bell text-yellow-300 mr-3"></i>
262
+ <div>
263
+ <p class="font-semibold" id="notification-title">Reminder Set!</p>
264
+ <p class="text-sm" id="notification-message">We'll notify you when this show is about to broadcast.</p>
265
+ </div>
266
+ </div>
267
+ </div>
268
+
269
+ <!-- Production Button & Panel -->
270
+ <div class="production-button" id="production-button">
271
+ <i class="fas fa-video"></i>
272
+ <div class="recording-indicator hidden" id="recording-indicator"></div>
273
+ </div>
274
+
275
+ <div class="production-panel" id="production-panel">
276
+ <div class="flex mb-4">
277
+ <div class="tab active" id="record-tab">Record</div>
278
+ <div class="tab inactive" id="edit-tab">Edit</div>
279
+ <div class="tab inactive" id="share-tab">Share</div>
280
+ <div class="tab inactive" id="rank-tab">Rankings</div>
281
+ </div>
282
+
283
+ <div id="record-section">
284
+ <h3 class="font-bold text-lg mb-4">Create Video Clips</h3>
285
+ <p class="text-sm text-gray-600 mb-4">Record your screen and audio to create short clips for your production. Perfect for capturing highlights or creating content snippets.</p>
286
+
287
+ <div class="clip-preview" id="clip-preview">
288
+ <div class="clip-preview-placeholder">
289
+ <i class="fas fa-video"></i>
290
+ <p>Preview will appear here</p>
291
+ </div>
292
+ </div>
293
+
294
+ <div class="mb-4">
295
+ <button id="start-recording" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-full text-sm font-medium transition">
296
+ <i class="fas fa-circle mr-1"></i> Start Recording (5s clips)
297
+ </button>
298
+ <button id="stop-recording" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-full text-sm font-medium transition ml-2 hidden">
299
+ <i class="fas fa-stop mr-1"></i> Stop
300
+ </button>
301
+ </div>
302
+
303
+ <div class="progress-bar">
304
+ <div class="progress-fill" id="progress-fill"></div>
305
+ </div>
306
+
307
+ <div id="clips-container" class="mb-4 max-h-40 overflow-y-auto">
308
+ <p class="text-gray-500 text-sm">Clips will appear here when recorded...</p>
309
+ </div>
310
+ </div>
311
+
312
+ <div id="edit-section" class="hidden">
313
+ <h3 class="font-bold text-lg mb-4">Edit Your Production</h3>
314
+ <p class="text-sm text-gray-600 mb-4">Combine your clips, add transitions, and create a polished final video.</p>
315
+
316
+ <div class="mb-4">
317
+ <label class="block text-sm font-medium text-gray-700 mb-1">Video Title</label>
318
+ <input type="text" id="video-title" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm" placeholder="My Awesome Video">
319
+ </div>
320
+
321
+ <div class="mb-4">
322
+ <label class="block text-sm font-medium text-gray-700 mb-1">Select Transition</label>
323
+ <select id="video-transition" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm">
324
+ <option value="none">No Transition</option>
325
+ <option value="fade">Fade</option>
326
+ <option value="slide">Slide</option>
327
+ <option value="zoom">Zoom</option>
328
+ </select>
329
+ </div>
330
+ </div>
331
+
332
+ <div id="share-section" class="hidden">
333
+ <h3 class="font-bold text-lg mb-4">Share with Bluetooth Group</h3>
334
+ <p class="text-sm text-gray-600 mb-4">Connect with nearby devices and share your clips with the group.</p>
335
+
336
+ <div class="flex items-center mb-4">
337
+ <button id="bluetooth-connect" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-full text-sm font-medium transition">
338
+ <i class="fas fa-bluetooth-b mr-1"></i> Connect Devices
339
+ </button>
340
+ <div id="connection-status" class="ml-3 text-sm">
341
+ <i class="fas fa-circle bluetooth-disconnected mr-1"></i>
342
+ <span>Not connected</span>
343
+ </div>
344
+ </div>
345
+
346
+ <div class="mb-4">
347
+ <label class="block text-sm font-medium text-gray-700 mb-1">Your Username</label>
348
+ <input type="text" id="username" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm" placeholder="Enter a username">
349
+ </div>
350
+
351
+ <div class="mb-4">
352
+ <label class="block text-sm font-medium text-gray-700 mb-1">Content Category</label>
353
+ <select id="content-category" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm">
354
+ <option value="general">General</option>
355
+ <option value="gaming">Gaming</option>
356
+ <option value="education">Education</option>
357
+ <option value="entertainment">Entertainment</option>
358
+ <option value="news">News</option>
359
+ </select>
360
+ </div>
361
+
362
+ <button id="share-clips" class="w-full bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-full text-sm font-medium transition mb-4">
363
+ <i class="fas fa-share-alt mr-1"></i> Share Selected Clips
364
+ </button>
365
+
366
+ <div id="shared-clips-container" class="max-h-40 overflow-y-auto">
367
+ <p class="text-gray-500 text-sm">Shared clips will appear here...</p>
368
+ </div>
369
+ </div>
370
+
371
+ <div id="rank-section" class="hidden">
372
+ <h3 class="font-bold text-lg mb-4">Group Rankings</h3>
373
+ <p class="text-sm text-gray-600 mb-4">See how your clips rank against others in your group.</p>
374
+
375
+ <div class="mb-4">
376
+ <label class="block text-sm font-medium text-gray-700 mb-1">Ranking Algorithm</label>
377
+ <select id="ranking-algorithm" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm">
378
+ <option value="engagement">Engagement Score</option>
379
+ <option value="quality">Quality Score</option>
380
+ <option value="consistency">Consistency Score</option>
381
+ <option value="composite">Composite Score</option>
382
+ </select>
383
+ </div>
384
+
385
+ <div id="rankings-container" class="max-h-60 overflow-y-auto">
386
+ <p class="text-gray-500 text-sm">Rankings will appear here when available...</p>
387
+ </div>
388
+ </div>
389
+
390
+ <div class="flex space-x-2">
391
+ <button id="generate-video" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-full text-sm font-medium transition flex-1">
392
+ <i class="fas fa-magic mr-1"></i> Generate Video
393
+ </button>
394
+ <button id="clear-clips" class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-full text-sm font-medium transition">
395
+ <i class="fas fa-trash mr-1"></i>
396
+ </button>
397
+ </div>
398
+ </div>
399
+
400
+ <!-- Header -->
401
+ <header class="gradient-bg text-white shadow-lg">
402
+ <div class="container mx-auto px-4 py-6">
403
+ <div class="flex justify-between items-center">
404
+ <div class="flex items-center space-x-3">
405
+ <i class="fas fa-stream text-3xl"></i>
406
+ <h1 class="text-2xl font-bold">StreamAI</h1>
407
+ </div>
408
+ <nav class="hidden md:flex space-x-6">
409
+ <a href="#" class="hover:text-indigo-200 transition">Home</a>
410
+ <a href="#" class="hover:text-indigo-200 transition">Features</a>
411
+ <a href="#" class="hover:text-indigo-200 transition">About</a>
412
+ <a href="#" class="hover:text-indigo-200 transition">Contact</a>
413
+ </nav>
414
+ <button class="md:hidden text-xl">
415
+ <i class="fas fa-bars"></i>
416
+ </button>
417
+ </div>
418
+ </div>
419
+ </header>
420
+
421
+ <!-- Hero Section -->
422
+ <section class="gradient-bg text-white py-16">
423
+ <div class="container mx-auto px-4 flex flex-col md:flex-row items-center">
424
+ <div class="md:w-1/2 mb-10 md:mb-0">
425
+ <h2 class="text-4xl md:text-5xl font-bold mb-4">AI-Powered Streaming Recommendations</h2>
426
+ <p class="text-xl mb-8 text-indigo-100">Get personalized streaming suggestions powered by Cloudflare Workers AI.</p>
427
+ <div class="flex space-x-4">
428
+ <button class="bg-white text-indigo-600 px-6 py-3 rounded-full font-semibold hover:bg-indigo-100 transition">
429
+ Try It Now
430
+ </button>
431
+ <button class="border-2 border-white text-white px-6 py-3 rounded-full font-semibold hover:bg-white hover:text-indigo-600 transition">
432
+ How It Works
433
+ </button>
434
+ </div>
435
+ </div>
436
+ <div class="md:w-1/2 flex justify-center">
437
+ <div class="relative w-64 h-64 md:w-80 md:h-80">
438
+ <div class="absolute inset-0 bg-indigo-500 rounded-full opacity-20 floating"></div>
439
+ <div class="absolute inset-4 bg-indigo-400 rounded-full opacity-30 floating" style="animation-delay: 0.5s;"></div>
440
+ <div class="absolute inset-8 bg-indigo-300 rounded-full opacity-40 floating" style="animation-delay: 1s;"></div>
441
+ <div class="absolute inset-12 bg-white rounded-full flex items-center justify-center">
442
+ <i class="fas fa-robot text-6xl text-indigo-600"></i>
443
+ </div>
444
+ </div>
445
+ </div>
446
+ </div>
447
+ </section>
448
+
449
+ <!-- AI Chat Interface -->
450
+ <section class="py-12 bg-white">
451
+ <div class="container mx-auto px-4">
452
+ <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">Your Personal Streaming Assistant</h2>
453
+
454
+ <div class="max-w-4xl mx-auto bg-gray-50 rounded-xl shadow-lg overflow-hidden">
455
+ <!-- Chat header -->
456
+ <div class="bg-indigo-600 text-white p-4 flex items-center">
457
+ <div class="w-10 h-10 rounded-full bg-indigo-400 flex items-center justify-center mr-3">
458
+ <i class="fas fa-robot"></i>
459
+ </div>
460
+ <div>
461
+ <h3 class="font-semibold">StreamAI Assistant</h3>
462
+ <p class="text-xs text-indigo-200">Powered by Cloudflare Workers AI</p>
463
+ </div>
464
+ <div class="ml-auto flex space-x-2">
465
+ <button class="w-8 h-8 rounded-full bg-indigo-500 hover:bg-indigo-400 flex items-center justify-center">
466
+ <i class="fas fa-ellipsis-h text-sm"></i>
467
+ </button>
468
+ </div>
469
+ </div>
470
+
471
+ <!-- Chat messages -->
472
+ <div class="h-96 overflow-y-auto p-4 space-y-4" id="chat-messages">
473
+ <div class="chat-bubble ai-bubble p-4 w-3/4">
474
+ <p>Hi there! 👋 I'm your StreamAI assistant powered by Cloudflare Workers AI. I can recommend movies, TV shows, and other streaming content based on your preferences. What are you in the mood for today?</p>
475
+ </div>
476
+ </div>
477
+
478
+ <!-- User input -->
479
+ <div class="border-t border-gray-200 p-4 bg-white">
480
+ <div class="flex items-center">
481
+ <input type="text" id="user-input" placeholder="Type your message..." class="flex-1 border border-gray-300 rounded-full py-3 px-4 focus:outline-none focus:ring-2 focus:ring-indigo-500">
482
+ <button id="send-btn" class="ml-3 w-12 h-12 rounded-full bg-indigo-600 text-white hover:bg-indigo-700 flex items-center justify-center transition">
483
+ <i class="fas fa-paper-plane"></i>
484
+ </button>
485
+ </div>
486
+ <div class="mt-2 flex space-x-2">
487
+ <button class="text-xs bg-gray-100 hover:bg-gray-200 px-3 py-1 rounded-full transition" onclick="quickPrompt('Recommend a comedy movie')">
488
+ Comedy
489
+ </button>
490
+ <button class="text-xs bg-gray-100 hover:bg-gray-200 px-3 py-1 rounded-full transition" onclick="quickPrompt('What should I watch if I feel nostalgic?')">
491
+ Nostalgic
492
+ </button>
493
+ <button class="text-xs bg-gray-100 hover:bg-gray-200 px-3 py-1 rounded-full transition" onclick="quickPrompt('Suggest a thriller series')">
494
+ Thriller
495
+ </button>
496
+ </div>
497
+ </div>
498
+ </div>
499
+ </div>
500
+ </section>
501
+
502
+ <!-- Recommended Streams Section -->
503
+ <section class="py-12 bg-gray-50">
504
+ <div class="container mx-auto px-4">
505
+ <h2 class="text-3xl font-bold text-center mb-6 text-gray-800">Recommended For You</h2>
506
+
507
+ <!-- RSS Feed Integration -->
508
+ <div class="max-w-4xl mx-auto mb-8 bg-white p-4 rounded-lg shadow">
509
+ <div class="flex items-center mb-2">
510
+ <i class="fas fa-rss-square text-orange-500 mr-2"></i>
511
+ <h3 class="font-semibold">Personalized RSS Feed</h3>
512
+ </div>
513
+ <div class="flex items-center space-x-2 overflow-x-auto pb-2">
514
+ <button class="rss-filter-btn px-3 py-1 bg-indigo-100 text-indigo-700 rounded-full text-sm whitespace-nowrap" data-filter="all">
515
+ All Content
516
+ </button>
517
+ <button class="rss-filter-btn px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm whitespace-nowrap" data-filter="news">
518
+ News Updates
519
+ </button>
520
+ <button class="rss-filter-btn px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm whitespace-nowrap" data-filter="trending">
521
+ Trending Now
522
+ </button>
523
+ <button class="rss-filter-btn px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm whitespace-nowrap" data-filter="personalized">
524
+ For You
525
+ </button>
526
+ </div>
527
+ <div id="rss-feed" class="mt-4 space-y-3">
528
+ <!-- RSS items will be loaded here -->
529
+ </div>
530
+ </div>
531
+
532
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4" id="recommendations-container">
533
+ <!-- Recommendations will be dynamically inserted here -->
534
+ </div>
535
+ </div>
536
+ </section>
537
+
538
+ <!-- How It Works Section -->
539
+ <section class="py-12 bg-white">
540
+ <div class="container mx-auto px-4">
541
+ <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">How StreamAI Works</h2>
542
+
543
+ <div class="grid md:grid-cols-3 gap-8">
544
+ <div class="text-center p-6 rounded-xl bg-gray-50 hover:shadow-lg transition">
545
+ <div class="w-16 h-16 bg-indigo-100 rounded-full flex items-center justify-center mx-auto mb-4">
546
+ <i class="fas fa-comment-alt text-indigo-600 text-xl"></i>
547
+ </div>
548
+ <h3 class="text-xl font-semibold mb-2">1. Chat with AI</h3>
549
+ <p class="text-gray-600">Tell our AI assistant what you're in the mood for or ask for recommendations based on your preferences.</p>
550
+ </div>
551
+ <div class="text-center p-6 rounded-xl bg-gray-50 hover:shadow-lg transition">
552
+ <div class="w-16 h-16 bg-indigo-100 rounded-full flex items-center justify-center mx-auto mb-4">
553
+ <i class="fas fa-brain text-indigo-600 text-xl"></i>
554
+ </div>
555
+ <h3 class="text-xl font-semibold mb-2">2. AI Processing</h3>
556
+ <p class="text-gray-600">Our Cloudflare Workers AI analyzes your request using advanced natural language processing.</p>
557
+ </div>
558
+ <div class="text-center p-6 rounded-xl bg-gray-50 hover:shadow-lg transition">
559
+ <div class="w-16 h-16 bg-indigo-100 rounded-full flex items-center justify-center mx-auto mb-4">
560
+ <i class="fas fa-film text-indigo-600 text-xl"></i>
561
+ </div>
562
+ <h3 class="text-xl font-semibold mb-2">3. Get Recommendations</h3>
563
+ <p class="text-gray-600">Receive personalized streaming suggestions with direct links to watch on your favorite platforms.</p>
564
+ </div>
565
+ </div>
566
+ </div>
567
+ </section>
568
+
569
+ <!-- Video Production Section -->
570
+ <section class="py-12 bg-gray-50">
571
+ <div class="container mx-auto px-4">
572
+ <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">Create Your Own Content</h2>
573
+
574
+ <div class="max-w-4xl mx-auto bg-white rounded-xl shadow-lg overflow-hidden">
575
+ <div class="p-8">
576
+ <div class="flex items-center mb-6">
577
+ <div class="w-14 h-14 rounded-full bg-gradient-to-r from-red-500 to-orange-500 flex items-center justify-center text-white mr-4">
578
+ <i class="fas fa-video text-2xl"></i>
579
+ </div>
580
+ <div>
581
+ <h3 class="text-2xl font-bold">Video Production Tools</h3>
582
+ <p class="text-gray-600">Record, edit, and share your own streaming content</p>
583
+ </div>
584
+ </div>
585
+
586
+ <div class="grid md:grid-cols-2 gap-8">
587
+ <div>
588
+ <h4 class="font-semibold text-lg mb-3">Record Live Clips</h4>
589
+ <p class="text-gray-600 mb-4">Easily capture 5-second clips of your screen and audio to create highlight reels or content snippets.</p>
590
+ <ul class="space-y-2 text-sm text-gray-600">
591
+ <li class="flex items-start">
592
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
593
+ <span>Automatically segmented into manageable clips</span>
594
+ </li>
595
+ <li class="flex items-start">
596
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
597
+ <span>Screen and audio recording with one click</span>
598
+ </li>
599
+ <li class="flex items-start">
600
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
601
+ <span>Preview clips before adding to your production</span>
602
+ </li>
603
+ <li class="flex items-start">
604
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
605
+ <span>Share with Bluetooth-connected groups</span>
606
+ </li>
607
+ </ul>
608
+ </div>
609
+ <div>
610
+ <h4 class="font-semibold text-lg mb-3">Edit & Combine</h4>
611
+ <p class="text-gray-600 mb-4">Combine your clips with smooth transitions to create professional-looking videos.</p>
612
+ <ul class="space-y-2 text-sm text-gray-600">
613
+ <li class="flex items-start">
614
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
615
+ <span>Multiple transition effects available</span>
616
+ </li>
617
+ <li class="flex items-start">
618
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
619
+ <span>Add titles and descriptions to your videos</span>
620
+ </li>
621
+ <li class="flex items-start">
622
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
623
+ <span>Export in multiple formats for sharing</span>
624
+ </li>
625
+ <li class="flex items-start">
626
+ <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
627
+ <span>Benchmark your content against group submissions</span>
628
+ </li>
629
+ </ul>
630
+ </div>
631
+ </div>
632
+
633
+ <div class="mt-8 pt-6 border-t border-gray-200">
634
+ <h4 class="font-semibold text-lg mb-4">Try It Now</h4>
635
+ <p class="text-gray-600 mb-4">Click the video production button in the bottom right corner to start creating your own content.</p>
636
+ <div class="flex items-center text-sm text-indigo-600">
637
+ <i class="fas fa-info-circle mr-2"></i>
638
+ <span>You'll need to grant screen recording permissions when prompted</span>
639
+ </div>
640
+ </div>
641
+ </div>
642
+ </div>
643
+ </div>
644
+ </section>
645
+
646
+ <!-- Footer -->
647
+ <footer class="bg-gray-800 text-white py-12">
648
+ <div class="container mx-auto px-4">
649
+ <div class="grid md:grid-cols-4 gap-8">
650
+ <div>
651
+ <h3 class="text-xl font-bold mb-4 flex items-center">
652
+ <i class="fas fa-stream mr-2"></i> StreamAI
653
+ </h3>
654
+ <p class="text-gray-400">Your personal streaming assistant powered by Cloudflare Workers AI technology.</p>
655
+ </div>
656
+ <div>
657
+ <h4 class="font-semibold mb-4">Quick Links</h4>
658
+ <ul class="space-y-2">
659
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Home</a></li>
660
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Features</a></li>
661
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Pricing</a></li>
662
+ <li><a href="#" class="text-gray-400 hover:text-white transition">FAQ</a></li>
663
+ </ul>
664
+ </div>
665
+ <div>
666
+ <h4 class="font-semibold mb-4">Streaming Platforms</h4>
667
+ <ul class="space-y-2">
668
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Netflix</a></li>
669
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Amazon Prime</a></li>
670
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Disney+</a></li>
671
+ <li><a href="#" class="text-gray-400 hover:text-white transition">HBO Max</a></li>
672
+ <li><a href="https://smplus.vhx.tv" target="_blank" class="text-gray-400 hover:text-white transition">SMPlus VHX</a></li>
673
+ </ul>
674
+ </div>
675
+ <div>
676
+ <h4 class="font-semibold mb-4">Connect With Us</h4>
677
+ <div class="flex space-x-4">
678
+ <a href="#" class="w-10 h-10 rounded-full bg-gray-700 hover:bg-indigo-600 flex items-center justify-center transition">
679
+ <i class="fab fa-twitter"></i>
680
+ </a>
681
+ <a href="#" class="w-10 h-10 rounded-full bg-gray-700 hover:bg-indigo-600 flex items-center justify-center transition">
682
+ <i class="fab fa-facebook-f"></i>
683
+ </a>
684
+ <a href="#" class="w-10 h-10 rounded-full bg-gray-700 hover:bg-indigo-600 flex items-center justify-center transition">
685
+ <i class="fab fa-instagram"></i>
686
+ </a>
687
+ <a href="#" class="w-10 h-10 rounded-full bg-gray-700 hover:bg-indigo-600 flex items-center justify-center transition">
688
+ <i class="fab fa-discord"></i>
689
+ </a>
690
+ </div>
691
+ </div>
692
+ </div>
693
+ <div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400">
694
+ <p>&copy; 2023 StreamAI. All rights reserved.</p>
695
+ </div>
696
+ </div>
697
+ </footer>
698
+
699
+ <script>
700
+ // Configuration for Cloudflare Workers AI
701
+ const AI_CONFIG = {
702
+ accountId: 'oFD0IMs0aV8eKMMMdTEF2zRQmtzvKMH43LX5ZWUJ',
703
+ gatewayId: 'streamai_gateway',
704
+ apiToken: 'masked_for_security', // In a real app, this would be handled server-side
705
+ model: '@cf/meta/llama-2-7b-chat-int8'
706
+ };
707
+
708
+ // Sample streaming data with SMPlus VHX added to the top
709
+ const streamingData = [
710
+ {
711
+ title: "SMPlus Exclusive Series",
712
+ type: "TV Series",
713
+ genre: "Drama, Action",
714
+ platform: "SMPlus VHX",
715
+ rating: "4.9",
716
+ year: "2023",
717
+ description: "An exclusive action-packed drama series only available on SMPlus VHX.",
718
+ broadcastTime: "2023-12-15T20:00:00"
719
+ },
720
+ {
721
+ title: "The Grand Adventure",
722
+ type: "Movie",
723
+ genre: "Adventure, Comedy",
724
+ platform: "Netflix",
725
+ rating: "4.8",
726
+ year: "2022",
727
+ description: "A hilarious journey across continents with unexpected twists.",
728
+ broadcastTime: "2023-12-10T19:30:00"
729
+ },
730
+ {
731
+ title: "Dark Secrets",
732
+ type: "TV Series",
733
+ genre: "Drama, Thriller",
734
+ platform: "HBO Max",
735
+ rating: "4.7",
736
+ year: "2021",
737
+ description: "A small town's dark past resurfaces with shocking revelations.",
738
+ broadcastTime: "2023-12-12T21:00:00"
739
+ },
740
+ {
741
+ title: "Space Explorers",
742
+ type: "Documentary",
743
+ genre: "Science, Space",
744
+ platform: "Disney+",
745
+ rating: "4.9",
746
+ year: "2023",
747
+ description: "The latest discoveries from the frontiers of space exploration.",
748
+ broadcastTime: "2023-12-14T18:00:00"
749
+ },
750
+ {
751
+ title: "Romantic Getaway",
752
+ type: "Movie",
753
+ genre: "Romance, Comedy",
754
+ platform: "Amazon Prime",
755
+ rating: "4.5",
756
+ year: "2021",
757
+ description: "Two strangers find love during an unexpected vacation.",
758
+ broadcastTime: "2023-12-16T20:30:00"
759
+ },
760
+ {
761
+ title: "Tech Today",
762
+ type: "News Show",
763
+ genre: "Technology, News",
764
+ platform: "SMPlus VHX",
765
+ rating: "4.6",
766
+ year: "2023",
767
+ description: "Daily tech news and gadget reviews from around the world.",
768
+ broadcastTime: "2023-12-17T09:00:00"
769
+ },
770
+ {
771
+ title: "Cooking Masters",
772
+ type: "Reality Show",
773
+ genre: "Food, Competition",
774
+ platform: "Netflix",
775
+ rating: "4.7",
776
+ year: "2023",
777
+ description: "Top chefs compete in intense culinary challenges.",
778
+ broadcastTime: "2023-12-18T20:00:00"
779
+ },
780
+ {
781
+ title: "History Unearthed",
782
+ type: "Documentary",
783
+ genre: "History, Education",
784
+ platform: "HBO Max",
785
+ rating: "4.8",
786
+ year: "2023",
787
+ description: "Fascinating historical discoveries and their modern implications.",
788
+ broadcastTime: "2023-12-19T21:00:00"
789
+ }
790
+ ];
791
+
792
+ // Sample RSS feed data
793
+ const rssFeedData = {
794
+ all: [
795
+ {
796
+ title: "New Episode: SMPlus Exclusive Series",
797
+ source: "SMPlus VHX",
798
+ time: "2 hours ago",
799
+ excerpt: "The latest episode of our exclusive series is now streaming with intense action scenes.",
800
+ category: "personalized"
801
+ },
802
+ {
803
+ title: "Trending: The Grand Adventure hits #1",
804
+ source: "Netflix",
805
+ time: "5 hours ago",
806
+ excerpt: "The comedy adventure movie is now the most-watched title on Netflix this week.",
807
+ category: "trending"
808
+ },
809
+ {
810
+ title: "Breaking: New streaming partnership announced",
811
+ source: "Streaming News",
812
+ time: "1 day ago",
813
+ excerpt: "Major platforms announce new content sharing agreement starting next month.",
814
+ category: "news"
815
+ },
816
+ {
817
+ title: "Recommended for you: Space Explorers",
818
+ source: "Disney+",
819
+ time: "1 day ago",
820
+ excerpt: "Based on your interest in science documentaries, we recommend this new series.",
821
+ category: "personalized"
822
+ },
823
+ {
824
+ title: "Upcoming: Romantic Getaway special event",
825
+ source: "Amazon Prime",
826
+ time: "2 days ago",
827
+ excerpt: "Join the cast for a live Q&A before the movie premiere this weekend.",
828
+ category: "trending"
829
+ }
830
+ ],
831
+ news: [
832
+ {
833
+ title: "Breaking: New streaming partnership announced",
834
+ source: "Streaming News",
835
+ time: "1 day ago",
836
+ excerpt: "Major platforms announce new content sharing agreement starting next month.",
837
+ category: "news"
838
+ },
839
+ {
840
+ title: "Streaming industry report Q4 2023",
841
+ source: "Tech Insights",
842
+ time: "3 days ago",
843
+ excerpt: "Latest statistics show continued growth in streaming subscriptions worldwide.",
844
+ category: "news"
845
+ }
846
+ ],
847
+ trending: [
848
+ {
849
+ title: "Trending: The Grand Adventure hits #1",
850
+ source: "Netflix",
851
+ time: "5 hours ago",
852
+ excerpt: "The comedy adventure movie is now the most-watched title on Netflix this week.",
853
+ category: "trending"
854
+ },
855
+ {
856
+ title: "Upcoming: Romantic Getaway special event",
857
+ source: "Amazon Prime",
858
+ time: "2 days ago",
859
+ excerpt: "Join the cast for a live Q&A before the movie premiere this weekend.",
860
+ category: "trending"
861
+ }
862
+ ],
863
+ personalized: [
864
+ {
865
+ title: "New Episode: SMPlus Exclusive Series",
866
+ source: "SMPlus VHX",
867
+ time: "2 hours ago",
868
+ excerpt: "The latest episode of our exclusive series is now streaming with intense action scenes.",
869
+ category: "personalized"
870
+ },
871
+ {
872
+ title: "Recommended for you: Space Explorers",
873
+ source: "Disney+",
874
+ time: "1 day ago",
875
+ excerpt: "Based on your interest in science documentaries, we recommend this new series.",
876
+ category: "personalized"
877
+ }
878
+ ]
879
+ };
880
+
881
+ // Video production variables
882
+ let isRecording = false;
883
+ let recordingInterval;
884
+ let recordedClips = [];
885
+ let mediaRecorder;
886
+ let audioContext;
887
+ let audioStream;
888
+ let videoStream;
889
+ let currentClipTime = 0;
890
+ let currentClipInterval;
891
+
892
+ // Bluetooth sharing variables
893
+ let isBluetoothConnected = false;
894
+ let bluetoothDevice;
895
+ let bluetoothServer;
896
+ let bluetoothService;
897
+ let bluetoothCharacteristic;
898
+ let sharedClips = [];
899
+ let groupMembers = [];
900
+ let username = "User" + Math.floor(Math.random() * 1000);
901
+ let currentCategory = "general";
902
+
903
+ // Initialize chat
904
+ document.addEventListener('DOMContentLoaded', function() {
905
+ const sendBtn = document.getElementById('send-btn');
906
+ const userInput = document.getElementById('user-input');
907
+ const chatMessages = document.getElementById('chat-messages');
908
+ const productionButton = document.getElementById('production-button');
909
+ const productionPanel = document.getElementById('production-panel');
910
+ const startRecordingBtn = document.getElementById('start-recording');
911
+ const stopRecordingBtn = document.getElementById('stop-recording');
912
+ const generateVideoBtn = document.getElementById('generate-video');
913
+ const clearClipsBtn = document.getElementById('clear-clips');
914
+ const rssFilterBtns = document.querySelectorAll('.rss-filter-btn');
915
+ const recordTab = document.getElementById('record-tab');
916
+ const editTab = document.getElementById('edit-tab');
917
+ const shareTab = document.getElementById('share-tab');
918
+ const rankTab = document.getElementById('rank-tab');
919
+ const recordSection = document.getElementById('record-section');
920
+ const editSection = document.getElementById('edit-section');
921
+ const shareSection = document.getElementById('share-section');
922
+ const rankSection = document.getElementById('rank-section');
923
+ const bluetoothConnectBtn = document.getElementById('bluetooth-connect');
924
+ const shareClipsBtn = document.getElementById('share-clips');
925
+ const usernameInput = document.getElementById('username');
926
+ const contentCategorySelect = document.getElementById('content-category');
927
+ const rankingAlgorithmSelect = document.getElementById('ranking-algorithm');
928
+
929
+ // Set default username
930
+ usernameInput.value = username;
931
+
932
+ // Load sample recommendations
933
+ loadRecommendations();
934
+
935
+ // Load RSS feed
936
+ loadRSSFeed('all');
937
+
938
+ // Send message on button click
939
+ sendBtn.addEventListener('click', sendMessage);
940
+
941
+ // Send message on Enter key
942
+ userInput.addEventListener('keypress', function(e) {
943
+ if (e.key === 'Enter') {
944
+ sendMessage();
945
+ }
946
+ });
947
+
948
+ // Toggle production panel
949
+ productionButton.addEventListener('click', function() {
950
+ productionPanel.classList.toggle('open');
951
+ });
952
+
953
+ // Start recording
954
+ startRecordingBtn.addEventListener('click', startRecording);
955
+
956
+ // Stop recording
957
+ stopRecordingBtn.addEventListener('click', stopRecording);
958
+
959
+ // Generate video
960
+ generateVideoBtn.addEventListener('click', generateShortVideo);
961
+
962
+ // Clear clips
963
+ clearClipsBtn.addEventListener('click', clearClips);
964
+
965
+ // Filter RSS feed
966
+ rssFilterBtns.forEach(btn => {
967
+ btn.addEventListener('click', function() {
968
+ // Update active button
969
+ rssFilterBtns.forEach(b => {
970
+ b.classList.remove('bg-indigo-100', 'text-indigo-700');
971
+ b.classList.add('bg-gray-100', 'text-gray-700');
972
+ });
973
+ this.classList.remove('bg-gray-100', 'text-gray-700');
974
+ this.classList.add('bg-indigo-100', 'text-indigo-700');
975
+
976
+ // Load filtered feed
977
+ loadRSSFeed(this.dataset.filter);
978
+ });
979
+ });
980
+
981
+ // Switch between record and edit tabs
982
+ recordTab.addEventListener('click', function() {
983
+ recordTab.classList.remove('inactive');
984
+ recordTab.classList.add('active');
985
+ editTab.classList.remove('active');
986
+ editTab.classList.add('inactive');
987
+ shareTab.classList.remove('active');
988
+ shareTab.classList.add('inactive');
989
+ rankTab.classList.remove('active');
990
+ rankTab.classList.add('inactive');
991
+ recordSection.classList.remove('hidden');
992
+ editSection.classList.add('hidden');
993
+ shareSection.classList.add('hidden');
994
+ rankSection.classList.add('hidden');
995
+ });
996
+
997
+ editTab.addEventListener('click', function() {
998
+ if (recordedClips.length === 0) {
999
+ showNotification("No Clips", "Record some clips first to edit them");
1000
+ return;
1001
+ }
1002
+
1003
+ editTab.classList.remove('inactive');
1004
+ editTab.classList.add('active');
1005
+ recordTab.classList.remove('active');
1006
+ recordTab.classList.add('inactive');
1007
+ shareTab.classList.remove('active');
1008
+ shareTab.classList.add('inactive');
1009
+ rankTab.classList.remove('active');
1010
+ rankTab.classList.add('inactive');
1011
+ recordSection.classList.add('hidden');
1012
+ editSection.classList.remove('hidden');
1013
+ shareSection.classList.add('hidden');
1014
+ rankSection.classList.add('hidden');
1015
+ });
1016
+
1017
+ shareTab.addEventListener('click', function() {
1018
+ shareTab.classList.remove('inactive');
1019
+ shareTab.classList.add('active');
1020
+ recordTab.classList.remove('active');
1021
+ recordTab.classList.add('inactive');
1022
+ editTab.classList.remove('active');
1023
+ editTab.classList.add('inactive');
1024
+ rankTab.classList.remove('active');
1025
+ rankTab.classList.add('inactive');
1026
+ recordSection.classList.add('hidden');
1027
+ editSection.classList.add('hidden');
1028
+ shareSection.classList.remove('hidden');
1029
+ rankSection.classList.add('hidden');
1030
+ });
1031
+
1032
+ rankTab.addEventListener('click', function() {
1033
+ if (sharedClips.length === 0) {
1034
+ showNotification("No Shared Clips", "Share some clips first to see rankings");
1035
+ return;
1036
+ }
1037
+
1038
+ rankTab.classList.remove('inactive');
1039
+ rankTab.classList.add('active');
1040
+ recordTab.classList.remove('active');
1041
+ recordTab.classList.add('inactive');
1042
+ editTab.classList.remove('active');
1043
+ editTab.classList.add('inactive');
1044
+ shareTab.classList.remove('active');
1045
+ shareTab.classList.add('inactive');
1046
+ recordSection.classList.add('hidden');
1047
+ editSection.classList.add('hidden');
1048
+ shareSection.classList.add('hidden');
1049
+ rankSection.classList.remove('hidden');
1050
+
1051
+ // Update rankings when tab is opened
1052
+ updateRankings();
1053
+ });
1054
+
1055
+ // Connect to Bluetooth
1056
+ bluetoothConnectBtn.addEventListener('click', connectBluetooth);
1057
+
1058
+ // Share clips
1059
+ shareClipsBtn.addEventListener('click', shareClipsWithGroup);
1060
+
1061
+ // Update username when changed
1062
+ usernameInput.addEventListener('change', function() {
1063
+ username = this.value || "User" + Math.floor(Math.random() * 1000);
1064
+ });
1065
+
1066
+ // Update category when changed
1067
+ contentCategorySelect.addEventListener('change', function() {
1068
+ currentCategory = this.value;
1069
+ });
1070
+
1071
+ // Update rankings when algorithm changes
1072
+ rankingAlgorithmSelect.addEventListener('change', updateRankings);
1073
+ });
1074
+
1075
+ // Show notification
1076
+ function showNotification(title, message) {
1077
+ const notification = document.getElementById('notification');
1078
+ const titleElement = document.getElementById('notification-title');
1079
+ const messageElement = document.getElementById('notification-message');
1080
+
1081
+ titleElement.textContent = title;
1082
+ messageElement.textContent = message;
1083
+
1084
+ notification.classList.remove('hidden');
1085
+ notification.classList.add('show');
1086
+
1087
+ setTimeout(() => {
1088
+ notification.classList.remove('show');
1089
+ setTimeout(() => notification.classList.add('hidden'), 300);
1090
+ }, 3000);
1091
+ }
1092
+
1093
+ // Quick prompt buttons
1094
+ function quickPrompt(prompt) {
1095
+ document.getElementById('user-input').value = prompt;
1096
+ sendMessage();
1097
+ }
1098
+
1099
+ // Send message to AI
1100
+ async function sendMessage() {
1101
+ const userInput = document.getElementById('user-input');
1102
+ const chatMessages = document.getElementById('chat-messages');
1103
+
1104
+ if (userInput.value.trim() === '') return;
1105
+
1106
+ // Add user message to chat
1107
+ const userMessage = document.createElement('div');
1108
+ userMessage.className = 'chat-bubble user-bubble p-4 w-3/4 ml-auto mb-4 fade-in';
1109
+ userMessage.innerHTML = `<p>${userInput.value}</p>`;
1110
+ chatMessages.appendChild(userMessage);
1111
+
1112
+ // Show typing indicator
1113
+ const typingIndicator = document.createElement('div');
1114
+ typingIndicator.className = 'chat-bubble ai-bubble p-4 w-1/2 mb-4';
1115
+ typingIndicator.innerHTML = '<div class="typing-indicator"><span></span><span></span><span></span></div>';
1116
+ chatMessages.appendChild(typingIndicator);
1117
+
1118
+ // Scroll to bottom
1119
+ chatMessages.scrollTop = chatMessages.scrollHeight;
1120
+
1121
+ // Save user message
1122
+ const userMessageText = userInput.value;
1123
+ userInput.value = '';
1124
+
1125
+ try {
1126
+ // Call Cloudflare Workers AI
1127
+ const aiResponse = await queryCloudflareAI(userMessageText);
1128
+
1129
+ // Remove typing indicator
1130
+ chatMessages.removeChild(typingIndicator);
1131
+
1132
+ // Add AI response to chat
1133
+ const aiMessage = document.createElement('div');
1134
+ aiMessage.className = 'chat-bubble ai-bubble p-4 w-3/4 fade-in';
1135
+ aiMessage.innerHTML = `<p>${aiResponse}</p>`;
1136
+ chatMessages.appendChild(aiMessage);
1137
+
1138
+ // Update recommendations based on AI response
1139
+ updateRecommendationsFromAI(aiResponse);
1140
+
1141
+ } catch (error) {
1142
+ // Remove typing indicator
1143
+ chatMessages.removeChild(typingIndicator);
1144
+
1145
+ // Show error message
1146
+ const errorMessage = document.createElement('div');
1147
+ errorMessage.className = 'chat-bubble ai-bubble p-4 w-3/4 fade-in';
1148
+ errorMessage.innerHTML = `<p class="text-red-500">Sorry, I'm having trouble connecting to the AI service. Please try again later.</p>`;
1149
+ chatMessages.appendChild(errorMessage);
1150
+ }
1151
+
1152
+ // Scroll to bottom
1153
+ chatMessages.scrollTop = chatMessages.scrollHeight;
1154
+ }
1155
+
1156
+ // Query Cloudflare Workers AI
1157
+ async function queryCloudflareAI(prompt) {
1158
+ // In a production environment, this would be handled by a backend service
1159
+ // to keep the API token secure. For this demo, we'll simulate the response.
1160
+
1161
+ console.log(`[DEBUG] Would call Cloudflare AI with prompt: "${prompt}"`);
1162
+
1163
+ // Simulate API call delay
1164
+ await new Promise(resolve => setTimeout(resolve, 1500));
1165
+
1166
+ // Simulate different responses based on prompt
1167
+ const lowerPrompt = prompt.toLowerCase();
1168
+
1169
+ if (lowerPrompt.includes('comedy') || lowerPrompt.includes('funny')) {
1170
+ return "I'd recommend these comedy options that should give you a good laugh:\n\n1. 'The Grand Adventure' (Netflix) - A hilarious journey with unexpected twists\n2. 'Office Shenanigans' (Hulu) - Workplace comedy at its finest\n\nComedy can really lift your mood! Would you like more suggestions?";
1171
+ }
1172
+ else if (lowerPrompt.includes('thriller') || lowerPrompt.includes('suspense')) {
1173
+ return "For thrilling content that will keep you on the edge of your seat, consider:\n\n1. 'Dark Secrets' (HBO Max) - A town's dark past resurfaces\n2. 'Midnight Caller' (Amazon Prime) - A psychological thriller about a mysterious phone call\n\nThese should provide plenty of suspense!";
1174
+ }
1175
+ else if (lowerPrompt.includes('romance') || lowerPrompt.includes('love')) {
1176
+ return "Romantic stories can be so heartwarming! Here are my top picks:\n\n1. 'Romantic Getaway' (Amazon Prime) - Two strangers find love on vacation\n2. 'Love in Paris' (Netflix) - A classic romantic tale set in the City of Love\n\nLet me know if you'd like something more specific!";
1177
+ }
1178
+ else if (lowerPrompt.includes('recommend') || lowerPrompt.includes('suggest')) {
1179
+ return "Based on your request, I'd recommend these excellent streaming options:\n\n1. 'SMPlus Exclusive Series' (SMPlus VHX) - Action-packed drama series\n2. 'Space Explorers' (Disney+) - Fascinating documentary about space\n\nI've updated the recommendations section with more options for you!";
1180
+ }
1181
+ else {
1182
+ return "I'm here to help you find the perfect streaming content! Could you tell me more about what you're looking for? For example, you could say 'recommend a sci-fi movie' or 'what should I watch if I feel like laughing?'";
1183
+ }
1184
+ }
1185
+
1186
+ // Update recommendations based on AI response
1187
+ function updateRecommendationsFromAI(aiResponse) {
1188
+ let filter = 'all';
1189
+
1190
+ if (aiResponse.includes('comedy')) {
1191
+ filter = 'comedy';
1192
+ } else if (aiResponse.includes('thriller') || aiResponse.includes('suspense')) {
1193
+ filter = 'thriller';
1194
+ } else if (aiResponse.includes('romance') || aiResponse.includes('love')) {
1195
+ filter = 'romance';
1196
+ }
1197
+
1198
+ loadRecommendations(filter);
1199
+ }
1200
+
1201
+ // Save show and set broadcast reminder
1202
+ function saveShow(title, broadcastTime) {
1203
+ // In a real app, this would save to a database
1204
+ console.log(`Saved show: ${title}`);
1205
+
1206
+ // Show notification
1207
+ showNotification("Reminder Set!", `We'll notify you when "${title}" is about to broadcast.`);
1208
+
1209
+ // In a real app, you would schedule a notification for the broadcast time
1210
+ if (broadcastTime) {
1211
+ const broadcastDate = new Date(broadcastTime);
1212
+ const now = new Date();
1213
+
1214
+ // Only schedule if broadcast is in the future
1215
+ if (broadcastDate > now) {
1216
+ const timeUntilBroadcast = broadcastDate - now;
1217
+
1218
+ // Schedule notification 30 minutes before broadcast
1219
+ setTimeout(() => {
1220
+ showNotification("Starting Soon!", `"${title}" will begin broadcasting in 30 minutes!`);
1221
+ }, timeUntilBroadcast - (30 * 60 * 1000));
1222
+ }
1223
+ }
1224
+ }
1225
+
1226
+ // Load recommendations
1227
+ function loadRecommendations(filter = 'all') {
1228
+ const container = document.getElementById('recommendations-container');
1229
+ container.innerHTML = '';
1230
+
1231
+ let filteredData = streamingData;
1232
+
1233
+ if (filter === 'comedy') {
1234
+ filteredData = streamingData.filter(item => item.genre.toLowerCase().includes('comedy'));
1235
+ } else if (filter === 'thriller') {
1236
+ filteredData = streamingData.filter(item => item.genre.toLowerCase().includes('thriller'));
1237
+ } else if (filter === 'romance') {
1238
+ filteredData = streamingData.filter(item => item.genre.toLowerCase().includes('romance'));
1239
+ }
1240
+
1241
+ filteredData.forEach(item => {
1242
+ const card = document.createElement('div');
1243
+ card.className = 'stream-card bg-white rounded-lg overflow-hidden shadow-md hover:shadow-xl transition duration-300 fade-in p-4';
1244
+ card.innerHTML = `
1245
+ <div class="mb-3">
1246
+ <div class="flex justify-between items-start">
1247
+ <h3 class="font-bold text-base">${item.title}</h3>
1248
+ <span class="bg-yellow-100 text-yellow-800 text-xs px-2 py-1 rounded-full flex items-center">
1249
+ <i class="fas fa-star text-yellow-500 mr-1 text-xs"></i> ${item.rating}
1250
+ </span>
1251
+ </div>
1252
+ <p class="text-gray-600 text-xs mb-1">${item.type} • ${item.genre} • ${item.year}</p>
1253
+ <div class="text-xs text-indigo-600 mb-2">${item.platform}</div>
1254
+ </div>
1255
+ <p class="text-gray-700 text-sm mb-4">${item.description}</p>
1256
+ <div class="flex justify-between items-center">
1257
+ <button class="text-indigo-600 hover:text-indigo-800 text-xs font-medium" onclick="saveShow('${item.title}', '${item.broadcastTime}')">
1258
+ <i class="far fa-bookmark mr-1"></i> Save
1259
+ </button>
1260
+ <a href="${item.platform === 'SMPlus VHX' ? 'https://smplus.vhx.tv' : '#'}" target="_blank" class="bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1 rounded-full text-xs font-medium transition">
1261
+ <i class="fas fa-play mr-1"></i> Watch
1262
+ </a>
1263
+ </div>
1264
+ `;
1265
+ container.appendChild(card);
1266
+ });
1267
+ }
1268
+
1269
+ // Load RSS feed
1270
+ function loadRSSFeed(filter) {
1271
+ const container = document.getElementById('rss-feed');
1272
+ container.innerHTML = '';
1273
+
1274
+ const feedItems = rssFeedData[filter] || rssFeedData.all;
1275
+
1276
+ feedItems.forEach(item => {
1277
+ const feedItem = document.createElement('div');
1278
+ feedItem.className = 'rss-item bg-gray-50 p-3 rounded-lg';
1279
+ feedItem.innerHTML = `
1280
+ <h4 class="font-medium text-sm mb-1">${item.title}</h4>
1281
+ <div class="flex items-center text-xs text-gray-500 mb-2">
1282
+ <span>${item.source}</span>
1283
+ <span class="mx-2">•</span>
1284
+ <span>${item.time}</span>
1285
+ </div>
1286
+ <p class="text-xs text-gray-700">${item.excerpt}</p>
1287
+ `;
1288
+ container.appendChild(feedItem);
1289
+ });
1290
+ }
1291
+
1292
+ // Start recording video and audio
1293
+ async function startRecording() {
1294
+ try {
1295
+ // Get user media
1296
+ videoStream = await navigator.mediaDevices.getDisplayMedia({
1297
+ video: true,
1298
+ audio: true
1299
+ });
1300
+
1301
+ audioStream = await navigator.mediaDevices.getUserMedia({
1302
+ audio: true
1303
+ });
1304
+
1305
+ // Create audio context
1306
+ audioContext = new AudioContext();
1307
+ const source = audioContext.createMediaStreamSource(audioStream);
1308
+ const destination = audioContext.createMediaStreamDestination();
1309
+ source.connect(destination);
1310
+
1311
+ // Combine video and audio streams
1312
+ const combinedStream = new MediaStream([
1313
+ ...videoStream.getVideoTracks(),
1314
+ ...destination.stream.getAudioTracks()
1315
+ ]);
1316
+
1317
+ // Create media recorder
1318
+ mediaRecorder = new MediaRecorder(combinedStream, {
1319
+ mimeType: 'video/webm'
1320
+ });
1321
+
1322
+ // Update preview with live recording
1323
+ const preview = document.getElementById('clip-preview');
1324
+ preview.innerHTML = '<video autoplay muted></video>';
1325
+ const previewVideo = preview.querySelector('video');
1326
+ previewVideo.srcObject = combinedStream;
1327
+
1328
+ // Set recording state
1329
+ isRecording = true;
1330
+ document.getElementById('recording-indicator').classList.remove('hidden');
1331
+ document.getElementById('start-recording').classList.add('hidden');
1332
+ document.getElementById('stop-recording').classList.remove('hidden');
1333
+
1334
+ // Start progress bar animation
1335
+ currentClipTime = 0;
1336
+ const progressFill = document.getElementById('progress-fill');
1337
+ progressFill.style.width = '0%';
1338
+
1339
+ currentClipInterval = setInterval(() => {
1340
+ currentClipTime += 100;
1341
+ const progressPercent = (currentClipTime / 5000) * 100;
1342
+ progressFill.style.width = `${progressPercent}%`;
1343
+ }, 100);
1344
+
1345
+ // Start recording in 5-second clips
1346
+ let clipCount = 0;
1347
+ recordingInterval = setInterval(() => {
1348
+ if (clipCount > 0) {
1349
+ // Stop current recording
1350
+ mediaRecorder.stop();
1351
+ }
1352
+
1353
+ // Start new recording
1354
+ mediaRecorder.start();
1355
+ clipCount++;
1356
+
1357
+ // Reset progress bar
1358
+ currentClipTime = 0;
1359
+ progressFill.style.width = '0%';
1360
+
1361
+ // Store clip data when available
1362
+ mediaRecorder.ondataavailable = (e) => {
1363
+ const clip = {
1364
+ blob: e.data,
1365
+ timestamp: new Date().toLocaleTimeString(),
1366
+ url: URL.createObjectURL(e.data),
1367
+ username: username,
1368
+ category: currentCategory,
1369
+ engagementScore: Math.random() * 5, // Simulated metrics
1370
+ qualityScore: 3 + Math.random() * 2,
1371
+ consistencyScore: 3 + Math.random() * 2
1372
+ };
1373
+ recordedClips.push(clip);
1374
+ updateClipsList();
1375
+ };
1376
+ }, 5000);
1377
+
1378
+ showNotification("Recording Started", "Recording 5-second clips of your screen and audio");
1379
+
1380
+ } catch (error) {
1381
+ console.error("Error starting recording:", error);
1382
+ showNotification("Recording Error", "Could not start recording. Please check permissions.");
1383
+ stopRecording();
1384
+ }
1385
+ }
1386
+
1387
+ // Stop recording
1388
+ function stopRecording() {
1389
+ if (mediaRecorder && mediaRecorder.state !== 'inactive') {
1390
+ mediaRecorder.stop();
1391
+ }
1392
+
1393
+ clearInterval(recordingInterval);
1394
+ clearInterval(currentClipInterval);
1395
+ isRecording = false;
1396
+
1397
+ // Stop all tracks
1398
+ if (videoStream) {
1399
+ videoStream.getTracks().forEach(track => track.stop());
1400
+ }
1401
+ if (audioStream) {
1402
+ audioStream.getTracks().forEach(track => track.stop());
1403
+ }
1404
+
1405
+ // Close audio context
1406
+ if (audioContext && audioContext.state !== 'closed') {
1407
+ audioContext.close();
1408
+ }
1409
+
1410
+ // Reset preview
1411
+ const preview = document.getElementById('clip-preview');
1412
+ preview.innerHTML = `
1413
+ <div class="clip-preview-placeholder">
1414
+ <i class="fas fa-video"></i>
1415
+ <p>Preview will appear here</p>
1416
+ </div>
1417
+ `;
1418
+
1419
+ // Reset progress bar
1420
+ document.getElementById('progress-fill').style.width = '0%';
1421
+
1422
+ // Update UI
1423
+ document.getElementById('recording-indicator').classList.add('hidden');
1424
+ document.getElementById('start-recording').classList.remove('hidden');
1425
+ document.getElementById('stop-recording').classList.add('hidden');
1426
+
1427
+ showNotification("Recording Stopped", `Captured ${recordedClips.length} clips ready for production`);
1428
+ }
1429
+
1430
+ // Update clips list
1431
+ function updateClipsList() {
1432
+ const container = document.getElementById('clips-container');
1433
+ container.innerHTML = '';
1434
+
1435
+ if (recordedClips.length === 0) {
1436
+ container.innerHTML = '<p class="text-gray-500 text-sm">Clips will appear here...</p>';
1437
+ return;
1438
+ }
1439
+
1440
+ recordedClips.forEach((clip, index) => {
1441
+ const clipItem = document.createElement('div');
1442
+ clipItem.className = 'clip-item';
1443
+ clipItem.innerHTML = `
1444
+ <i class="fas fa-video text-gray-500 mr-2"></i>
1445
+ <span class="text-sm flex-1">Clip ${index + 1}</span>
1446
+ <span class="text-xs text-gray-500">${clip.timestamp}</span>
1447
+ `;
1448
+
1449
+ // Add click handler to preview clip
1450
+ clipItem.addEventListener('click', () => {
1451
+ const preview = document.getElementById('clip-preview');
1452
+ preview.innerHTML = '<video controls></video>';
1453
+ const previewVideo = preview.querySelector('video');
1454
+ previewVideo.src = clip.url;
1455
+ });
1456
+
1457
+ container.appendChild(clipItem);
1458
+ });
1459
+ }
1460
+
1461
+ // Clear all clips
1462
+ function clearClips() {
1463
+ if (recordedClips.length === 0) return;
1464
+
1465
+ // In a real app, we would properly revoke the object URLs
1466
+ recordedClips.forEach(clip => {
1467
+ if (clip.url) {
1468
+ URL.revokeObjectURL(clip.url);
1469
+ }
1470
+ });
1471
+
1472
+ recordedClips = [];
1473
+ updateClipsList();
1474
+
1475
+ // Reset preview
1476
+ const preview = document.getElementById('clip-preview');
1477
+ preview.innerHTML = `
1478
+ <div class="clip-preview-placeholder">
1479
+ <i class="fas fa-video"></i>
1480
+ <p>Preview will appear here</p>
1481
+ </div>
1482
+ `;
1483
+
1484
+ showNotification("Clips Cleared", "All recorded clips have been removed");
1485
+ }
1486
+
1487
+ // Generate short video from clips
1488
+ function generateShortVideo() {
1489
+ if (recordedClips.length === 0) {
1490
+ showNotification("No Clips", "Please record some clips first");
1491
+ return;
1492
+ }
1493
+
1494
+ // In a real app, this would use a video editing library to combine clips
1495
+ // and sync with audio. For this demo, we'll simulate the process.
1496
+
1497
+ showNotification("Video Generation", "Processing your clips into a short video...");
1498
+
1499
+ setTimeout(() => {
1500
+ // Simulate processing time
1501
+ const videoUrl = URL.createObjectURL(new Blob(["Simulated video content"], { type: 'video/mp4' }));
1502
+
1503
+ // Create download link
1504
+ const a = document.createElement('a');
1505
+ a.href = videoUrl;
1506
+ a.download = 'streamai-short.mp4';
1507
+ a.click();
1508
+
1509
+ showNotification("Video Ready", "Your short video has been generated and downloaded");
1510
+ }, 3000);
1511
+ }
1512
+
1513
+ // Connect to Bluetooth devices
1514
+ async function connectBluetooth() {
1515
+ try {
1516
+ // Request Bluetooth device
1517
+ bluetoothDevice = await navigator.bluetooth.requestDevice({
1518
+ acceptAllDevices: true,
1519
+ optionalServices: ['generic_access']
1520
+ });
1521
+
1522
+ // Connect to the GATT Server
1523
+ bluetoothServer = await bluetoothDevice.gatt.connect();
1524
+
1525
+ // Get the service
1526
+ bluetoothService = await bluetoothServer.getPrimaryService('generic_access');
1527
+
1528
+ // Get the characteristic
1529
+ bluetoothCharacteristic = await bluetoothService.getCharacteristic('device_name');
1530
+
1531
+ // Update connection status
1532
+ isBluetoothConnected = true;
1533
+ const statusElement = document.getElementById('connection-status');
1534
+ statusElement.innerHTML = `
1535
+ <i class="fas fa-circle bluetooth-connected mr-1"></i>
1536
+ <span>Connected to ${bluetoothDevice.name || 'device'}</span>
1537
+ `;
1538
+
1539
+ // Simulate discovering group members
1540
+ groupMembers = [
1541
+ { name: "User" + Math.floor(Math.random() * 1000), device: "Device 1" },
1542
+ { name: "User" + Math.floor(Math.random() * 1000), device: "Device 2" },
1543
+ { name: "User" + Math.floor(Math.random() * 1000), device: "Device 3" }
1544
+ ];
1545
+
1546
+ showNotification("Bluetooth Connected", `Connected to ${bluetoothDevice.name}. Found ${groupMembers.length} group members.`);
1547
+
1548
+ } catch (error) {
1549
+ console.error("Bluetooth connection error:", error);
1550
+ isBluetoothConnected = false;
1551
+ document.getElementById('connection-status').innerHTML = `
1552
+ <i class="fas fa-circle bluetooth-disconnected mr-1"></i>
1553
+ <span>Not connected</span>
1554
+ `;
1555
+ showNotification("Connection Failed", "Could not connect to Bluetooth device");
1556
+ }
1557
+ }
1558
+
1559
+ // Share clips with Bluetooth group
1560
+ async function shareClipsWithGroup() {
1561
+ if (!isBluetoothConnected) {
1562
+ showNotification("Not Connected", "Please connect to Bluetooth first");
1563
+ return;
1564
+ }
1565
+
1566
+ if (recordedClips.length === 0) {
1567
+ showNotification("No Clips", "Please record some clips first");
1568
+ return;
1569
+ }
1570
+
1571
+ // In a real app, this would actually send the clips over Bluetooth
1572
+ // For this demo, we'll simulate the sharing process
1573
+
1574
+ showNotification("Sharing Clips", "Sharing your clips with the group...");
1575
+
1576
+ // Simulate sharing delay
1577
+ setTimeout(() => {
1578
+ // Add metadata to clips and add to shared clips
1579
+ recordedClips.forEach(clip => {
1580
+ const sharedClip = {
1581
+ ...clip,
1582
+ sharedBy: username,
1583
+ category: currentCategory,
1584
+ timestamp: new Date().toLocaleTimeString(),
1585
+ likes: Math.floor(Math.random() * 10),
1586
+ views: Math.floor(Math.random() * 50)
1587
+ };
1588
+ sharedClips.push(sharedClip);
1589
+ });
1590
+
1591
+ // Update shared clips display
1592
+ updateSharedClipsList();
1593
+
1594
+ showNotification("Clips Shared", `Shared ${recordedClips.length} clips with ${groupMembers.length} group members`);
1595
+ }, 2000);
1596
+ }
1597
+
1598
+ // Update shared clips list
1599
+ function updateSharedClipsList() {
1600
+ const container = document.getElementById('shared-clips-container');
1601
+ container.innerHTML = '';
1602
+
1603
+ if (sharedClips.length === 0) {
1604
+ container.innerHTML = '<p class="text-gray-500 text-sm">Shared clips will appear here...</p>';
1605
+ return;
1606
+ }
1607
+
1608
+ sharedClips.forEach((clip, index) => {
1609
+ const clipItem = document.createElement('div');
1610
+ clipItem.className = 'clip-item';
1611
+ clipItem.innerHTML = `
1612
+ <i class="fas fa-video text-gray-500 mr-2"></i>
1613
+ <span class="text-sm flex-1">Clip ${index + 1}</span>
1614
+ <span class="user-tag">${clip.sharedBy}</span>
1615
+ <span class="category-tag">${clip.category}</span>
1616
+ `;
1617
+
1618
+ // Add click handler to preview clip
1619
+ clipItem.addEventListener('click', () => {
1620
+ const preview = document.getElementById('clip-preview');
1621
+ preview.innerHTML = '<video controls></video>';
1622
+ const previewVideo = preview.querySelector('video');
1623
+ previewVideo.src = clip.url;
1624
+ });
1625
+
1626
+ container.appendChild(clipItem);
1627
+ });
1628
+ }
1629
+
1630
+ // Benchmarking algorithm to rank clips
1631
+ function benchmarkClips() {
1632
+ if (sharedClips.length === 0) return [];
1633
+
1634
+ // Calculate scores for each clip
1635
+ sharedClips.forEach(clip => {
1636
+ // Composite score is weighted average of all metrics
1637
+ clip.compositeScore = (
1638
+ clip.engagementScore * 0.4 +
1639
+ clip.qualityScore * 0.3 +
1640
+ clip.consistencyScore * 0.3
1641
+ );
1642
+
1643
+ // Add some randomness to simulate different algorithms
1644
+ clip.engagementScore = Math.min(5, clip.engagementScore + Math.random() * 0.5 - 0.25);
1645
+ clip.qualityScore = Math.min(5, clip.qualityScore + Math.random() * 0.5 - 0.25);
1646
+ clip.consistencyScore = Math.min(5, clip.consistencyScore + Math.random() * 0.5 - 0.25);
1647
+ });
1648
+
1649
+ // Sort based on selected algorithm
1650
+ const algorithm = document.getElementById('ranking-algorithm').value;
1651
+ let sortedClips = [...sharedClips];
1652
+
1653
+ switch (algorithm) {
1654
+ case 'engagement':
1655
+ sortedClips.sort((a, b) => b.engagementScore - a.engagementScore);
1656
+ break;
1657
+ case 'quality':
1658
+ sortedClips.sort((a, b) => b.qualityScore - a.qualityScore);
1659
+ break;
1660
+ case 'consistency':
1661
+ sortedClips.sort((a, b) => b.consistencyScore - a.consistencyScore);
1662
+ break;
1663
+ case 'composite':
1664
+ default:
1665
+ sortedClips.sort((a, b) => b.compositeScore - a.compositeScore);
1666
+ break;
1667
+ }
1668
+
1669
+ return sortedClips;
1670
+ }
1671
+
1672
+ // Update rankings display
1673
+ function updateRankings() {
1674
+ const container = document.getElementById('rankings-container');
1675
+ container.innerHTML = '';
1676
+
1677
+ const rankedClips = benchmarkClips();
1678
+
1679
+ if (rankedClips.length === 0) {
1680
+ container.innerHTML = '<p class="text-gray-500 text-sm">Rankings will appear here when available...</p>';
1681
+ return;
1682
+ }
1683
+
1684
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ Keep all components operable modify Create Video Clips create an algorithm to benchmark each clip within a Bluetooth connected group sharing contentwith optional username, category, and feed consistency and make the algorithm rank each feed in the panel add all necessary components