From 9d1ad7f783dd1206da281d047e0ab26f62bda6d6 Mon Sep 17 00:00:00 2001 From: koko210Serve Date: Mon, 27 Apr 2026 23:43:18 +0300 Subject: [PATCH] Add 'Set as Activity' button to each activity entry in Web UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each activity in the mood lists now has a 🎯 Set button that immediately sets it as the bot's current Discord activity (30-min manual override), so users can pick from existing entries instead of typing manually. --- bot/static/index.html | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/bot/static/index.html b/bot/static/index.html index 50eec74..4d2776a 100644 --- a/bot/static/index.html +++ b/bot/static/index.html @@ -6918,17 +6918,21 @@ function activitiesRenderSection(section) { function activitiesRenderView(section, mood, entries) { let html = ''; - for (const entry of entries) { + for (let i = 0; i < entries.length; i++) { + const entry = entries[i]; const icons = { listening: '🎵', playing: '🎮', watching: '📺', competing: '🏆', streaming: '🔴' }; const labels = { listening: 'Listening to', playing: 'Playing', watching: 'Watching', competing: 'Competing in', streaming: 'Streaming' }; const icon = icons[entry.type] || '🎮'; const label = labels[entry.type] || 'Playing'; + // Encode entry data for the "Set as Activity" button + const entryData = encodeURIComponent(JSON.stringify({ type: entry.type, name: entry.name, state: entry.state || '', url: entry.url || '' })); html += `
`; html += `${icon}`; html += `${label} ${escapeHtml(entry.name)}`; if (entry.state) html += ` — ${escapeHtml(entry.state)}`; html += ``; html += `weight: ${entry.weight}`; + html += ``; html += `
`; } html += `
`; @@ -7129,6 +7133,32 @@ async function activitySetManual() { } } +async function activitySetFromEntry(btnElement) { + const raw = btnElement.getAttribute('data-entry'); + if (!raw) return; + let entry; + try { entry = JSON.parse(decodeURIComponent(raw)); } catch { return; } + const type = entry.type; + const name = entry.name; + const state = entry.state || null; + const url = entry.url || null; + + if (!name) { showNotification('Activity name is empty', 'error'); return; } + if (type === 'streaming' && !url) { showNotification('Streaming requires a URL', 'error'); return; } + + try { + const body = { type, name }; + if (state) body.state = state; + if (url) body.url = url; + await apiCall('/activities/current', 'POST', body); + const icon = _activityTypeIcon(type); + showNotification(`${icon} Set activity: ${name}`, 'success'); + await activityRefreshCurrent(); + } catch (e) { + showNotification('Failed to set activity: ' + e.message, 'error'); + } +} + async function activityClearManual() { try { await apiCall('/activities/current', 'DELETE');