merge: integrate hotmail邮箱支持 into dev
This commit is contained in:
@@ -238,6 +238,33 @@ header {
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.section-mini-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.section-mini-copy {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.section-mini-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.section-hint {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.data-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -309,6 +336,23 @@ header {
|
||||
.data-input::placeholder { color: var(--text-muted); }
|
||||
.data-input:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
||||
|
||||
.data-textarea {
|
||||
width: 100%;
|
||||
min-height: 88px;
|
||||
resize: vertical;
|
||||
padding: 8px 10px;
|
||||
background: var(--bg-base);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--text-primary);
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
outline: none;
|
||||
transition: border-color var(--transition), box-shadow var(--transition);
|
||||
}
|
||||
.data-textarea::placeholder { color: var(--text-muted); }
|
||||
.data-textarea:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
||||
|
||||
.data-input-with-icon {
|
||||
padding-right: 38px;
|
||||
}
|
||||
@@ -340,6 +384,189 @@ header {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.hotmail-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.hotmail-actions-row .data-label {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.hotmail-import-row {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.hotmail-import-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.hotmail-list-shell {
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: var(--radius-sm);
|
||||
background: color-mix(in srgb, var(--bg-base) 82%, transparent);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: 2px;
|
||||
transition: max-height var(--transition), border-color var(--transition), box-shadow var(--transition);
|
||||
}
|
||||
|
||||
.hotmail-list-shell.is-collapsed {
|
||||
max-height: 236px;
|
||||
}
|
||||
|
||||
.hotmail-list-shell.is-expanded {
|
||||
max-height: 440px;
|
||||
}
|
||||
|
||||
.hotmail-list-shell::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.hotmail-list-shell::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.hotmail-list-shell::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.hotmail-list-shell::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-muted);
|
||||
}
|
||||
|
||||
.hotmail-accounts-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.hotmail-account-item {
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg-base);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.hotmail-account-item.is-current {
|
||||
border-color: var(--blue);
|
||||
box-shadow: 0 0 0 1px var(--blue-glow);
|
||||
}
|
||||
|
||||
.hotmail-account-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.hotmail-account-title-row {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.hotmail-account-email {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.hotmail-copy-btn {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
transition: background var(--transition), color var(--transition), transform var(--transition);
|
||||
}
|
||||
|
||||
.hotmail-copy-btn:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.hotmail-copy-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.hotmail-status-chip {
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.hotmail-status-chip.status-authorized {
|
||||
background: var(--green-soft);
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
.hotmail-status-chip.status-used {
|
||||
background: var(--orange-soft);
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.hotmail-status-chip.status-disabled {
|
||||
background: var(--bg-surface);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.hotmail-status-chip.status-pending {
|
||||
background: var(--orange-soft);
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.hotmail-status-chip.status-error {
|
||||
background: var(--red-soft);
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
.hotmail-account-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 6px 10px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.hotmail-account-error {
|
||||
font-size: 12px;
|
||||
color: var(--red);
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.hotmail-account-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.hotmail-empty {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
border: 1px dashed var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.data-select {
|
||||
flex: 1;
|
||||
padding: 7px 10px;
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<div class="data-row">
|
||||
<span class="data-label">邮箱服务</span>
|
||||
<select id="select-mail-provider" class="data-select">
|
||||
<option value="hotmail-api">Hotmail(微软 Graph)</option>
|
||||
<option value="163">163 邮箱 (mail.163.com)</option>
|
||||
<option value="163-vip">163 VIP 邮箱 (webmail.vip.163.com)</option>
|
||||
<option value="qq">QQ 邮箱 (wx.mail.qq.com)</option>
|
||||
@@ -158,6 +159,49 @@
|
||||
<span id="display-localhost-url" class="data-value mono truncate">等待中...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="hotmail-section" class="data-card hotmail-card" style="display:none;">
|
||||
<div class="section-mini-header">
|
||||
<div class="section-mini-copy">
|
||||
<span class="section-label">Hotmail 账号池</span>
|
||||
<span class="section-hint">每轮自动分配一个可用账号</span>
|
||||
</div>
|
||||
<div class="section-mini-actions">
|
||||
<button id="btn-clear-used-hotmail-accounts" class="btn btn-ghost btn-xs" type="button">清空已用</button>
|
||||
<button id="btn-delete-all-hotmail-accounts" class="btn btn-ghost btn-xs" type="button">全部删除</button>
|
||||
<button id="btn-toggle-hotmail-list" class="btn btn-ghost btn-xs" type="button" aria-expanded="false">展开列表</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<span class="data-label">邮箱</span>
|
||||
<input type="text" id="input-hotmail-email" class="data-input" placeholder="name@hotmail.com" />
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<span class="data-label">客户端 ID</span>
|
||||
<input type="text" id="input-hotmail-client-id" class="data-input mono" placeholder="微软应用客户端 ID" />
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<span class="data-label">邮箱密码</span>
|
||||
<input type="password" id="input-hotmail-password" class="data-input" placeholder="可选,仅用于记录" />
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<span class="data-label">刷新令牌</span>
|
||||
<input type="password" id="input-hotmail-refresh-token" class="data-input mono" placeholder="必填,粘贴刷新令牌(refresh token)" />
|
||||
</div>
|
||||
<div class="data-row hotmail-actions-row">
|
||||
<span class="data-label"></span>
|
||||
<button id="btn-add-hotmail-account" class="btn btn-primary btn-sm" type="button">添加账号</button>
|
||||
</div>
|
||||
<div class="data-row hotmail-import-row">
|
||||
<span class="data-label">批量导入</span>
|
||||
<div class="hotmail-import-box">
|
||||
<textarea id="input-hotmail-import" class="data-textarea mono" placeholder="账号----密码----客户端ID----刷新令牌 name@hotmail.com----password----client-id----refresh-token"></textarea>
|
||||
<button id="btn-import-hotmail-accounts" class="btn btn-outline btn-sm" type="button">导入</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="hotmail-list-shell" class="hotmail-list-shell is-collapsed">
|
||||
<div id="hotmail-accounts-list" class="hotmail-accounts-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="status-bar" class="status-bar">
|
||||
<div class="status-dot"></div>
|
||||
<span id="display-status">就绪</span>
|
||||
@@ -265,6 +309,7 @@
|
||||
</div>
|
||||
|
||||
<div id="toast-container"></div>
|
||||
<script src="../hotmail-utils.js"></script>
|
||||
<script src="sidepanel.js"></script>
|
||||
</body>
|
||||
|
||||
|
||||
+594
-22
@@ -37,6 +37,19 @@ const inputVpsUrl = document.getElementById('input-vps-url');
|
||||
const inputVpsPassword = document.getElementById('input-vps-password');
|
||||
const selectMailProvider = document.getElementById('select-mail-provider');
|
||||
const selectEmailGenerator = document.getElementById('select-email-generator');
|
||||
const hotmailSection = document.getElementById('hotmail-section');
|
||||
const inputHotmailEmail = document.getElementById('input-hotmail-email');
|
||||
const inputHotmailClientId = document.getElementById('input-hotmail-client-id');
|
||||
const inputHotmailPassword = document.getElementById('input-hotmail-password');
|
||||
const inputHotmailRefreshToken = document.getElementById('input-hotmail-refresh-token');
|
||||
const inputHotmailImport = document.getElementById('input-hotmail-import');
|
||||
const btnAddHotmailAccount = document.getElementById('btn-add-hotmail-account');
|
||||
const btnImportHotmailAccounts = document.getElementById('btn-import-hotmail-accounts');
|
||||
const btnClearUsedHotmailAccounts = document.getElementById('btn-clear-used-hotmail-accounts');
|
||||
const btnDeleteAllHotmailAccounts = document.getElementById('btn-delete-all-hotmail-accounts');
|
||||
const btnToggleHotmailList = document.getElementById('btn-toggle-hotmail-list');
|
||||
const hotmailListShell = document.getElementById('hotmail-list-shell');
|
||||
const hotmailAccountsList = document.getElementById('hotmail-accounts-list');
|
||||
const rowInbucketHost = document.getElementById('row-inbucket-host');
|
||||
const inputInbucketHost = document.getElementById('input-inbucket-host');
|
||||
const rowInbucketMailbox = document.getElementById('row-inbucket-mailbox');
|
||||
@@ -56,6 +69,7 @@ const btnAutoStartClose = document.getElementById('btn-auto-start-close');
|
||||
const btnAutoStartCancel = document.getElementById('btn-auto-start-cancel');
|
||||
const btnAutoStartRestart = document.getElementById('btn-auto-start-restart');
|
||||
const btnAutoStartContinue = document.getElementById('btn-auto-start-continue');
|
||||
const autoHintText = document.querySelector('.auto-hint');
|
||||
const STEP_DEFAULT_STATUSES = {
|
||||
1: 'pending',
|
||||
2: 'pending',
|
||||
@@ -88,9 +102,19 @@ let cloudflareDomainEditMode = false;
|
||||
let modalChoiceResolver = null;
|
||||
let currentModalActions = [];
|
||||
let scheduledCountdownTimer = null;
|
||||
let hotmailActionInFlight = false;
|
||||
let hotmailListExpanded = false;
|
||||
|
||||
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 COPY_ICON = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';
|
||||
const parseHotmailImportText = window.HotmailUtils?.parseHotmailImportText;
|
||||
const shouldClearHotmailCurrentSelection = window.HotmailUtils?.shouldClearHotmailCurrentSelection;
|
||||
const upsertHotmailAccountInList = window.HotmailUtils?.upsertHotmailAccountInList;
|
||||
const filterHotmailAccountsByUsage = window.HotmailUtils?.filterHotmailAccountsByUsage;
|
||||
const getHotmailBulkActionLabel = window.HotmailUtils?.getHotmailBulkActionLabel;
|
||||
const getHotmailListToggleLabel = window.HotmailUtils?.getHotmailListToggleLabel;
|
||||
const HOTMAIL_LIST_EXPANDED_STORAGE_KEY = 'multipage-hotmail-list-expanded';
|
||||
|
||||
// ============================================================
|
||||
// Toast Notifications
|
||||
@@ -707,12 +731,227 @@ function getEmailGeneratorUiCopy() {
|
||||
};
|
||||
}
|
||||
|
||||
function getHotmailAccounts(state = latestState) {
|
||||
return Array.isArray(state?.hotmailAccounts) ? state.hotmailAccounts : [];
|
||||
}
|
||||
|
||||
function getCurrentHotmailAccount(state = latestState) {
|
||||
const currentId = state?.currentHotmailAccountId;
|
||||
return getHotmailAccounts(state).find((account) => account.id === currentId) || null;
|
||||
}
|
||||
|
||||
function getHotmailAccountsByUsage(mode = 'all', state = latestState) {
|
||||
const accounts = getHotmailAccounts(state);
|
||||
if (typeof filterHotmailAccountsByUsage === 'function') {
|
||||
return filterHotmailAccountsByUsage(accounts, mode);
|
||||
}
|
||||
if (mode === 'used') {
|
||||
return accounts.filter((account) => Boolean(account?.used));
|
||||
}
|
||||
return accounts.slice();
|
||||
}
|
||||
|
||||
function getHotmailBulkActionText(mode, count) {
|
||||
if (typeof getHotmailBulkActionLabel === 'function') {
|
||||
return getHotmailBulkActionLabel(mode, count);
|
||||
}
|
||||
const normalizedCount = Number.isFinite(Number(count)) ? Math.max(0, Number(count)) : 0;
|
||||
const prefix = mode === 'used' ? '清空已用' : '全部删除';
|
||||
const suffix = normalizedCount > 0 ? `(${normalizedCount})` : '';
|
||||
return `${prefix}${suffix}`;
|
||||
}
|
||||
|
||||
function getHotmailListToggleText(expanded, count) {
|
||||
if (typeof getHotmailListToggleLabel === 'function') {
|
||||
return getHotmailListToggleLabel(expanded, count);
|
||||
}
|
||||
const normalizedCount = Number.isFinite(Number(count)) ? Math.max(0, Number(count)) : 0;
|
||||
const suffix = normalizedCount > 0 ? `(${normalizedCount})` : '';
|
||||
return `${expanded ? '收起列表' : '展开列表'}${suffix}`;
|
||||
}
|
||||
|
||||
function updateHotmailListViewport() {
|
||||
const count = getHotmailAccounts().length;
|
||||
const usedCount = getHotmailAccountsByUsage('used').length;
|
||||
if (btnClearUsedHotmailAccounts) {
|
||||
btnClearUsedHotmailAccounts.textContent = getHotmailBulkActionText('used', usedCount);
|
||||
btnClearUsedHotmailAccounts.disabled = usedCount === 0;
|
||||
}
|
||||
if (btnDeleteAllHotmailAccounts) {
|
||||
btnDeleteAllHotmailAccounts.textContent = getHotmailBulkActionText('all', count);
|
||||
btnDeleteAllHotmailAccounts.disabled = count === 0;
|
||||
}
|
||||
if (btnToggleHotmailList) {
|
||||
btnToggleHotmailList.textContent = getHotmailListToggleText(hotmailListExpanded, count);
|
||||
btnToggleHotmailList.setAttribute('aria-expanded', String(hotmailListExpanded));
|
||||
btnToggleHotmailList.disabled = count === 0;
|
||||
}
|
||||
if (hotmailListShell) {
|
||||
hotmailListShell.classList.toggle('is-expanded', hotmailListExpanded);
|
||||
hotmailListShell.classList.toggle('is-collapsed', !hotmailListExpanded);
|
||||
}
|
||||
}
|
||||
|
||||
function setHotmailListExpanded(expanded, options = {}) {
|
||||
const { persist = true } = options;
|
||||
hotmailListExpanded = Boolean(expanded);
|
||||
updateHotmailListViewport();
|
||||
if (persist) {
|
||||
localStorage.setItem(HOTMAIL_LIST_EXPANDED_STORAGE_KEY, hotmailListExpanded ? '1' : '0');
|
||||
}
|
||||
}
|
||||
|
||||
function initHotmailListExpandedState() {
|
||||
const saved = localStorage.getItem(HOTMAIL_LIST_EXPANDED_STORAGE_KEY);
|
||||
setHotmailListExpanded(saved === '1', { persist: false });
|
||||
}
|
||||
|
||||
function shouldClearCurrentHotmailSelectionLocally(account) {
|
||||
if (typeof shouldClearHotmailCurrentSelection === 'function') {
|
||||
return shouldClearHotmailCurrentSelection(account);
|
||||
}
|
||||
return Boolean(account) && account.used === true;
|
||||
}
|
||||
|
||||
function upsertHotmailAccountListLocally(accounts, nextAccount) {
|
||||
if (typeof upsertHotmailAccountInList === 'function') {
|
||||
return upsertHotmailAccountInList(accounts, nextAccount);
|
||||
}
|
||||
|
||||
const list = Array.isArray(accounts) ? accounts.slice() : [];
|
||||
if (!nextAccount?.id) return list;
|
||||
|
||||
const existingIndex = list.findIndex((account) => account?.id === nextAccount.id);
|
||||
if (existingIndex === -1) {
|
||||
list.push(nextAccount);
|
||||
return list;
|
||||
}
|
||||
|
||||
list[existingIndex] = nextAccount;
|
||||
return list;
|
||||
}
|
||||
|
||||
function refreshHotmailSelectionUI() {
|
||||
renderHotmailAccounts();
|
||||
if (selectMailProvider.value === 'hotmail-api') {
|
||||
const currentAccount = getCurrentHotmailAccount();
|
||||
inputEmail.value = currentAccount?.email || latestState?.email || '';
|
||||
}
|
||||
}
|
||||
|
||||
function applyHotmailAccountMutation(account, options = {}) {
|
||||
if (!account?.id) return;
|
||||
const { preserveCurrentSelection = false } = options;
|
||||
|
||||
const nextState = {
|
||||
hotmailAccounts: upsertHotmailAccountListLocally(getHotmailAccounts(), account),
|
||||
};
|
||||
|
||||
if (!preserveCurrentSelection
|
||||
&& latestState?.currentHotmailAccountId === account.id
|
||||
&& shouldClearCurrentHotmailSelectionLocally(account)) {
|
||||
nextState.currentHotmailAccountId = null;
|
||||
if (selectMailProvider.value === 'hotmail-api') {
|
||||
nextState.email = null;
|
||||
}
|
||||
}
|
||||
|
||||
syncLatestState(nextState);
|
||||
refreshHotmailSelectionUI();
|
||||
}
|
||||
|
||||
function formatDateTime(timestamp) {
|
||||
const value = Number(timestamp);
|
||||
if (!Number.isFinite(value) || value <= 0) {
|
||||
return '未使用';
|
||||
}
|
||||
return new Date(value).toLocaleString('zh-CN', { hour12: false });
|
||||
}
|
||||
|
||||
function getHotmailAvailabilityLabel(account) {
|
||||
if (account.used) return '已用';
|
||||
return '可分配';
|
||||
}
|
||||
|
||||
function getHotmailStatusLabel(account) {
|
||||
if (account.used) return '已用';
|
||||
|
||||
switch (account.status) {
|
||||
case 'authorized':
|
||||
return '可用';
|
||||
case 'error':
|
||||
return '异常';
|
||||
default:
|
||||
return '待校验';
|
||||
}
|
||||
}
|
||||
|
||||
function getHotmailStatusClass(account) {
|
||||
if (account.used) return 'status-used';
|
||||
return `status-${account.status || 'pending'}`;
|
||||
}
|
||||
|
||||
function clearHotmailForm() {
|
||||
inputHotmailEmail.value = '';
|
||||
inputHotmailClientId.value = '';
|
||||
inputHotmailPassword.value = '';
|
||||
inputHotmailRefreshToken.value = '';
|
||||
}
|
||||
|
||||
function renderHotmailAccounts() {
|
||||
if (!hotmailAccountsList) return;
|
||||
const accounts = getHotmailAccounts();
|
||||
const currentId = latestState?.currentHotmailAccountId || '';
|
||||
|
||||
if (!accounts.length) {
|
||||
hotmailAccountsList.innerHTML = '<div class="hotmail-empty">还没有 Hotmail 账号,先添加一条再校验。</div>';
|
||||
updateHotmailListViewport();
|
||||
return;
|
||||
}
|
||||
|
||||
hotmailAccountsList.innerHTML = accounts.map((account) => `
|
||||
<div class="hotmail-account-item${account.id === currentId ? ' is-current' : ''}">
|
||||
<div class="hotmail-account-top">
|
||||
<div class="hotmail-account-title-row">
|
||||
<div class="hotmail-account-email">${escapeHtml(account.email || '(未命名账号)')}</div>
|
||||
<button
|
||||
class="hotmail-copy-btn"
|
||||
type="button"
|
||||
data-account-action="copy-email"
|
||||
data-account-id="${escapeHtml(account.id)}"
|
||||
title="复制邮箱"
|
||||
aria-label="复制邮箱 ${escapeHtml(account.email || '')}"
|
||||
>${COPY_ICON}</button>
|
||||
</div>
|
||||
<span class="hotmail-status-chip ${escapeHtml(getHotmailStatusClass(account))}">${escapeHtml(getHotmailStatusLabel(account))}</span>
|
||||
</div>
|
||||
<div class="hotmail-account-meta">
|
||||
<span>客户端 ID:${escapeHtml(account.clientId ? `${account.clientId.slice(0, 10)}...` : '未填写')}</span>
|
||||
<span>刷新令牌:${account.refreshToken ? '已保存' : '未保存'}</span>
|
||||
<span>分配状态: ${escapeHtml(getHotmailAvailabilityLabel(account))}</span>
|
||||
<span>上次校验: ${escapeHtml(formatDateTime(account.lastAuthAt))}</span>
|
||||
<span>上次使用: ${escapeHtml(formatDateTime(account.lastUsedAt))}</span>
|
||||
</div>
|
||||
${account.lastError ? `<div class="hotmail-account-error">${escapeHtml(account.lastError)}</div>` : ''}
|
||||
<div class="hotmail-account-actions">
|
||||
<button class="btn btn-outline btn-sm" type="button" data-account-action="select" data-account-id="${escapeHtml(account.id)}">使用此账号</button>
|
||||
<button class="btn btn-outline btn-sm" type="button" data-account-action="toggle-used" data-account-id="${escapeHtml(account.id)}">${account.used ? '标记未用' : '标记已用'}</button>
|
||||
<button class="btn btn-primary btn-sm" type="button" data-account-action="verify" data-account-id="${escapeHtml(account.id)}">校验</button>
|
||||
<button class="btn btn-outline btn-sm" type="button" data-account-action="test" data-account-id="${escapeHtml(account.id)}">复制最新验证码</button>
|
||||
<button class="btn btn-ghost btn-sm" type="button" data-account-action="delete" data-account-id="${escapeHtml(account.id)}">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
updateHotmailListViewport();
|
||||
}
|
||||
|
||||
function updateMailProviderUI() {
|
||||
const useInbucket = selectMailProvider.value === 'inbucket';
|
||||
const useHotmail = selectMailProvider.value === 'hotmail-api';
|
||||
rowInbucketHost.style.display = useInbucket ? '' : 'none';
|
||||
rowInbucketMailbox.style.display = useInbucket ? '' : 'none';
|
||||
const useCloudflare = selectEmailGenerator.value === 'cloudflare';
|
||||
rowCfDomain.style.display = useCloudflare ? '' : 'none';
|
||||
rowCfDomain.style.display = !useHotmail && useCloudflare ? '' : 'none';
|
||||
const { domains } = getCloudflareDomainsFromState();
|
||||
if (useCloudflare) {
|
||||
setCloudflareDomainEditMode(cloudflareDomainEditMode || domains.length === 0, { clearInput: false });
|
||||
@@ -720,11 +959,27 @@ function updateMailProviderUI() {
|
||||
setCloudflareDomainEditMode(false, { clearInput: false });
|
||||
}
|
||||
|
||||
if (hotmailSection) {
|
||||
hotmailSection.style.display = useHotmail ? '' : 'none';
|
||||
}
|
||||
selectEmailGenerator.disabled = useHotmail;
|
||||
btnFetchEmail.hidden = useHotmail;
|
||||
inputEmail.readOnly = useHotmail;
|
||||
const uiCopy = getEmailGeneratorUiCopy();
|
||||
inputEmail.placeholder = uiCopy.placeholder;
|
||||
inputEmail.placeholder = useHotmail ? '由 Hotmail 账号池自动分配' : uiCopy.placeholder;
|
||||
if (!btnFetchEmail.disabled) {
|
||||
btnFetchEmail.textContent = uiCopy.buttonLabel;
|
||||
}
|
||||
if (autoHintText) {
|
||||
autoHintText.textContent = useHotmail
|
||||
? '请先校验并选择一个 Hotmail 账号'
|
||||
: '先自动获取邮箱,或手动粘贴邮箱后再继续';
|
||||
}
|
||||
if (useHotmail) {
|
||||
const currentAccount = getCurrentHotmailAccount();
|
||||
inputEmail.value = currentAccount?.email || latestState?.email || '';
|
||||
}
|
||||
renderHotmailAccounts();
|
||||
}
|
||||
|
||||
async function saveCloudflareDomainSettings(domains, activeDomain, options = {}) {
|
||||
@@ -981,6 +1236,70 @@ function syncToggleButtonLabel(button, input, labels) {
|
||||
button.title = isHidden ? labels.show : labels.hide;
|
||||
}
|
||||
|
||||
async function copyTextToClipboard(text) {
|
||||
const value = String(text || '').trim();
|
||||
if (!value) {
|
||||
throw new Error('没有可复制的内容。');
|
||||
}
|
||||
if (!navigator.clipboard?.writeText) {
|
||||
throw new Error('当前环境不支持剪贴板复制。');
|
||||
}
|
||||
await navigator.clipboard.writeText(value);
|
||||
}
|
||||
|
||||
async function deleteHotmailAccountsByMode(mode) {
|
||||
const isUsedMode = mode === 'used';
|
||||
const targetAccounts = getHotmailAccountsByUsage(isUsedMode ? 'used' : 'all');
|
||||
if (!targetAccounts.length) {
|
||||
showToast(isUsedMode ? '没有已用账号可清空。' : '没有可删除的 Hotmail 账号。', 'warn');
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmed = await openConfirmModal({
|
||||
title: isUsedMode ? '清空已用账号' : '全部删除账号',
|
||||
message: isUsedMode
|
||||
? `确认删除当前 ${targetAccounts.length} 个已用 Hotmail 账号吗?`
|
||||
: `确认删除全部 ${targetAccounts.length} 个 Hotmail 账号吗?`,
|
||||
confirmLabel: isUsedMode ? '确认清空已用' : '确认全部删除',
|
||||
confirmVariant: isUsedMode ? 'btn-outline' : 'btn-danger',
|
||||
});
|
||||
if (!confirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'DELETE_HOTMAIL_ACCOUNTS',
|
||||
source: 'sidepanel',
|
||||
payload: { mode: isUsedMode ? 'used' : 'all' },
|
||||
});
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
||||
const targetIds = new Set(targetAccounts.map((account) => account.id));
|
||||
const nextAccounts = isUsedMode
|
||||
? getHotmailAccounts().filter((account) => !targetIds.has(account.id))
|
||||
: [];
|
||||
const nextState = { hotmailAccounts: nextAccounts };
|
||||
if (latestState?.currentHotmailAccountId && targetIds.has(latestState.currentHotmailAccountId)) {
|
||||
nextState.currentHotmailAccountId = null;
|
||||
if (selectMailProvider.value === 'hotmail-api') {
|
||||
nextState.email = null;
|
||||
}
|
||||
}
|
||||
syncLatestState(nextState);
|
||||
refreshHotmailSelectionUI();
|
||||
|
||||
showToast(
|
||||
isUsedMode
|
||||
? `已清空 ${response.deletedCount || 0} 个已用 Hotmail 账号`
|
||||
: `已删除全部 ${response.deletedCount || 0} 个 Hotmail 账号`,
|
||||
'success',
|
||||
2200
|
||||
);
|
||||
}
|
||||
|
||||
function syncPasswordToggleLabel() {
|
||||
syncToggleButtonLabel(btnTogglePassword, inputPassword, {
|
||||
show: '显示密码',
|
||||
@@ -1060,17 +1379,25 @@ document.querySelectorAll('.step-btn').forEach(btn => {
|
||||
syncLatestState({ customPassword: inputPassword.value });
|
||||
}
|
||||
let email = inputEmail.value.trim();
|
||||
if (!email) {
|
||||
try {
|
||||
email = await fetchGeneratedEmail({ showFailureToast: false });
|
||||
} catch (err) {
|
||||
showToast(`自动获取失败:${err.message},请手动粘贴邮箱后重试。`, 'warn');
|
||||
return;
|
||||
if (selectMailProvider.value === 'hotmail-api') {
|
||||
const response = await chrome.runtime.sendMessage({ type: 'EXECUTE_STEP', source: 'sidepanel', payload: { step } });
|
||||
if (response?.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
} else {
|
||||
let email = inputEmail.value.trim();
|
||||
if (!email) {
|
||||
try {
|
||||
email = await fetchGeneratedEmail({ showFailureToast: false });
|
||||
} catch (err) {
|
||||
showToast(`自动获取失败:${err.message},请手动粘贴邮箱后重试。`, 'warn');
|
||||
return;
|
||||
}
|
||||
}
|
||||
const response = await chrome.runtime.sendMessage({ type: 'EXECUTE_STEP', source: 'sidepanel', payload: { step, email } });
|
||||
if (response?.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
}
|
||||
const response = await chrome.runtime.sendMessage({ type: 'EXECUTE_STEP', source: 'sidepanel', payload: { step, email } });
|
||||
if (response?.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
} else {
|
||||
const response = await chrome.runtime.sendMessage({ type: 'EXECUTE_STEP', source: 'sidepanel', payload: { step } });
|
||||
@@ -1085,9 +1412,234 @@ document.querySelectorAll('.step-btn').forEach(btn => {
|
||||
});
|
||||
|
||||
btnFetchEmail.addEventListener('click', async () => {
|
||||
if (selectMailProvider.value === 'hotmail-api') {
|
||||
return;
|
||||
}
|
||||
await fetchGeneratedEmail().catch(() => { });
|
||||
});
|
||||
|
||||
btnToggleHotmailList?.addEventListener('click', () => {
|
||||
setHotmailListExpanded(!hotmailListExpanded);
|
||||
});
|
||||
|
||||
btnClearUsedHotmailAccounts?.addEventListener('click', async () => {
|
||||
if (hotmailActionInFlight) return;
|
||||
hotmailActionInFlight = true;
|
||||
btnClearUsedHotmailAccounts.disabled = true;
|
||||
try {
|
||||
await deleteHotmailAccountsByMode('used');
|
||||
} catch (err) {
|
||||
showToast(err.message, 'error');
|
||||
} finally {
|
||||
hotmailActionInFlight = false;
|
||||
updateHotmailListViewport();
|
||||
}
|
||||
});
|
||||
|
||||
btnDeleteAllHotmailAccounts?.addEventListener('click', async () => {
|
||||
if (hotmailActionInFlight) return;
|
||||
hotmailActionInFlight = true;
|
||||
btnDeleteAllHotmailAccounts.disabled = true;
|
||||
try {
|
||||
await deleteHotmailAccountsByMode('all');
|
||||
} catch (err) {
|
||||
showToast(err.message, 'error');
|
||||
} finally {
|
||||
hotmailActionInFlight = false;
|
||||
updateHotmailListViewport();
|
||||
}
|
||||
});
|
||||
|
||||
btnAddHotmailAccount?.addEventListener('click', async () => {
|
||||
if (hotmailActionInFlight) return;
|
||||
|
||||
const email = inputHotmailEmail.value.trim();
|
||||
const clientId = inputHotmailClientId.value.trim();
|
||||
const refreshToken = inputHotmailRefreshToken.value.trim();
|
||||
if (!email) {
|
||||
showToast('请先填写 Hotmail 邮箱。', 'warn');
|
||||
return;
|
||||
}
|
||||
if (!clientId) {
|
||||
showToast('请先填写微软应用客户端 ID。', 'warn');
|
||||
return;
|
||||
}
|
||||
if (!refreshToken) {
|
||||
showToast('请先填写刷新令牌(refresh token)。', 'warn');
|
||||
return;
|
||||
}
|
||||
|
||||
hotmailActionInFlight = true;
|
||||
btnAddHotmailAccount.disabled = true;
|
||||
|
||||
try {
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'UPSERT_HOTMAIL_ACCOUNT',
|
||||
source: 'sidepanel',
|
||||
payload: {
|
||||
email,
|
||||
clientId,
|
||||
password: inputHotmailPassword.value,
|
||||
refreshToken,
|
||||
},
|
||||
});
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
||||
showToast(`已保存 Hotmail 账号 ${email}`, 'success', 1800);
|
||||
clearHotmailForm();
|
||||
} catch (err) {
|
||||
showToast(`保存 Hotmail 账号失败:${err.message}`, 'error');
|
||||
} finally {
|
||||
hotmailActionInFlight = false;
|
||||
btnAddHotmailAccount.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
btnImportHotmailAccounts?.addEventListener('click', async () => {
|
||||
if (hotmailActionInFlight) return;
|
||||
if (typeof parseHotmailImportText !== 'function') {
|
||||
showToast('导入解析器未加载,请刷新扩展后重试。', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const rawText = inputHotmailImport.value.trim();
|
||||
if (!rawText) {
|
||||
showToast('请先粘贴账号导入内容。', 'warn');
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedAccounts = parseHotmailImportText(rawText);
|
||||
if (!parsedAccounts.length) {
|
||||
showToast('没有解析到有效账号,请检查格式是否为 账号----密码----ID----Token。', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
hotmailActionInFlight = true;
|
||||
btnImportHotmailAccounts.disabled = true;
|
||||
|
||||
try {
|
||||
for (const account of parsedAccounts) {
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'UPSERT_HOTMAIL_ACCOUNT',
|
||||
source: 'sidepanel',
|
||||
payload: account,
|
||||
});
|
||||
if (response?.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
}
|
||||
|
||||
inputHotmailImport.value = '';
|
||||
showToast(`已导入 ${parsedAccounts.length} 条 Hotmail 账号`, 'success', 2200);
|
||||
} catch (err) {
|
||||
showToast(`批量导入失败:${err.message}`, 'error');
|
||||
} finally {
|
||||
hotmailActionInFlight = false;
|
||||
btnImportHotmailAccounts.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
hotmailAccountsList?.addEventListener('click', async (event) => {
|
||||
const actionButton = event.target.closest('[data-account-action]');
|
||||
if (!actionButton || hotmailActionInFlight) {
|
||||
return;
|
||||
}
|
||||
|
||||
const accountId = actionButton.dataset.accountId;
|
||||
const action = actionButton.dataset.accountAction;
|
||||
if (!accountId || !action) {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetAccount = getHotmailAccounts().find((account) => account.id === accountId) || null;
|
||||
|
||||
hotmailActionInFlight = true;
|
||||
actionButton.disabled = true;
|
||||
|
||||
try {
|
||||
if (action === 'copy-email') {
|
||||
if (!targetAccount?.email) throw new Error('未找到可复制的邮箱地址。');
|
||||
await copyTextToClipboard(targetAccount.email);
|
||||
showToast(`已复制 ${targetAccount.email}`, 'success', 1800);
|
||||
} else if (action === 'select') {
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'SELECT_HOTMAIL_ACCOUNT',
|
||||
source: 'sidepanel',
|
||||
payload: { accountId },
|
||||
});
|
||||
if (response?.error) throw new Error(response.error);
|
||||
syncLatestState({ currentHotmailAccountId: response.account.id });
|
||||
applyHotmailAccountMutation(response.account, { preserveCurrentSelection: true });
|
||||
showToast(`已切换当前 Hotmail 账号为 ${response.account.email}`, 'success', 1800);
|
||||
} else if (action === 'toggle-used') {
|
||||
if (!targetAccount) throw new Error('未找到目标 Hotmail 账号。');
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'PATCH_HOTMAIL_ACCOUNT',
|
||||
source: 'sidepanel',
|
||||
payload: {
|
||||
accountId,
|
||||
updates: { used: !targetAccount.used },
|
||||
},
|
||||
});
|
||||
if (response?.error) throw new Error(response.error);
|
||||
applyHotmailAccountMutation(response.account);
|
||||
showToast(`账号 ${response.account.email} 已${response.account.used ? '标记为已用' : '恢复为未用'}`, 'success', 2200);
|
||||
} else if (action === 'verify') {
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'VERIFY_HOTMAIL_ACCOUNT',
|
||||
source: 'sidepanel',
|
||||
payload: { accountId },
|
||||
});
|
||||
if (response?.error) throw new Error(response.error);
|
||||
applyHotmailAccountMutation(response.account, { preserveCurrentSelection: true });
|
||||
showToast(`账号 ${response.account.email} 校验通过`, 'success', 2200);
|
||||
} else if (action === 'test') {
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'TEST_HOTMAIL_ACCOUNT',
|
||||
source: 'sidepanel',
|
||||
payload: { accountId },
|
||||
});
|
||||
if (response?.error) throw new Error(response.error);
|
||||
applyHotmailAccountMutation(response.account, { preserveCurrentSelection: true });
|
||||
if (response.latestCode) {
|
||||
await copyTextToClipboard(response.latestCode);
|
||||
const mailbox = response.latestMailbox ? `(${response.latestMailbox})` : '';
|
||||
showToast(`已复制最新验证码 ${response.latestCode}${mailbox}`, 'success', 2600);
|
||||
} else if (response.latestSubject) {
|
||||
const mailbox = response.latestMailbox ? `(${response.latestMailbox})` : '';
|
||||
showToast(`最新邮件${mailbox}没有验证码:${response.latestSubject}`, 'warn', 3200);
|
||||
} else {
|
||||
showToast('当前没有可读取的最新邮件。', 'warn', 2600);
|
||||
}
|
||||
} else if (action === 'delete') {
|
||||
const confirmed = await openConfirmModal({
|
||||
title: '删除账号',
|
||||
message: '确认删除这个 Hotmail 账号吗?对应 token 也会一起移除。',
|
||||
confirmLabel: '确认删除',
|
||||
confirmVariant: 'btn-danger',
|
||||
});
|
||||
if (!confirmed) {
|
||||
return;
|
||||
}
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: 'DELETE_HOTMAIL_ACCOUNT',
|
||||
source: 'sidepanel',
|
||||
payload: { accountId },
|
||||
});
|
||||
if (response?.error) throw new Error(response.error);
|
||||
showToast('Hotmail 账号已删除', 'success', 1800);
|
||||
}
|
||||
} catch (err) {
|
||||
showToast(err.message, 'error');
|
||||
} finally {
|
||||
hotmailActionInFlight = false;
|
||||
actionButton.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
btnTogglePassword.addEventListener('click', () => {
|
||||
inputPassword.type = inputPassword.type === 'password' ? 'text' : 'password';
|
||||
syncPasswordToggleLabel();
|
||||
@@ -1208,8 +1760,15 @@ btnReset.addEventListener('click', async () => {
|
||||
}
|
||||
|
||||
await chrome.runtime.sendMessage({ type: 'RESET', source: 'sidepanel' });
|
||||
syncLatestState({ stepStatuses: STEP_DEFAULT_STATUSES });
|
||||
syncAutoRunState({ autoRunning: false, autoRunPhase: 'idle', autoRunCurrentRun: 0, autoRunTotalRuns: 1, autoRunAttemptRun: 0, scheduledAutoRunAt: null });
|
||||
syncLatestState({ stepStatuses: STEP_DEFAULT_STATUSES, currentHotmailAccountId: null, email: null });
|
||||
syncAutoRunState({
|
||||
autoRunning: false,
|
||||
autoRunPhase: 'idle',
|
||||
autoRunCurrentRun: 0,
|
||||
autoRunTotalRuns: 1,
|
||||
autoRunAttemptRun: 0,
|
||||
scheduledAutoRunAt: null,
|
||||
});
|
||||
displayOauthUrl.textContent = '等待中...';
|
||||
displayOauthUrl.classList.remove('has-value');
|
||||
displayLocalhostUrl.textContent = '等待中...';
|
||||
@@ -1226,6 +1785,7 @@ btnReset.addEventListener('click', async () => {
|
||||
updateStopButtonState(false);
|
||||
updateButtonStates();
|
||||
updateProgressCounter();
|
||||
renderHotmailAccounts();
|
||||
});
|
||||
|
||||
// Clear log
|
||||
@@ -1235,6 +1795,9 @@ btnClearLog.addEventListener('click', () => {
|
||||
|
||||
// Save settings on change
|
||||
inputEmail.addEventListener('change', async () => {
|
||||
if (selectMailProvider.value === 'hotmail-api') {
|
||||
return;
|
||||
}
|
||||
const email = inputEmail.value.trim();
|
||||
if (email) {
|
||||
await chrome.runtime.sendMessage({ type: 'SAVE_EMAIL', source: 'sidepanel', payload: { email } });
|
||||
@@ -1411,24 +1974,32 @@ chrome.runtime.onMessage.addListener((message) => {
|
||||
applyAutoRunStatus(currentAutoRun);
|
||||
updateProgressCounter();
|
||||
updateButtonStates();
|
||||
renderHotmailAccounts();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'DATA_UPDATED': {
|
||||
syncLatestState(message.payload);
|
||||
if (message.payload.email) {
|
||||
inputEmail.value = message.payload.email;
|
||||
if (message.payload.email !== undefined) {
|
||||
inputEmail.value = message.payload.email || '';
|
||||
}
|
||||
if (message.payload.password !== undefined) {
|
||||
inputPassword.value = message.payload.password || '';
|
||||
}
|
||||
if (message.payload.oauthUrl) {
|
||||
displayOauthUrl.textContent = message.payload.oauthUrl;
|
||||
displayOauthUrl.classList.add('has-value');
|
||||
if (message.payload.oauthUrl !== undefined) {
|
||||
displayOauthUrl.textContent = message.payload.oauthUrl || '等待中...';
|
||||
displayOauthUrl.classList.toggle('has-value', Boolean(message.payload.oauthUrl));
|
||||
}
|
||||
if (message.payload.localhostUrl) {
|
||||
displayLocalhostUrl.textContent = message.payload.localhostUrl;
|
||||
displayLocalhostUrl.classList.add('has-value');
|
||||
if (message.payload.localhostUrl !== undefined) {
|
||||
displayLocalhostUrl.textContent = message.payload.localhostUrl || '等待中...';
|
||||
displayLocalhostUrl.classList.toggle('has-value', Boolean(message.payload.localhostUrl));
|
||||
}
|
||||
if (message.payload.currentHotmailAccountId !== undefined || message.payload.hotmailAccounts !== undefined) {
|
||||
renderHotmailAccounts();
|
||||
if (selectMailProvider.value === 'hotmail-api') {
|
||||
const currentAccount = getCurrentHotmailAccount();
|
||||
inputEmail.value = currentAccount?.email || latestState?.email || '';
|
||||
}
|
||||
}
|
||||
if (message.payload.autoRunDelayEnabled !== undefined) {
|
||||
inputAutoDelayEnabled.checked = Boolean(message.payload.autoRunDelayEnabled);
|
||||
@@ -1488,6 +2059,7 @@ btnTheme.addEventListener('click', () => {
|
||||
|
||||
initializeManualStepActions();
|
||||
initTheme();
|
||||
initHotmailListExpandedState();
|
||||
updateSaveButtonState();
|
||||
restoreState().then(() => {
|
||||
syncPasswordToggleLabel();
|
||||
|
||||
Reference in New Issue
Block a user