fix(sidepanel): restore plus settings before auto run
This commit is contained in:
@@ -284,11 +284,16 @@
|
|||||||
}
|
}
|
||||||
if (generator === 'icloud') {
|
if (generator === 'icloud') {
|
||||||
const stateFetchMode = String(mergedState.icloudFetchMode || '').trim().toLowerCase();
|
const stateFetchMode = String(mergedState.icloudFetchMode || '').trim().toLowerCase();
|
||||||
return fetchIcloudHideMyEmail({
|
const icloudOptions = {
|
||||||
generateNew: Boolean(options.generateNew) || stateFetchMode === 'always_new',
|
generateNew: Boolean(options.generateNew) || stateFetchMode === 'always_new',
|
||||||
hostPreference: mergedState.icloudHostPreference,
|
};
|
||||||
preferredHost: mergedState.preferredIcloudHost,
|
if (mergedState.icloudHostPreference !== undefined) {
|
||||||
});
|
icloudOptions.hostPreference = mergedState.icloudHostPreference;
|
||||||
|
}
|
||||||
|
if (mergedState.preferredIcloudHost !== undefined) {
|
||||||
|
icloudOptions.preferredHost = mergedState.preferredIcloudHost;
|
||||||
|
}
|
||||||
|
return fetchIcloudHideMyEmail(icloudOptions);
|
||||||
}
|
}
|
||||||
if (generator === 'cloudflare') {
|
if (generator === 'cloudflare') {
|
||||||
return fetchCloudflareEmail(mergedState, options);
|
return fetchCloudflareEmail(mergedState, options);
|
||||||
|
|||||||
@@ -70,4 +70,3 @@
|
|||||||
- 用户手动停止会中断当前计划;恢复时是否回到步骤 7,取决于当前页面状态与回调是否过期:
|
- 用户手动停止会中断当前计划;恢复时是否回到步骤 7,取决于当前页面状态与回调是否过期:
|
||||||
- 回调未过期且仍在可恢复链路:优先当前链路继续;
|
- 回调未过期且仍在可恢复链路:优先当前链路继续;
|
||||||
- 回调已过期或链路断裂:回步骤 7 重拉授权。
|
- 回调已过期或链路断裂:回步骤 7 重拉授权。
|
||||||
|
|
||||||
|
|||||||
+208
-18
@@ -162,6 +162,7 @@ const inputCodex2ApiAdminKey = document.getElementById('input-codex2api-admin-ke
|
|||||||
const rowCustomPassword = document.getElementById('row-custom-password');
|
const rowCustomPassword = document.getElementById('row-custom-password');
|
||||||
const rowPlusMode = document.getElementById('row-plus-mode');
|
const rowPlusMode = document.getElementById('row-plus-mode');
|
||||||
const inputPlusModeEnabled = document.getElementById('input-plus-mode-enabled');
|
const inputPlusModeEnabled = document.getElementById('input-plus-mode-enabled');
|
||||||
|
const selectPlusPaymentMethod = document.getElementById('select-plus-payment-method');
|
||||||
const rowPayPalAccount = document.getElementById('row-paypal-account');
|
const rowPayPalAccount = document.getElementById('row-paypal-account');
|
||||||
const selectPayPalAccount = document.getElementById('select-paypal-account');
|
const selectPayPalAccount = document.getElementById('select-paypal-account');
|
||||||
const btnAddPayPalAccount = document.getElementById('btn-add-paypal-account');
|
const btnAddPayPalAccount = document.getElementById('btn-add-paypal-account');
|
||||||
@@ -291,6 +292,7 @@ const inputAutoSkipFailuresThreadIntervalMinutes = document.getElementById('inpu
|
|||||||
const inputAutoDelayEnabled = document.getElementById('input-auto-delay-enabled');
|
const inputAutoDelayEnabled = document.getElementById('input-auto-delay-enabled');
|
||||||
const inputAutoDelayMinutes = document.getElementById('input-auto-delay-minutes');
|
const inputAutoDelayMinutes = document.getElementById('input-auto-delay-minutes');
|
||||||
const inputAutoStepDelaySeconds = document.getElementById('input-auto-step-delay-seconds');
|
const inputAutoStepDelaySeconds = document.getElementById('input-auto-step-delay-seconds');
|
||||||
|
const inputOAuthFlowTimeoutEnabled = document.getElementById('input-oauth-flow-timeout-enabled');
|
||||||
const inputVerificationResendCount = document.getElementById('input-verification-resend-count');
|
const inputVerificationResendCount = document.getElementById('input-verification-resend-count');
|
||||||
const rowPhoneVerificationEnabled = document.getElementById('row-phone-verification-enabled');
|
const rowPhoneVerificationEnabled = document.getElementById('row-phone-verification-enabled');
|
||||||
const btnTogglePhoneVerificationSection = document.getElementById('btn-toggle-phone-verification-section');
|
const btnTogglePhoneVerificationSection = document.getElementById('btn-toggle-phone-verification-section');
|
||||||
@@ -402,6 +404,7 @@ const btnAutoStartContinue = document.getElementById('btn-auto-start-continue');
|
|||||||
const autoHintText = document.querySelector('.auto-hint');
|
const autoHintText = document.querySelector('.auto-hint');
|
||||||
const stepsList = document.querySelector('.steps-list');
|
const stepsList = document.querySelector('.steps-list');
|
||||||
let currentPlusModeEnabled = false;
|
let currentPlusModeEnabled = false;
|
||||||
|
let currentPlusPaymentMethod = 'paypal';
|
||||||
let heroSmsCountrySelectionOrder = [];
|
let heroSmsCountrySelectionOrder = [];
|
||||||
let phoneSmsProviderOrderSelection = [];
|
let phoneSmsProviderOrderSelection = [];
|
||||||
let heroSmsCountryMenuSearchKeyword = '';
|
let heroSmsCountryMenuSearchKeyword = '';
|
||||||
@@ -417,7 +420,7 @@ const fiveSimCountrySearchTextByCode = new Map();
|
|||||||
let nexSmsCountrySelectionOrder = [];
|
let nexSmsCountrySelectionOrder = [];
|
||||||
let nexSmsCountryMenuSearchKeyword = '';
|
let nexSmsCountryMenuSearchKeyword = '';
|
||||||
const nexSmsCountrySearchTextById = new Map();
|
const nexSmsCountrySearchTextById = new Map();
|
||||||
let stepDefinitions = getStepDefinitionsForMode(false);
|
let stepDefinitions = getStepDefinitionsForMode(false, currentPlusPaymentMethod);
|
||||||
let STEP_IDS = stepDefinitions.map((step) => Number(step.id)).filter(Number.isFinite);
|
let STEP_IDS = stepDefinitions.map((step) => Number(step.id)).filter(Number.isFinite);
|
||||||
let STEP_DEFAULT_STATUSES = Object.fromEntries(STEP_IDS.map((stepId) => [stepId, 'pending']));
|
let STEP_DEFAULT_STATUSES = Object.fromEntries(STEP_IDS.map((stepId) => [stepId, 'pending']));
|
||||||
let SKIPPABLE_STEPS = new Set(STEP_IDS);
|
let SKIPPABLE_STEPS = new Set(STEP_IDS);
|
||||||
@@ -538,8 +541,22 @@ const AUTO_RUN_PLUS_RISK_PROMPT_DISMISSED_STORAGE_KEY = 'multipage-auto-run-plus
|
|||||||
const PLUS_CONTRIBUTION_PROMPT_LEDGER_STORAGE_KEY = 'multipage-plus-contribution-prompt-ledger';
|
const PLUS_CONTRIBUTION_PROMPT_LEDGER_STORAGE_KEY = 'multipage-plus-contribution-prompt-ledger';
|
||||||
const PHONE_VERIFICATION_SECTION_EXPANDED_STORAGE_KEY = 'multipage-phone-verification-section-expanded';
|
const PHONE_VERIFICATION_SECTION_EXPANDED_STORAGE_KEY = 'multipage-phone-verification-section-expanded';
|
||||||
|
|
||||||
function getStepDefinitionsForMode(plusModeEnabled = false) {
|
function normalizePlusPaymentMethod(value = '') {
|
||||||
return (window.MultiPageStepDefinitions?.getSteps?.({ plusModeEnabled }) || [])
|
return String(value || '').trim().toLowerCase() === 'gopay' ? 'gopay' : 'paypal';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedPlusPaymentMethod() {
|
||||||
|
if (typeof selectPlusPaymentMethod !== 'undefined' && selectPlusPaymentMethod) {
|
||||||
|
return normalizePlusPaymentMethod(selectPlusPaymentMethod.value);
|
||||||
|
}
|
||||||
|
return normalizePlusPaymentMethod(latestState?.plusPaymentMethod || currentPlusPaymentMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethod = 'paypal') {
|
||||||
|
return (window.MultiPageStepDefinitions?.getSteps?.({
|
||||||
|
plusModeEnabled,
|
||||||
|
plusPaymentMethod: normalizePlusPaymentMethod(plusPaymentMethod),
|
||||||
|
}) || [])
|
||||||
.sort((left, right) => {
|
.sort((left, right) => {
|
||||||
const leftOrder = Number.isFinite(left.order) ? left.order : left.id;
|
const leftOrder = Number.isFinite(left.order) ? left.order : left.id;
|
||||||
const rightOrder = Number.isFinite(right.order) ? right.order : right.id;
|
const rightOrder = Number.isFinite(right.order) ? right.order : right.id;
|
||||||
@@ -548,9 +565,10 @@ function getStepDefinitionsForMode(plusModeEnabled = false) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function rebuildStepDefinitionState(plusModeEnabled = false) {
|
function rebuildStepDefinitionState(plusModeEnabled = false, plusPaymentMethod = 'paypal') {
|
||||||
currentPlusModeEnabled = Boolean(plusModeEnabled);
|
currentPlusModeEnabled = Boolean(plusModeEnabled);
|
||||||
stepDefinitions = getStepDefinitionsForMode(currentPlusModeEnabled);
|
currentPlusPaymentMethod = normalizePlusPaymentMethod(plusPaymentMethod);
|
||||||
|
stepDefinitions = getStepDefinitionsForMode(currentPlusModeEnabled, currentPlusPaymentMethod);
|
||||||
STEP_IDS = stepDefinitions.map((step) => Number(step.id)).filter(Number.isFinite);
|
STEP_IDS = stepDefinitions.map((step) => Number(step.id)).filter(Number.isFinite);
|
||||||
STEP_DEFAULT_STATUSES = Object.fromEntries(STEP_IDS.map((stepId) => [stepId, 'pending']));
|
STEP_DEFAULT_STATUSES = Object.fromEntries(STEP_IDS.map((stepId) => [stepId, 'pending']));
|
||||||
SKIPPABLE_STEPS = new Set(STEP_IDS);
|
SKIPPABLE_STEPS = new Set(STEP_IDS);
|
||||||
@@ -843,6 +861,8 @@ let cloudflareTempEmailDomainEditMode = false;
|
|||||||
let modalChoiceResolver = null;
|
let modalChoiceResolver = null;
|
||||||
let currentModalActions = [];
|
let currentModalActions = [];
|
||||||
let modalResultBuilder = null;
|
let modalResultBuilder = null;
|
||||||
|
let activePlusManualConfirmationRequestId = '';
|
||||||
|
let plusManualConfirmationDialogInFlight = false;
|
||||||
let scheduledCountdownTimer = null;
|
let scheduledCountdownTimer = null;
|
||||||
let configMenuOpen = false;
|
let configMenuOpen = false;
|
||||||
let configActionInFlight = false;
|
let configActionInFlight = false;
|
||||||
@@ -1279,6 +1299,95 @@ async function openConfirmModalWithOption({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function openPlusManualConfirmationDialog(options = {}) {
|
||||||
|
const method = String(options.method || '').trim().toLowerCase();
|
||||||
|
const title = String(options.title || '').trim() || (method === 'gopay' ? 'GoPay 订阅确认' : '手动确认');
|
||||||
|
const message = String(options.message || '').trim()
|
||||||
|
|| (method === 'gopay'
|
||||||
|
? '请在当前订阅页中手动完成 GoPay 订阅,完成后点击“我已完成订阅”继续。'
|
||||||
|
: '请先在页面中完成当前手动操作,完成后点击确认继续。');
|
||||||
|
return openActionModal({
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
actions: [
|
||||||
|
{ id: 'cancel', label: '取消等待', variant: 'btn-ghost' },
|
||||||
|
{ id: 'confirm', label: '我已完成订阅', variant: 'btn-primary' },
|
||||||
|
],
|
||||||
|
alert: method === 'gopay'
|
||||||
|
? { text: '确认后流程会直接继续到 Plus 模式第 10 步 OAuth 登录。', tone: 'info' }
|
||||||
|
: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncPlusManualConfirmationDialog() {
|
||||||
|
const requestId = String(latestState?.plusManualConfirmationRequestId || '').trim();
|
||||||
|
const pending = Boolean(latestState?.plusManualConfirmationPending);
|
||||||
|
if (!pending || !requestId || plusManualConfirmationDialogInFlight || activePlusManualConfirmationRequestId === requestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const step = Number(latestState?.plusManualConfirmationStep) || 0;
|
||||||
|
const method = String(latestState?.plusManualConfirmationMethod || '').trim().toLowerCase();
|
||||||
|
const title = latestState?.plusManualConfirmationTitle;
|
||||||
|
const message = latestState?.plusManualConfirmationMessage;
|
||||||
|
activePlusManualConfirmationRequestId = requestId;
|
||||||
|
plusManualConfirmationDialogInFlight = true;
|
||||||
|
let shouldReopenDialog = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const choice = await openPlusManualConfirmationDialog({
|
||||||
|
method,
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
const currentRequestId = String(latestState?.plusManualConfirmationRequestId || '').trim();
|
||||||
|
const stillPending = Boolean(latestState?.plusManualConfirmationPending);
|
||||||
|
if (!stillPending || currentRequestId !== requestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (choice == null) {
|
||||||
|
shouldReopenDialog = true;
|
||||||
|
showToast('当前订阅确认仍在等待中,将重新弹出确认窗口。', 'info', 1800);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmed = choice === 'confirm';
|
||||||
|
const response = await chrome.runtime.sendMessage({
|
||||||
|
type: 'RESOLVE_PLUS_MANUAL_CONFIRMATION',
|
||||||
|
source: 'sidepanel',
|
||||||
|
payload: {
|
||||||
|
step,
|
||||||
|
requestId,
|
||||||
|
confirmed,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (response?.error) {
|
||||||
|
throw new Error(response.error);
|
||||||
|
}
|
||||||
|
if (confirmed) {
|
||||||
|
showToast(method === 'gopay' ? 'GoPay 订阅已确认,正在继续 OAuth 登录...' : '已确认,流程继续执行中...', 'info', 2200);
|
||||||
|
} else {
|
||||||
|
showToast(method === 'gopay' ? '已取消 GoPay 订阅等待。' : '已取消当前手动确认。', 'warn', 2200);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showToast(error?.message || String(error || '未知错误'), 'error');
|
||||||
|
} finally {
|
||||||
|
if (activePlusManualConfirmationRequestId === requestId) {
|
||||||
|
activePlusManualConfirmationRequestId = '';
|
||||||
|
}
|
||||||
|
plusManualConfirmationDialogInFlight = false;
|
||||||
|
if (
|
||||||
|
shouldReopenDialog
|
||||||
|
&& latestState?.plusManualConfirmationPending
|
||||||
|
&& String(latestState?.plusManualConfirmationRequestId || '').trim() === requestId
|
||||||
|
) {
|
||||||
|
setTimeout(() => {
|
||||||
|
void syncPlusManualConfirmationDialog();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isPromptDismissed(storageKey) {
|
function isPromptDismissed(storageKey) {
|
||||||
return localStorage.getItem(storageKey) === '1';
|
return localStorage.getItem(storageKey) === '1';
|
||||||
}
|
}
|
||||||
@@ -2707,6 +2816,13 @@ function collectSettingsPayload() {
|
|||||||
const currentPayPalAccount = typeof getCurrentPayPalAccount === 'function'
|
const currentPayPalAccount = typeof getCurrentPayPalAccount === 'function'
|
||||||
? getCurrentPayPalAccount(latestState)
|
? getCurrentPayPalAccount(latestState)
|
||||||
: payPalAccounts.find((account) => account?.id === String(latestState?.currentPayPalAccountId || '').trim()) || null;
|
: payPalAccounts.find((account) => account?.id === String(latestState?.currentPayPalAccountId || '').trim()) || null;
|
||||||
|
const plusPaymentMethod = typeof getSelectedPlusPaymentMethod === 'function'
|
||||||
|
? getSelectedPlusPaymentMethod()
|
||||||
|
: (String(
|
||||||
|
(typeof selectPlusPaymentMethod !== 'undefined' && selectPlusPaymentMethod
|
||||||
|
? selectPlusPaymentMethod.value
|
||||||
|
: latestState?.plusPaymentMethod) || ''
|
||||||
|
).trim().toLowerCase() === 'gopay' ? 'gopay' : 'paypal');
|
||||||
return {
|
return {
|
||||||
...(contributionModeEnabled ? {} : {
|
...(contributionModeEnabled ? {} : {
|
||||||
panelMode: selectPanelMode.value,
|
panelMode: selectPanelMode.value,
|
||||||
@@ -2744,6 +2860,7 @@ function collectSettingsPayload() {
|
|||||||
plusModeEnabled: typeof inputPlusModeEnabled !== 'undefined' && inputPlusModeEnabled
|
plusModeEnabled: typeof inputPlusModeEnabled !== 'undefined' && inputPlusModeEnabled
|
||||||
? Boolean(inputPlusModeEnabled.checked)
|
? Boolean(inputPlusModeEnabled.checked)
|
||||||
: Boolean(latestState?.plusModeEnabled),
|
: Boolean(latestState?.plusModeEnabled),
|
||||||
|
plusPaymentMethod,
|
||||||
paypalEmail: String(currentPayPalAccount?.email || latestState?.paypalEmail || '').trim(),
|
paypalEmail: String(currentPayPalAccount?.email || latestState?.paypalEmail || '').trim(),
|
||||||
paypalPassword: String(currentPayPalAccount?.password || latestState?.paypalPassword || ''),
|
paypalPassword: String(currentPayPalAccount?.password || latestState?.paypalPassword || ''),
|
||||||
currentPayPalAccountId: String(latestState?.currentPayPalAccountId || '').trim(),
|
currentPayPalAccountId: String(latestState?.currentPayPalAccountId || '').trim(),
|
||||||
@@ -2797,6 +2914,9 @@ function collectSettingsPayload() {
|
|||||||
autoRunDelayEnabled: inputAutoDelayEnabled.checked,
|
autoRunDelayEnabled: inputAutoDelayEnabled.checked,
|
||||||
autoRunDelayMinutes: normalizeAutoDelayMinutes(inputAutoDelayMinutes.value),
|
autoRunDelayMinutes: normalizeAutoDelayMinutes(inputAutoDelayMinutes.value),
|
||||||
autoStepDelaySeconds: normalizeAutoStepDelaySeconds(inputAutoStepDelaySeconds.value),
|
autoStepDelaySeconds: normalizeAutoStepDelaySeconds(inputAutoStepDelaySeconds.value),
|
||||||
|
oauthFlowTimeoutEnabled: typeof inputOAuthFlowTimeoutEnabled !== 'undefined' && inputOAuthFlowTimeoutEnabled
|
||||||
|
? Boolean(inputOAuthFlowTimeoutEnabled.checked)
|
||||||
|
: true,
|
||||||
phoneVerificationEnabled: Boolean(inputPhoneVerificationEnabled?.checked),
|
phoneVerificationEnabled: Boolean(inputPhoneVerificationEnabled?.checked),
|
||||||
phoneSmsProvider: phoneSmsProviderValue,
|
phoneSmsProvider: phoneSmsProviderValue,
|
||||||
phoneSmsProviderOrder: phoneSmsProviderOrderValue,
|
phoneSmsProviderOrder: phoneSmsProviderOrderValue,
|
||||||
@@ -6361,13 +6481,18 @@ function updatePlusModeUI() {
|
|||||||
const enabled = typeof inputPlusModeEnabled !== 'undefined' && inputPlusModeEnabled
|
const enabled = typeof inputPlusModeEnabled !== 'undefined' && inputPlusModeEnabled
|
||||||
? Boolean(inputPlusModeEnabled.checked)
|
? Boolean(inputPlusModeEnabled.checked)
|
||||||
: false;
|
: false;
|
||||||
|
const paymentMethod = getSelectedPlusPaymentMethod();
|
||||||
|
if (typeof selectPlusPaymentMethod !== 'undefined' && selectPlusPaymentMethod) {
|
||||||
|
selectPlusPaymentMethod.value = paymentMethod;
|
||||||
|
selectPlusPaymentMethod.style.display = enabled ? '' : 'none';
|
||||||
|
}
|
||||||
[
|
[
|
||||||
typeof rowPayPalAccount !== 'undefined' ? rowPayPalAccount : null,
|
typeof rowPayPalAccount !== 'undefined' ? rowPayPalAccount : null,
|
||||||
].forEach((row) => {
|
].forEach((row) => {
|
||||||
if (!row) {
|
if (!row) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
row.style.display = enabled ? '' : 'none';
|
row.style.display = enabled && paymentMethod === 'paypal' ? '' : 'none';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6435,10 +6560,10 @@ function scheduleSettingsAutoSave() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function saveSettings(options = {}) {
|
async function saveSettings(options = {}) {
|
||||||
const { silent = false } = options;
|
const { silent = false, force = false } = options;
|
||||||
clearTimeout(settingsAutoSaveTimer);
|
clearTimeout(settingsAutoSaveTimer);
|
||||||
|
|
||||||
if (!settingsDirty && !settingsSaveInFlight && silent) {
|
if (!force && !settingsDirty && !settingsSaveInFlight && silent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6484,6 +6609,12 @@ async function saveSettings(options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function persistCurrentSettingsForAction() {
|
||||||
|
clearTimeout(settingsAutoSaveTimer);
|
||||||
|
await waitForSettingsSaveIdle();
|
||||||
|
await saveSettings({ silent: true, force: true });
|
||||||
|
}
|
||||||
|
|
||||||
function applyAutoRunStatus(payload = currentAutoRun) {
|
function applyAutoRunStatus(payload = currentAutoRun) {
|
||||||
syncAutoRunState(payload);
|
syncAutoRunState(payload);
|
||||||
const runLabel = getAutoRunLabel(currentAutoRun);
|
const runLabel = getAutoRunLabel(currentAutoRun);
|
||||||
@@ -6494,7 +6625,13 @@ function applyAutoRunStatus(payload = currentAutoRun) {
|
|||||||
|
|
||||||
setSettingsCardLocked(settingsCardLocked);
|
setSettingsCardLocked(settingsCardLocked);
|
||||||
|
|
||||||
inputRunCount.disabled = currentAutoRun.autoRunning || shouldLockRunCountToEmailPool();
|
const lockedRunCount = getLockedRunCountFromEmailPool();
|
||||||
|
const shouldSyncAutoRunTotalRuns = currentAutoRun.autoRunning
|
||||||
|
|| locked
|
||||||
|
|| paused
|
||||||
|
|| scheduled;
|
||||||
|
|
||||||
|
inputRunCount.disabled = currentAutoRun.autoRunning || lockedRunCount > 0;
|
||||||
btnAutoRun.disabled = currentAutoRun.autoRunning;
|
btnAutoRun.disabled = currentAutoRun.autoRunning;
|
||||||
btnFetchEmail.disabled = locked
|
btnFetchEmail.disabled = locked
|
||||||
|| isCustomMailProvider()
|
|| isCustomMailProvider()
|
||||||
@@ -6502,7 +6639,9 @@ function applyAutoRunStatus(payload = currentAutoRun) {
|
|||||||
inputEmail.disabled = locked;
|
inputEmail.disabled = locked;
|
||||||
inputAutoSkipFailures.disabled = scheduled;
|
inputAutoSkipFailures.disabled = scheduled;
|
||||||
|
|
||||||
if (currentAutoRun.totalRuns > 0) {
|
if (lockedRunCount > 0) {
|
||||||
|
inputRunCount.value = String(lockedRunCount);
|
||||||
|
} else if (shouldSyncAutoRunTotalRuns && currentAutoRun.totalRuns > 0) {
|
||||||
inputRunCount.value = String(currentAutoRun.totalRuns);
|
inputRunCount.value = String(currentAutoRun.totalRuns);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6603,14 +6742,17 @@ function renderStepsList() {
|
|||||||
updateButtonStates();
|
updateButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncStepDefinitionsForMode(plusModeEnabled = false, options = {}) {
|
function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethod = 'paypal', options = {}) {
|
||||||
const nextPlusModeEnabled = Boolean(plusModeEnabled);
|
const nextPlusModeEnabled = Boolean(plusModeEnabled);
|
||||||
const shouldRender = Boolean(options.render) || nextPlusModeEnabled !== currentPlusModeEnabled;
|
const nextPlusPaymentMethod = normalizePlusPaymentMethod(plusPaymentMethod);
|
||||||
|
const shouldRender = Boolean(options.render)
|
||||||
|
|| nextPlusModeEnabled !== currentPlusModeEnabled
|
||||||
|
|| nextPlusPaymentMethod !== currentPlusPaymentMethod;
|
||||||
if (!shouldRender) {
|
if (!shouldRender) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildStepDefinitionState(nextPlusModeEnabled);
|
rebuildStepDefinitionState(nextPlusModeEnabled, nextPlusPaymentMethod);
|
||||||
renderStepsList();
|
renderStepsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6620,7 +6762,7 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, options = {}) {
|
|||||||
|
|
||||||
function applySettingsState(state) {
|
function applySettingsState(state) {
|
||||||
if (typeof syncStepDefinitionsForMode === 'function') {
|
if (typeof syncStepDefinitionsForMode === 'function') {
|
||||||
syncStepDefinitionsForMode(Boolean(state?.plusModeEnabled));
|
syncStepDefinitionsForMode(Boolean(state?.plusModeEnabled), state?.plusPaymentMethod);
|
||||||
}
|
}
|
||||||
const fallbackIpProxyService = '711proxy';
|
const fallbackIpProxyService = '711proxy';
|
||||||
const fallbackIpProxyMode = 'account';
|
const fallbackIpProxyMode = 'account';
|
||||||
@@ -6677,6 +6819,9 @@ function applySettingsState(state) {
|
|||||||
if (typeof inputPlusModeEnabled !== 'undefined' && inputPlusModeEnabled) {
|
if (typeof inputPlusModeEnabled !== 'undefined' && inputPlusModeEnabled) {
|
||||||
inputPlusModeEnabled.checked = Boolean(state?.plusModeEnabled);
|
inputPlusModeEnabled.checked = Boolean(state?.plusModeEnabled);
|
||||||
}
|
}
|
||||||
|
if (typeof selectPlusPaymentMethod !== 'undefined' && selectPlusPaymentMethod) {
|
||||||
|
selectPlusPaymentMethod.value = normalizePlusPaymentMethod(state?.plusPaymentMethod);
|
||||||
|
}
|
||||||
inputVpsUrl.value = state?.vpsUrl || '';
|
inputVpsUrl.value = state?.vpsUrl || '';
|
||||||
inputVpsPassword.value = state?.vpsPassword || '';
|
inputVpsPassword.value = state?.vpsPassword || '';
|
||||||
setLocalCpaStep9Mode(state?.localCpaStep9Mode);
|
setLocalCpaStep9Mode(state?.localCpaStep9Mode);
|
||||||
@@ -6853,6 +6998,11 @@ function applySettingsState(state) {
|
|||||||
inputAutoDelayEnabled.checked = Boolean(state?.autoRunDelayEnabled);
|
inputAutoDelayEnabled.checked = Boolean(state?.autoRunDelayEnabled);
|
||||||
inputAutoDelayMinutes.value = String(normalizeAutoDelayMinutes(state?.autoRunDelayMinutes));
|
inputAutoDelayMinutes.value = String(normalizeAutoDelayMinutes(state?.autoRunDelayMinutes));
|
||||||
inputAutoStepDelaySeconds.value = formatAutoStepDelayInputValue(state?.autoStepDelaySeconds);
|
inputAutoStepDelaySeconds.value = formatAutoStepDelayInputValue(state?.autoStepDelaySeconds);
|
||||||
|
if (typeof inputOAuthFlowTimeoutEnabled !== 'undefined' && inputOAuthFlowTimeoutEnabled) {
|
||||||
|
inputOAuthFlowTimeoutEnabled.checked = state?.oauthFlowTimeoutEnabled !== undefined
|
||||||
|
? Boolean(state.oauthFlowTimeoutEnabled)
|
||||||
|
: true;
|
||||||
|
}
|
||||||
if (inputVerificationResendCount) {
|
if (inputVerificationResendCount) {
|
||||||
const restoredVerificationResendCount = state?.verificationResendCount !== undefined
|
const restoredVerificationResendCount = state?.verificationResendCount !== undefined
|
||||||
? state.verificationResendCount
|
? state.verificationResendCount
|
||||||
@@ -6950,7 +7100,12 @@ function applySettingsState(state) {
|
|||||||
if (normalized === 'nexsms') return 'nexsms';
|
if (normalized === 'nexsms') return 'nexsms';
|
||||||
return 'hero-sms';
|
return 'hero-sms';
|
||||||
});
|
});
|
||||||
const providerOrderForRestore = resolveNormalizedProviderOrderForRuntime(state || {});
|
const providerOrderForRestore = typeof resolveNormalizedProviderOrderForRuntime === 'function'
|
||||||
|
? resolveNormalizedProviderOrderForRuntime(state || {})
|
||||||
|
: [normalizeProvider(
|
||||||
|
state?.phoneSmsProvider
|
||||||
|
|| (typeof DEFAULT_PHONE_SMS_PROVIDER !== 'undefined' ? DEFAULT_PHONE_SMS_PROVIDER : 'hero-sms')
|
||||||
|
)];
|
||||||
const activeProvider = providerOrderForRestore[0] || normalizeProvider(
|
const activeProvider = providerOrderForRestore[0] || normalizeProvider(
|
||||||
state?.phoneSmsProvider
|
state?.phoneSmsProvider
|
||||||
|| (typeof DEFAULT_PHONE_SMS_PROVIDER !== 'undefined' ? DEFAULT_PHONE_SMS_PROVIDER : 'hero-sms')
|
|| (typeof DEFAULT_PHONE_SMS_PROVIDER !== 'undefined' ? DEFAULT_PHONE_SMS_PROVIDER : 'hero-sms')
|
||||||
@@ -7028,6 +7183,9 @@ function applySettingsState(state) {
|
|||||||
queueLuckmailPurchaseRefresh();
|
queueLuckmailPurchaseRefresh();
|
||||||
}
|
}
|
||||||
updateButtonStates();
|
updateButtonStates();
|
||||||
|
if (typeof syncPlusManualConfirmationDialog === 'function') {
|
||||||
|
void syncPlusManualConfirmationDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function restoreState() {
|
async function restoreState() {
|
||||||
@@ -9122,6 +9280,7 @@ stepsList?.addEventListener('click', async (event) => {
|
|||||||
if (!(await maybeTakeoverAutoRun(`执行步骤 ${step}`))) {
|
if (!(await maybeTakeoverAutoRun(`执行步骤 ${step}`))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
await persistCurrentSettingsForAction();
|
||||||
if (step === 3) {
|
if (step === 3) {
|
||||||
if (inputPassword.value !== (latestState?.customPassword || '')) {
|
if (inputPassword.value !== (latestState?.customPassword || '')) {
|
||||||
await chrome.runtime.sendMessage({
|
await chrome.runtime.sendMessage({
|
||||||
@@ -9363,8 +9522,8 @@ async function startAutoRunFromCurrentSettings() {
|
|||||||
console.warn('Failed to refresh contribution content hint before auto run:', error);
|
console.warn('Failed to refresh contribution content hint before auto run:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof settingsDirty !== 'undefined' && settingsDirty && typeof saveSettings === 'function') {
|
if (typeof persistCurrentSettingsForAction === 'function') {
|
||||||
await saveSettings({ silent: true });
|
await persistCurrentSettingsForAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
const customEmailPoolEnabled = typeof usesCustomEmailPoolGenerator === 'function'
|
const customEmailPoolEnabled = typeof usesCustomEmailPoolGenerator === 'function'
|
||||||
@@ -9646,7 +9805,15 @@ inputPassword.addEventListener('blur', () => {
|
|||||||
|
|
||||||
inputPlusModeEnabled?.addEventListener('change', () => {
|
inputPlusModeEnabled?.addEventListener('change', () => {
|
||||||
updatePlusModeUI();
|
updatePlusModeUI();
|
||||||
syncStepDefinitionsForMode(Boolean(inputPlusModeEnabled.checked), { render: true });
|
syncStepDefinitionsForMode(Boolean(inputPlusModeEnabled.checked), getSelectedPlusPaymentMethod(), { render: true });
|
||||||
|
markSettingsDirty(true);
|
||||||
|
saveSettings({ silent: true }).catch(() => { });
|
||||||
|
});
|
||||||
|
|
||||||
|
selectPlusPaymentMethod?.addEventListener('change', () => {
|
||||||
|
selectPlusPaymentMethod.value = normalizePlusPaymentMethod(selectPlusPaymentMethod.value);
|
||||||
|
updatePlusModeUI();
|
||||||
|
syncStepDefinitionsForMode(Boolean(inputPlusModeEnabled?.checked), selectPlusPaymentMethod.value, { render: true });
|
||||||
markSettingsDirty(true);
|
markSettingsDirty(true);
|
||||||
saveSettings({ silent: true }).catch(() => { });
|
saveSettings({ silent: true }).catch(() => { });
|
||||||
});
|
});
|
||||||
@@ -10504,6 +10671,11 @@ inputAutoDelayMinutes.addEventListener('blur', () => {
|
|||||||
saveSettings({ silent: true }).catch(() => { });
|
saveSettings({ silent: true }).catch(() => { });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
inputOAuthFlowTimeoutEnabled?.addEventListener('change', () => {
|
||||||
|
markSettingsDirty(true);
|
||||||
|
saveSettings({ silent: true }).catch(() => { });
|
||||||
|
});
|
||||||
|
|
||||||
inputPhoneVerificationEnabled?.addEventListener('change', () => {
|
inputPhoneVerificationEnabled?.addEventListener('change', () => {
|
||||||
if (inputPhoneVerificationEnabled.checked) {
|
if (inputPhoneVerificationEnabled.checked) {
|
||||||
setPhoneVerificationSectionExpanded(true);
|
setPhoneVerificationSectionExpanded(true);
|
||||||
@@ -11224,6 +11396,20 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
|||||||
) {
|
) {
|
||||||
updateMailProviderUI();
|
updateMailProviderUI();
|
||||||
}
|
}
|
||||||
|
if (message.payload.plusModeEnabled !== undefined && inputPlusModeEnabled) {
|
||||||
|
inputPlusModeEnabled.checked = Boolean(message.payload.plusModeEnabled);
|
||||||
|
}
|
||||||
|
if (message.payload.plusPaymentMethod !== undefined && selectPlusPaymentMethod) {
|
||||||
|
selectPlusPaymentMethod.value = normalizePlusPaymentMethod(message.payload.plusPaymentMethod);
|
||||||
|
}
|
||||||
|
if (message.payload.plusModeEnabled !== undefined || message.payload.plusPaymentMethod !== undefined) {
|
||||||
|
syncStepDefinitionsForMode(
|
||||||
|
Boolean(latestState?.plusModeEnabled),
|
||||||
|
latestState?.plusPaymentMethod,
|
||||||
|
{ render: true }
|
||||||
|
);
|
||||||
|
updatePlusModeUI();
|
||||||
|
}
|
||||||
if (message.payload.currentHotmailAccountId !== undefined || message.payload.hotmailAccounts !== undefined) {
|
if (message.payload.currentHotmailAccountId !== undefined || message.payload.hotmailAccounts !== undefined) {
|
||||||
renderHotmailAccounts();
|
renderHotmailAccounts();
|
||||||
if (selectMailProvider.value === 'hotmail-api') {
|
if (selectMailProvider.value === 'hotmail-api') {
|
||||||
@@ -11303,6 +11489,9 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
|||||||
if (message.payload.autoStepDelaySeconds !== undefined) {
|
if (message.payload.autoStepDelaySeconds !== undefined) {
|
||||||
inputAutoStepDelaySeconds.value = formatAutoStepDelayInputValue(message.payload.autoStepDelaySeconds);
|
inputAutoStepDelaySeconds.value = formatAutoStepDelayInputValue(message.payload.autoStepDelaySeconds);
|
||||||
}
|
}
|
||||||
|
if (message.payload.oauthFlowTimeoutEnabled !== undefined && typeof inputOAuthFlowTimeoutEnabled !== 'undefined' && inputOAuthFlowTimeoutEnabled) {
|
||||||
|
inputOAuthFlowTimeoutEnabled.checked = Boolean(message.payload.oauthFlowTimeoutEnabled);
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
message.payload.verificationResendCount !== undefined
|
message.payload.verificationResendCount !== undefined
|
||||||
@@ -11509,6 +11698,7 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
|||||||
}
|
}
|
||||||
updateAccountRunHistorySettingsUI();
|
updateAccountRunHistorySettingsUI();
|
||||||
renderContributionMode();
|
renderContributionMode();
|
||||||
|
void syncPlusManualConfirmationDialog();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
const test = require('node:test');
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
|
||||||
|
const sidepanelSource = fs.readFileSync('sidepanel/sidepanel.js', 'utf8');
|
||||||
|
|
||||||
|
function extractFunction(name) {
|
||||||
|
const asyncStart = sidepanelSource.indexOf(`async function ${name}`);
|
||||||
|
const normalStart = sidepanelSource.indexOf(`function ${name}`);
|
||||||
|
const start = asyncStart !== -1
|
||||||
|
? asyncStart
|
||||||
|
: normalStart;
|
||||||
|
if (start === -1) {
|
||||||
|
throw new Error(`Function ${name} not found`);
|
||||||
|
}
|
||||||
|
const signatureEnd = sidepanelSource.indexOf(')', start);
|
||||||
|
const bodyStart = sidepanelSource.indexOf('{', signatureEnd);
|
||||||
|
let depth = 0;
|
||||||
|
let end = bodyStart;
|
||||||
|
for (; end < sidepanelSource.length; end += 1) {
|
||||||
|
const char = sidepanelSource[end];
|
||||||
|
if (char === '{') {
|
||||||
|
depth += 1;
|
||||||
|
} else if (char === '}') {
|
||||||
|
depth -= 1;
|
||||||
|
if (depth === 0) {
|
||||||
|
end += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sidepanelSource.slice(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
test('sidepanel step definitions keep the selected Plus payment method', () => {
|
||||||
|
const bundle = [
|
||||||
|
extractFunction('normalizePlusPaymentMethod'),
|
||||||
|
extractFunction('getStepDefinitionsForMode'),
|
||||||
|
extractFunction('rebuildStepDefinitionState'),
|
||||||
|
extractFunction('syncStepDefinitionsForMode'),
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const api = new Function(`
|
||||||
|
const calls = [];
|
||||||
|
const window = {
|
||||||
|
MultiPageStepDefinitions: {
|
||||||
|
getSteps(options) {
|
||||||
|
calls.push({ type: 'getSteps', options });
|
||||||
|
return [{ id: options.plusPaymentMethod === 'gopay' ? 7 : 6, order: 1 }];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let currentPlusModeEnabled = false;
|
||||||
|
let currentPlusPaymentMethod = 'paypal';
|
||||||
|
let stepDefinitions = [];
|
||||||
|
let STEP_IDS = [];
|
||||||
|
let STEP_DEFAULT_STATUSES = {};
|
||||||
|
let SKIPPABLE_STEPS = new Set();
|
||||||
|
function renderStepsList() {
|
||||||
|
calls.push({ type: 'render', stepIds: [...STEP_IDS] });
|
||||||
|
}
|
||||||
|
${bundle}
|
||||||
|
return {
|
||||||
|
calls,
|
||||||
|
syncStepDefinitionsForMode,
|
||||||
|
getCurrentPlusPaymentMethod: () => currentPlusPaymentMethod,
|
||||||
|
getStepIds: () => [...STEP_IDS],
|
||||||
|
};
|
||||||
|
`)();
|
||||||
|
|
||||||
|
api.syncStepDefinitionsForMode(true, 'gopay', { render: true });
|
||||||
|
|
||||||
|
assert.equal(api.getCurrentPlusPaymentMethod(), 'gopay');
|
||||||
|
assert.deepEqual(api.getStepIds(), [7]);
|
||||||
|
assert.deepEqual(api.calls[0], {
|
||||||
|
type: 'getSteps',
|
||||||
|
options: { plusModeEnabled: true, plusPaymentMethod: 'gopay' },
|
||||||
|
});
|
||||||
|
assert.deepEqual(api.calls[1], { type: 'render', stepIds: [7] });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sidepanel Plus UI hides PayPal account selector while GoPay is selected', () => {
|
||||||
|
const bundle = [
|
||||||
|
extractFunction('normalizePlusPaymentMethod'),
|
||||||
|
extractFunction('getSelectedPlusPaymentMethod'),
|
||||||
|
extractFunction('updatePlusModeUI'),
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const api = new Function(`
|
||||||
|
let latestState = { plusPaymentMethod: 'gopay' };
|
||||||
|
let currentPlusPaymentMethod = 'paypal';
|
||||||
|
const inputPlusModeEnabled = { checked: true };
|
||||||
|
const selectPlusPaymentMethod = { value: 'gopay', style: { display: 'none' } };
|
||||||
|
const rowPayPalAccount = { style: { display: '' } };
|
||||||
|
${bundle}
|
||||||
|
return { updatePlusModeUI, selectPlusPaymentMethod, rowPayPalAccount };
|
||||||
|
`)();
|
||||||
|
|
||||||
|
api.updatePlusModeUI();
|
||||||
|
|
||||||
|
assert.equal(api.selectPlusPaymentMethod.style.display, '');
|
||||||
|
assert.equal(api.rowPayPalAccount.style.display, 'none');
|
||||||
|
|
||||||
|
api.selectPlusPaymentMethod.value = 'paypal';
|
||||||
|
api.updatePlusModeUI();
|
||||||
|
assert.equal(api.rowPayPalAccount.style.display, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sidepanel resolves pending GoPay manual confirmation from DATA_UPDATED state', async () => {
|
||||||
|
const bundle = [
|
||||||
|
extractFunction('openPlusManualConfirmationDialog'),
|
||||||
|
extractFunction('syncPlusManualConfirmationDialog'),
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const api = new Function(`
|
||||||
|
const events = [];
|
||||||
|
let latestState = {
|
||||||
|
plusManualConfirmationPending: true,
|
||||||
|
plusManualConfirmationRequestId: 'gopay-request-1',
|
||||||
|
plusManualConfirmationStep: 7,
|
||||||
|
plusManualConfirmationMethod: 'gopay',
|
||||||
|
plusManualConfirmationTitle: 'GoPay 订阅确认',
|
||||||
|
plusManualConfirmationMessage: '请确认订阅。',
|
||||||
|
};
|
||||||
|
let activePlusManualConfirmationRequestId = '';
|
||||||
|
let plusManualConfirmationDialogInFlight = false;
|
||||||
|
function openActionModal(options) {
|
||||||
|
events.push({ type: 'modal', options });
|
||||||
|
return Promise.resolve('confirm');
|
||||||
|
}
|
||||||
|
function showToast(message, tone) {
|
||||||
|
events.push({ type: 'toast', message, tone });
|
||||||
|
}
|
||||||
|
const chrome = {
|
||||||
|
runtime: {
|
||||||
|
async sendMessage(message) {
|
||||||
|
events.push({ type: 'send', message });
|
||||||
|
latestState = {
|
||||||
|
...latestState,
|
||||||
|
plusManualConfirmationPending: false,
|
||||||
|
};
|
||||||
|
return { ok: true };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
${bundle}
|
||||||
|
return { events, syncPlusManualConfirmationDialog };
|
||||||
|
`)();
|
||||||
|
|
||||||
|
await api.syncPlusManualConfirmationDialog();
|
||||||
|
|
||||||
|
assert.equal(api.events[0].type, 'modal');
|
||||||
|
assert.equal(api.events[0].options.title, 'GoPay 订阅确认');
|
||||||
|
assert.deepEqual(api.events[1], {
|
||||||
|
type: 'send',
|
||||||
|
message: {
|
||||||
|
type: 'RESOLVE_PLUS_MANUAL_CONFIRMATION',
|
||||||
|
source: 'sidepanel',
|
||||||
|
payload: {
|
||||||
|
step: 7,
|
||||||
|
requestId: 'gopay-request-1',
|
||||||
|
confirmed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
assert.match(api.events[2].message, /GoPay/);
|
||||||
|
assert.equal(api.events[2].tone, 'info');
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user