diff --git a/packages/kit-bg/src/dbs/simple/entity/SimpleDbEntityAccountSelector.ts b/packages/kit-bg/src/dbs/simple/entity/SimpleDbEntityAccountSelector.ts index db9452b383d..1deb37d5512 100644 --- a/packages/kit-bg/src/dbs/simple/entity/SimpleDbEntityAccountSelector.ts +++ b/packages/kit-bg/src/dbs/simple/entity/SimpleDbEntityAccountSelector.ts @@ -1,3 +1,5 @@ +import { cloneDeep } from 'lodash'; + import { backgroundMethod } from '@onekeyhq/shared/src/background/backgroundDecorators'; import { EAppEventBusNames, @@ -144,7 +146,7 @@ export class SimpleDbEntityAccountSelector extends SimpleDbEntityBase { + if ( + sceneName === EAccountSelectorSceneName.discover && + eventPayload && + eventPayload.selectedAccount && + eventPayload.sceneName === sceneName && + eventPayload.sceneUrl === sceneUrl && + // @ts-ignore + eventPayload?.$$isRemoteEvent + ) { + await actions.current.updateSelectedAccount({ + num: eventPayload.num, + builder: () => eventPayload.selectedAccount, + updateMeta: { + eventEmitDisabled: true, // avoid infinite loop: event -> updateSelectedAccount -> event + }, + }); + } + + await syncHomeAndSwap(eventPayload); + }, + [actions, sceneName, sceneUrl, syncHomeAndSwap], + ); + useEffect(() => { appEventBus.on( EAppEventBusNames.AccountSelectorSelectedAccountUpdate, - syncHomeAndSwap, + syncSceneData, ); return () => { appEventBus.off( EAppEventBusNames.AccountSelectorSelectedAccountUpdate, - syncHomeAndSwap, + syncSceneData, ); }; - }, [syncHomeAndSwap]); + }, [syncSceneData]); useEffect(() => { void (async () => { diff --git a/packages/kit/src/components/AccountSelector/hooks/useAutoSelectNetwork.tsx b/packages/kit/src/components/AccountSelector/hooks/useAutoSelectNetwork.tsx index 57dc775b117..22f147ff2b7 100644 --- a/packages/kit/src/components/AccountSelector/hooks/useAutoSelectNetwork.tsx +++ b/packages/kit/src/components/AccountSelector/hooks/useAutoSelectNetwork.tsx @@ -1,9 +1,12 @@ import { useEffect } from 'react'; import { useDebugComponentRemountLog } from '@onekeyhq/shared/src/utils/debug/debugUtils'; +import networkUtils from '@onekeyhq/shared/src/utils/networkUtils'; +import { EAccountSelectorSceneName } from '@onekeyhq/shared/types'; import { useAccountSelectorActions, + useAccountSelectorSceneInfo, useAccountSelectorStorageReadyAtom, useSelectedAccount, } from '../../../states/jotai/contexts/accountSelector'; @@ -11,17 +14,31 @@ import { import { useAccountSelectorAvailableNetworks } from './useAccountSelectorAvailableNetworks'; export function useAutoSelectNetwork({ num }: { num: number }) { - const { - selectedAccount: { networkId }, - } = useSelectedAccount({ num }); + const { selectedAccount } = useSelectedAccount({ num }); + const { networkId } = selectedAccount; const [isReady] = useAccountSelectorStorageReadyAtom(); const { networkIds, defaultNetworkId } = useAccountSelectorAvailableNetworks({ num, }); + const { sceneName, sceneUrl } = useAccountSelectorSceneInfo(); + const actions = useAccountSelectorActions(); + if (sceneName === EAccountSelectorSceneName.discover) { + // console.log('useAutoSelectNetwork::: sceneName', { + // selectedAccount, + // sceneName, + // sceneUrl, + // networkId, + // networkIds, + // defaultNetworkId, + // isReady, + // num, + // }); + } + // ** auto select first network if no network selected yet useEffect(() => { if (!isReady) { @@ -40,14 +57,38 @@ export function useAutoSelectNetwork({ num }: { num: number }) { usedNetworkId = defaultNetworkId; } } + + if ( + usedNetworkId && + sceneName === EAccountSelectorSceneName.discover && + networkUtils.isAllNetwork({ networkId: usedNetworkId }) + ) { + usedNetworkId = ''; + } + if (usedNetworkId) { + if (sceneName === EAccountSelectorSceneName.discover) { + // console.log( + // 'useAutoSelectNetwork::: updateSelectedAccountNetwork', + // usedNetworkId, + // ); + } + void actions.current.updateSelectedAccountNetwork({ num, networkId: usedNetworkId, }); } } - }, [actions, defaultNetworkId, isReady, networkId, networkIds, num]); + }, [ + actions, + defaultNetworkId, + isReady, + networkId, + networkIds, + num, + sceneName, + ]); // TODO UI unmount & mount unexpectedly, cause hooks rerun // TODO useUpdateEffect() diff --git a/packages/kit/src/states/jotai/contexts/accountSelector/actions.tsx b/packages/kit/src/states/jotai/contexts/accountSelector/actions.tsx index 5fe8fc121c8..2e59f4fc106 100644 --- a/packages/kit/src/states/jotai/contexts/accountSelector/actions.tsx +++ b/packages/kit/src/states/jotai/contexts/accountSelector/actions.tsx @@ -54,6 +54,7 @@ import accountSelectorUtils from '@onekeyhq/shared/src/utils/accountSelectorUtil import accountUtils from '@onekeyhq/shared/src/utils/accountUtils'; import bufferUtils from '@onekeyhq/shared/src/utils/bufferUtils'; import { memoFn } from '@onekeyhq/shared/src/utils/cacheUtils'; +import networkUtils from '@onekeyhq/shared/src/utils/networkUtils'; import timerUtils from '@onekeyhq/shared/src/utils/timerUtils'; import { EAccountSelectorAutoSelectTriggerBy, @@ -90,6 +91,7 @@ export type IAccountSelectorSyncFromSceneParams = { sceneNum: number; }; num: number; + withNetworkSync?: boolean; }; export type IFinalizeWalletSetupCreateWalletResult = { @@ -294,6 +296,11 @@ class AccountSelectorActions extends ContextJotaiActionsBase { }, ); + getCurrentSceneInfo = contextAtomMethod(async (get) => { + const contextData = get(accountSelectorContextDataAtom()); + return contextData; + }); + updateSelectedAccount = contextAtomMethod( async ( get, @@ -306,7 +313,7 @@ class AccountSelectorActions extends ContextJotaiActionsBase { ) => IAccountSelectorSelectedAccount; }, ) => { - const contextData = get(accountSelectorContextDataAtom()); + const sceneInfo = await this.getCurrentSceneInfo.call(set); // if (!contextData) { // return; // } @@ -319,6 +326,13 @@ class AccountSelectorActions extends ContextJotaiActionsBase { return; } + if ( + sceneInfo?.sceneName === EAccountSelectorSceneName.discover && + newSelectedAccount?.indexedAccountId === 'hd-1--0' + ) { + // debugger; + } + const newNetworkId = newSelectedAccount?.networkId; const oldNetworkId = oldSelectedAccount?.networkId; const newDeriveType = newSelectedAccount?.deriveType; @@ -348,13 +362,13 @@ class AccountSelectorActions extends ContextJotaiActionsBase { } }; - if (contextData?.sceneName) { - await fixDeriveTypeByGlobal({ sceneName: contextData?.sceneName }); + if (sceneInfo?.sceneName) { + await fixDeriveTypeByGlobal({ sceneName: sceneInfo?.sceneName }); const shouldUseGlobalDeriveType = await backgroundApiProxy.serviceAccountSelector.shouldUseGlobalDeriveType( { - sceneName: contextData?.sceneName, + sceneName: sceneInfo?.sceneName, }, ); if (!shouldUseGlobalDeriveType && newSelectedAccount?.networkId) { @@ -1326,6 +1340,19 @@ class AccountSelectorActions extends ContextJotaiActionsBase { // **** emit event if (!eventEmitDisabled) { + if ( + networkUtils.isAllNetwork({ + networkId: payload.selectedAccount?.networkId, + }) + ) { + // debugger; + } + if (sceneName === EAccountSelectorSceneName.discover) { + if (payload?.selectedAccount?.indexedAccountId === 'hd-1--0') { + // alert('AccountSelectorSelectedAccountUpdate'); + // debugger; + } + } appEventBus.emit( EAppEventBusNames.AccountSelectorSelectedAccountUpdate, payload, @@ -1366,7 +1393,12 @@ class AccountSelectorActions extends ContextJotaiActionsBase { ); syncFromScene = contextAtomMethod( - async (get, set, { from, num }: IAccountSelectorSyncFromSceneParams) => { + async ( + get, + set, + { from, num, withNetworkSync }: IAccountSelectorSyncFromSceneParams, + ) => { + const sceneInfo = await this.getCurrentSceneInfo.call(set); const { sceneName, sceneUrl, sceneNum } = from; const selectedAccount = @@ -1378,7 +1410,24 @@ class AccountSelectorActions extends ContextJotaiActionsBase { await this.updateSelectedAccount.call(set, { num, - builder: (v) => selectedAccount || v, + builder: (v) => { + if (selectedAccount) { + // networkId won't be synced in default + if (!withNetworkSync) { + selectedAccount.networkId = v?.networkId; + } + if ( + sceneInfo?.sceneName === EAccountSelectorSceneName.discover && + networkUtils.isAllNetwork({ + networkId: selectedAccount.networkId, + }) + ) { + selectedAccount.networkId = v?.networkId; + } + return selectedAccount; + } + return v; + }, }); }, ); diff --git a/packages/kit/src/views/DAppConnection/components/DAppAccountList/DAppAccountListItem.tsx b/packages/kit/src/views/DAppConnection/components/DAppAccountList/DAppAccountListItem.tsx index 26ee499c95d..728ef6cdb62 100644 --- a/packages/kit/src/views/DAppConnection/components/DAppAccountList/DAppAccountListItem.tsx +++ b/packages/kit/src/views/DAppConnection/components/DAppAccountList/DAppAccountListItem.tsx @@ -55,6 +55,7 @@ function DAppAccountListInitFromHome({ // required delay here, should be called after AccountSelectEffects AutoSelect await timerUtils.wait(600); if (shouldSyncFromHome) { + // alert('syncFromScene home'); await actions.current.syncFromScene({ from: { sceneName: EAccountSelectorSceneName.home, diff --git a/packages/kit/src/views/DAppConnection/dappTest.html b/packages/kit/src/views/DAppConnection/dappTest.html new file mode 100644 index 00000000000..a4cad66f68a --- /dev/null +++ b/packages/kit/src/views/DAppConnection/dappTest.html @@ -0,0 +1,75 @@ + + + + ETH DApp Demo + + +
+ + +
+ + +

+ + + + diff --git a/packages/kit/src/views/DAppConnection/hooks/useHandleAccountChanged.ts b/packages/kit/src/views/DAppConnection/hooks/useHandleAccountChanged.ts index 0beeba1f340..eee06f9c883 100644 --- a/packages/kit/src/views/DAppConnection/hooks/useHandleAccountChanged.ts +++ b/packages/kit/src/views/DAppConnection/hooks/useHandleAccountChanged.ts @@ -1,5 +1,7 @@ import { useEffect, useRef } from 'react'; +import { useThrottledCallback } from 'use-debounce'; + import type { IAccountSelectorActiveAccountInfo } from '@onekeyhq/kit/src/states/jotai/contexts/accountSelector'; import { useActiveAccount, @@ -7,8 +9,6 @@ import { } from '@onekeyhq/kit/src/states/jotai/contexts/accountSelector'; import type { IAccountSelectorSelectedAccount } from '@onekeyhq/kit-bg/src/dbs/simple/entity/SimpleDbEntityAccountSelector'; -import { useDebounce } from '../../../hooks/useDebounce'; - export type IHandleAccountChangedParams = { activeAccount: IAccountSelectorActiveAccountInfo; selectedAccount: IAccountSelectorSelectedAccount; @@ -29,26 +29,30 @@ export function useHandleDiscoveryAccountChanged({ const { activeAccount } = useActiveAccount({ num }); const { selectedAccount } = useSelectedAccount({ num }); - // Due to the high number of renderings of `activeAccount`, we are using debounce handling. - const debouncedActiveAccount = useDebounce(activeAccount, 200); - const debouncedSelectedAccount = useDebounce(selectedAccount, 200); + const accountAddress = activeAccount?.account?.address; + + const activeAccountDepsId = [ + accountAddress || '', + activeAccount?.wallet?.id ?? '', + activeAccount?.account?.id ?? '', + activeAccount?.indexedAccount?.id ?? '', + activeAccount?.dbAccount?.id ?? '', + activeAccount?.network?.id ?? '', + ].join('-'); const activeAccountRef = useRef(activeAccount); const selectedAccountRef = useRef(selectedAccount); - useEffect(() => { - activeAccountRef.current = activeAccount; - selectedAccountRef.current = selectedAccount; - }, [activeAccount, selectedAccount]); + const accountAddressRef = useRef(accountAddress); + activeAccountRef.current = activeAccount; + selectedAccountRef.current = selectedAccount; + accountAddressRef.current = accountAddress; - useEffect(() => { - if (handleAccountChanged) { - // ensure the selected account is the same as the active account + const handleAccountChangedThrottle = useThrottledCallback( + () => { if ( - (debouncedActiveAccount.isOthersWallet && - debouncedActiveAccount.account?.id === - debouncedSelectedAccount.othersWalletAccountId) || - debouncedActiveAccount.indexedAccount?.id === - debouncedSelectedAccount.indexedAccountId + handleAccountChanged && + activeAccountDepsId && + activeAccountRef.current ) { handleAccountChanged( { @@ -58,11 +62,17 @@ export function useHandleDiscoveryAccountChanged({ num, ); } + }, + 200, + { + leading: false, + trailing: true, + }, + ); + + useEffect(() => { + if (activeAccountDepsId && activeAccountRef.current) { + handleAccountChangedThrottle(); } - }, [ - debouncedActiveAccount, - debouncedSelectedAccount, - handleAccountChanged, - num, - ]); + }, [activeAccountDepsId, handleAccountChangedThrottle]); } diff --git a/packages/shared/src/eventBus/appEventBus.ts b/packages/shared/src/eventBus/appEventBus.ts index 9df29f9541c..46a244dd2c2 100644 --- a/packages/shared/src/eventBus/appEventBus.ts +++ b/packages/shared/src/eventBus/appEventBus.ts @@ -326,6 +326,15 @@ class AppEventBus extends CrossEventEmitter { defaultLogger.app.eventBus.emitToSelf({ eventName: type, }); + try { + // @ts-ignore + if (payload?.$$isRemoteEvent) { + // @ts-ignore + delete payload.$$isRemoteEvent; + } + } catch (e) { + // ignore + } this.emitToSelf(type, payload); } void this.emitToRemote(type, payload); @@ -373,6 +382,15 @@ class AppEventBus extends CrossEventEmitter { } async emitToRemote(type: string, payload: any) { + try { + if (payload) { + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + payload.$$isRemoteEvent = true; + } + } catch (e) { + // ignore + } if (platformEnv.isExtensionOffscreen || platformEnv.isWebEmbed) { // request background throw new Error('offscreen or webembed event bus not support yet.'); diff --git a/packages/shared/src/utils/debug/debugUtils.ts b/packages/shared/src/utils/debug/debugUtils.ts index 733de4419dd..68d35dce3f5 100644 --- a/packages/shared/src/utils/debug/debugUtils.ts +++ b/packages/shared/src/utils/debug/debugUtils.ts @@ -19,10 +19,12 @@ export function useDebugComponentRemountLog({ useEffect(() => { if (process.env.NODE_ENV !== 'production') { - console.log( + console.groupCollapsed( `@@ComponentRemountLog mounted: ${nameRef.current}`, - stringUtils.safeStringify(payloadRef.current), ); + console.log(stringUtils.safeStringify(payloadRef.current)); + console.log('href: ', globalThis?.location?.href); + console.groupEnd(); } return () => { if (process.env.NODE_ENV !== 'production') {