Skip to content

Commit bcac632

Browse files
authored
Merge pull request #9 from Unity-Lab-AI/develop
Develop
2 parents f145425 + bc8f4ee commit bcac632

File tree

9 files changed

+1724
-3302
lines changed

9 files changed

+1724
-3302
lines changed

ChatInterface.js

Lines changed: 0 additions & 1423 deletions
This file was deleted.

Screensaver.js

Lines changed: 0 additions & 650 deletions
This file was deleted.

chat.js

Lines changed: 666 additions & 0 deletions
Large diffs are not rendered by default.

favicon.ico

37.2 KB
Binary file not shown.

index.html

Lines changed: 90 additions & 832 deletions
Large diffs are not rendered by default.

screensaver.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// screensaver.js
2+
document.addEventListener("DOMContentLoaded", () => {
3+
const screensaverContainer = document.getElementById("screensaver-container");
4+
const toggleScreensaverButton = document.getElementById("toggle-screensaver");
5+
const fullscreenButton = document.getElementById("fullscreen-screensaver");
6+
const stopButton = document.getElementById("screensaver-exit");
7+
const playPauseButton = document.getElementById("screensaver-playpause");
8+
const saveButton = document.getElementById("screensaver-save");
9+
const copyButton = document.getElementById("screensaver-copy");
10+
const screensaverImage = document.getElementById("screensaver-image");
11+
12+
// Extended controls.
13+
const promptInput = document.getElementById("screensaver-prompt");
14+
const timerInput = document.getElementById("screensaver-timer");
15+
const aspectSelect = document.getElementById("screensaver-aspect");
16+
const enhanceCheckbox = document.getElementById("screensaver-enhance");
17+
const privateCheckbox = document.getElementById("screensaver-private");
18+
const modelSelect = document.getElementById("screensaver-model");
19+
20+
let screensaverActive = false;
21+
let imageInterval;
22+
let paused = false;
23+
24+
function generateSeed() {
25+
const length = Math.floor(Math.random() * 8) + 1;
26+
let seed = "";
27+
for (let i = 0; i < length; i++) {
28+
seed += Math.floor(Math.random() * 10);
29+
}
30+
return seed;
31+
}
32+
33+
function getDimensions(aspect) {
34+
switch (aspect) {
35+
case "widescreen":
36+
return { width: 1280, height: 720 };
37+
case "square":
38+
return { width: 1024, height: 1024 };
39+
case "portrait":
40+
return { width: 720, height: 1280 };
41+
default:
42+
return { width: 1280, height: 720 };
43+
}
44+
}
45+
46+
function fetchNewImage() {
47+
const prompt = promptInput.value || "random artistic scene, high quality, detailed";
48+
const { width, height } = getDimensions(aspectSelect.value);
49+
const seed = generateSeed();
50+
const model = modelSelect.value || "flux";
51+
const enhance = enhanceCheckbox.checked;
52+
const priv = privateCheckbox.checked;
53+
const url = `https://image.pollinations.ai/prompt/${encodeURIComponent(prompt)}?width=${width}&height=${height}&seed=${seed}&model=${model}&nologo=true&private=${priv}&enhance=${enhance}`;
54+
screensaverImage.src = url;
55+
}
56+
57+
function setOrResetInterval() {
58+
clearInterval(imageInterval);
59+
const intervalSeconds = parseInt(timerInput.value) || 30;
60+
imageInterval = setInterval(() => {
61+
if (!paused) fetchNewImage();
62+
}, intervalSeconds * 1000);
63+
}
64+
65+
function startScreensaver() {
66+
screensaverActive = true;
67+
paused = false;
68+
screensaverContainer.classList.remove("hidden");
69+
fetchNewImage();
70+
setOrResetInterval();
71+
playPauseButton.textContent = "⏸️";
72+
}
73+
74+
function stopScreensaver() {
75+
screensaverActive = false;
76+
paused = false;
77+
screensaverContainer.classList.add("hidden");
78+
clearInterval(imageInterval);
79+
}
80+
81+
function togglePause() {
82+
paused = !paused;
83+
playPauseButton.textContent = paused ? "▶️" : "⏸️";
84+
}
85+
86+
function saveImage() {
87+
fetch(screensaverImage.src)
88+
.then(response => response.blob())
89+
.then(blob => {
90+
const url = window.URL.createObjectURL(blob);
91+
const a = document.createElement("a");
92+
a.style.display = "none";
93+
a.href = url;
94+
a.download = "generated_image.jpg";
95+
document.body.appendChild(a);
96+
a.click();
97+
window.URL.revokeObjectURL(url);
98+
document.body.removeChild(a);
99+
})
100+
.catch(err => console.error("Error downloading image:", err));
101+
}
102+
103+
function copyImage() {
104+
fetch(screensaverImage.src)
105+
.then(response => response.blob())
106+
.then(blob => {
107+
const item = new ClipboardItem({ "image/png": blob });
108+
return navigator.clipboard.write([item]);
109+
})
110+
.then(() => alert("Image copied to clipboard"))
111+
.catch(err => console.error("Error copying image:", err));
112+
}
113+
114+
timerInput.addEventListener("change", () => {
115+
if (screensaverActive) setOrResetInterval();
116+
});
117+
118+
toggleScreensaverButton.addEventListener("click", () => {
119+
if (screensaverActive) {
120+
stopScreensaver();
121+
} else {
122+
startScreensaver();
123+
}
124+
});
125+
126+
fullscreenButton.addEventListener("click", () => {
127+
if (!document.fullscreenElement) {
128+
screensaverContainer.requestFullscreen();
129+
} else {
130+
document.exitFullscreen();
131+
}
132+
});
133+
134+
stopButton.addEventListener("click", stopScreensaver);
135+
playPauseButton.addEventListener("click", togglePause);
136+
saveButton.addEventListener("click", saveImage);
137+
copyButton.addEventListener("click", copyImage);
138+
});

storage.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// storage.js
2+
document.addEventListener("DOMContentLoaded", () => {
3+
const sessionListEl = document.getElementById("session-list");
4+
let sessions = loadSessions();
5+
6+
if (!localStorage.getItem("currentSessionId")) {
7+
const newSession = createSession("New Chat");
8+
localStorage.setItem("currentSessionId", newSession.id);
9+
}
10+
11+
renderSessions();
12+
13+
window.Storage = {
14+
getSessions,
15+
createSession,
16+
deleteSession,
17+
getCurrentSession,
18+
setCurrentSessionId,
19+
updateSessionMessages,
20+
renameSession,
21+
setSessionModel
22+
};
23+
24+
function getSessions() {
25+
return sessions;
26+
}
27+
28+
function createSession(name) {
29+
const newId = Date.now().toString();
30+
const session = {
31+
id: newId,
32+
name,
33+
model: "unity", // Default model set to "unity"
34+
messages: [],
35+
lastUpdated: Date.now()
36+
};
37+
sessions.push(session);
38+
saveSessions();
39+
return session;
40+
}
41+
42+
function deleteSession(sessionId) {
43+
sessions = sessions.filter(s => s.id !== sessionId);
44+
saveSessions();
45+
if (localStorage.getItem("currentSessionId") === sessionId) {
46+
// Clear chat box if the current session is deleted.
47+
const chatBox = document.getElementById("chat-box");
48+
if (chatBox) chatBox.innerHTML = "";
49+
50+
if (sessions.length > 0) {
51+
localStorage.setItem("currentSessionId", sessions[0].id);
52+
} else {
53+
const newSession = createSession("New Chat");
54+
localStorage.setItem("currentSessionId", newSession.id);
55+
}
56+
}
57+
renderSessions();
58+
}
59+
60+
function renameSession(sessionId, newName) {
61+
const session = sessions.find(s => s.id === sessionId);
62+
if (session) {
63+
let cleanName = newName;
64+
if (typeof newName === "object") {
65+
cleanName = JSON.stringify(newName);
66+
} else if (newName && newName.startsWith("{") && newName.endsWith("}")) {
67+
try {
68+
const parsed = JSON.parse(newName);
69+
cleanName = parsed.response || parsed.chatTitle || newName;
70+
} catch (e) {
71+
console.error("Error parsing session name JSON:", e);
72+
}
73+
}
74+
session.name = cleanName;
75+
session.lastUpdated = Date.now();
76+
saveSessions();
77+
renderSessions();
78+
}
79+
}
80+
81+
// FIXED: Ensure a valid session is always returned.
82+
function getCurrentSession() {
83+
const currentId = localStorage.getItem("currentSessionId");
84+
let session = sessions.find(s => s.id === currentId);
85+
if (!session) {
86+
session = createSession("New Chat");
87+
localStorage.setItem("currentSessionId", session.id);
88+
}
89+
return session;
90+
}
91+
92+
function setCurrentSessionId(sessionId) {
93+
localStorage.setItem("currentSessionId", sessionId);
94+
renderSessions();
95+
}
96+
97+
function setSessionModel(sessionId, modelName) {
98+
const session = sessions.find(s => s.id === sessionId);
99+
if (session) {
100+
session.model = modelName;
101+
session.lastUpdated = Date.now();
102+
saveSessions();
103+
}
104+
}
105+
106+
function updateSessionMessages(sessionId, messages) {
107+
const session = sessions.find(s => s.id === sessionId);
108+
if (session) {
109+
session.messages = messages;
110+
session.lastUpdated = Date.now();
111+
saveSessions();
112+
}
113+
}
114+
115+
function loadSessions() {
116+
const raw = localStorage.getItem("pollinations_sessions");
117+
return raw ? JSON.parse(raw) : [];
118+
}
119+
120+
function saveSessions() {
121+
localStorage.setItem("pollinations_sessions", JSON.stringify(sessions));
122+
}
123+
124+
function renderSessions() {
125+
sessionListEl.innerHTML = "";
126+
sessions.sort((a, b) => b.lastUpdated - a.lastUpdated);
127+
sessions.forEach(session => {
128+
const li = document.createElement("li");
129+
li.classList.add("session-item");
130+
131+
const titleSpan = document.createElement("span");
132+
titleSpan.classList.add("session-title");
133+
let displayName = session.name;
134+
if (displayName && displayName.startsWith("{") && displayName.endsWith("}")) {
135+
try {
136+
const parsed = JSON.parse(displayName);
137+
displayName = parsed.response || parsed.chatTitle || displayName;
138+
} catch (e) {
139+
console.error("Error parsing session name JSON:", e);
140+
}
141+
}
142+
titleSpan.textContent = displayName;
143+
144+
const editBtn = document.createElement("button");
145+
editBtn.classList.add("session-edit-btn");
146+
editBtn.textContent = "✎";
147+
editBtn.addEventListener("click", e => {
148+
e.stopPropagation();
149+
const newName = prompt("Rename session:", session.name);
150+
if (newName && newName.trim() !== "") {
151+
renameSession(session.id, newName.trim());
152+
}
153+
});
154+
li.appendChild(titleSpan);
155+
li.appendChild(editBtn);
156+
157+
const delBtn = document.createElement("button");
158+
delBtn.classList.add("session-delete-btn");
159+
delBtn.textContent = "✕";
160+
delBtn.addEventListener("click", e => {
161+
e.stopPropagation();
162+
deleteSession(session.id);
163+
});
164+
li.appendChild(delBtn);
165+
166+
li.addEventListener("click", () => {
167+
localStorage.setItem("currentSessionId", session.id);
168+
location.reload();
169+
});
170+
171+
if (session.id === localStorage.getItem("currentSessionId")) {
172+
li.style.backgroundColor = "rgba(255,255,255,0.2)";
173+
}
174+
175+
sessionListEl.appendChild(li);
176+
});
177+
}
178+
});

0 commit comments

Comments
 (0)