贡献功能开发
This commit is contained in:
+165
-10
@@ -30,6 +30,14 @@ const updateCardSummary = document.getElementById('update-card-summary');
|
||||
const updateReleaseList = document.getElementById('update-release-list');
|
||||
const btnOpenRelease = document.getElementById('btn-open-release');
|
||||
const settingsCard = document.getElementById('settings-card');
|
||||
const contributionModePanel = document.getElementById('contribution-mode-panel');
|
||||
const contributionModeText = document.getElementById('contribution-mode-text');
|
||||
const contributionOauthStatus = document.getElementById('contribution-oauth-status');
|
||||
const contributionCallbackStatus = document.getElementById('contribution-callback-status');
|
||||
const contributionModeSummary = document.getElementById('contribution-mode-summary');
|
||||
const btnStartContribution = document.getElementById('btn-start-contribution');
|
||||
const btnOpenContributionUpload = document.getElementById('btn-open-contribution-upload');
|
||||
const btnExitContributionMode = document.getElementById('btn-exit-contribution-mode');
|
||||
const displayOauthUrl = document.getElementById('display-oauth-url');
|
||||
const displayLocalhostUrl = document.getElementById('display-localhost-url');
|
||||
const displayStatus = document.getElementById('display-status');
|
||||
@@ -43,6 +51,7 @@ const btnTogglePassword = document.getElementById('btn-toggle-password');
|
||||
const btnSaveSettings = document.getElementById('btn-save-settings');
|
||||
const btnStop = document.getElementById('btn-stop');
|
||||
const btnReset = document.getElementById('btn-reset');
|
||||
const btnContributionMode = document.getElementById('btn-contribution-mode');
|
||||
const stepsProgress = document.getElementById('steps-progress');
|
||||
const btnAutoRun = document.getElementById('btn-auto-run');
|
||||
const btnAutoContinue = document.getElementById('btn-auto-continue');
|
||||
@@ -76,6 +85,7 @@ const rowSub2ApiGroup = document.getElementById('row-sub2api-group');
|
||||
const inputSub2ApiGroup = document.getElementById('input-sub2api-group');
|
||||
const rowSub2ApiDefaultProxy = document.getElementById('row-sub2api-default-proxy');
|
||||
const inputSub2ApiDefaultProxy = document.getElementById('input-sub2api-default-proxy');
|
||||
const rowCustomPassword = document.getElementById('row-custom-password');
|
||||
const selectMailProvider = document.getElementById('select-mail-provider');
|
||||
const btnMailLogin = document.getElementById('btn-mail-login');
|
||||
const rowMail2925Mode = document.getElementById('row-mail-2925-mode');
|
||||
@@ -171,6 +181,7 @@ const inputAutoDelayEnabled = document.getElementById('input-auto-delay-enabled'
|
||||
const inputAutoDelayMinutes = document.getElementById('input-auto-delay-minutes');
|
||||
const inputAutoStepDelaySeconds = document.getElementById('input-auto-step-delay-seconds');
|
||||
const inputVerificationResendCount = document.getElementById('input-verification-resend-count');
|
||||
const rowAccountRunHistoryTextEnabled = document.getElementById('row-account-run-history-text-enabled');
|
||||
const inputAccountRunHistoryTextEnabled = document.getElementById('input-account-run-history-text-enabled');
|
||||
const rowAccountRunHistoryHelperBaseUrl = document.getElementById('row-account-run-history-helper-base-url');
|
||||
const inputAccountRunHistoryHelperBaseUrl = document.getElementById('input-account-run-history-helper-base-url');
|
||||
@@ -771,18 +782,23 @@ async function openAutoRunFallbackRiskConfirmModal(totalRuns, fallbackThreadInte
|
||||
|
||||
function updateConfigMenuControls() {
|
||||
const disabled = configActionInFlight || settingsSaveInFlight;
|
||||
const contributionModeEnabled = Boolean(latestState?.contributionMode);
|
||||
if (contributionModeEnabled && configMenuOpen) {
|
||||
configMenuOpen = false;
|
||||
}
|
||||
const importLocked = disabled
|
||||
|| contributionModeEnabled
|
||||
|| currentAutoRun.autoRunning
|
||||
|| Object.values(getStepStatuses()).some((status) => status === 'running');
|
||||
if (btnConfigMenu) {
|
||||
btnConfigMenu.disabled = disabled;
|
||||
btnConfigMenu.disabled = disabled || contributionModeEnabled;
|
||||
btnConfigMenu.setAttribute('aria-expanded', String(configMenuOpen));
|
||||
}
|
||||
if (configMenu) {
|
||||
configMenu.hidden = !configMenuOpen;
|
||||
configMenu.hidden = contributionModeEnabled || !configMenuOpen;
|
||||
}
|
||||
if (btnExportSettings) {
|
||||
btnExportSettings.disabled = disabled;
|
||||
btnExportSettings.disabled = disabled || contributionModeEnabled;
|
||||
}
|
||||
if (btnImportSettings) {
|
||||
btnImportSettings.disabled = importLocked;
|
||||
@@ -865,6 +881,12 @@ function hasSavedProgress(state = latestState) {
|
||||
return Object.values(statuses).some((status) => status !== 'pending');
|
||||
}
|
||||
|
||||
function isContributionModeSwitchBlocked(state = latestState) {
|
||||
const statuses = getStepStatuses(state);
|
||||
const anyRunning = Object.values(statuses).some((status) => status === 'running');
|
||||
return anyRunning || isAutoRunLockedPhase() || isAutoRunPausedPhase() || isAutoRunScheduledPhase();
|
||||
}
|
||||
|
||||
function shouldOfferAutoModeChoice(state = latestState) {
|
||||
return hasSavedProgress(state) && getFirstUnfinishedStep(state) !== null;
|
||||
}
|
||||
@@ -1300,6 +1322,7 @@ function collectSettingsPayload() {
|
||||
const selectedCloudflareTempEmailDomain = normalizeCloudflareTempEmailDomainValue(
|
||||
!cloudflareTempEmailDomainEditMode ? selectTempEmailDomain.value : tempEmailActiveDomain
|
||||
) || tempEmailActiveDomain;
|
||||
const contributionModeEnabled = Boolean(latestState?.contributionMode);
|
||||
return {
|
||||
panelMode: selectPanelMode.value,
|
||||
vpsUrl: inputVpsUrl.value.trim(),
|
||||
@@ -1310,14 +1333,18 @@ function collectSettingsPayload() {
|
||||
sub2apiPassword: inputSub2ApiPassword.value,
|
||||
sub2apiGroupName: inputSub2ApiGroup.value.trim(),
|
||||
sub2apiDefaultProxyName: inputSub2ApiDefaultProxy.value.trim(),
|
||||
customPassword: inputPassword.value,
|
||||
...(contributionModeEnabled ? {} : {
|
||||
customPassword: inputPassword.value,
|
||||
}),
|
||||
mailProvider: selectMailProvider.value,
|
||||
mail2925Mode: getSelectedMail2925Mode(),
|
||||
emailGenerator: selectEmailGenerator.value,
|
||||
autoDeleteUsedIcloudAlias: checkboxAutoDeleteIcloud?.checked,
|
||||
icloudHostPreference: selectIcloudHostPreference?.value || 'auto',
|
||||
accountRunHistoryTextEnabled: Boolean(inputAccountRunHistoryTextEnabled?.checked),
|
||||
accountRunHistoryHelperBaseUrl: normalizeAccountRunHistoryHelperBaseUrlValue(inputAccountRunHistoryHelperBaseUrl?.value),
|
||||
...(contributionModeEnabled ? {} : {
|
||||
accountRunHistoryTextEnabled: Boolean(inputAccountRunHistoryTextEnabled?.checked),
|
||||
accountRunHistoryHelperBaseUrl: normalizeAccountRunHistoryHelperBaseUrlValue(inputAccountRunHistoryHelperBaseUrl?.value),
|
||||
}),
|
||||
...buildManagedAliasBaseEmailPayload(),
|
||||
inbucketHost: inputInbucketHost.value.trim(),
|
||||
inbucketMailbox: inputInbucketMailbox.value.trim(),
|
||||
@@ -1442,7 +1469,9 @@ function updateAccountRunHistorySettingsUI() {
|
||||
return;
|
||||
}
|
||||
|
||||
rowAccountRunHistoryHelperBaseUrl.style.display = inputAccountRunHistoryTextEnabled.checked ? '' : 'none';
|
||||
rowAccountRunHistoryHelperBaseUrl.style.display = inputAccountRunHistoryTextEnabled.checked && !latestState?.contributionMode
|
||||
? ''
|
||||
: 'none';
|
||||
}
|
||||
|
||||
function setSettingsCardLocked(locked) {
|
||||
@@ -1613,6 +1642,7 @@ function applyAutoRunStatus(payload = currentAutoRun) {
|
||||
syncScheduledCountdownTicker();
|
||||
updateStopButtonState(scheduled || paused || locked || Object.values(getStepStatuses()).some(status => status === 'running'));
|
||||
updateConfigMenuControls();
|
||||
renderContributionMode();
|
||||
}
|
||||
|
||||
function initializeManualStepActions() {
|
||||
@@ -1794,6 +1824,7 @@ async function restoreState() {
|
||||
|
||||
updateStatusDisplay(latestState);
|
||||
updateProgressCounter();
|
||||
renderContributionMode();
|
||||
} catch (err) {
|
||||
console.error('Failed to restore state:', err);
|
||||
}
|
||||
@@ -2008,7 +2039,7 @@ async function initializeReleaseInfo() {
|
||||
}
|
||||
|
||||
function syncPasswordField(state) {
|
||||
inputPassword.value = state.customPassword || state.password || '';
|
||||
inputPassword.value = state?.contributionMode ? '' : (state.customPassword || state.password || '');
|
||||
}
|
||||
|
||||
function isCustomMailProvider(provider = selectMailProvider.value) {
|
||||
@@ -2569,6 +2600,7 @@ function updateButtonStates() {
|
||||
if (selectIcloudHostPreference) selectIcloudHostPreference.disabled = disableIcloudControls;
|
||||
if (checkboxAutoDeleteIcloud) checkboxAutoDeleteIcloud.disabled = disableIcloudControls;
|
||||
updateStopButtonState(anyRunning || autoScheduled || isAutoRunPausedPhase() || autoLocked);
|
||||
renderContributionMode();
|
||||
}
|
||||
|
||||
function updateStopButtonState(active) {
|
||||
@@ -2943,7 +2975,66 @@ const renderAccountRecords = accountRecordsManager?.render
|
||||
|| (() => { });
|
||||
const bindAccountRecordEvents = accountRecordsManager?.bindEvents
|
||||
|| (() => { });
|
||||
const closeAccountRecordsPanel = accountRecordsManager?.closePanel
|
||||
|| (() => { });
|
||||
bindAccountRecordEvents();
|
||||
const contributionModeManager = window.SidepanelContributionMode?.createContributionModeManager({
|
||||
state: {
|
||||
getLatestState: () => latestState,
|
||||
},
|
||||
dom: {
|
||||
btnConfigMenu,
|
||||
btnContributionMode,
|
||||
contributionCallbackStatus,
|
||||
btnExitContributionMode,
|
||||
btnOpenAccountRecords,
|
||||
btnOpenContributionUpload,
|
||||
btnStartContribution,
|
||||
contributionModePanel,
|
||||
contributionModeSummary,
|
||||
contributionModeText,
|
||||
contributionOauthStatus,
|
||||
rowAccountRunHistoryHelperBaseUrl,
|
||||
rowAccountRunHistoryTextEnabled,
|
||||
rowCustomPassword,
|
||||
rowLocalCpaStep9Mode,
|
||||
rowSub2ApiDefaultProxy,
|
||||
rowSub2ApiEmail,
|
||||
rowSub2ApiGroup,
|
||||
rowSub2ApiPassword,
|
||||
rowSub2ApiUrl,
|
||||
rowVpsPassword,
|
||||
rowVpsUrl,
|
||||
selectPanelMode,
|
||||
},
|
||||
helpers: {
|
||||
applySettingsState,
|
||||
closeAccountRecordsPanel,
|
||||
closeConfigMenu,
|
||||
getContributionNickname: () => latestState?.email || '',
|
||||
isModeSwitchBlocked: isContributionModeSwitchBlocked,
|
||||
openConfirmModal,
|
||||
openExternalUrl,
|
||||
showToast,
|
||||
startContributionAutoRun: () => startAutoRunFromCurrentSettings(),
|
||||
updateAccountRunHistorySettingsUI,
|
||||
updateConfigMenuControls,
|
||||
updatePanelModeUI,
|
||||
updateStatusDisplay,
|
||||
},
|
||||
runtime: {
|
||||
sendMessage: (message) => chrome.runtime.sendMessage(message),
|
||||
},
|
||||
constants: {
|
||||
contributionOauthUrl: 'https://apikey.qzz.io/oauth/',
|
||||
contributionUploadUrl: 'https://apikey.qzz.io/',
|
||||
},
|
||||
});
|
||||
const renderContributionMode = contributionModeManager?.render
|
||||
|| (() => { });
|
||||
const bindContributionModeEvents = contributionModeManager?.bindEvents
|
||||
|| (() => { });
|
||||
bindContributionModeEvents();
|
||||
renderStepsList();
|
||||
|
||||
async function exportSettingsFile() {
|
||||
@@ -3287,9 +3378,64 @@ autoStartModal?.addEventListener('click', (event) => {
|
||||
});
|
||||
btnAutoStartClose?.addEventListener('click', () => resolveModalChoice(null));
|
||||
|
||||
async function startAutoRunFromCurrentSettings() {
|
||||
const totalRuns = getRunCountValue();
|
||||
let mode = 'restart';
|
||||
const autoRunSkipFailures = inputAutoSkipFailures.checked;
|
||||
const fallbackThreadIntervalMinutes = normalizeAutoRunThreadIntervalMinutes(
|
||||
inputAutoSkipFailuresThreadIntervalMinutes.value
|
||||
);
|
||||
inputAutoSkipFailuresThreadIntervalMinutes.value = String(fallbackThreadIntervalMinutes);
|
||||
|
||||
if (shouldOfferAutoModeChoice()) {
|
||||
const startStep = getFirstUnfinishedStep();
|
||||
const runningStep = getRunningSteps()[0] ?? null;
|
||||
const choice = await openAutoStartChoiceDialog(startStep, { runningStep });
|
||||
if (!choice) {
|
||||
return false;
|
||||
}
|
||||
mode = choice;
|
||||
}
|
||||
|
||||
if (shouldWarnAutoRunFallbackRisk(totalRuns, autoRunSkipFailures)
|
||||
&& !isAutoRunFallbackRiskPromptDismissed()) {
|
||||
const result = await openAutoRunFallbackRiskConfirmModal(totalRuns, fallbackThreadIntervalMinutes);
|
||||
if (!result.confirmed) {
|
||||
return false;
|
||||
}
|
||||
if (result.dismissPrompt) {
|
||||
setAutoRunFallbackRiskPromptDismissed(true);
|
||||
}
|
||||
}
|
||||
|
||||
btnAutoRun.disabled = true;
|
||||
inputRunCount.disabled = true;
|
||||
const delayEnabled = inputAutoDelayEnabled.checked;
|
||||
const delayMinutes = normalizeAutoDelayMinutes(inputAutoDelayMinutes.value);
|
||||
inputAutoDelayMinutes.value = String(delayMinutes);
|
||||
btnAutoRun.innerHTML = delayEnabled
|
||||
? '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg> 璁″垝涓?..'
|
||||
: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg> 杩愯涓?..';
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
type: delayEnabled ? 'SCHEDULE_AUTO_RUN' : 'AUTO_RUN',
|
||||
source: 'sidepanel',
|
||||
payload: {
|
||||
totalRuns,
|
||||
delayMinutes,
|
||||
autoRunSkipFailures,
|
||||
mode,
|
||||
},
|
||||
});
|
||||
if (response?.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Auto Run
|
||||
btnAutoRun.addEventListener('click', async () => {
|
||||
try {
|
||||
return await startAutoRunFromCurrentSettings();
|
||||
const totalRuns = getRunCountValue();
|
||||
let mode = 'restart';
|
||||
const autoRunSkipFailures = inputAutoSkipFailures.checked;
|
||||
@@ -3989,12 +4135,20 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
||||
if (message.payload.email !== undefined) {
|
||||
inputEmail.value = message.payload.email || '';
|
||||
}
|
||||
if (message.payload.password !== undefined) {
|
||||
inputPassword.value = message.payload.password || '';
|
||||
if (
|
||||
message.payload.password !== undefined
|
||||
|| message.payload.customPassword !== undefined
|
||||
|| message.payload.contributionMode !== undefined
|
||||
) {
|
||||
syncPasswordField(latestState || {});
|
||||
}
|
||||
if (message.payload.localCpaStep9Mode !== undefined) {
|
||||
setLocalCpaStep9Mode(message.payload.localCpaStep9Mode);
|
||||
}
|
||||
if (message.payload.panelMode !== undefined) {
|
||||
selectPanelMode.value = message.payload.panelMode || 'cpa';
|
||||
updatePanelModeUI();
|
||||
}
|
||||
if (message.payload.oauthUrl !== undefined) {
|
||||
displayOauthUrl.textContent = message.payload.oauthUrl || '等待中...';
|
||||
displayOauthUrl.classList.toggle('has-value', Boolean(message.payload.oauthUrl));
|
||||
@@ -4097,6 +4251,7 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
|
||||
)
|
||||
);
|
||||
}
|
||||
renderContributionMode();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user