From 7ba1a7be0c884a813e00ac6e374cdf8ee18bf021 Mon Sep 17 00:00:00 2001 From: YuBai Date: Thu, 5 Mar 2026 20:38:48 +0800 Subject: [PATCH] feat: implement lazy login to eliminate startup network request Replace eager login verification on startup with assumeLoggedIn(), which sets login state from saved credentials without any network call. Real verification is deferred until sync (which needs the actual user ID) or when the settings page is opened. - UserComponent: add verified flag, assumeLoggedIn(), isVerified() - main.ts: replace onLayoutReady(login) with assumeLoggedIn(); fix inverted condition bug in checkLogin() (!needLogin -> needLogin) - DoubanSyncModal: remove redundant login check before checkLogin() - LoginSettingsHelper: handle assumed-but-unverified state in constructLoginUI() Co-Authored-By: Claude Sonnet 4.6 --- .../wanxp/douban/component/DoubanSyncModal.ts | 3 --- .../douban/setting/LoginSettingsHelper.ts | 22 +++++++++---------- src/org/wanxp/douban/user/UserComponent.ts | 20 +++++++++++++++++ src/org/wanxp/main.ts | 15 ++++++++----- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/org/wanxp/douban/component/DoubanSyncModal.ts b/src/org/wanxp/douban/component/DoubanSyncModal.ts index 16f00a7..b58fe94 100644 --- a/src/org/wanxp/douban/component/DoubanSyncModal.ts +++ b/src/org/wanxp/douban/component/DoubanSyncModal.ts @@ -169,9 +169,6 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T const syncButton = new ButtonComponent(controls) .setButtonText(i18nHelper.getMessage('110007')) .onClick(async () => { - if (!this.plugin.userComponent.isLogin()) { - await this.plugin.userComponent.login(); - } if(!await this.plugin.checkLogin(this.context)) { return; } diff --git a/src/org/wanxp/douban/setting/LoginSettingsHelper.ts b/src/org/wanxp/douban/setting/LoginSettingsHelper.ts index c1a3405..768fa54 100644 --- a/src/org/wanxp/douban/setting/LoginSettingsHelper.ts +++ b/src/org/wanxp/douban/setting/LoginSettingsHelper.ts @@ -10,17 +10,17 @@ export function constructLoginUI(containerEl: HTMLElement, manager: SettingsMana // containerEl.createEl('h3', { text: i18nHelper.getMessage('1210') }); const userComponent = manager.plugin.userComponent; - if (userComponent.needLogin()) { - try { - userComponent.login() - .then(() => { - constructDoubanLoginSettingsUI(containerEl, manager); - }); - }catch (e) { - log.debug(i18nHelper.getMessage('100101')); - constructDoubanLoginSettingsUI(containerEl, manager); - } - }else { + if (userComponent.isLogin() && !userComponent.isVerified()) { + // Assumed login — verify to get user ID/name for settings display + userComponent.login() + .then(() => constructDoubanLoginSettingsUI(containerEl, manager)) + .catch(() => constructDoubanLoginSettingsUI(containerEl, manager)); + } else if (userComponent.needLogin()) { + // Has credentials but not yet logged in + userComponent.login() + .then(() => constructDoubanLoginSettingsUI(containerEl, manager)) + .catch(() => constructDoubanLoginSettingsUI(containerEl, manager)); + } else { constructDoubanLoginSettingsUI(containerEl, manager); } diff --git a/src/org/wanxp/douban/user/UserComponent.ts b/src/org/wanxp/douban/user/UserComponent.ts index 236f124..a79e6bb 100644 --- a/src/org/wanxp/douban/user/UserComponent.ts +++ b/src/org/wanxp/douban/user/UserComponent.ts @@ -15,6 +15,7 @@ import {DoubanHttpUtil} from "../../utils/DoubanHttpUtil"; export default class UserComponent { private settingsManager: SettingsManager; private user: User; + private verified: boolean = false; constructor(settingsManager: SettingsManager) { this.settingsManager = settingsManager; @@ -39,11 +40,26 @@ export default class UserComponent { this.user.login = false; } this.user = null; + this.verified = false; this.settingsManager.updateSetting('loginCookiesContent', ''); this.settingsManager.updateSetting('loginHeadersContent', ''); } + assumeLoggedIn(): void { + const headers: any = this.settingsManager.getSetting('loginHeadersContent'); + const cookies: any = this.settingsManager.getSetting('loginCookiesContent'); + if (headers || cookies) { + this.user = new User(); + this.user.login = true; + this.verified = false; + } + } + + isVerified(): boolean { + return this.verified; + } + needLogin() { @@ -68,6 +84,7 @@ export default class UserComponent { this.settingsManager.debug(`配置界面:loginCookie:豆瓣headers信息正常,${user&&user.id?'获取用户信息成功id:'+ StringUtil.confuse(user.id) + ',用户名:'+ StringUtil.confuse(user.name) :'获取用户信息失败'}`); }); if(this.user) { + this.verified = true; this.settingsManager.updateSetting('loginHeadersContent', JSON.stringify(headers)); } return this.user; @@ -139,6 +156,9 @@ export default class UserComponent { this.user = user; this.settingsManager.debug(`主界面:loginByCookie:豆瓣cookies信息正常,${user&&user.id?'获取用户信息成功id:'+ StringUtil.confuse(user.id) + ',用户名:'+ StringUtil.confuse(user.name) :'获取用户信息失败'}`); }); + if (this.user && this.user.id) { + this.verified = true; + } return this.user; } } diff --git a/src/org/wanxp/main.ts b/src/org/wanxp/main.ts index 33ee153..88565b7 100644 --- a/src/org/wanxp/main.ts +++ b/src/org/wanxp/main.ts @@ -285,8 +285,8 @@ export default class DoubanPlugin extends Plugin { this.settingsManager = new SettingsManager(this.app, this); // this.fetchOnlineData(this.settingsManager); this.userComponent = new UserComponent(this.settingsManager); - await this.userComponent.login(); this.netFileHandler = new NetFileHandler(this.fileHandler); + this.userComponent.assumeLoggedIn(); this.settingTab = new DoubanSettingTab(this.app, this); this.addSettingTab(this.settingTab); @@ -356,11 +356,16 @@ export default class DoubanPlugin extends Plugin { async checkLogin(context: HandleContext):Promise { this.settingsManager.debug('主界面:同步时的登录状态检测'); - if (!context.userComponent.needLogin()) { - this.settingsManager.debug('主界面:同步时的登录状态检测完成: 无用户信息, 尝试获取用户信息'); - await context.userComponent.login(); + const uc = context.userComponent; + // If assumed-logged-in but not verified, verify now (sync needs real user ID) + if (uc.isLogin() && !uc.isVerified()) { + await uc.login(); } - if (!context.userComponent.isLogin()) { + // If has saved credentials but not logged in, try login + if (uc.needLogin()) { + await uc.login(); + } + if (!uc.isLogin()) { this.settingsManager.debug('主界面:同步时的登录状态检测完成: 尝试获取用户信息失败'); new Notice(i18nHelper.getMessage('140303')); return false;