DSDUDEd commited on
Commit
da777d1
·
verified ·
1 Parent(s): 1fd2ecb

Update script.js

Browse files
Files changed (1) hide show
  1. script.js +155 -120
script.js CHANGED
@@ -34,49 +34,14 @@ document.addEventListener("DOMContentLoaded", () => {
34
  chatSection.appendChild(commentsContainer);
35
  chatSection.appendChild(commentInput);
36
 
37
- // ------------------
38
- // CSS for Immersion
39
- // ------------------
40
- document.body.style.margin = "0";
41
- document.body.style.height = "100vh";
42
- document.body.style.overflow = "hidden";
43
- document.documentElement.style.height = "100%";
44
- chatSection.style.height = "100%";
45
- aiAppsSection.style.height = "100%";
46
- chatContainer.style.height = "calc(100% - 50px)";
47
- chatContainer.style.overflowY = "auto";
48
- commentsContainer.style.overflowY = "auto";
49
-
50
- // Custom cursor
51
- const cursor = document.createElement("style");
52
- cursor.innerHTML = `
53
- * { cursor: url('https://cdn-icons-png.flaticon.com/512/32/32339.png'), auto !important; }
54
- `;
55
- document.head.appendChild(cursor);
56
-
57
- // Custom favicon/logo
58
- const favicon = document.createElement("link");
59
- favicon.rel = "icon";
60
- favicon.href = "https://cdn-icons-png.flaticon.com/512/4712/4712301.png";
61
- document.head.appendChild(favicon);
62
-
63
  // ------------------
64
  // Helper Functions
65
  // ------------------
66
  function addMessage(content, sender) {
67
  const bubble = document.createElement("div");
68
  bubble.className = "chat-bubble " + sender;
69
- bubble.style.margin = "5px";
70
- bubble.style.padding = "10px";
71
- bubble.style.borderRadius = "12px";
72
- bubble.style.maxWidth = "70%";
73
- bubble.style.wordWrap = "break-word";
74
- bubble.style.animation = "fadeIn 0.3s ease-out";
75
-
76
  bubble.textContent = (sender === "user" ? userEmoji : aiEmoji) + " " + content;
77
- if (sender === "ai") chatContainer.appendChild(bubble);
78
- else chatContainer.appendChild(bubble);
79
-
80
  chatContainer.scrollTop = chatContainer.scrollHeight;
81
  }
82
 
@@ -95,54 +60,111 @@ document.addEventListener("DOMContentLoaded", () => {
95
  }
96
 
97
  // ------------------
98
- // AI Thinking Animation
99
  // ------------------
100
- function showTyping() {
101
- typing.style.display = "block";
102
- typing.textContent = aiEmoji + " AI thinking";
103
- let dots = 0;
104
- typing._interval = setInterval(() => {
105
- dots = (dots + 1) % 4;
106
- typing.textContent = aiEmoji + " AI thinking" + ".".repeat(dots);
107
- }, 500);
108
- }
109
-
110
- function hideTyping() {
111
- typing.style.display = "none";
112
- typing.textContent = "";
113
- clearInterval(typing._interval);
 
 
114
  }
115
 
116
  // ------------------
117
- // Fullscreen helpers
118
  // ------------------
119
- function requestFullscreen() {
120
- if (document.fullscreenEnabled && !document.fullscreenElement) {
121
- document.documentElement.requestFullscreen().catch(() => {});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  }
123
  }
124
 
125
- document.addEventListener("fullscreenchange", () => {
126
- if (!document.fullscreenElement) requestFullscreen();
127
- });
128
-
129
  // ------------------
130
- // Hide HuggingFace UI
131
  // ------------------
132
- function hideHuggingFaceUI() {
133
- const header = document.querySelector("header") || document.querySelector(".css-1c1wz1k");
134
- const footer = document.querySelector("footer") || document.querySelector(".css-1o72pil");
135
- const toolbar = document.querySelector('[data-testid="space-header"]');
136
- const tabStrip = document.querySelector('[data-testid="space-tabs"]');
137
-
138
- if (header) header.style.display = "none";
139
- if (footer) footer.style.display = "none";
140
- if (toolbar) toolbar.style.display = "none";
141
- if (tabStrip) tabStrip.style.display = "none";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
- setTimeout(hideHuggingFaceUI, 500);
144
- }
145
- hideHuggingFaceUI();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
  // ------------------
148
  // Chat Handler
@@ -153,11 +175,10 @@ document.addEventListener("DOMContentLoaded", () => {
153
  if (!message) return;
154
  addMessage(message, "user");
155
  input.value = "";
156
-
157
- showTyping();
158
 
159
  const modelChoice = customModelURL || document.getElementById("model-select").value;
160
-
161
  try {
162
  const res = await fetch("/api/chat", {
163
  method: "POST",
@@ -165,19 +186,36 @@ document.addEventListener("DOMContentLoaded", () => {
165
  body: JSON.stringify({ message, model: modelChoice, max_tokens: maxTokens })
166
  });
167
  const data = await res.json();
168
- hideTyping();
169
-
170
  if (data.error) addMessage("Error: " + data.error, "ai");
171
  else addMessage(data.response, "ai");
172
  } catch (err) {
173
- hideTyping();
 
174
  addMessage("Error: Could not reach server", "ai");
175
  console.error(err);
176
  }
177
  };
178
 
179
  // ------------------
180
- // Load AI Apps / Comments / Login / Signup (unchanged)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  // ------------------
182
  async function loadAIApps() {
183
  if (!token) return;
@@ -185,7 +223,6 @@ document.addEventListener("DOMContentLoaded", () => {
185
  const res = await fetch("/api/apps", { headers: authHeaders() });
186
  const data = await res.json();
187
  appsContainer.innerHTML = "";
188
-
189
  if (data && data.length > 0) {
190
  data.forEach((app) => {
191
  const div = document.createElement("div");
@@ -193,15 +230,16 @@ document.addEventListener("DOMContentLoaded", () => {
193
  div.innerHTML = `<h3>${app.name}</h3><p>Language: ${app.language}</p><button onclick="openAIApp('${app.id}')">Open App</button>`;
194
  appsContainer.appendChild(div);
195
  });
196
- } else {
197
- appsContainer.textContent = "No AI apps yet.";
198
- }
199
  } catch (err) {
 
200
  appsContainer.textContent = "Error loading AI apps.";
201
- console.error(err);
202
  }
203
  }
204
 
 
 
 
205
  async function loadComments() {
206
  if (!token) return;
207
  try {
@@ -211,8 +249,8 @@ document.addEventListener("DOMContentLoaded", () => {
211
  if (data && data.length > 0) data.forEach(c => addComment(c.content, c.user_id));
212
  else commentsContainer.textContent = "No comments yet.";
213
  } catch (err) {
 
214
  commentsContainer.textContent = "Error loading comments.";
215
- console.error(err);
216
  }
217
  }
218
 
@@ -231,47 +269,44 @@ document.addEventListener("DOMContentLoaded", () => {
231
  addComment(content, "You");
232
  e.target.value = "";
233
  }
234
- } catch (err) {
235
- console.error(err);
236
- }
237
  }
238
  });
239
 
240
- window.openAIApp = function (appId) {
241
- alert("Opening AI App ID: " + appId);
242
- };
243
-
244
  // ------------------
245
- // Session / Fullscreen
246
  // ------------------
247
- async function checkSession() {
248
- if (!token) return false;
249
- try {
250
- const res = await fetch("/api/session", { headers: authHeaders() });
251
- const data = await res.json();
252
- if (data.user) {
253
- loginForm.style.display = "none";
254
- signupForm.style.display = "none";
255
- chatSection.style.display = "block";
256
- aiAppsSection.style.display = "block";
257
 
258
- loadComments();
259
- loadAIApps();
 
 
260
 
261
- setTimeout(requestFullscreen, 500);
262
- return true;
263
- } else {
264
- localStorage.removeItem("jwtToken");
265
- token = null;
266
- return false;
267
- }
268
- } catch (err) {
269
- console.error(err);
270
- localStorage.removeItem("jwtToken");
271
- token = null;
272
- return false;
273
- }
274
  }
 
 
 
 
275
 
276
- checkSession();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  });
 
34
  chatSection.appendChild(commentsContainer);
35
  chatSection.appendChild(commentInput);
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  // ------------------
38
  // Helper Functions
39
  // ------------------
40
  function addMessage(content, sender) {
41
  const bubble = document.createElement("div");
42
  bubble.className = "chat-bubble " + sender;
 
 
 
 
 
 
 
43
  bubble.textContent = (sender === "user" ? userEmoji : aiEmoji) + " " + content;
44
+ chatContainer.appendChild(bubble);
 
 
45
  chatContainer.scrollTop = chatContainer.scrollHeight;
46
  }
47
 
 
60
  }
61
 
62
  // ------------------
63
+ // Email Verification
64
  // ------------------
65
+ async function handleEmailVerification(email) {
66
+ const code = prompt("Enter the verification code sent to your email:");
67
+ if (!code) return alert("Verification code required.");
68
+ try {
69
+ const res = await fetch("/api/verify_email", {
70
+ method: "POST",
71
+ headers: { "Content-Type": "application/json" },
72
+ body: JSON.stringify({ email, code })
73
+ });
74
+ const data = await res.json();
75
+ if (data.error) alert("❌ " + data.error);
76
+ else alert("✅ " + data.message);
77
+ } catch (err) {
78
+ alert("❌ Could not verify email.");
79
+ console.error(err);
80
+ }
81
  }
82
 
83
  // ------------------
84
+ // Check Session
85
  // ------------------
86
+ async function checkSession() {
87
+ if (!token) return false;
88
+ try {
89
+ const res = await fetch("/api/session", { headers: authHeaders() });
90
+ const data = await res.json();
91
+ if (data.user) {
92
+ loginForm.style.display = "none";
93
+ signupForm.style.display = "none";
94
+ chatSection.style.display = "block";
95
+ aiAppsSection.style.display = "block";
96
+ loadComments();
97
+ setTimeout(() => document.documentElement.requestFullscreen?.(), 500);
98
+ return true;
99
+ } else {
100
+ localStorage.removeItem("jwtToken");
101
+ token = null;
102
+ return false;
103
+ }
104
+ } catch (err) {
105
+ console.error("Session check failed:", err);
106
+ localStorage.removeItem("jwtToken");
107
+ token = null;
108
+ return false;
109
  }
110
  }
111
 
 
 
 
 
112
  // ------------------
113
+ // Login Handler
114
  // ------------------
115
+ document.getElementById("login-btn").onclick = async () => {
116
+ const email = document.getElementById("login-email").value.trim();
117
+ const password = document.getElementById("login-password").value.trim();
118
+ if (!email || !password) return alert("Please enter email and password.");
119
+ try {
120
+ const res = await fetch("/api/login", {
121
+ method: "POST",
122
+ headers: { "Content-Type": "application/json" },
123
+ body: JSON.stringify({ email, password })
124
+ });
125
+ const data = await res.json();
126
+ if (data.error) alert("❌ " + data.error);
127
+ else {
128
+ token = data.token;
129
+ localStorage.setItem("jwtToken", token);
130
+ loginForm.style.display = "none";
131
+ chatSection.style.display = "block";
132
+ aiAppsSection.style.display = "block";
133
+ loadAIApps();
134
+ loadComments();
135
+ setTimeout(() => document.documentElement.requestFullscreen?.(), 500);
136
+ }
137
+ } catch (err) {
138
+ alert("❌ Login failed: Could not reach server");
139
+ console.error(err);
140
+ }
141
+ };
142
 
143
+ // ------------------
144
+ // Signup Handler
145
+ // ------------------
146
+ document.getElementById("signup-btn")?.addEventListener("click", async () => {
147
+ const email = document.getElementById("signup-email").value.trim();
148
+ const username = document.getElementById("signup-username").value.trim();
149
+ const password = document.getElementById("signup-password").value.trim();
150
+ if (!email || !username || !password) return alert("All fields are required.");
151
+ try {
152
+ const res = await fetch("/api/signup", {
153
+ method: "POST",
154
+ headers: { "Content-Type": "application/json" },
155
+ body: JSON.stringify({ email, username, password })
156
+ });
157
+ const data = await res.json();
158
+ if (data.error) alert("❌ " + data.error);
159
+ else {
160
+ alert("✅ " + data.message);
161
+ await handleEmailVerification(email);
162
+ }
163
+ } catch (err) {
164
+ alert("❌ Signup failed: Could not reach server");
165
+ console.error(err);
166
+ }
167
+ });
168
 
169
  // ------------------
170
  // Chat Handler
 
175
  if (!message) return;
176
  addMessage(message, "user");
177
  input.value = "";
178
+ typing.textContent = aiEmoji + " AI thinking…";
179
+ typing.style.display = "block";
180
 
181
  const modelChoice = customModelURL || document.getElementById("model-select").value;
 
182
  try {
183
  const res = await fetch("/api/chat", {
184
  method: "POST",
 
186
  body: JSON.stringify({ message, model: modelChoice, max_tokens: maxTokens })
187
  });
188
  const data = await res.json();
189
+ typing.style.display = "none";
190
+ typing.textContent = "";
191
  if (data.error) addMessage("Error: " + data.error, "ai");
192
  else addMessage(data.response, "ai");
193
  } catch (err) {
194
+ typing.style.display = "none";
195
+ typing.textContent = "";
196
  addMessage("Error: Could not reach server", "ai");
197
  console.error(err);
198
  }
199
  };
200
 
201
  // ------------------
202
+ // Settings Modal
203
+ // ------------------
204
+ document.getElementById("settings-btn").onclick = () => (modal.style.display = "block");
205
+ document.getElementById("close-settings").onclick = () => (modal.style.display = "none");
206
+ document.getElementById("user-emoji").oninput = (e) => (userEmoji = e.target.value);
207
+ document.getElementById("ai-emoji").oninput = (e) => (aiEmoji = e.target.value);
208
+ document.getElementById("max-tokens").oninput = (e) => (maxTokens = parseInt(e.target.value));
209
+ document.getElementById("load-custom-model").onclick = () => {
210
+ const url = document.getElementById("custom-model").value.trim();
211
+ if (url) {
212
+ customModelURL = url;
213
+ alert("Custom model URL will be used!");
214
+ }
215
+ };
216
+
217
+ // ------------------
218
+ // Load AI Apps / Bots
219
  // ------------------
220
  async function loadAIApps() {
221
  if (!token) return;
 
223
  const res = await fetch("/api/apps", { headers: authHeaders() });
224
  const data = await res.json();
225
  appsContainer.innerHTML = "";
 
226
  if (data && data.length > 0) {
227
  data.forEach((app) => {
228
  const div = document.createElement("div");
 
230
  div.innerHTML = `<h3>${app.name}</h3><p>Language: ${app.language}</p><button onclick="openAIApp('${app.id}')">Open App</button>`;
231
  appsContainer.appendChild(div);
232
  });
233
+ } else appsContainer.textContent = "No AI apps yet.";
 
 
234
  } catch (err) {
235
+ console.error("Failed to load AI apps:", err);
236
  appsContainer.textContent = "Error loading AI apps.";
 
237
  }
238
  }
239
 
240
+ // ------------------
241
+ // Comments
242
+ // ------------------
243
  async function loadComments() {
244
  if (!token) return;
245
  try {
 
249
  if (data && data.length > 0) data.forEach(c => addComment(c.content, c.user_id));
250
  else commentsContainer.textContent = "No comments yet.";
251
  } catch (err) {
252
+ console.error("Failed to load comments:", err);
253
  commentsContainer.textContent = "Error loading comments.";
 
254
  }
255
  }
256
 
 
269
  addComment(content, "You");
270
  e.target.value = "";
271
  }
272
+ } catch (err) { console.error(err); }
 
 
273
  }
274
  });
275
 
 
 
 
 
276
  // ------------------
277
+ // Open AI App
278
  // ------------------
279
+ window.openAIApp = function (appId) { alert("Opening AI App ID: " + appId); };
 
 
 
 
 
 
 
 
 
280
 
281
+ // ------------------
282
+ // Run session check on load
283
+ // ------------------
284
+ checkSession().then((valid) => { if (valid) loadAIApps(); });
285
 
286
+ // ------------------
287
+ // Persistent Fullscreen
288
+ // ------------------
289
+ function requestFullscreenPersistent() {
290
+ if (!document.fullscreenElement) document.documentElement.requestFullscreen?.().catch(() => {});
 
 
 
 
 
 
 
 
291
  }
292
+ setInterval(requestFullscreenPersistent, 1000);
293
+ document.addEventListener("fullscreenchange", () => {
294
+ if (!document.fullscreenElement) requestFullscreenPersistent();
295
+ });
296
 
297
+ // ------------------
298
+ // Hide HuggingFace UI
299
+ // ------------------
300
+ function hideHuggingFaceUI() {
301
+ const header = document.querySelector("header") || document.querySelector(".css-1c1wz1k");
302
+ const footer = document.querySelector("footer") || document.querySelector(".css-1o72pil");
303
+ const toolbar = document.querySelector('[data-testid="space-header"]');
304
+ const tabStrip = document.querySelector('[data-testid="space-tabs"]');
305
+ if (header) header.style.display = "none";
306
+ if (footer) footer.style.display = "none";
307
+ if (toolbar) toolbar.style.display = "none";
308
+ if (tabStrip) tabStrip.style.display = "none";
309
+ setTimeout(hideHuggingFaceUI, 500);
310
+ }
311
+ hideHuggingFaceUI();
312
  });