feat(sidepanel): 更新邮箱状态处理逻辑并增强设置卡片的锁定状态管理

This commit is contained in:
QLHazyCoder
2026-04-13 00:15:50 +08:00
parent b31459b3b8
commit be8e2e25c2
4 changed files with 111 additions and 11 deletions
+15 -1
View File
@@ -229,9 +229,13 @@ function broadcastDataUpdate(payload) {
}).catch(() => { });
}
async function setEmailState(email) {
async function setEmailStateSilently(email) {
await setState({ email });
broadcastDataUpdate({ email });
}
async function setEmailState(email) {
await setEmailStateSilently(email);
if (email) {
await resumeAutoRunIfWaitingForEmail();
}
@@ -2539,6 +2543,16 @@ async function handleMessage(message, sender) {
}
// Side panel data updates
case 'SET_EMAIL_STATE': {
const state = await getState();
if (isAutoRunLockedState(state)) {
throw new Error('自动流程运行中,当前不能手动修改邮箱。');
}
const email = String(message.payload?.email || '').trim() || null;
await setEmailStateSilently(email);
return { ok: true, email };
}
case 'SAVE_EMAIL': {
const state = await getState();
if (isAutoRunLockedState(state)) {
+22
View File
@@ -238,6 +238,20 @@ header {
box-shadow: var(--shadow-sm);
}
.data-card.is-locked {
position: relative;
overflow: hidden;
}
.data-card.is-locked::after {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background: color-mix(in srgb, var(--bg-base) 18%, transparent);
pointer-events: none;
}
.section-mini-header {
display: flex;
align-items: center;
@@ -283,6 +297,10 @@ header {
min-width: 0;
}
.data-value-actions {
justify-content: space-between;
}
.input-with-icon {
position: relative;
flex: 1;
@@ -307,6 +325,10 @@ header {
min-width: 0;
}
.data-value-fill {
flex: 1;
}
.data-value.has-value { color: var(--text-primary); }
.mono {
+12 -8
View File
@@ -62,7 +62,7 @@
</header>
<section id="data-section">
<div class="data-card">
<div id="settings-card" class="data-card">
<div class="data-row">
<span class="data-label">来源</span>
<select id="select-panel-mode" class="data-select">
@@ -81,7 +81,11 @@
</div>
<div class="data-row" id="row-vps-password">
<span class="data-label">管理密钥</span>
<input type="password" id="input-vps-password" class="data-input" placeholder="请输入 CPA 管理密钥" />
<div class="input-with-icon">
<input type="password" id="input-vps-password" class="data-input data-input-with-icon" placeholder="请输入 CPA 管理密钥" />
<button id="btn-toggle-vps-password" class="input-icon-btn" type="button" aria-label="显示管理密钥"
title="显示管理密钥"></button>
</div>
</div>
<div class="data-row" id="row-local-cpa-step9-mode">
<span class="data-label">本地 CPA</span>
@@ -108,14 +112,11 @@
</div>
<div class="data-row">
<span class="data-label">codex密码</span>
<div class="data-inline">
<div class="input-with-icon">
<input type="password" id="input-password" class="data-input data-input-with-icon"
<div class="input-with-icon">
<input type="password" id="input-password" class="data-input data-input-with-icon"
placeholder="codex密码,留空则自动生成" />
<button id="btn-toggle-password" class="input-icon-btn" type="button" aria-label="显示密码"
title="显示密码"></button>
</div>
<button id="btn-save-settings" class="btn btn-outline btn-sm" type="button">保存</button>
</div>
</div>
<div class="data-row">
@@ -186,7 +187,10 @@
</div>
<div class="data-row">
<span class="data-label">回调</span>
<span id="display-localhost-url" class="data-value mono truncate">等待中...</span>
<div class="data-inline data-value-actions">
<span id="display-localhost-url" class="data-value data-value-fill mono truncate">等待中...</span>
<button id="btn-save-settings" class="btn btn-outline btn-sm" type="button">保存</button>
</div>
</div>
</div>
<div id="hotmail-section" class="data-card hotmail-card" style="display:none;">
+62 -2
View File
@@ -11,6 +11,7 @@ const STATUS_ICONS = {
};
const logArea = document.getElementById('log-area');
const settingsCard = document.getElementById('settings-card');
const displayOauthUrl = document.getElementById('display-oauth-url');
const displayLocalhostUrl = document.getElementById('display-localhost-url');
const displayStatus = document.getElementById('display-status');
@@ -549,6 +550,48 @@ function setLocalCpaStep9Mode(mode) {
});
}
function setSettingsCardLocked(locked) {
if (!settingsCard) {
return;
}
settingsCard.classList.toggle('is-locked', locked);
settingsCard.toggleAttribute('inert', locked);
}
async function setRuntimeEmailState(email) {
const normalizedEmail = String(email || '').trim() || null;
const response = await chrome.runtime.sendMessage({
type: 'SET_EMAIL_STATE',
source: 'sidepanel',
payload: { email: normalizedEmail },
});
if (response?.error) {
throw new Error(response.error);
}
return normalizedEmail;
}
async function clearRegistrationEmail(options = {}) {
const { silent = false } = options;
if (!inputEmail.value.trim() && !latestState?.email) {
return;
}
inputEmail.value = '';
syncLatestState({ email: null });
try {
await setRuntimeEmailState(null);
} catch (err) {
if (!silent) {
showToast(`清空邮箱失败:${err.message}`, 'error');
}
throw err;
}
}
function markSettingsDirty(isDirty = true) {
settingsDirty = isDirty;
updateSaveButtonState();
@@ -615,6 +658,9 @@ function applyAutoRunStatus(payload = currentAutoRun) {
const locked = isAutoRunLockedPhase();
const paused = isAutoRunPausedPhase();
const scheduled = isAutoRunScheduledPhase();
const settingsCardLocked = scheduled || locked;
setSettingsCardLocked(settingsCardLocked);
inputRunCount.disabled = currentAutoRun.autoRunning;
btnAutoRun.disabled = currentAutoRun.autoRunning;
@@ -1915,8 +1961,18 @@ inputEmail.addEventListener('change', async () => {
return;
}
const email = inputEmail.value.trim();
if (email) {
await chrome.runtime.sendMessage({ type: 'SAVE_EMAIL', source: 'sidepanel', payload: { email } });
inputEmail.value = email;
try {
if (email) {
const response = await chrome.runtime.sendMessage({ type: 'SAVE_EMAIL', source: 'sidepanel', payload: { email } });
if (response?.error) {
throw new Error(response.error);
}
} else {
await setRuntimeEmailState(null);
}
} catch (err) {
showToast(err.message, 'error');
}
});
inputEmail.addEventListener('input', updateButtonStates);
@@ -1953,6 +2009,7 @@ selectMailProvider.addEventListener('change', () => {
selectEmailGenerator.addEventListener('change', () => {
updateMailProviderUI();
clearRegistrationEmail({ silent: true }).catch(() => { });
markSettingsDirty(true);
saveSettings({ silent: true }).catch(() => { });
});
@@ -2140,6 +2197,9 @@ chrome.runtime.onMessage.addListener((message) => {
if (message.payload.password !== undefined) {
inputPassword.value = message.payload.password || '';
}
if (message.payload.localCpaStep9Mode !== undefined) {
setLocalCpaStep9Mode(message.payload.localCpaStep9Mode);
}
if (message.payload.oauthUrl !== undefined) {
displayOauthUrl.textContent = message.payload.oauthUrl || '等待中...';
displayOauthUrl.classList.toggle('has-value', Boolean(message.payload.oauthUrl));