diff --git a/packages/app-settings/src/index.tsx b/packages/app-settings/src/index.tsx index fd25d30a3e..9ac9d406e2 100644 --- a/packages/app-settings/src/index.tsx +++ b/packages/app-settings/src/index.tsx @@ -18,10 +18,12 @@ import translate from './translate'; type Props = AppProps & I18nProps; -type State = SettingsStruct & { - types?: { [index: string]: any } | null, - typesError?: boolean, - typesPlaceholder?: string +type State = { + settings: SettingsStruct & { + types?: { [index: string]: any } | null, + typesError?: boolean, + typesPlaceholder?: string + } }; class App extends React.PureComponent { @@ -30,19 +32,21 @@ class App extends React.PureComponent { const types = store.get('types') || {}; const names = Object.keys(types); - const state = settings.get(); + const presets = settings.get(); this.state = { - ...state, - typesPlaceholder: names.length - ? names.join(', ') - : undefined + settings: { + ...presets, + typesPlaceholder: names.length + ? names.join(', ') + : undefined + } }; } render () { const { t } = this.props; - const { apiUrl, i18nLang, typesPlaceholder, typesError, uiMode, uiTheme } = this.state; + const { settings: { apiUrl, i18nLang, typesPlaceholder, typesError, uiMode, uiTheme } } = this.state; return (
@@ -113,7 +117,12 @@ class App extends React.PureComponent { } private onChangeApiUrl = (apiUrl: string): void => { - this.setState({ apiUrl }); + this.setState(({ settings }: State) => ({ + settings: { + ...settings, + apiUrl + } + })); } private onChangeLang = (i18nLang: string): void => { @@ -129,34 +138,50 @@ class App extends React.PureComponent { typeRegistry.register(types); - this.setState({ - types, - typesError: false, - typesPlaceholder - }); + this.setState(({ settings }: State) => ({ + settings: { + ...settings, + types, + typesError: false, + typesPlaceholder + } + })); } catch (error) { console.error('Registering types:', error); - this.setState({ - types: null, - typesError: true, - typesPlaceholder: error.message - }); + this.setState(({ settings }: State) => ({ + settings: { + ...settings, + types: null, + typesError: true, + typesPlaceholder: error.message + } + })); } } private onChangeUiMode = (uiMode: string): void => { - this.setState({ uiMode }); + this.setState(({ settings }: State) => ({ + settings: { + ...settings, + uiMode + } + })); } private onChangeUiTheme = (uiTheme: string): void => { - this.setState({ uiTheme }); + this.setState(({ settings }: State) => ({ + settings: { + ...settings, + uiTheme + } + })); } private save = (): void => { - const { types, typesError } = this.state; + const { settings: { types, typesError } } = this.state; - settings.set(this.state); + settings.set(this.state.settings); if (types && !typesError) { store.set('types', types); diff --git a/packages/app-staking/src/Overview/CurrentList.tsx b/packages/app-staking/src/Overview/CurrentList.tsx index acbd8676ea..4d30f9cde3 100644 --- a/packages/app-staking/src/Overview/CurrentList.tsx +++ b/packages/app-staking/src/Overview/CurrentList.tsx @@ -7,14 +7,18 @@ import { I18nProps } from '@polkadot/ui-app/types'; import React from 'react'; import { AccountId, Balance } from '@polkadot/types'; +import { HeaderExtended } from '@polkadot/types/Header'; +import { withCall, withMulti } from '@polkadot/ui-api/with'; import { AddressMini, AddressRow } from '@polkadot/ui-app/index'; import keyring from '@polkadot/ui-keyring'; import translate from '../translate'; +import { numberFormat } from '@polkadot/ui-reactive/util'; type Props = I18nProps & { balances: DerivedBalancesMap, balanceArray: (_address: AccountId | string) => Array | undefined, + chain_subscribeNewHead?: HeaderExtended, current: Array, next: Array }; @@ -68,7 +72,7 @@ class CurrentList extends React.PureComponent { } private renderColumn (addresses: Array, defaultName: string) { - const { balances, balanceArray, t } = this.props; + const { balances, balanceArray, chain_subscribeNewHead, t } = this.props; if (addresses.length === 0) { return ( @@ -76,6 +80,14 @@ class CurrentList extends React.PureComponent { ); } + let lastBlock: string = ''; + let lastAuthor: string; + + if (chain_subscribeNewHead) { + lastBlock = `#${numberFormat(chain_subscribeNewHead.blockNumber)}`; + lastAuthor = (chain_subscribeNewHead.author || '').toString(); + } + return (
{addresses.map((address) => { @@ -100,6 +112,12 @@ class CurrentList extends React.PureComponent { withCopy={false} withNonce={false} /> +
+ {lastAuthor === address ? lastBlock : ''} +
); })} @@ -108,4 +126,8 @@ class CurrentList extends React.PureComponent { } } -export default translate(CurrentList); +export default withMulti( + CurrentList, + translate, + withCall('derive.chain.subscribeNewHead') +); diff --git a/packages/app-staking/src/Overview/index.css b/packages/app-staking/src/Overview/index.css index a41ba2928c..8b27dcc8ef 100644 --- a/packages/app-staking/src/Overview/index.css +++ b/packages/app-staking/src/Overview/index.css @@ -52,6 +52,30 @@ .validator--IntensionsList, .validator--ValidatorsList { display: flex; + + article.ui--hoverable { + position: relative; + + .blockNumber { + font-size: 1.5rem; + font-weight: 100; + height: 0; + line-height: 1.5rem; + right: 1.5rem; + opacity: 0; + position: absolute; + top: 1rem; + transform: scale(0); + transition: all 0.25s ease-in; + vertical-align: middle; + + &.latest { + height: auto; + opacity: 1; + transform: scale(1); + } + } + } } .validator--current,