azils3 commited on
Commit
a24cb71
·
verified ·
1 Parent(s): 93e4365

Update static/js/script.js

Browse files
Files changed (1) hide show
  1. static/js/script.js +695 -536
static/js/script.js CHANGED
@@ -1,537 +1,696 @@
1
- // Function to log messages to the logs div
2
- function logMessage(message) {
3
- const logsDiv = document.getElementById('logs');
4
- const logEntry = document.createElement('div');
5
- logEntry.textContent = message;
6
- logsDiv.appendChild(logEntry);
7
- logsDiv.scrollTop = logsDiv.scrollHeight; // Scroll to the bottom
8
- }
9
-
10
- // Function to generate video
11
- function generateVideo() {
12
- const formData = new FormData(document.getElementById('videoForm'));
13
- const apiKey = document.getElementById('apiKey').value; // Get API key from hidden input
14
-
15
- fetch('/api/generate-video', {
16
- method: 'POST',
17
- headers: {
18
- 'X-API-Key': apiKey
19
- },
20
- body: formData
21
- })
22
- .then(response => {
23
- if (response.ok) {
24
- return response.blob().then(blob => {
25
- const url = window.URL.createObjectURL(blob);
26
- const video = document.getElementById('generatedVideo');
27
- video.src = url;
28
- video.load(); // Load the video
29
- video.play(); // Play the video
30
- logMessage('Video generation successful!');
31
- document.getElementById('downloadVideoButton').disabled = false; // Enable download button
32
- });
33
- } else {
34
- return response.json().then(data => {
35
- throw new Error(data.error || 'Video generation failed');
36
- });
37
- }
38
- })
39
- .catch(error => {
40
- console.error('Error:', error);
41
- alert('Video generation failed: ' + error.message);
42
- logMessage('Video generation failed: ' + error.message);
43
- document.getElementById('downloadVideoButton').disabled = true; // Disable download button
44
- });
45
- }
46
-
47
- // Function to show popup
48
- function showPopup() {
49
- const textGenerator = document.getElementById('text-generator').value;
50
- const textGeneratorModel = document.getElementById('text-generator-model').value;
51
- const imageGenerator = document.getElementById('image-generator').value;
52
- const imageGeneratorModel = document.querySelector('.style-card.selected') ? document.querySelector('.style-card.selected').querySelector('.style-label').textContent : '';
53
- const speechGenerator = document.getElementById('speech-generator').value;
54
- const speechGeneratorVoice = document.querySelector('.voice-box.selected') ? document.querySelector('.voice-box.selected').querySelector('.voice-name').textContent : '';
55
- const disableSubtitles = document.getElementById('disable-subtitles').checked;
56
- const subtitlesColor = document.getElementById('subtitles-color').value;
57
- const subtitleFontName = document.getElementById('subtitle-font-name').value;
58
- const maxCharacterPerLine = document.getElementById('max-character-per-line').value;
59
- const subtitleFontSize = document.getElementById('subtitle-font-size').value;
60
- const subtitleStrokeWidth = document.getElementById('subtitle-stroke-width').value;
61
- const lines = document.querySelector('.line-button.active').textContent.replace(' Line', '');
62
- const highlightColor = document.getElementById('highlight-color').value;
63
- const niche = document.getElementById('niche').value;
64
- const language = document.getElementById('language').value;
65
-
66
- const selectedOptions = {
67
- "text_generator": textGenerator,
68
- "text_generator_model": textGeneratorModel,
69
- "image_generator": imageGenerator,
70
- "image_generator_model": imageGeneratorModel,
71
- "speech_generator": speechGenerator,
72
- "speech_generator_voice": speechGeneratorVoice,
73
- "disable_subtitles": disableSubtitles,
74
- "subtitles_color": subtitlesColor,
75
- "subtitle_font_name": subtitleFontName,
76
- "max_character_per_line": parseInt(maxCharacterPerLine),
77
- "subtitle_font_size": parseInt(subtitleFontSize),
78
- "subtitle_stroke_width": parseInt(subtitleStrokeWidth),
79
- "max_lines": parseInt(lines),
80
- "highlight_color": highlightColor,
81
- "niche": niche,
82
- "language": language
83
- };
84
-
85
- document.getElementById('popupOptions').textContent = JSON.stringify(selectedOptions, null, 2);
86
- document.getElementById('popupOverlay').style.display = 'flex';
87
-
88
- // Update form data
89
- document.getElementById('text_generator').value = textGenerator;
90
- document.getElementById('text_generator_model').value = textGeneratorModel;
91
- document.getElementById('image_generator').value = imageGenerator;
92
- document.getElementById('image_generator_model').value = imageGeneratorModel;
93
- document.getElementById('speech_generator').value = speechGenerator;
94
- document.getElementById('speech_generator_voice').value = speechGeneratorVoice;
95
- document.getElementById('disable_subtitles').checked = disableSubtitles;
96
- document.getElementById('subtitles_color').value = subtitlesColor;
97
- document.getElementById('subtitle_font_name').value = subtitleFontName;
98
- document.getElementById('subtitle_font_size').value = subtitleFontSize;
99
- document.getElementById('subtitle_stroke_color').value = document.getElementById('subtitle-stroke-color').value;
100
- document.getElementById('subtitle_stroke_width').value = subtitleStrokeWidth;
101
- document.getElementById('max_character_per_line').value = maxCharacterPerLine;
102
- document.getElementById('max_lines').value = lines;
103
- document.getElementById('highlight_color').value = highlightColor;
104
- document.getElementById('niche_hidden').value = niche;
105
- document.getElementById('language_hidden').value = language;
106
- }
107
-
108
- // Function to play or pause the generated video
109
- function playPauseVideo() {
110
- const video = document.getElementById('generatedVideo');
111
- if (video) {
112
- if (video.paused) {
113
- video.play();
114
- document.querySelector('.video-controls .control-button i').className = 'fas fa-pause';
115
- } else {
116
- video.pause();
117
- document.querySelector('.video-controls .control-button i').className = 'fas fa-play';
118
- }
119
- }
120
- }
121
-
122
- // Function to hide popup
123
- function hidePopup() {
124
- document.getElementById('popupOverlay').style.display = 'none';
125
- }
126
-
127
- // Function to show upgrade popup
128
- function showUpgradePopup() {
129
- document.getElementById('upgradePopupOverlay').style.display = 'flex';
130
- }
131
-
132
- // Function to hide upgrade popup
133
- function hideUpgradePopup() {
134
- document.getElementById('upgradePopupOverlay').style.display = 'none';
135
- }
136
-
137
- // Tab Switching
138
- document.querySelectorAll('.sidebar-item[data-tab]').forEach(item => {
139
- item.addEventListener('click', () => {
140
- document.querySelectorAll('.sidebar-item').forEach(i => i.classList.remove('active'));
141
- item.classList.add('active');
142
-
143
- document.querySelectorAll('.tab-content').forEach(content => content.style.display = 'none');
144
-
145
- const tabId = item.getAttribute('data-tab') + '-content';
146
- document.getElementById(tabId).style.display = 'block';
147
- });
148
- });
149
-
150
- // Style Card Selection
151
- function selectImage(element) {
152
- document.querySelectorAll('.style-card').forEach(card => {
153
- card.classList.remove('selected');
154
- });
155
- element.classList.add('selected');
156
-
157
- const imgSrc = element.querySelector('img').src;
158
- document.getElementById('preview-image').src = imgSrc;
159
- }
160
-
161
- // Populate Models Dropdown based on TEXT GENERATOR selection
162
- document.getElementById('text-generator').addEventListener('change', function() {
163
- const selectedTextGen = this.value;
164
- const modelsDropdown = document.getElementById('text-generator-model');
165
- modelsDropdown.innerHTML = '';
166
- fetch(`/text-generator-models/${selectedTextGen}`)
167
- .then(response => response.json())
168
- .then(data => {
169
- data.models.forEach(model => {
170
- const option = document.createElement('option');
171
- option.value = model;
172
- option.textContent = model;
173
- modelsDropdown.appendChild(option);
174
- });
175
- })
176
- .catch(error => {
177
- console.error('Error fetching text generator models:', error);
178
- logMessage('Error fetching text generator models: ' + error.message);
179
- });
180
- });
181
-
182
- // Populate Style Cards based on IMAGE GENERATOR selection
183
- document.getElementById('image-generator').addEventListener('change', function() {
184
- const selectedImageGen = this.value;
185
- const styleGrid = document.getElementById('style-grid');
186
- styleGrid.innerHTML = '';
187
- fetch(`/image-generator-models/${selectedImageGen}`)
188
- .then(response => response.json())
189
- .then(data => {
190
- data.models.forEach((style, index) => {
191
- const styleCard = document.createElement('div');
192
- styleCard.className = 'style-card';
193
- styleCard.onclick = function() { selectImage(this); };
194
- styleCard.innerHTML = `
195
- <img alt="${style} style image" src="/static/media/Image_Generators/${selectedImageGen.toLowerCase()}/${style.replace(/[\s\(]/g, '_').replace(/\)/g, '').toLowerCase()}.jpg"/>
196
- <div class="style-label">${style}</div>
197
- `;
198
- styleGrid.appendChild(styleCard);
199
- if (index === 0) { // Default to first style
200
- selectImage(styleCard);
201
- }
202
- });
203
- })
204
- .catch(error => {
205
- console.error('Error fetching image generator models:', error);
206
- logMessage('Error fetching image generator models: ' + error.message);
207
- });
208
- });
209
-
210
- // Populate Voices Grid based on SPEECH GENERATOR selection
211
- document.getElementById('speech-generator').addEventListener('change', function() {
212
- const selectedSpeechGen = this.value;
213
- const voiceGrid = document.getElementById('voice-grid');
214
- voiceGrid.innerHTML = '';
215
- fetch(`/speech-generator-models/${selectedSpeechGen}`)
216
- .then(response => response.json())
217
- .then(data => {
218
- data.models.forEach((voice, index) => {
219
- const voiceBox = document.createElement('div');
220
- voiceBox.className = 'voice-box';
221
- voiceBox.onclick = function() { selectVoice(this); };
222
- voiceBox.innerHTML = `
223
- <div class="voice-profile" style="background-color: ${index % 2 === 0 ? '#ff5733' : '#3399ff'};">
224
- ${index % 2 === 0 ? '' : '♂'}
225
- </div>
226
- <div class="voice-name">${voice}</div>
227
- <button class="play-button" onclick="playVoice('${voice}')">Play</button>
228
- `;
229
- voiceGrid.appendChild(voiceBox);
230
- if (index === 0) { // Default to first voice
231
- selectVoice(voiceBox);
232
- }
233
- });
234
- })
235
- .catch(error => {
236
- console.error('Error fetching speech generator models:', error);
237
- logMessage('Error fetching speech generator models: ' + error.message);
238
- });
239
- });
240
-
241
- // Voice Selection
242
- function selectVoice(element) {
243
- document.querySelectorAll('.voice-box').forEach(box => {
244
- box.classList.remove('selected');
245
- });
246
- element.classList.add('selected');
247
-
248
- const selectedVoiceName = element.querySelector('.voice-name').textContent;
249
- document.getElementById('preview-image').alt = `Preview of the selected voice: ${selectedVoiceName}`;
250
- }
251
-
252
- // Function to play voice
253
- function playVoice(voiceName) {
254
- const selectedSpeechGen = document.getElementById('speech-generator').value;
255
- const voiceNameSanitized = voiceName.toLowerCase().replace(/\s+/g, '_');
256
- const audioUrl = `/static/media/Speech_Generators/${selectedSpeechGen.toLowerCase()}/${voiceNameSanitized}.mp3`;
257
- const audio = new Audio(audioUrl);
258
- audio.play();
259
- }
260
-
261
- // Function to select music
262
- function selectMusic(element) {
263
- document.querySelectorAll('.music-box').forEach(box => {
264
- box.classList.remove('selected');
265
- });
266
- element.classList.add('selected');
267
-
268
- const selectedMusicName = element.querySelector('.music-name').textContent;
269
- document.getElementById('preview-image').alt = `Preview of the selected music: ${selectedMusicName}`;
270
- }
271
-
272
- // Function to play or stop music
273
- function playStopMusic(audioUrl, button) {
274
- const audio = new Audio(audioUrl);
275
- if (button.textContent === 'Play') {
276
- audio.play();
277
- button.textContent = 'Stop';
278
- } else {
279
- audio.pause();
280
- button.textContent = 'Play';
281
- }
282
- }
283
-
284
- // Set lines per caption
285
- function setLines(lines) {
286
- document.querySelectorAll('.line-button').forEach(button => {
287
- button.classList.remove('active');
288
- });
289
- document.querySelector(`.line-button:nth-child(${lines})`).classList.add('active');
290
- document.getElementById('max_lines').value = lines;
291
- }
292
-
293
- // Function to generate script
294
- function generateScript() {
295
- logMessage('Generating script...');
296
- const niche = document.getElementById('niche').value;
297
- const language = document.getElementById('language').value;
298
- const textGenerator = document.getElementById('text-generator').value;
299
- const textGeneratorModel = document.getElementById('text-generator-model').value;
300
-
301
- const request = {
302
- niche: niche,
303
- language: language,
304
- text_generator: textGenerator,
305
- text_generator_model: textGeneratorModel
306
- };
307
-
308
- fetch('/generate-script', {
309
- method: 'POST',
310
- headers: {
311
- 'Content-Type': 'application/json'
312
- },
313
- body: JSON.stringify(request)
314
- })
315
- .then(response => response.json())
316
- .then(data => {
317
- document.getElementById('generated-topic').value = data.topic;
318
- document.getElementById('generated-script').value = data.script;
319
- document.getElementById('generated-image-prompts').value = data.image_prompts.join(', ');
320
- document.getElementById('generated-metadata').value = JSON.stringify(data.metadata, null, 2);
321
- logMessage('Script generated successfully!');
322
- })
323
- .catch(error => {
324
- console.error('Error:', error);
325
- alert('Script generation failed: ' + error.message);
326
- logMessage('Script generation failed: ' + error.message);
327
- });
328
- }
329
-
330
- // Function to start loading
331
- function startLoading() {
332
- document.getElementById('popupOverlay').style.display = 'none';
333
-
334
- // Update video limit
335
- const videoLimitElement = document.getElementById('videoLimit');
336
- const currentLimit = parseInt(videoLimitElement.textContent.split('/')[0], 10);
337
- const maxLimit = parseInt(videoLimitElement.textContent.split('/')[1], 10);
338
- if (currentLimit < maxLimit) {
339
- videoLimitElement.textContent = `${currentLimit + 1}/${maxLimit}`;
340
- } else {
341
- alert('You have reached your daily video generation limit!');
342
- return;
343
- }
344
-
345
- // Clear previous content in the video-preview div
346
- const videoContainer = document.querySelector('.video-container');
347
- videoContainer.innerHTML = '';
348
-
349
- // Clear logs
350
- const logsDiv = document.getElementById('logs');
351
- logsDiv.innerHTML = '';
352
-
353
- // Call the generateVideo function to trigger video generation
354
- generateVideo();
355
- }
356
-
357
- // Function to download the generated video
358
- function downloadVideo() {
359
- const video = document.getElementById('generatedVideo');
360
- if (video && video.src) {
361
- const a = document.createElement('a');
362
- a.href = video.src;
363
- a.download = 'generated_video.mp4';
364
- document.body.appendChild(a);
365
- a.click();
366
- document.body.removeChild(a);
367
- } else {
368
- alert('No video to download.');
369
- }
370
- }
371
-
372
- // Profile Icon Click Event
373
- document.getElementById('profileIcon').addEventListener('click', function(event) {
374
- event.stopPropagation();
375
- const menu = document.getElementById('profileMenu');
376
- if (menu.style.display === 'block') {
377
- menu.style.display = 'none';
378
- } else {
379
- menu.style.display = 'block';
380
- }
381
- });
382
-
383
- // Close Profile Menu when clicking outside
384
- document.addEventListener('click', function(event) {
385
- const profileIcon = document.getElementById('profileIcon');
386
- const profileMenu = document.getElementById('profileMenu');
387
- if (!profileIcon.contains(event.target) && !profileMenu.contains(event.target)) {
388
- profileMenu.style.display = 'none';
389
- }
390
- });
391
-
392
- // Update slider values
393
- document.getElementById('max-character-per-line').addEventListener('input', function() {
394
- document.getElementById('max_chars_value').textContent = this.value;
395
- document.getElementById('max_character_per_line').value = this.value;
396
- });
397
-
398
- document.getElementById('subtitle-font-size').addEventListener('input', function() {
399
- document.getElementById('subtitle-font-size-value').textContent = this.value;
400
- document.getElementById('subtitle_font_size').value = this.value;
401
- });
402
-
403
- document.getElementById('subtitle-stroke-width').addEventListener('input', function() {
404
- document.getElementById('subtitle-stroke-width-value').textContent = this.value;
405
- document.getElementById('subtitle_stroke_width').value = this.value;
406
- });
407
-
408
- // Search functionality for Image tab
409
- document.getElementById('image-search').addEventListener('input', function() {
410
- const query = this.value.toLowerCase();
411
- const styleCards = document.querySelectorAll('.style-card');
412
- styleCards.forEach(card => {
413
- const label = card.querySelector('.style-label').textContent.toLowerCase();
414
- if (label.includes(query)) {
415
- card.style.display = 'block';
416
- } else {
417
- card.style.display = 'none';
418
- }
419
- });
420
- });
421
-
422
- // Search functionality for Audio tab
423
- document.getElementById('audio-search').addEventListener('input', function() {
424
- const query = this.value.toLowerCase();
425
- const voiceBoxes = document.querySelectorAll('.voice-box');
426
- voiceBoxes.forEach(box => {
427
- const name = box.querySelector('.voice-name').textContent.toLowerCase();
428
- if (name.includes(query)) {
429
- box.style.display = 'block';
430
- } else {
431
- box.style.display = 'none';
432
- }
433
- });
434
- });
435
-
436
- // Search functionality for Music tab
437
- document.getElementById('music-search').addEventListener('input', function() {
438
- const query = this.value.toLowerCase();
439
- const musicBoxes = document.querySelectorAll('.music-box');
440
- musicBoxes.forEach(box => {
441
- const name = box.querySelector('.music-name').textContent.toLowerCase();
442
- if (name.includes(query)) {
443
- box.style.display = 'block';
444
- } else {
445
- box.style.display = 'none';
446
- }
447
- });
448
- });
449
-
450
- // Initialize everything when the page loads
451
- document.addEventListener('DOMContentLoaded', function() {
452
- fetchUserData();
453
- setupSearch();
454
- populateFonts();
455
- populateMusics();
456
- });
457
-
458
- // Fetch User Data
459
- async function fetchUserData() {
460
- try {
461
- const response = await fetch('/api/user-data');
462
- const userData = await response.json();
463
- document.getElementById('user_id').value = userData.uuid;
464
- document.getElementById('username').value = userData.username;
465
- document.getElementById('profile_path').value = userData.profile_path;
466
- document.getElementById('videoLimit').textContent = userData.limit;
467
- document.getElementById('apiKey').value = userData.api_key; // Set API key in hidden input
468
- } catch (error) {
469
- console.error('Failed to fetch user data:', error);
470
- logMessage('Failed to fetch user data: ' + error.message);
471
- }
472
- }
473
-
474
- // Populate Fonts Dropdown
475
- async function populateFonts() {
476
- try {
477
- const response = await fetch('/available-fonts');
478
- const fonts = await response.json();
479
- const fontsDropdown = document.getElementById('subtitle-font-name');
480
- fonts.fonts.forEach(font => {
481
- const option = document.createElement('option');
482
- option.value = font;
483
- option.textContent = font;
484
- fontsDropdown.appendChild(option);
485
- });
486
- } catch (error) {
487
- console.error('Error fetching fonts:', error);
488
- logMessage('Error fetching fonts: ' + error.message);
489
- }
490
- }
491
-
492
- // Populate Musics Grid
493
- async function populateMusics() {
494
- try {
495
- const response = await fetch('/available-musics');
496
- const musics = await response.json();
497
- const musicGrid = document.getElementById('music-grid');
498
- musics.musics.forEach(music => {
499
- const musicBox = document.createElement('div');
500
- musicBox.className = 'music-box';
501
- musicBox.onclick = function() { selectMusic(this); };
502
- musicBox.innerHTML = `
503
- <div class="music-profile" style="background-color: #ff5733;">
504
- 🎶
505
- </div>
506
- <div class="music-name">${music}</div>
507
- <button class="play-stop-button" onclick="playStopMusic('/static/music/${music}', this)">Play</button>
508
- `;
509
- musicGrid.appendChild(musicBox);
510
- });
511
- } catch (error) {
512
- console.error('Error fetching musics:', error);
513
- logMessage('Error fetching musics: ' + error.message);
514
- }
515
- }
516
-
517
- // Search Functionality
518
- function setupSearch() {
519
- const searchInput = document.getElementById('videoSearch');
520
- searchInput.addEventListener('input', function() {
521
- const query = this.value.toLowerCase();
522
- document.querySelectorAll('.thumbnail-card').forEach(card => {
523
- const title = card.querySelector('.thumbnail-label').textContent.toLowerCase();
524
- card.style.display = title.includes(query) ? 'block' : 'none';
525
- });
526
- });
527
- }
528
-
529
- // Navigate to different pages
530
- function navigateToPage(page) {
531
- window.location.href = `/${page}`;
532
- }
533
-
534
- // Logout
535
- function logout() {
536
- window.location.href = '/logout';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
537
  }
 
1
+ // script.js
2
+ const API_KEY = 'your_secret_api_key';
3
+
4
+ // Tab Switching
5
+ document.querySelectorAll('.sidebar-item[data-tab]').forEach(item => {
6
+ item.addEventListener('click', () => {
7
+ document.querySelectorAll('.sidebar-item').forEach(i => i.classList.remove('active'));
8
+ item.classList.add('active');
9
+ document.querySelectorAll('.tab-content').forEach(content => content.style.display = 'none');
10
+ const tabId = item.getAttribute('data-tab') + '-content';
11
+ document.getElementById(tabId).style.display = 'block';
12
+ loadTabContent(tabId);
13
+ });
14
+ });
15
+
16
+ // Profile Photo Click Event
17
+ document.getElementById('profilePhoto').addEventListener('click', function() {
18
+ const menu = document.getElementById('profileMenu');
19
+ if (menu.style.display === 'block') {
20
+ menu.style.display = 'none';
21
+ } else {
22
+ menu.style.display = 'block';
23
+ }
24
+ });
25
+
26
+ // Close Profile Menu when clicking outside
27
+ window.onclick = function(event) {
28
+ if (!event.target.matches('#profilePhoto')) {
29
+ const menu = document.getElementById('profileMenu');
30
+ if (menu.style.display === 'block') {
31
+ menu.style.display = 'none';
32
+ }
33
+ }
34
+ };
35
+
36
+ // Toggle Sidebar
37
+ document.getElementById('toggleSidebar').addEventListener('click', function() {
38
+ document.getElementById('sidebar').classList.toggle('active');
39
+ });
40
+
41
+ // Fetch System Info
42
+ async function fetchSystemInfo() {
43
+ try {
44
+ const response = await fetch('/api/system-info', {
45
+ headers: {
46
+ 'Authorization': API_KEY
47
+ }
48
+ });
49
+ const data = await response.json();
50
+ document.getElementById('osName').textContent = data.os.name;
51
+ document.getElementById('osVersion').textContent = data.os.version;
52
+ document.getElementById('uptime').textContent = data.uptime;
53
+ document.getElementById('storage').textContent = `${(data.storage.total / (1024 ** 3)).toFixed(2)} GB / ${(data.storage.free / (1024 ** 3)).toFixed(2)} GB`;
54
+ } catch (error) {
55
+ console.error('Failed to fetch system info:', error);
56
+ }
57
+ }
58
+
59
+ // Fetch Bot Stats
60
+ async function fetchBotStats() {
61
+ try {
62
+ const response = await fetch('/api/bot-stats', {
63
+ headers: {
64
+ 'Authorization': API_KEY
65
+ }
66
+ });
67
+ const data = await response.json();
68
+ document.getElementById('totalFiles').textContent = data.total_files;
69
+ document.getElementById('totalUsers').textContent = data.total_users;
70
+ document.getElementById('totalChats').textContent = data.total_chats;
71
+ document.getElementById('storageUsed').textContent = data.storage_used;
72
+ document.getElementById('storageFree').textContent = data.storage_free;
73
+ } catch (error) {
74
+ console.error('Failed to fetch bot stats:', error);
75
+ }
76
+ }
77
+
78
+ // Fetch Bot Status
79
+ async function fetchBotStatus() {
80
+ try {
81
+ const response = await fetch('/api/bot-status', {
82
+ headers: {
83
+ 'Authorization': API_KEY
84
+ }
85
+ });
86
+ const data = await response.json();
87
+ document.getElementById('cpuUsage').textContent = `${data.cpu_usage}%`;
88
+ document.getElementById('ramUsage').textContent = `${data.ram_usage}%`;
89
+ document.getElementById('storageUsed').textContent = data.used_storage;
90
+ document.getElementById('storageFree').textContent = data.free_storage;
91
+ } catch (error) {
92
+ console.error('Failed to fetch bot status:', error);
93
+ }
94
+ }
95
+
96
+ // Load Tab Content
97
+ async function loadTabContent(tabId) {
98
+ if (tabId === 'filters-content') {
99
+ loadFilters();
100
+ } else if (tabId === 'global-filters-content') {
101
+ loadGlobalFilters();
102
+ } else if (tabId === 'users-content') {
103
+ loadUsers();
104
+ } else if (tabId === 'chats-content') {
105
+ loadChats();
106
+ } else if (tabId === 'files-content') {
107
+ loadFiles();
108
+ } else if (tabId === 'connections-content') {
109
+ loadConnections();
110
+ } else if (tabId === 'stats-content') {
111
+ fetchBotStatus();
112
+ }
113
+ }
114
+
115
+ // Load Filters
116
+ async function loadFilters() {
117
+ try {
118
+ const response = await fetch('/api/filters?chat_id=123456789', { // Replace with actual chat ID
119
+ headers: {
120
+ 'Authorization': API_KEY
121
+ }
122
+ });
123
+ const data = await response.json();
124
+ const filtersList = document.getElementById('filtersList');
125
+ filtersList.innerHTML = '';
126
+ data.filters.forEach(filter => {
127
+ const filterItem = document.createElement('div');
128
+ filterItem.className = 'stat-card';
129
+ filterItem.innerHTML = `
130
+ <div class="stat-header">
131
+ <div>
132
+ <h3>${filter}</h3>
133
+ </div>
134
+ <div class="stat-icon">
135
+ <i class="fas fa-filter"></i>
136
+ </div>
137
+ </div>
138
+ <button onclick="deleteFilter('${filter}')">Delete</button>
139
+ `;
140
+ filtersList.appendChild(filterItem);
141
+ });
142
+ } catch (error) {
143
+ console.error('Failed to load filters:', error);
144
+ }
145
+ }
146
+
147
+ // Load Global Filters
148
+ async function loadGlobalFilters() {
149
+ try {
150
+ const response = await fetch('/api/gfilters', {
151
+ headers: {
152
+ 'Authorization': API_KEY
153
+ }
154
+ });
155
+ const data = await response.json();
156
+ const gfiltersList = document.getElementById('gfiltersList');
157
+ gfiltersList.innerHTML = '';
158
+ data.filters.forEach(filter => {
159
+ const filterItem = document.createElement('div');
160
+ filterItem.className = 'stat-card';
161
+ filterItem.innerHTML = `
162
+ <div class="stat-header">
163
+ <div>
164
+ <h3>${filter}</h3>
165
+ </div>
166
+ <div class="stat-icon">
167
+ <i class="fas fa-globe"></i>
168
+ </div>
169
+ </div>
170
+ <button onclick="deleteGFilter('${filter}')">Delete</button>
171
+ `;
172
+ gfiltersList.appendChild(filterItem);
173
+ });
174
+ } catch (error) {
175
+ console.error('Failed to load global filters:', error);
176
+ }
177
+ }
178
+
179
+ // Load Users
180
+ async function loadUsers() {
181
+ try {
182
+ const response = await fetch('/api/users', {
183
+ headers: {
184
+ 'Authorization': API_KEY
185
+ }
186
+ });
187
+ const data = await response.json();
188
+ const usersList = document.getElementById('usersList');
189
+ usersList.innerHTML = '';
190
+ data.users.forEach(user => {
191
+ const userItem = document.createElement('div');
192
+ userItem.className = 'stat-card';
193
+ userItem.innerHTML = `
194
+ <div class="stat-header">
195
+ <div>
196
+ <h3>${user.name}</h3>
197
+ <p>ID: ${user.id}</p>
198
+ </div>
199
+ <div class="stat-icon">
200
+ <i class="fas fa-user"></i>
201
+ </div>
202
+ </div>
203
+ <button onclick="banUser('${user.id}', '${user.ban_status.ban_reason}')">${user.ban_status.is_banned ? 'Unban' : 'Ban'}</button>
204
+ `;
205
+ usersList.appendChild(userItem);
206
+ });
207
+ } catch (error) {
208
+ console.error('Failed to load users:', error);
209
+ }
210
+ }
211
+
212
+ // Load Chats
213
+ async function loadChats() {
214
+ try {
215
+ const response = await fetch('/api/chats', {
216
+ headers: {
217
+ 'Authorization': API_KEY
218
+ }
219
+ });
220
+ const data = await response.json();
221
+ const chatsList = document.getElementById('chatsList');
222
+ chatsList.innerHTML = '';
223
+ data.chats.forEach(chat => {
224
+ const chatItem = document.createElement('div');
225
+ chatItem.className = 'stat-card';
226
+ chatItem.innerHTML = `
227
+ <div class="stat-header">
228
+ <div>
229
+ <h3>${chat.title}</h3>
230
+ <p>ID: ${chat.id}</p>
231
+ </div>
232
+ <div class="stat-icon">
233
+ <i class="fas fa-comment-dots"></i>
234
+ </div>
235
+ </div>
236
+ <button onclick="disableChat('${chat.id}', '${chat.chat_status.reason}')">${chat.chat_status.is_disabled ? 'Enable' : 'Disable'}</button>
237
+ `;
238
+ chatsList.appendChild(chatItem);
239
+ });
240
+ } catch (error) {
241
+ console.error('Failed to load chats:', error);
242
+ }
243
+ }
244
+
245
+ // Load Files
246
+ async function loadFiles() {
247
+ try {
248
+ const response = await fetch('/api/files', {
249
+ headers: {
250
+ 'Authorization': API_KEY
251
+ }
252
+ });
253
+ const data = await response.json();
254
+ const filesList = document.getElementById('filesList');
255
+ filesList.innerHTML = '';
256
+ data.files.forEach(file => {
257
+ const fileItem = document.createElement('div');
258
+ fileItem.className = 'stat-card';
259
+ fileItem.innerHTML = `
260
+ <div class="stat-header">
261
+ <div>
262
+ <h3>${file.file_name}</h3>
263
+ <p>Size: ${get_size(file.file_size)}</p>
264
+ </div>
265
+ <div class="stat-icon">
266
+ <i class="fas fa-file"></i>
267
+ </div>
268
+ </div>
269
+ <button onclick="deleteFile('${file.file_id}')">Delete</button>
270
+ `;
271
+ filesList.appendChild(fileItem);
272
+ });
273
+ } catch (error) {
274
+ console.error('Failed to load files:', error);
275
+ }
276
+ }
277
+
278
+ // Load Connections
279
+ async function loadConnections() {
280
+ try {
281
+ const response = await fetch('/api/connections', {
282
+ headers: {
283
+ 'Authorization': API_KEY
284
+ }
285
+ });
286
+ const data = await response.json();
287
+ const connectionsList = document.getElementById('connectionsList');
288
+ connectionsList.innerHTML = '';
289
+ data.connections.forEach(connection => {
290
+ const connectionItem = document.createElement('div');
291
+ connectionItem.className = 'stat-card';
292
+ connectionItem.innerHTML = `
293
+ <div class="stat-header">
294
+ <div>
295
+ <h3>${connection.title}</h3>
296
+ <p>ID: ${connection.id}</p>
297
+ </div>
298
+ <div class="stat-icon">
299
+ <i class="fas fa-link"></i>
300
+ </div>
301
+ </div>
302
+ <button onclick="deleteConnection('${connection.id}', '${connection.user_id}')">Delete</button>
303
+ `;
304
+ connectionsList.appendChild(connectionItem);
305
+ });
306
+ } catch (error) {
307
+ console.error('Failed to load connections:', error);
308
+ }
309
+ }
310
+
311
+ // Add Filter
312
+ document.getElementById('addFilterForm').addEventListener('submit', async function(event) {
313
+ event.preventDefault();
314
+ const chatId = document.getElementById('chatId').value;
315
+ const text = document.getElementById('filterText').value;
316
+ const replyText = document.getElementById('replyText').value;
317
+ const btn = document.getElementById('btn').value;
318
+ const file = document.getElementById('file').value;
319
+ const alert = document.getElementById('alert').value;
320
+ try {
321
+ const response = await fetch('/api/add-filter', {
322
+ method: 'POST',
323
+ headers: {
324
+ 'Content-Type': 'application/x-www-form-urlencoded',
325
+ 'Authorization': API_KEY
326
+ },
327
+ body: `chat_id=${encodeURIComponent(chatId)}&text=${encodeURIComponent(text)}&reply_text=${encodeURIComponent(replyText)}&btn=${encodeURIComponent(btn)}&file=${encodeURIComponent(file)}&alert=${encodeURIComponent(alert)}`,
328
+ });
329
+ const data = await response.json();
330
+ alert(data.message);
331
+ loadFilters();
332
+ } catch (error) {
333
+ console.error('Failed to add filter:', error);
334
+ alert('Failed to add filter');
335
+ }
336
+ });
337
+
338
+ // Delete Filter
339
+ async function deleteFilter(text) {
340
+ try {
341
+ const response = await fetch('/api/delete-filter', {
342
+ method: 'POST',
343
+ headers: {
344
+ 'Content-Type': 'application/x-www-form-urlencoded',
345
+ 'Authorization': API_KEY
346
+ },
347
+ body: `chat_id=123456789&text=${encodeURIComponent(text)}`, // Replace with actual chat ID
348
+ });
349
+ const data = await response.json();
350
+ alert(data.message);
351
+ loadFilters();
352
+ } catch (error) {
353
+ console.error('Failed to delete filter:', error);
354
+ alert('Failed to delete filter');
355
+ }
356
+ }
357
+
358
+ // Add Global Filter
359
+ document.getElementById('addGFilterForm').addEventListener('submit', async function(event) {
360
+ event.preventDefault();
361
+ const text = document.getElementById('gfilterText').value;
362
+ const replyText = document.getElementById('greplyText').value;
363
+ const btn = document.getElementById('gbtn').value;
364
+ const file = document.getElementById('gfile').value;
365
+ const alert = document.getElementById('galert').value;
366
+ try {
367
+ const response = await fetch('/api/add-gfilter', {
368
+ method: 'POST',
369
+ headers: {
370
+ 'Content-Type': 'application/x-www-form-urlencoded',
371
+ 'Authorization': API_KEY
372
+ },
373
+ body: `text=${encodeURIComponent(text)}&reply_text=${encodeURIComponent(replyText)}&btn=${encodeURIComponent(btn)}&file=${encodeURIComponent(file)}&alert=${encodeURIComponent(alert)}`,
374
+ });
375
+ const data = await response.json();
376
+ alert(data.message);
377
+ loadGlobalFilters();
378
+ } catch (error) {
379
+ console.error('Failed to add global filter:', error);
380
+ alert('Failed to add global filter');
381
+ }
382
+ });
383
+
384
+ // Delete Global Filter
385
+ async function deleteGFilter(text) {
386
+ try {
387
+ const response = await fetch('/api/delete-gfilter', {
388
+ method: 'POST',
389
+ headers: {
390
+ 'Content-Type': 'application/x-www-form-urlencoded',
391
+ 'Authorization': API_KEY
392
+ },
393
+ body: `text=${encodeURIComponent(text)}`,
394
+ });
395
+ const data = await response.json();
396
+ alert(data.message);
397
+ loadGlobalFilters();
398
+ } catch (error) {
399
+ console.error('Failed to delete global filter:', error);
400
+ alert('Failed to delete global filter');
401
+ }
402
+ }
403
+
404
+ // Ban User
405
+ async function banUser(userId, banReason) {
406
+ try {
407
+ const response = await fetch('/api/ban-user', {
408
+ method: 'POST',
409
+ headers: {
410
+ 'Content-Type': 'application/x-www-form-urlencoded',
411
+ 'Authorization': API_KEY
412
+ },
413
+ body: `user_id=${encodeURIComponent(userId)}&ban_reason=${encodeURIComponent(banReason)}`,
414
+ });
415
+ const data = await response.json();
416
+ alert(data.message);
417
+ loadUsers();
418
+ } catch (error) {
419
+ console.error('Failed to ban user:', error);
420
+ alert('Failed to ban user');
421
+ }
422
+ }
423
+
424
+ // Unban User
425
+ async function unbanUser(userId) {
426
+ try {
427
+ const response = await fetch('/api/unban-user', {
428
+ method: 'POST',
429
+ headers: {
430
+ 'Content-Type': 'application/x-www-form-urlencoded',
431
+ 'Authorization': API_KEY
432
+ },
433
+ body: `user_id=${encodeURIComponent(userId)}`,
434
+ });
435
+ const data = await response.json();
436
+ alert(data.message);
437
+ loadUsers();
438
+ } catch (error) {
439
+ console.error('Failed to unban user:', error);
440
+ alert('Failed to unban user');
441
+ }
442
+ }
443
+
444
+ // Disable Chat
445
+ async function disableChat(chatId, reason) {
446
+ try {
447
+ const response = await fetch('/api/disable-chat', {
448
+ method: 'POST',
449
+ headers: {
450
+ 'Content-Type': 'application/x-www-form-urlencoded',
451
+ 'Authorization': API_KEY
452
+ },
453
+ body: `chat_id=${encodeURIComponent(chatId)}&reason=${encodeURIComponent(reason)}`,
454
+ });
455
+ const data = await response.json();
456
+ alert(data.message);
457
+ loadChats();
458
+ } catch (error) {
459
+ console.error('Failed to disable chat:', error);
460
+ alert('Failed to disable chat');
461
+ }
462
+ }
463
+
464
+ // Enable Chat
465
+ async function enableChat(chatId) {
466
+ try {
467
+ const response = await fetch('/api/enable-chat', {
468
+ method: 'POST',
469
+ headers: {
470
+ 'Content-Type': 'application/x-www-form-urlencoded',
471
+ 'Authorization': API_KEY
472
+ },
473
+ body: `chat_id=${encodeURIComponent(chatId)}`,
474
+ });
475
+ const data = await response.json();
476
+ alert(data.message);
477
+ loadChats();
478
+ } catch (error) {
479
+ console.error('Failed to enable chat:', error);
480
+ alert('Failed to enable chat');
481
+ }
482
+ }
483
+
484
+ // Upload File
485
+ document.getElementById('uploadFileForm').addEventListener('submit', async function(event) {
486
+ event.preventDefault();
487
+ const formData = new FormData(this);
488
+ try {
489
+ const response = await fetch('/api/upload-file', {
490
+ method: 'POST',
491
+ headers: {
492
+ 'Authorization': API_KEY
493
+ },
494
+ body: formData,
495
+ });
496
+ const data = await response.json();
497
+ alert(data.message);
498
+ loadFiles();
499
+ } catch (error) {
500
+ console.error('Failed to upload file:', error);
501
+ alert('Failed to upload file');
502
+ }
503
+ });
504
+
505
+ // Delete File
506
+ async function deleteFile(fileId) {
507
+ try {
508
+ const response = await fetch('/api/delete-file', {
509
+ method: 'POST',
510
+ headers: {
511
+ 'Content-Type': 'application/x-www-form-urlencoded',
512
+ 'Authorization': API_KEY
513
+ },
514
+ body: `file_id=${encodeURIComponent(fileId)}`,
515
+ });
516
+ const data = await response.json();
517
+ alert(data.message);
518
+ loadFiles();
519
+ } catch (error) {
520
+ console.error('Failed to delete file:', error);
521
+ alert('Failed to delete file');
522
+ }
523
+ }
524
+
525
+ // Broadcast Message
526
+ document.getElementById('broadcastForm').addEventListener('submit', async function(event) {
527
+ event.preventDefault();
528
+ const messageText = document.getElementById('broadcastText').value;
529
+ try {
530
+ const response = await fetch('/api/broadcast', {
531
+ method: 'POST',
532
+ headers: {
533
+ 'Content-Type': 'application/x-www-form-urlencoded',
534
+ 'Authorization': API_KEY
535
+ },
536
+ body: `message_text=${encodeURIComponent(messageText)}`,
537
+ });
538
+ const data = await response.json();
539
+ alert(`Broadcast completed. Success: ${data.success}, Blocked: ${data.blocked}, Deleted: ${data.deleted}`);
540
+ } catch (error) {
541
+ console.error('Failed to broadcast message:', error);
542
+ alert('Failed to broadcast message');
543
+ }
544
+ });
545
+
546
+ // Add Connection
547
+ document.getElementById('addConnectionForm').addEventListener('submit', async function(event) {
548
+ event.preventDefault();
549
+ const groupId = document.getElementById('groupId').value;
550
+ const userId = document.getElementById('userId').value;
551
+ try {
552
+ const response = await fetch('/api/add-connection', {
553
+ method: 'POST',
554
+ headers: {
555
+ 'Content-Type': 'application/x-www-form-urlencoded',
556
+ 'Authorization': API_KEY
557
+ },
558
+ body: `group_id=${encodeURIComponent(groupId)}&user_id=${encodeURIComponent(userId)}`,
559
+ });
560
+ const data = await response.json();
561
+ alert(data.message);
562
+ loadConnections();
563
+ } catch (error) {
564
+ console.error('Failed to add connection:', error);
565
+ alert('Failed to add connection');
566
+ }
567
+ });
568
+
569
+ // Delete Connection
570
+ async function deleteConnection(groupId, userId) {
571
+ try {
572
+ const response = await fetch('/api/delete-connection', {
573
+ method: 'POST',
574
+ headers: {
575
+ 'Content-Type': 'application/x-www-form-urlencoded',
576
+ 'Authorization': API_KEY
577
+ },
578
+ body: `group_id=${encodeURIComponent(groupId)}&user_id=${encodeURIComponent(userId)}`,
579
+ });
580
+ const data = await response.json();
581
+ alert(data.message);
582
+ loadConnections();
583
+ } catch (error) {
584
+ console.error('Failed to delete connection:', error);
585
+ alert('Failed to delete connection');
586
+ }
587
+ }
588
+
589
+ // Save Settings
590
+ document.getElementById('saveSettingsForm').addEventListener('submit', async function(event) {
591
+ event.preventDefault();
592
+ const chatId = document.getElementById('settingsChatId').value;
593
+ const settingKey = document.getElementById('settingKey').value;
594
+ const settingValue = document.getElementById('settingValue').value;
595
+ try {
596
+ const response = await fetch('/api/save-settings', {
597
+ method: 'POST',
598
+ headers: {
599
+ 'Content-Type': 'application/x-www-form-urlencoded',
600
+ 'Authorization': API_KEY
601
+ },
602
+ body: `chat_id=${encodeURIComponent(chatId)}&setting_key=${encodeURIComponent(settingKey)}&setting_value=${encodeURIComponent(settingValue)}`,
603
+ });
604
+ const data = await response.json();
605
+ alert(data.message);
606
+ } catch (error) {
607
+ console.error('Failed to save settings:', error);
608
+ alert('Failed to save settings');
609
+ }
610
+ });
611
+
612
+ // Restart Bot
613
+ document.getElementById('restartBotForm').addEventListener('submit', async function(event) {
614
+ event.preventDefault();
615
+ try {
616
+ const response = await fetch('/api/restart-bot', {
617
+ method: 'POST',
618
+ headers: {
619
+ 'Content-Type': 'application/x-www-form-urlencoded',
620
+ 'Authorization': API_KEY
621
+ },
622
+ body: `admin_id=${encodeURIComponent(${ADMINS[0]})}`, // Replace with actual admin ID
623
+ });
624
+ const data = await response.json();
625
+ alert(data.message);
626
+ } catch (error) {
627
+ console.error('Failed to restart bot:', error);
628
+ alert('Failed to restart bot');
629
+ }
630
+ });
631
+
632
+ // Performance Chart
633
+ const performanceCtx = document.getElementById('performanceChart').getContext('2d');
634
+ new Chart(performanceCtx, {
635
+ type: 'line',
636
+ data: {
637
+ labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
638
+ datasets: [{
639
+ label: 'Uploads',
640
+ data: [65, 59, 80, 81, 56, 55],
641
+ borderColor: '#3b82f6',
642
+ tension: 0.4
643
+ }]
644
+ },
645
+ options: {
646
+ responsive: true,
647
+ maintainAspectRatio: false,
648
+ scales: {
649
+ y: {
650
+ beginAtZero: true
651
+ }
652
+ }
653
+ }
654
+ });
655
+
656
+ // Platform Distribution Chart
657
+ const platformCtx = document.getElementById('platformChart').getContext('2d');
658
+ new Chart(platformCtx, {
659
+ type: 'doughnut',
660
+ data: {
661
+ labels: ['YouTube', 'Instagram', 'Facebook', 'WhatsApp', 'Pinterest', 'LinkedIn', 'TikTok', 'Twitter', 'Reddit', 'Telegram'],
662
+ datasets: [{
663
+ data: [45, 30, 25, 15, 10, 8, 7, 6, 5, 4],
664
+ backgroundColor: ['#ff0000', '#e4405f', '#1877F2', '#25D366', '#BD081C', '#0077B5', '#000000', '#1DA1F2', '#FF4500', '#0088CC']
665
+ }]
666
+ },
667
+ options: {
668
+ responsive: true,
669
+ maintainAspectRatio: false
670
+ }
671
+ });
672
+
673
+ // Fetch System Info on Page Load
674
+ document.addEventListener('DOMContentLoaded', function() {
675
+ fetchSystemInfo();
676
+ fetchBotStats();
677
+ fetchBotStatus();
678
+ loadFilters();
679
+ loadGlobalFilters();
680
+ loadUsers();
681
+ loadChats();
682
+ loadFiles();
683
+ loadConnections();
684
+ });
685
+
686
+ // Utility Function to Format Size
687
+ function get_size(size) {
688
+ const units = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB"];
689
+ size = parseFloat(size);
690
+ let i = 0;
691
+ while (size >= 1024.0 && i < units.length) {
692
+ i += 1;
693
+ size /= 1024.0;
694
+ }
695
+ return `${size.toFixed(2)} ${units[i]}`;
696
  }