统一侧边栏确认弹窗交互

This commit is contained in:
QLHazyCoder
2026-04-09 02:02:48 +08:00
parent ed97ec4a4a
commit f204f38bdb
+93 -20
View File
@@ -37,6 +37,7 @@ const inputInbucketMailbox = document.getElementById('input-inbucket-mailbox');
const inputRunCount = document.getElementById('input-run-count'); const inputRunCount = document.getElementById('input-run-count');
const inputAutoSkipFailures = document.getElementById('input-auto-skip-failures'); const inputAutoSkipFailures = document.getElementById('input-auto-skip-failures');
const autoStartModal = document.getElementById('auto-start-modal'); const autoStartModal = document.getElementById('auto-start-modal');
const autoStartTitle = autoStartModal?.querySelector('.modal-title');
const autoStartMessage = document.getElementById('auto-start-message'); const autoStartMessage = document.getElementById('auto-start-message');
const btnAutoStartClose = document.getElementById('btn-auto-start-close'); const btnAutoStartClose = document.getElementById('btn-auto-start-close');
const btnAutoStartCancel = document.getElementById('btn-auto-start-cancel'); const btnAutoStartCancel = document.getElementById('btn-auto-start-cancel');
@@ -66,7 +67,8 @@ let currentAutoRun = {
let settingsDirty = false; let settingsDirty = false;
let settingsSaveInFlight = false; let settingsSaveInFlight = false;
let settingsAutoSaveTimer = null; let settingsAutoSaveTimer = null;
let autoStartChoiceResolver = null; let modalChoiceResolver = null;
let currentModalActions = [];
const EYE_OPEN_ICON = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>'; const EYE_OPEN_ICON = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>';
const EYE_CLOSED_ICON = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17.94 17.94A10.94 10.94 0 0 1 12 19C5 19 1 12 1 12a21.77 21.77 0 0 1 5.06-6.94"/><path d="M9.9 4.24A10.94 10.94 0 0 1 12 5c7 0 11 7 11 7a21.86 21.86 0 0 1-2.16 3.19"/><path d="M1 1l22 22"/><path d="M14.12 14.12a3 3 0 1 1-4.24-4.24"/></svg>'; const EYE_CLOSED_ICON = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17.94 17.94A10.94 10.94 0 0 1 12 19C5 19 1 12 1 12a21.77 21.77 0 0 1 5.06-6.94"/><path d="M9.9 4.24A10.94 10.94 0 0 1 12 5c7 0 11 7 11 7a21.86 21.86 0 0 1-2.16 3.19"/><path d="M1 1l22 22"/><path d="M14.12 14.12a3 3 0 1 1-4.24-4.24"/></svg>';
@@ -110,33 +112,89 @@ function dismissToast(toast) {
toast.addEventListener('animationend', () => toast.remove()); toast.addEventListener('animationend', () => toast.remove());
} }
function resolveAutoStartChoice(choice) { function resetActionModalButtons() {
if (autoStartChoiceResolver) { const buttons = [btnAutoStartCancel, btnAutoStartRestart, btnAutoStartContinue];
autoStartChoiceResolver(choice); buttons.forEach((button) => {
autoStartChoiceResolver = null; if (!button) return;
button.hidden = true;
button.disabled = false;
button.onclick = null;
});
currentModalActions = [];
} }
function configureActionModalButton(button, action) {
if (!button) return;
if (!action) {
button.hidden = true;
button.onclick = null;
return;
}
button.hidden = false;
button.disabled = false;
button.textContent = action.label;
button.className = `btn ${action.variant || 'btn-outline'} btn-sm`;
button.onclick = () => resolveModalChoice(action.id);
}
function resolveModalChoice(choice) {
if (modalChoiceResolver) {
modalChoiceResolver(choice);
modalChoiceResolver = null;
}
resetActionModalButtons();
if (autoStartModal) { if (autoStartModal) {
autoStartModal.hidden = true; autoStartModal.hidden = true;
} }
} }
function openAutoStartChoiceDialog(startStep) { function openActionModal({ title, message, actions }) {
if (!autoStartModal) { if (!autoStartModal) {
return Promise.resolve('restart'); return Promise.resolve(null);
} }
if (autoStartChoiceResolver) { if (modalChoiceResolver) {
resolveAutoStartChoice(null); resolveModalChoice(null);
} }
autoStartMessage.textContent = `检测到当前已有流程进度。继续当前会从步骤 ${startStep} 开始自动执行,重新开始会清空当前流程进度并从步骤 1 新开一轮。`; autoStartTitle.textContent = title;
autoStartMessage.textContent = message;
currentModalActions = actions || [];
configureActionModalButton(btnAutoStartCancel, currentModalActions[0]);
configureActionModalButton(btnAutoStartRestart, currentModalActions[1]);
configureActionModalButton(btnAutoStartContinue, currentModalActions[2]);
autoStartModal.hidden = false; autoStartModal.hidden = false;
return new Promise((resolve) => { return new Promise((resolve) => {
autoStartChoiceResolver = resolve; modalChoiceResolver = resolve;
}); });
} }
function openAutoStartChoiceDialog(startStep) {
return openActionModal({
title: '启动自动',
message: `检测到当前已有流程进度。继续当前会从步骤 ${startStep} 开始自动执行,重新开始会清空当前流程进度并从步骤 1 新开一轮。`,
actions: [
{ id: null, label: '取消', variant: 'btn-ghost' },
{ id: 'restart', label: '重新开始', variant: 'btn-outline' },
{ id: 'continue', label: '继续当前', variant: 'btn-primary' },
],
});
}
async function openConfirmModal({ title, message, confirmLabel = '确认', confirmVariant = 'btn-primary' }) {
const choice = await openActionModal({
title,
message,
actions: [
{ id: null, label: '取消', variant: 'btn-ghost' },
{ id: 'confirm', label: confirmLabel, variant: confirmVariant },
],
});
return choice === 'confirm';
}
function isDoneStatus(status) { function isDoneStatus(status) {
return status === 'completed' || status === 'manual_completed' || status === 'skipped'; return status === 'completed' || status === 'manual_completed' || status === 'skipped';
} }
@@ -634,7 +692,12 @@ async function maybeTakeoverAutoRun(actionLabel) {
return true; return true;
} }
const confirmed = confirm(`当前自动流程已暂停。若继续${actionLabel},将停止自动流程并切换为手动控制。是否继续?`); const confirmed = await openConfirmModal({
title: '接管自动',
message: `当前自动流程已暂停。若继续${actionLabel},将停止自动流程并切换为手动控制。是否继续?`,
confirmLabel: '确认接管',
confirmVariant: 'btn-primary',
});
if (!confirmed) { if (!confirmed) {
return false; return false;
} }
@@ -648,7 +711,12 @@ async function handleSkipStep(step) {
return; return;
} }
const confirmed = confirm(`这不会真正执行步骤 ${step},只会直接跳过该步骤并放行后续步骤。是否继续?`); const confirmed = await openConfirmModal({
title: '跳过步骤',
message: `这不会真正执行步骤 ${step},只会直接跳过该步骤并放行后续步骤。是否继续?`,
confirmLabel: `跳过步骤 ${step}`,
confirmVariant: 'btn-primary',
});
if (!confirmed) { if (!confirmed) {
return; return;
} }
@@ -736,13 +804,10 @@ btnStop.addEventListener('click', async () => {
autoStartModal?.addEventListener('click', (event) => { autoStartModal?.addEventListener('click', (event) => {
if (event.target === autoStartModal) { if (event.target === autoStartModal) {
resolveAutoStartChoice(null); resolveModalChoice(null);
} }
}); });
btnAutoStartClose?.addEventListener('click', () => resolveAutoStartChoice(null)); btnAutoStartClose?.addEventListener('click', () => resolveModalChoice(null));
btnAutoStartCancel?.addEventListener('click', () => resolveAutoStartChoice(null));
btnAutoStartRestart?.addEventListener('click', () => resolveAutoStartChoice('restart'));
btnAutoStartContinue?.addEventListener('click', () => resolveAutoStartChoice('continue'));
// Auto Run // Auto Run
btnAutoRun.addEventListener('click', async () => { btnAutoRun.addEventListener('click', async () => {
@@ -793,7 +858,16 @@ btnAutoContinue.addEventListener('click', async () => {
// Reset // Reset
btnReset.addEventListener('click', async () => { btnReset.addEventListener('click', async () => {
if (confirm('确认重置全部步骤和数据吗?')) { const confirmed = await openConfirmModal({
title: '重置流程',
message: '确认重置全部步骤和数据吗?',
confirmLabel: '确认重置',
confirmVariant: 'btn-danger',
});
if (!confirmed) {
return;
}
await chrome.runtime.sendMessage({ type: 'RESET', source: 'sidepanel' }); await chrome.runtime.sendMessage({ type: 'RESET', source: 'sidepanel' });
syncLatestState({ stepStatuses: STEP_DEFAULT_STATUSES }); syncLatestState({ stepStatuses: STEP_DEFAULT_STATUSES });
syncAutoRunState({ autoRunning: false, autoRunPhase: 'idle', autoRunCurrentRun: 0, autoRunTotalRuns: 1, autoRunAttemptRun: 0 }); syncAutoRunState({ autoRunning: false, autoRunPhase: 'idle', autoRunCurrentRun: 0, autoRunTotalRuns: 1, autoRunAttemptRun: 0 });
@@ -813,7 +887,6 @@ btnReset.addEventListener('click', async () => {
updateStopButtonState(false); updateStopButtonState(false);
updateButtonStates(); updateButtonStates();
updateProgressCounter(); updateProgressCounter();
}
}); });
// Clear log // Clear log