diff --git a/packages/extension-ui/src/Popup/index.tsx b/packages/extension-ui/src/Popup/index.tsx index 793f6587..9e5e4517 100644 --- a/packages/extension-ui/src/Popup/index.tsx +++ b/packages/extension-ui/src/Popup/index.tsx @@ -3,14 +3,15 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { AccountJson, AccountsContext, AuthorizeRequest, MetadataRequest, SigningRequest } from '@polkadot/extension-base/background/types'; +import { SettingsStruct } from '@polkadot/ui-settings/types'; import React, { useEffect, useState } from 'react'; import { Route, Switch } from 'react-router'; -import settings from '@polkadot/ui-settings'; +import uiSettings from '@polkadot/ui-settings'; import { setSS58Format } from '@polkadot/util-crypto'; import { Loading } from '../components'; -import { AccountContext, ActionContext, AuthorizeReqContext, MediaContext, MetadataReqContext, SigningReqContext } from '../components/contexts'; +import { AccountContext, ActionContext, AuthorizeReqContext, MediaContext, MetadataReqContext, SettingsContext, SigningReqContext } from '../components/contexts'; import ToastProvider from '../components/Toast/ToastProvider'; import { subscribeAccounts, subscribeAuthorizeRequests, subscribeMetadataRequests, subscribeSigningRequests } from '../messaging'; import { buildHierarchy } from '../utils/buildHierarchy'; @@ -27,12 +28,7 @@ import Metadata from './Metadata'; import Signing from './Signing'; import Welcome from './Welcome'; -// load the ui settings, actually only used for address prefix atm -// probably overkill (however can replace once we have actual others) -const { prefix } = settings.get(); - -// FIXME Duplicated in Settings, horrible... -setSS58Format(prefix === -1 ? 42 : prefix); +const startSettings = uiSettings.get(); // Request permission for video, based on access we can hide/show import async function requestMediaAccess (cameraOn: boolean): Promise { @@ -64,12 +60,14 @@ function initAccountContext (accounts: AccountJson[]): AccountsContext { export default function Popup (): React.ReactElement { const [accounts, setAccounts] = useState(null); + const [accountCtx, setAccountCtx] = useState({ accounts: [], hierarchy: [] }); const [authRequests, setAuthRequests] = useState(null); - const [cameraOn, setCameraOn] = useState(settings.get().camera === 'on'); + const [cameraOn, setCameraOn] = useState(startSettings.camera === 'on'); const [mediaAllowed, setMediaAllowed] = useState(false); const [metaRequests, setMetaRequests] = useState(null); const [signRequests, setSignRequests] = useState(null); const [isWelcomeDone, setWelcomeDone] = useState(false); + const [settingsCtx, setSettingsCtx] = useState(startSettings); const _onAction = (to?: string): void => { setWelcomeDone(window.localStorage.getItem('welcome_read') === 'ok'); @@ -85,15 +83,25 @@ export default function Popup (): React.ReactElement { subscribeAuthorizeRequests(setAuthRequests), subscribeMetadataRequests(setMetaRequests), subscribeSigningRequests(setSignRequests) - ]).catch((error: Error) => console.error(error)); + ]).catch(console.error); - settings.on('change', ({ camera }): void => setCameraOn(camera === 'on')); + uiSettings.on('change', (settings): void => { + setSettingsCtx(settings); + setCameraOn(settings.camera === 'on'); + setSS58Format(settings.prefix === -1 ? 42 : settings.prefix); + }); _onAction(); }, []); useEffect((): void => { - requestMediaAccess(cameraOn).then(setMediaAllowed).catch(console.error); + setAccountCtx(initAccountContext(accounts || [])); + }, [accounts]); + + useEffect((): void => { + requestMediaAccess(cameraOn) + .then(setMediaAllowed) + .catch(console.error); }, [cameraOn]); const Root = isWelcomeDone @@ -109,34 +117,36 @@ export default function Popup (): React.ReactElement { return ( {accounts && authRequests && metaRequests && signRequests && ( - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + )} ); diff --git a/packages/extension-ui/src/components/Address.tsx b/packages/extension-ui/src/components/Address.tsx index 5567812c..f83a0beb 100644 --- a/packages/extension-ui/src/components/Address.tsx +++ b/packages/extension-ui/src/components/Address.tsx @@ -2,22 +2,21 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ThemeProps } from '../types'; - import { AccountJson, AccountWithChildren } from '@polkadot/extension-base/background/types'; import { Chain } from '@polkadot/extension-chains/types'; +import { SettingsStruct } from '@polkadot/ui-settings/types'; +import { ThemeProps } from '../types'; import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; import CopyToClipboard from 'react-copy-to-clipboard'; import styled from 'styled-components'; -import settings from '@polkadot/ui-settings'; import { decodeAddress, encodeAddress } from '@polkadot/util-crypto'; import copy from '../assets/copy.svg'; import details from '../assets/details.svg'; import parentArrow from '../assets/arrowParentLabel.svg'; -import { AccountContext } from './contexts'; +import { AccountContext, SettingsContext } from './contexts'; import Identicon from './Identicon'; import Menu from './Menu'; import Svg from './Svg'; @@ -52,7 +51,7 @@ function findAccount (accounts: AccountJson[], publicKey: Uint8Array): AccountJs } // recodes an supplied address using the prefix/genesisHash, include the actual saved account & chain -function recodeAddress (address: string, accounts: AccountWithChildren[], chain: Chain | null): Recoded { +function recodeAddress (address: string, accounts: AccountWithChildren[], chain: Chain | null, settings: SettingsStruct): Recoded { // decode and create a shortcut for the encoded address const publicKey = decodeAddress(address); @@ -72,6 +71,7 @@ const ACCOUNTS_SCREEN_HEIGHT = 500; function Address ({ actions, address, children, className, genesisHash, name, parentName, suri }: Props): React.ReactElement { const { accounts } = useContext(AccountContext); + const settings = useContext(SettingsContext); const chain = useMetadata(genesisHash); const [{ account, formatted, prefix }, setRecoded] = useState({ account: null, formatted: null, prefix: 42 }); const [showActionsMenu, setShowActionsMenu] = useState(false); @@ -83,9 +83,9 @@ function Address ({ actions, address, children, className, genesisHash, name, pa useEffect((): void => { address && setRecoded( - recodeAddress(address, accounts, chain) + recodeAddress(address, accounts, chain, settings) ); - }, [accounts, address, chain]); + }, [accounts, address, chain, settings]); useEffect(() => { if (!showActionsMenu) { diff --git a/packages/extension-ui/src/components/contexts.tsx b/packages/extension-ui/src/components/contexts.tsx index 27dcca6d..1cd03638 100644 --- a/packages/extension-ui/src/components/contexts.tsx +++ b/packages/extension-ui/src/components/contexts.tsx @@ -3,9 +3,11 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { AccountsContext, AuthorizeRequest, MetadataRequest, SigningRequest } from '@polkadot/extension-base/background/types'; +import { SettingsStruct } from '@polkadot/ui-settings/types'; +import { AvailableThemes } from './themes'; import React from 'react'; -import { AvailableThemes } from '.'; +import settings from '@polkadot/ui-settings'; // eslint-disable-next-line @typescript-eslint/no-unused-vars const noop = (): void => undefined; @@ -15,6 +17,7 @@ const ActionContext = React.createContext<(to?: string) => void>(noop); const AuthorizeReqContext = React.createContext([]); const MediaContext = React.createContext(false); const MetadataReqContext = React.createContext([]); +const SettingsContext = React.createContext(settings.get()); const SigningReqContext = React.createContext([]); const ThemeSwitchContext = React.createContext<(theme: AvailableThemes) => void>(noop); const ToastContext = React.createContext<({show: (message: string) => void})>({ show: noop }); @@ -25,6 +28,7 @@ export { AuthorizeReqContext, MediaContext, MetadataReqContext, + SettingsContext, SigningReqContext, ThemeSwitchContext, ToastContext diff --git a/packages/extension-ui/src/partials/Settings.tsx b/packages/extension-ui/src/partials/Settings.tsx index 9457e57c..951d65a0 100644 --- a/packages/extension-ui/src/partials/Settings.tsx +++ b/packages/extension-ui/src/partials/Settings.tsx @@ -6,7 +6,6 @@ import { Theme, ThemeProps } from '../types'; import React, { useCallback, useContext, useState, useEffect } from 'react'; import styled, { ThemeContext } from 'styled-components'; -import { setSS58Format } from '@polkadot/util-crypto'; import settings from '@polkadot/ui-settings'; import FullScreenIcon from '../assets/fullscreen.svg'; @@ -38,18 +37,10 @@ function Settings ({ className, reference }: Props): React.ReactElement { settings.set({ camera: camera ? 'on' : 'off' }); }, [camera]); - // FIXME check against index, we need a better solution const _onChangePrefix = useCallback( (value: string): void => { - const prefix = parseInt(value, 10); - - setSS58Format(prefix); setPrefix(value); - - settings.set({ prefix }); - - // FIXME We don't want to reload here - location.reload(); + settings.set({ prefix: parseInt(value, 10) }); }, [] );