From 7c80643aba266fc0279c593f1951931f3fbb9ce2 Mon Sep 17 00:00:00 2001 From: enes Date: Wed, 11 Sep 2024 16:44:45 +0200 Subject: [PATCH] fix(login): extension login infinite loading Fixes #196 --- src/pages/nostr/index.tsx | 75 ++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/src/pages/nostr/index.tsx b/src/pages/nostr/index.tsx index bd99485..8726c6e 100644 --- a/src/pages/nostr/index.tsx +++ b/src/pages/nostr/index.tsx @@ -18,12 +18,16 @@ import { } from '../../store/actions' import { LoginMethods } from '../../store/auth/types' import { Dispatch } from '../../store/store' -import { npubToHex, queryNip05 } from '../../utils' +import { npubToHex, queryNip05, timeout } from '../../utils' import { hexToBytes } from '@noble/hashes/utils' import { NIP05_REGEX } from '../../constants' import styles from './styles.module.scss' +import { TimeoutError } from '../../types/errors/TimeoutError' +const EXTENSION_LOGIN_DELAY_SECONDS = 2 +const EXTENSION_LOGIN_TIMEOUT_SECONDS = EXTENSION_LOGIN_DELAY_SECONDS + 10 + export const Nostr = () => { const [searchParams] = useSearchParams() @@ -36,6 +40,7 @@ export const Nostr = () => { const [isLoading, setIsLoading] = useState(false) const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('') + const [isExtensionSlow, setIsExtensionSlow] = useState(false) const [inputValue, setInputValue] = useState('') const [authUrl, setAuthUrl] = useState() @@ -72,27 +77,39 @@ export const Nostr = () => { } const loginWithExtension = async () => { - setIsLoading(true) - setLoadingSpinnerDesc('Capturing pubkey from nostr extension') + try { + // Wait EXTENSION_LOGIN_DELAY_SECONDS before showing extension delay message + const waitTimeout = window.setTimeout(() => { + setIsExtensionSlow(true) + }, 2000) - nostrController - .capturePublicKey() - .then(async (pubkey) => { - dispatch(updateLoginMethod(LoginMethods.extension)) + setIsLoading(true) + setLoadingSpinnerDesc('Capturing pubkey from nostr extension') - setLoadingSpinnerDesc('Authenticating and finding metadata') - const redirectPath = - await authController.authAndGetMetadataAndRelaysMap(pubkey) + const pubkey = await nostrController.capturePublicKey() + dispatch(updateLoginMethod(LoginMethods.extension)) - if (redirectPath) navigateAfterLogin(redirectPath) - }) - .catch((err) => { - toast.error('Error capturing public key from nostr extension: ' + err) - }) - .finally(() => { - setIsLoading(false) - setLoadingSpinnerDesc('') - }) + setLoadingSpinnerDesc('Authenticating and finding metadata') + const redirectPath = await Promise.race([ + authController.authAndGetMetadataAndRelaysMap(pubkey), + timeout(EXTENSION_LOGIN_TIMEOUT_SECONDS * 1000) + ]) + + if (redirectPath) { + window.clearTimeout(waitTimeout) + navigateAfterLogin(redirectPath) + } + } catch (error) { + if (error instanceof TimeoutError) { + toast.error("Extension didn't respond in time") + } else { + toast.error('Error capturing public key from nostr extension: ' + error) + } + } finally { + setIsLoading(false) + setLoadingSpinnerDesc('') + setIsExtensionSlow(false) + } } /** @@ -354,7 +371,25 @@ export const Nostr = () => { return ( <> - {isLoading && } + {isLoading && ( + + {isExtensionSlow && ( + <> +

Extension is not responding

+ + + )} +
+ )} {isNostrExtensionAvailable && ( <>