fix: replace alert dialogs with visual feedback for command buttons

- Chip buttons flash theme color briefly on success
- Send buttons flash green on success
- Remove showAlert for all commands except errors and plan start
- Add scale-down on press for tactile feel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dj-oyu 2026-02-22 05:56:19 +09:00
parent f14d42f3df
commit 1a50c63f84

View file

@ -255,6 +255,7 @@
.send-btn:active { opacity: 0.8; } .send-btn:active { opacity: 0.8; }
.send-btn:disabled { opacity: 0.5; } .send-btn:disabled { opacity: 0.5; }
.send-btn.sent { background: var(--done); transition: background 0.15s; }
.empty-state { .empty-state {
text-align: center; text-align: center;
@ -287,10 +288,13 @@
transition: all 0.2s; transition: all 0.2s;
} }
.cmd-chip:active { .cmd-chip:active { transform: scale(0.93); }
.cmd-chip.sent {
background: var(--btn); background: var(--btn);
color: var(--btn-text); color: var(--btn-text);
border-color: var(--btn); border-color: var(--btn);
transition: all 0.15s;
} }
.refresh-btn { .refresh-btn {
@ -383,51 +387,67 @@ document.querySelectorAll('.tab').forEach(tab => {
// Quick command chips // Quick command chips
document.querySelectorAll('.cmd-chip').forEach(chip => { document.querySelectorAll('.cmd-chip').forEach(chip => {
chip.addEventListener('click', () => { chip.addEventListener('click', async () => {
sendCommand(chip.dataset.cmd); const ok = await sendCommand(chip.dataset.cmd);
if (ok) flashSent(chip);
}); });
}); });
async function sendCommand(cmd) { async function sendCommand(cmd) {
if (!cmd.startsWith('/')) return; if (!cmd.startsWith('/')) return false;
try { try {
const sep = '/miniapp/api/command'.includes('?') ? '&' : '?'; const res = await fetch(API_BASE + '/miniapp/api/command?initData=' + encodeURIComponent(initData), {
const res = await fetch(API_BASE + '/miniapp/api/command' + sep + 'initData=' + encodeURIComponent(initData), {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ command: cmd }), body: JSON.stringify({ command: cmd }),
}); });
if (!res.ok) throw new Error('API error: ' + res.status); if (!res.ok) throw new Error('API error: ' + res.status);
tg.showAlert('Sent: ' + cmd); return true;
} catch (e) { } catch (e) {
tg.showAlert('Failed to send command'); tg.showAlert('Failed to send command');
return false;
} }
} }
function sendCustomCmd() { async function sendCustomCmd() {
const input = document.getElementById('custom-cmd'); const input = document.getElementById('custom-cmd');
const btn = input.nextElementSibling;
const cmd = input.value.trim(); const cmd = input.value.trim();
if (!cmd) return; if (!cmd) return;
if (!cmd.startsWith('/')) { if (!cmd.startsWith('/')) {
tg.showAlert('Command must start with /'); tg.showAlert('Command must start with /');
return; return;
} }
sendCommand(cmd); const ok = await sendCommand(cmd);
if (ok) {
input.value = ''; input.value = '';
flashSent(btn);
}
} }
function sendSkillCommand() { async function sendSkillCommand() {
if (!selectedSkill) return; if (!selectedSkill) return;
const msg = document.getElementById('skill-msg').value.trim(); const msg = document.getElementById('skill-msg').value.trim();
const cmd = msg ? '/skill ' + selectedSkill + ' ' + msg : '/skill ' + selectedSkill; const cmd = msg ? '/skill ' + selectedSkill + ' ' + msg : '/skill ' + selectedSkill;
sendCommand(cmd); const btn = document.getElementById('send-skill-btn');
const ok = await sendCommand(cmd);
if (ok) flashSent(btn);
} }
function startPlan() { async function startPlan() {
const input = document.getElementById('plan-task'); const input = document.getElementById('plan-task');
const task = input.value.trim(); const task = input.value.trim();
if (!task) return; if (!task) return;
sendCommand('/plan ' + task); const ok = await sendCommand('/plan ' + task);
if (ok) {
input.value = '';
tg.showAlert('Plan started!');
}
}
function flashSent(el) {
el.classList.add('sent');
setTimeout(() => el.classList.remove('sent'), 600);
} }
async function apiFetch(path) { async function apiFetch(path) {