Skip to content

Commit 5d7a8d2

Browse files
authored
Merge pull request #18 from Unity-Lab-AI/codex/add-refreshpolliimage-helper-utility
refactor: centralize Polli image refresh helper
2 parents 14f7a29 + a6cc176 commit 5d7a8d2

4 files changed

Lines changed: 117 additions & 137 deletions

File tree

chat-storage.js

Lines changed: 29 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -334,73 +334,37 @@ document.addEventListener("DOMContentLoaded", () => {
334334
showToast("Failed to download image: " + err.message);
335335
});
336336
}
337-
function refreshImage(img, imageId) {
338-
console.log(`Refreshing image with ID: ${imageId}`);
339-
if (!img.src) {
340-
showToast("No image source to refresh.");
341-
return;
342-
}
343-
const urlObj = new URL(img.src);
344-
if (!window.polliClient || !window.polliClient.imageBase) {
345-
showToast("Image client not ready.");
337+
function refreshImage(img, imageId) {
338+
console.log(`Refreshing image with ID: ${imageId}`);
339+
const { url: finalUrl, error } = window.refreshPolliImage(img?.src, {
340+
width: img.naturalWidth,
341+
height: img.naturalHeight,
342+
});
343+
if (!finalUrl) {
344+
showToast(error || "Failed to refresh image");
346345
return;
347346
}
348-
const baseOrigin = new URL(window.polliClient.imageBase).origin;
349-
if (urlObj.origin !== baseOrigin) {
350-
showToast("Can't refresh: not a polliLib image URL.");
351-
return;
352-
}
353-
const newSeed = Math.floor(Math.random() * 1000000);
354-
let prompt = '';
355-
try {
356-
const parts = urlObj.pathname.split('/');
357-
const i = parts.indexOf('prompt');
358-
if (i >= 0 && parts[i+1]) prompt = decodeURIComponent(parts[i+1]);
359-
} catch {}
360-
const width = Number(urlObj.searchParams.get('width')) || img.naturalWidth || 512;
361-
const height = Number(urlObj.searchParams.get('height')) || img.naturalHeight || 512;
362-
const model = urlObj.searchParams.get('model') || (document.getElementById('model-select')?.value || undefined);
363-
let newUrl = img.src;
364-
try {
365-
if (window.polliLib && window.polliClient && prompt) {
366-
newUrl = window.polliLib.mcp.generateImageUrl(window.polliClient, {
367-
prompt, width, height, seed: newSeed, nologo: true, model
368-
});
369-
} else {
370-
urlObj.searchParams.set('seed', String(newSeed));
371-
newUrl = urlObj.toString();
372-
}
373-
} catch (e) {
374-
console.warn('polliLib generateImageUrl failed; falling back to seed swap', e);
375-
urlObj.searchParams.set('seed', String(newSeed));
376-
newUrl = urlObj.toString();
377-
}
378-
const newUrlObj = new URL(newUrl);
379-
if (!newUrlObj.searchParams.has('referrer') && window.polliClient?.referrer) {
380-
newUrlObj.searchParams.set('referrer', window.polliClient.referrer); // retain referrer for API tiering
381-
}
382-
const finalUrl = newUrlObj.toString();
383-
const loadingDiv = document.createElement("div");
384-
loadingDiv.className = "ai-image-loading";
385-
const spinner = document.createElement("div");
386-
spinner.className = "loading-spinner";
387-
loadingDiv.appendChild(spinner);
388-
loadingDiv.style.width = img.width + "px";
389-
loadingDiv.style.height = img.height + "px";
390-
img.parentNode.insertBefore(loadingDiv, img);
391-
img.style.display = "none";
392-
img.onload = () => {
393-
loadingDiv.remove();
394-
img.style.display = "block";
395-
showToast("Image refreshed with new seed");
396-
};
397-
img.onerror = () => {
398-
loadingDiv.innerHTML = "⚠️ Failed to refresh image";
399-
loadingDiv.style.display = "flex";
400-
loadingDiv.style.justifyContent = "center";
401-
loadingDiv.style.alignItems = "center";
402-
showToast("Failed to refresh image");
403-
};
347+
const loadingDiv = document.createElement("div");
348+
loadingDiv.className = "ai-image-loading";
349+
const spinner = document.createElement("div");
350+
spinner.className = "loading-spinner";
351+
loadingDiv.appendChild(spinner);
352+
loadingDiv.style.width = img.width + "px";
353+
loadingDiv.style.height = img.height + "px";
354+
img.parentNode.insertBefore(loadingDiv, img);
355+
img.style.display = "none";
356+
img.onload = () => {
357+
loadingDiv.remove();
358+
img.style.display = "block";
359+
showToast("Image refreshed with new seed");
360+
};
361+
img.onerror = () => {
362+
loadingDiv.innerHTML = "⚠️ Failed to refresh image";
363+
loadingDiv.style.display = "flex";
364+
loadingDiv.style.justifyContent = "center";
365+
loadingDiv.style.alignItems = "center";
366+
showToast("Failed to refresh image");
367+
};
404368
img.src = finalUrl;
405369
}
406370
function openImageInNewTab(img, imageId) {

index.html

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -466,10 +466,11 @@ <h3 class="modal-title">Voice Chat</h3>
466466

467467
<!-- UI now safely uses PolliLib's default client -->
468468
<script defer src="ui.js"></script>
469-
470-
<script defer src="chat-storage.js"></script>
471-
<script defer src="chat-init.js"></script>
472-
<script defer src="simple.js"></script>
473-
</body>
469+
470+
<script defer src="polli-utils.js"></script>
471+
<script defer src="chat-storage.js"></script>
472+
<script defer src="chat-init.js"></script>
473+
<script defer src="simple.js"></script>
474+
</body>
474475

475476
</html>

polli-utils.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
(function(global){
2+
function refreshPolliImage(url, options = {}) {
3+
if (!url) {
4+
return { error: 'No image source to refresh.' };
5+
}
6+
let urlObj;
7+
try {
8+
urlObj = new URL(url);
9+
} catch {
10+
return { error: 'Invalid image URL.' };
11+
}
12+
if (!global.polliClient || !global.polliClient.imageBase) {
13+
return { error: 'Image client not ready.' };
14+
}
15+
const baseOrigin = new URL(global.polliClient.imageBase).origin;
16+
if (urlObj.origin !== baseOrigin) {
17+
return { error: "Can't refresh: not a polliLib image URL." };
18+
}
19+
const newSeed = Math.floor(Math.random() * 1000000);
20+
let prompt = '';
21+
try {
22+
const parts = urlObj.pathname.split('/');
23+
const i = parts.indexOf('prompt');
24+
if (i >= 0 && parts[i + 1]) prompt = decodeURIComponent(parts[i + 1]);
25+
} catch {}
26+
const width = options.width || Number(urlObj.searchParams.get('width')) || 512;
27+
const height = options.height || Number(urlObj.searchParams.get('height')) || 512;
28+
const model = options.model || urlObj.searchParams.get('model') || (document.getElementById('model-select')?.value || undefined);
29+
let newUrl = url;
30+
try {
31+
if (global.polliLib && global.polliClient && prompt) {
32+
newUrl = global.polliLib.mcp.generateImageUrl(global.polliClient, {
33+
prompt, width, height, seed: newSeed, nologo: true, model
34+
});
35+
} else {
36+
urlObj.searchParams.set('seed', String(newSeed));
37+
newUrl = urlObj.toString();
38+
}
39+
} catch (e) {
40+
console.warn('polliLib generateImageUrl failed; falling back to seed swap', e);
41+
urlObj.searchParams.set('seed', String(newSeed));
42+
newUrl = urlObj.toString();
43+
}
44+
const newUrlObj = new URL(newUrl);
45+
if (!newUrlObj.searchParams.has('referrer') && global.polliClient?.referrer) {
46+
newUrlObj.searchParams.set('referrer', global.polliClient.referrer);
47+
}
48+
return { url: newUrlObj.toString() };
49+
}
50+
global.refreshPolliImage = refreshPolliImage;
51+
})(window);

simple.js

Lines changed: 31 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -562,75 +562,39 @@ document.addEventListener("DOMContentLoaded", () => {
562562
});
563563
}
564564

565-
function refreshImage(img, imageId) {
566-
console.log(`Refreshing image with ID: ${imageId} in simple mode`);
567-
if (!img.src) {
568-
window.showToast("No image source to refresh.");
569-
return;
570-
}
571-
const urlObj = new URL(img.src);
572-
if (!window.polliClient || !window.polliClient.imageBase) {
573-
window.showToast("Image client not ready.");
565+
function refreshImage(img, imageId) {
566+
console.log(`Refreshing image with ID: ${imageId} in simple mode`);
567+
const { url: finalUrl, error } = window.refreshPolliImage(img?.src, {
568+
width: img.naturalWidth,
569+
height: img.naturalHeight,
570+
});
571+
if (!finalUrl) {
572+
window.showToast(error || "Failed to refresh image");
574573
return;
575574
}
576-
const baseOrigin = new URL(window.polliClient.imageBase).origin;
577-
if (urlObj.origin !== baseOrigin) {
578-
window.showToast("Can't refresh: not a polliLib image URL.");
579-
return;
580-
}
581-
const newSeed = Math.floor(Math.random() * 1000000);
582-
let prompt = '';
583-
try {
584-
const parts = urlObj.pathname.split('/');
585-
const i = parts.indexOf('prompt');
586-
if (i >= 0 && parts[i+1]) prompt = decodeURIComponent(parts[i+1]);
587-
} catch {}
588-
const width = Number(urlObj.searchParams.get('width')) || img.naturalWidth || 512;
589-
const height = Number(urlObj.searchParams.get('height')) || img.naturalHeight || 512;
590-
const model = urlObj.searchParams.get('model') || (document.getElementById('model-select')?.value || undefined);
591-
let newUrl = img.src;
592-
try {
593-
if (window.polliLib && window.polliClient && prompt) {
594-
newUrl = window.polliLib.mcp.generateImageUrl(window.polliClient, {
595-
prompt, width, height, seed: newSeed, nologo: true, model
596-
});
597-
} else {
598-
urlObj.searchParams.set('seed', String(newSeed));
599-
newUrl = urlObj.toString();
600-
}
601-
} catch (e) {
602-
console.warn('polliLib generateImageUrl failed; falling back to seed swap', e);
603-
urlObj.searchParams.set('seed', String(newSeed));
604-
newUrl = urlObj.toString();
605-
}
606-
const newUrlObj = new URL(newUrl);
607-
if (!newUrlObj.searchParams.has('referrer') && window.polliClient?.referrer) {
608-
newUrlObj.searchParams.set('referrer', window.polliClient.referrer); // retain referrer for API tiering
609-
}
610-
const finalUrl = newUrlObj.toString();
611-
612-
const loadingDiv = document.createElement("div");
613-
loadingDiv.className = "simple-ai-image-loading";
614-
const spinner = document.createElement("div");
615-
spinner.className = "simple-loading-spinner";
616-
loadingDiv.appendChild(spinner);
617-
loadingDiv.style.width = img.width + "px";
618-
loadingDiv.style.height = img.height + "px";
619-
img.parentNode.insertBefore(loadingDiv, img);
620-
img.style.display = "none";
621-
622-
img.onload = () => {
623-
loadingDiv.remove();
624-
img.style.display = "block";
625-
window.showToast("Image refreshed with new seed");
626-
};
627-
img.onerror = () => {
628-
loadingDiv.innerHTML = "⚠️ Failed to refresh image";
629-
loadingDiv.style.display = "flex";
630-
loadingDiv.style.justifyContent = "center";
631-
loadingDiv.style.alignItems = "center";
632-
window.showToast("Failed to refresh image");
633-
};
575+
576+
const loadingDiv = document.createElement("div");
577+
loadingDiv.className = "simple-ai-image-loading";
578+
const spinner = document.createElement("div");
579+
spinner.className = "simple-loading-spinner";
580+
loadingDiv.appendChild(spinner);
581+
loadingDiv.style.width = img.width + "px";
582+
loadingDiv.style.height = img.height + "px";
583+
img.parentNode.insertBefore(loadingDiv, img);
584+
img.style.display = "none";
585+
586+
img.onload = () => {
587+
loadingDiv.remove();
588+
img.style.display = "block";
589+
window.showToast("Image refreshed with new seed");
590+
};
591+
img.onerror = () => {
592+
loadingDiv.innerHTML = "⚠️ Failed to refresh image";
593+
loadingDiv.style.display = "flex";
594+
loadingDiv.style.justifyContent = "center";
595+
loadingDiv.style.alignItems = "center";
596+
window.showToast("Failed to refresh image");
597+
};
634598
img.src = finalUrl;
635599
}
636600

0 commit comments

Comments
 (0)