diff --git a/js/app.js b/js/app.js index e29aab5e..c39c6bf9 100644 --- a/js/app.js +++ b/js/app.js @@ -2878,6 +2878,11 @@ class Application { } async handleAuthLogin(detail = {}) { + const postLoginPromise = + detail && typeof detail.postLoginPromise?.then === "function" + ? detail.postLoginPromise + : Promise.resolve(detail?.postLogin ?? null); + if (detail && typeof detail === "object") { try { detail.__handled = true; @@ -2890,15 +2895,32 @@ class Application { this.resetViewLoggingState(); } - await this.nwcSettingsService.onLogin({ + this.applyAuthenticatedUiState(); + + const loginContext = { pubkey: detail?.pubkey || this.pubkey, previousPubkey: detail?.previousPubkey, identityChanged: Boolean(detail?.identityChanged), - }); + }; + + const nwcPromise = this.nwcSettingsService + .onLogin(loginContext) + .catch((error) => { + console.error("Failed to process NWC settings during login:", error); + throw error; + }); if (this.profileController) { try { - await this.profileController.handleAuthLogin(detail); + const maybePromise = this.profileController.handleAuthLogin(detail); + if (maybePromise && typeof maybePromise.then === "function") { + maybePromise.catch((error) => { + console.error( + "Failed to process login within the profile controller:", + error, + ); + }); + } } catch (error) { console.error( "Failed to process login within the profile controller:", @@ -2909,11 +2931,22 @@ class Application { this.renderSavedProfiles(); } - this.applyAuthenticatedUiState(); - const activePubkey = detail?.pubkey || this.pubkey; - if (activePubkey && detail?.postLogin?.profile) { - this.updateActiveProfileUI(activePubkey, detail.postLogin.profile); + postLoginPromise + .then((postLogin) => { + if (activePubkey && postLogin?.profile) { + this.updateActiveProfileUI(activePubkey, postLogin.profile); + } + this.forceRefreshAllProfiles(); + }) + .catch((error) => { + console.error("Post-login hydration failed:", error); + }); + + try { + await nwcPromise; + } catch (error) { + // Error already logged above; continue so UI can recover. } try { @@ -2921,7 +2954,9 @@ class Application { } catch (error) { console.error("Failed to refresh videos after login:", error); } + this.forceRefreshAllProfiles(); + if (this.uploadModal?.refreshCloudflareBucketPreview) { await this.uploadModal.refreshCloudflareBucketPreview(); } diff --git a/js/services/authService.js b/js/services/authService.js index 6f1cc131..3d3f4ee2 100644 --- a/js/services/authService.js +++ b/js/services/authService.js @@ -365,18 +365,66 @@ export default class AuthService { this.emitProfileList("login"); } - const postLogin = await this.applyPostLoginState(); + const activeLoginPubkey = getPubkey(); + const normalizedLoginPubkey = + this.normalizeHexPubkey(activeLoginPubkey) || activeLoginPubkey || null; const detail = { - pubkey: getPubkey(), + pubkey: activeLoginPubkey, npub: getCurrentUserNpub(), previousPubkey: previousPubkey || null, identityChanged, savedProfiles: this.cloneSavedProfiles(), activeProfilePubkey: getActiveProfilePubkey(), - postLogin, + postLogin: { + pubkey: normalizedLoginPubkey, + blocksLoaded: false, + relaysLoaded: false, + profile: null, + }, + postLoginPromise: null, + postLoginError: null, }; + const postLoginPromise = Promise.resolve() + .then(() => this.applyPostLoginState()) + .then((postLogin) => { + detail.postLogin = postLogin; + detail.postLoginError = null; + + try { + this.emitProfileList("post-login"); + } catch (error) { + this.log("[AuthService] Failed to emit profile list after login", error); + } + + this.emit("auth:post-login", { + ...detail, + postLogin, + postLoginError: null, + savedProfiles: this.cloneSavedProfiles(), + activeProfilePubkey: getActiveProfilePubkey(), + }); + + return postLogin; + }) + .catch((error) => { + this.log("[AuthService] applyPostLoginState failed", error); + detail.postLoginError = error; + + this.emit("auth:post-login", { + ...detail, + postLogin: detail.postLogin, + postLoginError: error, + savedProfiles: this.cloneSavedProfiles(), + activeProfilePubkey: getActiveProfilePubkey(), + }); + + return null; + }); + + detail.postLoginPromise = postLoginPromise; + try { Object.defineProperty(detail, "__handled", { configurable: true, diff --git a/js/ui/profileModalController.js b/js/ui/profileModalController.js index 3a77edda..0566d61d 100644 --- a/js/ui/profileModalController.js +++ b/js/ui/profileModalController.js @@ -3856,6 +3856,11 @@ export class ProfileModalController { } async handleAuthLogin(detail = {}) { + const postLoginPromise = + detail && typeof detail.postLoginPromise?.then === "function" + ? detail.postLoginPromise + : Promise.resolve(detail?.postLogin ?? null); + const savedProfiles = Array.isArray(detail?.savedProfiles) ? detail.savedProfiles : null; @@ -3893,6 +3898,19 @@ export class ProfileModalController { this.populateProfileRelays(); this.refreshWalletPaneState(); + postLoginPromise + .then(() => { + this.populateBlockedList(); + this.populateProfileRelays(); + this.refreshWalletPaneState(); + }) + .catch((error) => { + console.warn( + "[profileModal] Failed to hydrate deferred login data:", + error, + ); + }); + return true; }