Skip to content

Commit 6a77e09

Browse files
committed
Voice mode added. simple mode added. image buttons added(functionality to come). url scrapping corrections. syntax highlighting additions.. simple mode(theme coming soon). modal for voice chat. image gen for voice chat. over a dozen voices. selections in multiple panels. image buttons fix coming soon
1 parent f3e25d9 commit 6a77e09

File tree

10 files changed

+2724
-1939
lines changed

10 files changed

+2724
-1939
lines changed

ai/chat-part1.js

Lines changed: 336 additions & 321 deletions
Large diffs are not rendered by default.

ai/chat-part2.js

Lines changed: 1002 additions & 218 deletions
Large diffs are not rendered by default.

ai/chat-part3.js

Lines changed: 416 additions & 528 deletions
Large diffs are not rendered by default.

ai/index.html

Lines changed: 134 additions & 379 deletions
Large diffs are not rendered by default.

ai/memory-api.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ document.addEventListener("DOMContentLoaded", () => {
8686
const updatedText = newText.trim();
8787

8888
try {
89-
memories[index] = updatedText;
90-
localStorage.setItem("pollinations_memory", JSON.stringify(memories));
89+
const currentMemories = this.getMemories();
90+
currentMemories[index] = updatedText;
91+
localStorage.setItem("pollinations_memory", JSON.stringify(currentMemories));
9192
console.log(`Memory at index ${index} updated to: ${updatedText}`);
9293
return true;
9394
} catch (err) {
@@ -113,4 +114,5 @@ document.addEventListener("DOMContentLoaded", () => {
113114
};
114115

115116
console.log("Memory API loaded and linked to Storage-based memory system.");
117+
116118
});

ai/screensaver.js

Lines changed: 57 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
// screensaver.js
2-
// Handles screensaver functionality with Pollinations API integration
3-
// Updated with safe=false for uncensored content and cross-browser/device support
4-
51
document.addEventListener("DOMContentLoaded", () => {
62
const screensaverContainer = document.getElementById("screensaver-container");
73
const toggleScreensaverButton = document.getElementById("toggle-screensaver");
@@ -24,7 +20,6 @@ document.addEventListener("DOMContentLoaded", () => {
2420
let paused = false;
2521
let isFullscreen = false;
2622

27-
// Set tooltips
2823
toggleScreensaverButton.title = "Toggle the screensaver on/off.";
2924
fullscreenButton.title = "Go full screen (or exit it).";
3025
stopButton.title = "Stop the screensaver.";
@@ -38,7 +33,6 @@ document.addEventListener("DOMContentLoaded", () => {
3833
enhanceCheckbox.title = "If enabled, the prompt is 'enhanced' via an LLM.";
3934
privateCheckbox.title = "If enabled, the image won't appear on the public feed.";
4035

41-
// Utility to detect browser for compatibility adjustments
4236
const getBrowserInfo = () => {
4337
const ua = navigator.userAgent.toLowerCase();
4438
return {
@@ -50,7 +44,6 @@ document.addEventListener("DOMContentLoaded", () => {
5044
};
5145
};
5246

53-
// Utility to create audio context for cross-browser support
5447
const createAudioContext = () => {
5548
const AudioContext = window.AudioContext || window.webkitAudioContext;
5649
if (!AudioContext) {
@@ -60,11 +53,10 @@ document.addEventListener("DOMContentLoaded", () => {
6053
return new AudioContext();
6154
};
6255

63-
// Utility to play audio with cross-browser compatibility
6456
const playAudio = (audioUrl) => {
6557
return new Promise((resolve, reject) => {
6658
const audio = new Audio(audioUrl);
67-
audio.crossOrigin = "anonymous"; // For CORS support
59+
audio.crossOrigin = "anonymous";
6860
audio.preload = "auto";
6961

7062
audio.play().catch((err) => {
@@ -91,7 +83,6 @@ document.addEventListener("DOMContentLoaded", () => {
9183
});
9284
};
9385

94-
// Save settings to localStorage
9586
function saveScreensaverSettings() {
9687
const settings = {
9788
prompt: promptInput.value,
@@ -104,7 +95,6 @@ document.addEventListener("DOMContentLoaded", () => {
10495
localStorage.setItem("screensaverSettings", JSON.stringify(settings));
10596
}
10697

107-
// Load settings from localStorage
10898
function loadScreensaverSettings() {
10999
const raw = localStorage.getItem("screensaverSettings");
110100
if (!raw) return;
@@ -123,17 +113,10 @@ document.addEventListener("DOMContentLoaded", () => {
123113

124114
loadScreensaverSettings();
125115

126-
// Generate a random seed
127116
function generateSeed() {
128-
const length = Math.floor(Math.random() * 8) + 1;
129-
let seed = "";
130-
for (let i = 0; i < length; i++) {
131-
seed += Math.floor(Math.random() * 10);
132-
}
133-
return seed;
117+
return Math.floor(Math.random() * 1000000).toString();
134118
}
135119

136-
// Get dimensions based on aspect ratio
137120
function getDimensions(aspect) {
138121
switch (aspect) {
139122
case "widescreen": return { width: 1280, height: 720 };
@@ -143,17 +126,14 @@ document.addEventListener("DOMContentLoaded", () => {
143126
}
144127
}
145128

146-
// FIXED: Fetch a new image from Pollinations API with nolog parameter
147129
function fetchNewImage() {
148130
saveScreensaverSettings();
149131
let prompt = promptInput.value || "random artistic scene, high quality, detailed";
150132

151-
// Keep the prompt concise and clean
152133
if (prompt.length > 100) {
153134
prompt = prompt.substring(0, 100);
154135
}
155136

156-
// Add quality terms
157137
prompt += ", high resolution, detailed";
158138

159139
const { width, height } = getDimensions(aspectSelect.value);
@@ -162,19 +142,15 @@ document.addEventListener("DOMContentLoaded", () => {
162142
const enhance = enhanceCheckbox.checked;
163143
const priv = privateCheckbox.checked;
164144

165-
// Use global config if available, otherwise hardcode safe=false
166-
const safeParam = window._pollinationsAPIConfig ? `safe=${window._pollinationsAPIConfig.safe}` : "safe=false";
167-
168-
// Add nolog=true parameter to prevent unwanted URL parameters
169-
const url = `https://image.pollinations.ai/prompt/${encodeURIComponent(prompt)}?width=${width}&height=${height}&seed=${seed}&model=${model}&nologo=true&private=${priv}&enhance=${enhance}&${safeParam}&nolog=true`;
145+
const url = `https://image.pollinations.ai/prompt/${encodeURIComponent(prompt)}?width=${width}&height=${height}&seed=${seed}&model=${model}&nologo=true&private=${priv}&enhance=${enhance}&safe=false&nolog=true`;
170146

171147
screensaverImage.style.opacity = "0.5";
172-
screensaverImage.crossOrigin = "anonymous"; // Enable CORS for cross-browser support
148+
screensaverImage.crossOrigin = "anonymous";
173149
screensaverImage.onload = () => {
174150
screensaverImage.style.opacity = "1";
175151
const browserInfo = getBrowserInfo();
176152
if (browserInfo.isSafari) {
177-
screensaverImage.style.webkitMaskImage = "none"; // Fix Safari rendering
153+
screensaverImage.style.webkitMaskImage = "none";
178154
}
179155
};
180156
screensaverImage.onerror = () => {
@@ -185,7 +161,6 @@ document.addEventListener("DOMContentLoaded", () => {
185161
screensaverImage.src = url;
186162
}
187163

188-
// Set or reset the image interval
189164
function setOrResetInterval() {
190165
clearInterval(imageInterval);
191166
const intervalSeconds = parseInt(timerInput.value) || 30;
@@ -195,7 +170,6 @@ document.addEventListener("DOMContentLoaded", () => {
195170
window.imageInterval = imageInterval;
196171
}
197172

198-
// Start the screensaver
199173
function startScreensaver() {
200174
screensaverActive = true;
201175
paused = false;
@@ -221,12 +195,10 @@ document.addEventListener("DOMContentLoaded", () => {
221195
document.body.style.overflow = "hidden";
222196
window.screensaverActive = true;
223197

224-
// Optional audio cue for screensaver start (placeholder)
225-
const audioUrl = "https://example.com/audio/start.mp3"; // Replace with actual audio API
198+
const audioUrl = "https://example.com/audio/start.mp3";
226199
playAudio(audioUrl).catch(err => console.warn("Audio cue failed:", err));
227200
}
228201

229-
// Stop the screensaver
230202
function stopScreensaver() {
231203
screensaverActive = false;
232204
paused = false;
@@ -251,7 +223,6 @@ document.addEventListener("DOMContentLoaded", () => {
251223
}
252224
}
253225

254-
// Toggle pause state
255226
function togglePause() {
256227
paused = !paused;
257228
playPauseButton.innerHTML = paused ? "▶️" : "⏸️";
@@ -260,89 +231,70 @@ document.addEventListener("DOMContentLoaded", () => {
260231
window.showToast(paused ? "Screensaver paused" : "Screensaver resumed");
261232
}
262233

263-
// Save the current image
264234
function saveImage() {
265235
if (!screensaverImage.src) {
266236
window.showToast("No image to save");
267237
return;
268238
}
269-
fetch(screensaverImage.src)
270-
.then(response => response.ok ? response.blob() : Promise.reject("Fetch failed"))
239+
fetch(screensaverImage.src, { mode: "cors" })
240+
.then(response => {
241+
if (!response.ok) throw new Error("Network response was not ok");
242+
return response.blob();
243+
})
271244
.then(blob => {
272-
const blobUrl = URL.createObjectURL(blob);
273-
const link = document.createElement("a");
274-
link.href = blobUrl;
275-
link.download = "screensaver-image.png";
276-
document.body.appendChild(link);
277-
link.click();
278-
document.body.removeChild(link);
279-
URL.revokeObjectURL(blobUrl);
280-
window.showToast("Image saved!");
245+
const url = URL.createObjectURL(blob);
246+
const a = document.createElement("a");
247+
a.href = url;
248+
a.download = `screensaver-image-${Date.now()}.png`;
249+
document.body.appendChild(a);
250+
a.click();
251+
document.body.removeChild(a);
252+
URL.revokeObjectURL(url);
253+
window.showToast("Image download initiated");
281254
})
282255
.catch(err => {
283256
console.error("Error saving image:", err);
284257
window.showToast("Failed to save image");
285258
});
286259
}
287260

288-
// Copy the current image to clipboard
289261
function copyImage() {
290262
if (!screensaverImage.src) {
291263
window.showToast("No image to copy");
292264
return;
293265
}
266+
if (!screensaverImage.complete || screensaverImage.naturalWidth === 0) {
267+
window.showToast("Image not fully loaded yet. Please try again.");
268+
return;
269+
}
294270
copyButton.textContent = "Copying...";
295271
const canvas = document.createElement("canvas");
296272
const ctx = canvas.getContext("2d");
297-
298-
if (screensaverImage.complete && screensaverImage.naturalWidth > 0) {
299-
canvas.width = screensaverImage.naturalWidth;
300-
canvas.height = screensaverImage.naturalHeight;
301-
ctx.drawImage(screensaverImage, 0, 0);
302-
canvas.toBlob(blob => {
303-
navigator.clipboard.write([new ClipboardItem({ "image/png": blob })])
304-
.then(() => {
305-
copyButton.textContent = "✅ Copied!";
306-
window.showToast("Image copied!");
307-
setTimeout(() => copyButton.textContent = "Copy Image", 1500);
308-
})
309-
.catch(err => {
310-
copyButton.textContent = "❌ Failed";
311-
window.showToast("Copy failed");
312-
setTimeout(() => copyButton.textContent = "Copy Image", 1500);
313-
});
314-
}, "image/png", 1.0);
315-
} else {
316-
const tempImg = new Image();
317-
tempImg.crossOrigin = "anonymous";
318-
tempImg.onload = () => {
319-
canvas.width = tempImg.naturalWidth;
320-
canvas.height = tempImg.naturalHeight;
321-
ctx.drawImage(tempImg, 0, 0);
322-
canvas.toBlob(blob => {
323-
navigator.clipboard.write([new ClipboardItem({ "image/png": blob })])
324-
.then(() => {
325-
copyButton.textContent = "✅ Copied!";
326-
window.showToast("Image copied!");
327-
setTimeout(() => copyButton.textContent = "Copy Image", 1500);
328-
})
329-
.catch(() => {
330-
copyButton.textContent = "❌ Failed";
331-
window.showToast("Copy failed");
332-
setTimeout(() => copyButton.textContent = "Copy Image", 1500);
333-
});
334-
}, "image/png", 1.0);
335-
};
336-
tempImg.onerror = () => {
337-
copyButton.textContent = "❌ Failed";
338-
window.showToast("Failed to load image");
339-
setTimeout(() => copyButton.textContent = "Copy Image", 1500);
340-
};
341-
tempImg.src = screensaverImage.src;
342-
}
273+
canvas.width = screensaverImage.naturalWidth;
274+
canvas.height = screensaverImage.naturalHeight;
275+
ctx.drawImage(screensaverImage, 0, 0);
276+
canvas.toBlob(blob => {
277+
if (!blob) {
278+
copyButton.textContent = "Copy Image";
279+
window.showToast("Failed to copy image: Unable to create blob.");
280+
return;
281+
}
282+
navigator.clipboard.write([new ClipboardItem({ "image/png": blob })])
283+
.then(() => {
284+
const dataURL = canvas.toDataURL("image/png");
285+
localStorage.setItem("lastCopiedImage", dataURL);
286+
copyButton.textContent = "✅ Copied!";
287+
window.showToast("Image copied to clipboard and saved to local storage");
288+
setTimeout(() => copyButton.textContent = "Copy Image", 1500);
289+
})
290+
.catch(err => {
291+
copyButton.textContent = "❌ Failed";
292+
window.showToast("Copy failed: " + err.message);
293+
setTimeout(() => copyButton.textContent = "Copy Image", 1500);
294+
});
295+
}, "image/png");
343296
}
344297

345-
// Toggle fullscreen mode
346298
function toggleFullscreen() {
347299
if (!screensaverActive) {
348300
window.showToast("Start the screensaver first!");
@@ -367,7 +319,6 @@ document.addEventListener("DOMContentLoaded", () => {
367319
}
368320
}
369321

370-
// Event listeners
371322
toggleScreensaverButton.addEventListener("click", () => {
372323
screensaverActive ? stopScreensaver() : startScreensaver();
373324
});
@@ -417,13 +368,21 @@ document.addEventListener("DOMContentLoaded", () => {
417368
}
418369
});
419370

420-
// Cross-browser toast notification
421371
window.showToast = function(message, duration = 3000) {
422372
let toast = document.getElementById("toast-notification");
423373
if (!toast) {
424374
toast = document.createElement("div");
425375
toast.id = "toast-notification";
426-
toast.style.cssText = "position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background-color:rgba(0,0,0,0.7);color:white;padding:10px 20px;border-radius:5px;z-index:9999;transition:opacity 0.3s;";
376+
toast.style.position = "fixed";
377+
toast.style.top = "5%";
378+
toast.style.left = "50%";
379+
toast.style.transform = "translateX(-50%)";
380+
toast.style.backgroundColor = "rgba(0,0,0,0.7)";
381+
toast.style.color = "white";
382+
toast.style.padding = "10px 20px";
383+
toast.style.borderRadius = "5px";
384+
toast.style.zIndex = "9999";
385+
toast.style.transition = "opacity 0.3s";
427386
document.body.appendChild(toast);
428387
}
429388
toast.textContent = message;
@@ -432,7 +391,6 @@ document.addEventListener("DOMContentLoaded", () => {
432391
toast.timeout = setTimeout(() => toast.style.opacity = "0", duration);
433392
};
434393

435-
// Expose functions globally
436394
window.startScreensaver = startScreensaver;
437395
window.stopScreensaver = stopScreensaver;
438396
window.togglePause = togglePause;

0 commit comments

Comments
 (0)