\d+)\/delete/, async (req, res) => {
diff --git a/views/admin/emojis.html b/views/admin/emojis.html
index fdb0f41..9536b19 100644
--- a/views/admin/emojis.html
+++ b/views/admin/emojis.html
@@ -24,6 +24,12 @@
+
+
+
+
@@ -123,6 +129,39 @@
const btnAddEmoji = document.getElementById('add-emoji');
if (btnAddEmoji) btnAddEmoji.addEventListener('click', addEmoji);
+
+ // Reconvert all emojis to WebP
+ const reconvertEmojis = async () => {
+ const btn = document.getElementById('reconvert-webp');
+ const status = document.getElementById('reconvert-status');
+ if (!btn || !status) return;
+ if (!confirm('Reconvert all non-WebP emojis to WebP? This will delete the originals.')) return;
+
+ btn.disabled = true;
+ status.textContent = '\u23F3 Converting\u2026';
+
+ try {
+ const csrf = '{{ csrf_token }}';
+ const res = await fetch('/api/v2/admin/emojis/reconvert', {
+ method: 'POST',
+ headers: { 'X-CSRF-Token': csrf, 'X-Requested-With': 'XMLHttpRequest' }
+ });
+ const result = await res.json();
+ if (result.success) {
+ status.textContent = '\u2705 Done \u2014 converted: ' + result.converted + ', skipped: ' + result.skipped + ', errors: ' + result.errors;
+ if (result.converted > 0) loadEmojis();
+ } else {
+ status.textContent = '\u274C Failed: ' + (result.message || 'Unknown error');
+ }
+ } catch (err) {
+ status.textContent = '\u274C Error: ' + err.message;
+ } finally {
+ btn.disabled = false;
+ }
+ };
+
+ const btnReconvert = document.getElementById('reconvert-webp');
+ if (btnReconvert) btnReconvert.addEventListener('click', reconvertEmojis);
// Live Update Listener (SSE dispatched via f0ckm.js)
document.addEventListener('f0ck:emojis_updated', loadEmojis);