From 639e9a3d3cdb82dcd0c260fa879deaecae95f81c Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Fri, 30 Jul 2021 12:00:31 +0800 Subject: [PATCH 01/60] fix: enhance tab list on the profile page --- .../twitter.com/injection/EnhancedProfile.tsx | 118 ++++++++++++++++++ .../twitter.com/ui-provider.ts | 2 + .../twitter.com/utils/selector.ts | 18 +++ packages/maskbook/src/social-network/types.ts | 2 + 4 files changed, 140 insertions(+) create mode 100644 packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx new file mode 100644 index 000000000000..07e297e17e67 --- /dev/null +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -0,0 +1,118 @@ +import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' +import { makeStyles } from '@material-ui/core' +import { useCallback, useState } from 'react' +import { createReactRootShadowed, startWatch } from '../../../utils' +import { + searchProfileActiveTabLabelSelector, + searchProfileActiveTabSelector, + searchProfileActiveTabStatusLineSelector, + searchProfileEmptySelector, + searchProfileTabListSelector, + searchProfileTabPageSelector, +} from '../utils/selector' + +function injectEnhancedProfileTab(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileTabListSelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +function injectEnhancedProfilePageState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} +export function injectEnhancedProfile(signal: AbortSignal) { + injectEnhancedProfileTab(signal) + injectEnhancedProfilePageForEmptyState(signal) + injectEnhancedProfilePageState(signal) +} + +const useEnhancedProfileStyles = makeStyles((theme) => ({ + tab: { + '&:hover': { + backgroundColor: 'rgba(29, 161, 242, 0.1)', + cursor: 'pointer', + }, + }, + button: { + display: 'flex', + minWidth: 56, + justifyContent: 'center', + alignItems: 'center', + textAlign: 'center', + padding: theme.spacing(2), + fontWeight: 700, + color: 'rgb(83, 100, 113)', + }, + active: { + dispaly: 'inline-flex', + borderRadius: 99999, + position: 'absolute', + bottom: 0, + minWidth: 56, + alignSelf: 'center', + height: 4, + backgroundColor: 'rgb(29, 161, 242)', + }, +})) +export interface EnhancedProfileTabProps {} + +export function EnhancedProfileTab(props: EnhancedProfileTabProps) { + const classes = useEnhancedProfileStyles() + const [active, setActive] = useState(false) + const onClick = useCallback(() => { + const eleEmpty = searchProfileEmptySelector().evaluate() + if (eleEmpty) eleEmpty.style.display = 'none' + + const ele = searchProfileTabPageSelector().evaluate() + if (ele) ele.style.display = 'none' + + const line = searchProfileActiveTabStatusLineSelector().evaluate() + if (line) line.style.display = 'none' + + const label = searchProfileActiveTabLabelSelector().evaluate() + if (label) label.style.color = 'rgb(83, 100, 113)' + + const tab = searchProfileActiveTabSelector().evaluate() + if (tab) { + tab.addEventListener( + 'click', + () => { + if (eleEmpty) eleEmpty.style.display = 'flex' + if (ele) ele.style.display = 'flex' + if (line) line.style.display = 'inline-flex' + if (label) label.style.color = 'unset' + + setActive(false) + }, + { once: true }, + ) + } + console.log(tab) + + setActive(true) + }, [active]) + return ( + <> +
+
+ NFTs + {active ?
: null} +
+
+ + ) +} + +export interface EnhancedProfilePageProps {} + +export function EnhancedProfileaPage(props: EnhancedProfilePageProps) { + return
NFTs Image List
+} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts index 29e70f34f217..3a6999996bd1 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts @@ -29,6 +29,7 @@ import { currentSelectedIdentity } from '../../settings/settings' import { injectPostInspectorAtTwitter } from './injection/PostInspector' import { ProfileIdentifier } from '../../database/type' import { unreachable } from '@dimensiondev/kit' +import { injectEnhancedProfile } from './injection/EnhancedProfile' const twitterUI: SocialNetworkUI.Definition = { ...twitterBase, @@ -77,6 +78,7 @@ const twitterUI: SocialNetworkUI.Definition = { pageInspector: injectPageInspectorDefault(), postInspector: injectPostInspectorAtTwitter, setupPrompt: injectSetupPromptAtTwitter, + enhancedProfile: injectEnhancedProfile, newPostComposition: { start: injectPostBoxComposed, supportedInputTypes: { diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts index 17e03bfc2dee..bc34ec565202 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts @@ -15,6 +15,24 @@ const querySelectorAll = (selector: string) => { return new LiveSelector().querySelectorAll(selector) } +//#region "Enhanced Profile" +export const searchProfileSelector: () => LiveSelector = () => + querySelector('[aria-label="Profile timelines"][role="navigation"]') +export const searchProfileTabListSelector: () => LiveSelector = () => + querySelector('[role="tablist"][data-testid="ScrollSnap-List"] > :last-child') +export const searchProfileTabPageSelector: () => LiveSelector = () => + querySelector('[data-testid="primaryColumn"] [role="region"] [aria-label]') +export const searchProfileEmptySelector: () => LiveSelector = () => + querySelector('[data-testid="primaryColumn"] [data-testid="emptyState"]') +export const searchProfileActiveTabSelector: () => LiveSelector = () => + querySelector('[role="tablist"] [role="tab"][aria-selected="true"]') +export const searchProfileActiveTabStatusLineSelector: () => LiveSelector = () => + querySelector('[role="tablist"] [role="tab"][aria-selected="true"] > div > div') +export const searchProfileActiveTabLabelSelector: () => LiveSelector = () => + querySelector('[role="tablist"] [role="tab"][aria-selected="true"] > div') + +//#endregion + export const rootSelector: () => LiveSelector = () => querySelector('#react-root') export const composeAnchorSelector: () => LiveSelector = () => diff --git a/packages/maskbook/src/social-network/types.ts b/packages/maskbook/src/social-network/types.ts index 74cd6a4338ac..ca8889919ac6 100644 --- a/packages/maskbook/src/social-network/types.ts +++ b/packages/maskbook/src/social-network/types.ts @@ -123,6 +123,8 @@ export namespace SocialNetworkUI { /** Inject UI to the search result */ searchResult?(signal: AbortSignal): void setupWizard?(signal: AbortSignal, for_: PersonaIdentifier): void + + enhancedProfile?(signal: AbortSignal): void } export interface NewPostComposition { start(signal: AbortSignal): void From fab30d4c6d0b871e25349fe9df698540f9564f0b Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Fri, 30 Jul 2021 12:18:12 +0800 Subject: [PATCH 02/60] fix: recover file --- packages/maskbook/src/social-network/ui.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/maskbook/src/social-network/ui.ts b/packages/maskbook/src/social-network/ui.ts index 1750694ef481..bee3de6f4b9c 100644 --- a/packages/maskbook/src/social-network/ui.ts +++ b/packages/maskbook/src/social-network/ui.ts @@ -80,6 +80,7 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI. ui.injection.userBadge?.(signal) setTimeout(activateSNSAdaptorPluginOnStart, 1000) + ui.injection.enhancedProfile?.(signal) startPluginSNSAdaptor(getCurrentSNSNetwork(ui.networkIdentifier), createPluginHost(signal)) From 799d433d215db225ee7503d1868645499f2b68da Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Fri, 30 Jul 2021 13:11:04 +0800 Subject: [PATCH 03/60] fix: tab list style --- .../twitter.com/injection/EnhancedProfile.tsx | 20 +++++++++++++++---- .../twitter.com/utils/selector.ts | 5 +++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 07e297e17e67..af058616aea2 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -1,5 +1,6 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' import { makeStyles } from '@material-ui/core' +import classNames from 'classnames' import { useCallback, useState } from 'react' import { createReactRootShadowed, startWatch } from '../../../utils' import { @@ -7,12 +8,13 @@ import { searchProfileActiveTabSelector, searchProfileActiveTabStatusLineSelector, searchProfileEmptySelector, + searchProfileTabListLastChildSelector, searchProfileTabListSelector, searchProfileTabPageSelector, } from '../utils/selector' function injectEnhancedProfileTab(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileTabListSelector()) + const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) startWatch(watcher, signal) createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() } @@ -51,6 +53,9 @@ const useEnhancedProfileStyles = makeStyles((theme) => ({ fontWeight: 700, color: 'rgb(83, 100, 113)', }, + hot: { + color: 'rgb(29, 161, 242)', + }, active: { dispaly: 'inline-flex', borderRadius: 99999, @@ -67,6 +72,13 @@ export interface EnhancedProfileTabProps {} export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const classes = useEnhancedProfileStyles() const [active, setActive] = useState(false) + + const onOpen = () => setActive(false) + const tabList = searchProfileTabListSelector().evaluate()?.querySelectorAll('div') + tabList?.forEach((v, i) => { + v.addEventListener('click', onOpen, { once: true }) + }) + const onClick = useCallback(() => { const eleEmpty = searchProfileEmptySelector().evaluate() if (eleEmpty) eleEmpty.style.display = 'none' @@ -88,21 +100,21 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { if (eleEmpty) eleEmpty.style.display = 'flex' if (ele) ele.style.display = 'flex' if (line) line.style.display = 'inline-flex' - if (label) label.style.color = 'unset' + if (label) label.style.color = '' setActive(false) + console.log('tab') }, { once: true }, ) } - console.log(tab) setActive(true) }, [active]) return ( <>
-
+
NFTs {active ?
: null}
diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts index bc34ec565202..aa6044d19d95 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts @@ -18,7 +18,7 @@ const querySelectorAll = (selector: string) => { //#region "Enhanced Profile" export const searchProfileSelector: () => LiveSelector = () => querySelector('[aria-label="Profile timelines"][role="navigation"]') -export const searchProfileTabListSelector: () => LiveSelector = () => +export const searchProfileTabListLastChildSelector: () => LiveSelector = () => querySelector('[role="tablist"][data-testid="ScrollSnap-List"] > :last-child') export const searchProfileTabPageSelector: () => LiveSelector = () => querySelector('[data-testid="primaryColumn"] [role="region"] [aria-label]') @@ -30,7 +30,8 @@ export const searchProfileActiveTabStatusLineSelector: () => LiveSelector('[role="tablist"] [role="tab"][aria-selected="true"] > div > div') export const searchProfileActiveTabLabelSelector: () => LiveSelector = () => querySelector('[role="tablist"] [role="tab"][aria-selected="true"] > div') - +export const searchProfileTabListSelector: () => LiveSelector = () => + querySelector('[role="tablist"][data-testid="ScrollSnap-List"]') //#endregion export const rootSelector: () => LiveSelector = () => querySelector('#react-root') From 7d361a4b70ff9f30b5edf2b3c5fc38088af9ce15 Mon Sep 17 00:00:00 2001 From: unclebill Date: Fri, 30 Jul 2021 16:45:37 +0800 Subject: [PATCH 04/60] feat: add collective list --- .../CollectibleList/CollectibleCard.tsx | 5 +-- .../CollectibleList/index.tsx | 34 +++++++++++-------- .../twitter.com/injection/EnhancedProfile.tsx | 8 ++++- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx index 3cc02e9a35d4..98fa0903eb9e 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx @@ -38,17 +38,18 @@ export interface CollectibleCardProps { provider: CollectibleProvider wallet: Wallet token: ERC721TokenAssetDetailed | ERC1155TokenAssetDetailed + readonly?: boolean } export function CollectibleCard(props: CollectibleCardProps) { - const { wallet, token, provider } = props + const { wallet, token, provider, readonly } = props const classes = useStyles(props) const chainId = useChainId() return ( - + {readonly ? null : } {token.asset?.image ? ( ({ export interface CollectibleListProps { wallet: Wallet + owner?: string + readonly?: boolean } -export function CollectibleList(props: CollectibleListProps) { - const { wallet } = props +export function CollectibleList({ wallet, owner, readonly }: CollectibleListProps) { const { t } = useI18N() const classes = useStyles() - const account = useAccount() + const defaultAcount = useAccount() + const account = owner ?? defaultAcount const [page, setPage] = useState(0) const provider = useValueRef(currentCollectibleDataProviderSettings) @@ -90,17 +92,19 @@ export function CollectibleList(props: CollectibleListProps) { ) - const dataSource = collectibles.filter((x) => { - const key = `${formatEthereumAddress(x.address)}_${x.tokenId}` - switch (x.type) { - case EthereumTokenType.ERC721: - return wallet.erc721_token_blacklist ? !wallet.erc721_token_blacklist.has(key) : true - case EthereumTokenType.ERC1155: - return wallet.erc1155_token_blacklist ? !wallet.erc1155_token_blacklist.has(key) : true - default: - return false - } - }) + const dataSource = owner + ? collectibles + : collectibles.filter((x) => { + const key = `${formatEthereumAddress(x.address)}_${x.tokenId}` + switch (x.type) { + case EthereumTokenType.ERC721: + return wallet.erc721_token_blacklist ? !wallet.erc721_token_blacklist.has(key) : true + case EthereumTokenType.ERC1155: + return wallet.erc1155_token_blacklist ? !wallet.erc1155_token_blacklist.has(key) : true + default: + return false + } + }) return ( @@ -128,7 +132,7 @@ export function CollectibleList(props: CollectibleListProps) { {dataSource.map((x) => (
- +
{x.asset?.name ?? x.name} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index af058616aea2..57f6c573c2f9 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -2,7 +2,9 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' import { makeStyles } from '@material-ui/core' import classNames from 'classnames' import { useCallback, useState } from 'react' +import { useWallet } from '@masknet/web3-shared' import { createReactRootShadowed, startWatch } from '../../../utils' +import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' import { searchProfileActiveTabLabelSelector, searchProfileActiveTabSelector, @@ -126,5 +128,9 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { export interface EnhancedProfilePageProps {} export function EnhancedProfileaPage(props: EnhancedProfilePageProps) { - return
NFTs Image List
+ const selectedWallet = useWallet() + if (!selectedWallet) { + return null + } + return } From c3639e7bccb490d66568c9dfb106b2107dc7da4c Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Fri, 30 Jul 2021 18:56:55 +0800 Subject: [PATCH 05/60] fix: tab style --- packages/maskbook/package.json | 1 + .../twitter.com/injection/EnhancedProfile.tsx | 50 +++- .../twitter.com/utils/selector.ts | 4 + pnpm-lock.yaml | 256 +++++++++++------- 4 files changed, 194 insertions(+), 117 deletions(-) diff --git a/packages/maskbook/package.json b/packages/maskbook/package.json index 61c024815346..f9c602775d01 100644 --- a/packages/maskbook/package.json +++ b/packages/maskbook/package.json @@ -65,6 +65,7 @@ "buffer": "^6.0.3", "classnames": "^2.3.1", "clipboard-polyfill": "^3.0.3", + "color": "^4.0.0", "crypto-browserify": "^3.12.0", "d3": "^5.16.0", "date-fns": "^2.23.0", diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 57f6c573c2f9..1a8d07609f39 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -1,11 +1,13 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { makeStyles } from '@material-ui/core' +import { MaskColorVar } from '@masknet/theme' +import { useWallet } from '@masknet/web3-shared' +import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' import { useCallback, useState } from 'react' -import { useWallet } from '@masknet/web3-shared' -import { createReactRootShadowed, startWatch } from '../../../utils' import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' +import { createReactRootShadowed, startWatch } from '../../../utils' import { + searchForegroundColorSelector, searchProfileActiveTabLabelSelector, searchProfileActiveTabSelector, searchProfileActiveTabStatusLineSelector, @@ -13,7 +15,9 @@ import { searchProfileTabListLastChildSelector, searchProfileTabListSelector, searchProfileTabPageSelector, + searchProfileTabSelector, } from '../utils/selector' +import Color from 'color' function injectEnhancedProfileTab(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) @@ -38,10 +42,13 @@ export function injectEnhancedProfile(signal: AbortSignal) { injectEnhancedProfilePageState(signal) } -const useEnhancedProfileStyles = makeStyles((theme) => ({ +const useEnhancedProfileStyles = makeStyles< + Theme, + { color: string; font: string; fontSize: string; padding: string; activeColor: string } +>((theme) => ({ tab: { '&:hover': { - backgroundColor: 'rgba(29, 161, 242, 0.1)', + backgroundColor: (props) => new Color(props.activeColor).alpha(0.1).toString(), cursor: 'pointer', }, }, @@ -51,12 +58,17 @@ const useEnhancedProfileStyles = makeStyles((theme) => ({ justifyContent: 'center', alignItems: 'center', textAlign: 'center', - padding: theme.spacing(2), + padding: (props) => props.padding, fontWeight: 700, - color: 'rgb(83, 100, 113)', + color: (props) => props.color, + font: (props) => props.font, + fontSize: (props) => props.fontSize, + '&:hover': { + color: (props) => props.activeColor, + }, }, hot: { - color: 'rgb(29, 161, 242)', + color: (props) => props.activeColor, }, active: { dispaly: 'inline-flex', @@ -66,13 +78,23 @@ const useEnhancedProfileStyles = makeStyles((theme) => ({ minWidth: 56, alignSelf: 'center', height: 4, - backgroundColor: 'rgb(29, 161, 242)', + backgroundColor: (props) => props.activeColor, }, })) export interface EnhancedProfileTabProps {} export function EnhancedProfileTab(props: EnhancedProfileTabProps) { - const classes = useEnhancedProfileStyles() + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + const style = window.getComputedStyle(eleTab) + const eleForegroundColorStyle = searchForegroundColorSelector().evaluate() + const foregroundColorStyle = window.getComputedStyle(eleForegroundColorStyle as Element) + const classes = useEnhancedProfileStyles({ + color: style.color, + font: style.font, + fontSize: style.fontSize, + padding: style.paddingBottom, + activeColor: foregroundColorStyle.borderColor, + }) const [active, setActive] = useState(false) const onOpen = () => setActive(false) @@ -82,6 +104,9 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { }) const onClick = useCallback(() => { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + const style = window.getComputedStyle(eleTab) + const eleEmpty = searchProfileEmptySelector().evaluate() if (eleEmpty) eleEmpty.style.display = 'none' @@ -92,10 +117,11 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { if (line) line.style.display = 'none' const label = searchProfileActiveTabLabelSelector().evaluate() - if (label) label.style.color = 'rgb(83, 100, 113)' + if (label) label.style.color = style.color const tab = searchProfileActiveTabSelector().evaluate() if (tab) { + tab.setAttribute('aria-selected', 'false') tab.addEventListener( 'click', () => { @@ -105,7 +131,7 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { if (label) label.style.color = '' setActive(false) - console.log('tab') + tab.setAttribute('aria-selected', 'true') }, { once: true }, ) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts index aa6044d19d95..15e3c06f929f 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts @@ -26,12 +26,16 @@ export const searchProfileEmptySelector: () => LiveSelector = () => querySelector('[data-testid="primaryColumn"] [data-testid="emptyState"]') export const searchProfileActiveTabSelector: () => LiveSelector = () => querySelector('[role="tablist"] [role="tab"][aria-selected="true"]') +export const searchProfileTabSelector: () => LiveSelector = () => + querySelector('[role="tablist"] [role="tab"][aria-selected="false"]') export const searchProfileActiveTabStatusLineSelector: () => LiveSelector = () => querySelector('[role="tablist"] [role="tab"][aria-selected="true"] > div > div') export const searchProfileActiveTabLabelSelector: () => LiveSelector = () => querySelector('[role="tablist"] [role="tab"][aria-selected="true"] > div') export const searchProfileTabListSelector: () => LiveSelector = () => querySelector('[role="tablist"][data-testid="ScrollSnap-List"]') +export const searchForegroundColorSelector: () => LiveSelector = () => + querySelector('[data-testid="primaryColumn"] [href="/i/flow/setup_profile"][role="link"]') //#endregion export const rootSelector: () => LiveSelector = () => querySelector('#react-root') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c98d8471db8d..68294a82e4d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -278,6 +278,7 @@ importers: chrome-launcher: ^0.14.0 classnames: ^2.3.1 clipboard-polyfill: ^3.0.3 + color: ^4.0.0 copy-webpack-plugin: ^9.0.1 crypto-browserify: ^3.12.0 d3: ^5.16.0 @@ -423,6 +424,7 @@ importers: buffer: 6.0.3 classnames: 2.3.1 clipboard-polyfill: 3.0.3 + color: 4.0.0 crypto-browserify: 3.12.0 d3: 5.16.0 date-fns: 2.23.0 @@ -448,14 +450,14 @@ importers: pvtsutils: 1.1.7 qrcode: 1.4.4 react-draggable: 4.4.3 - react-feather: 2.0.9_react@18.0.0-alpha-aecb3b6d1 - react-highlight-words: 0.17.0_react@18.0.0-alpha-aecb3b6d1 - react-middle-ellipsis: 1.2.1_f991c289939c8299bed5e4a6a5a79a62 - react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 - react-router-dom: 5.2.0_react@18.0.0-alpha-aecb3b6d1 - react-use: 17.2.4_f991c289939c8299bed5e4a6a5a79a62 - react-virtualized-auto-sizer: 1.0.5_f991c289939c8299bed5e4a6a5a79a62 - react-window: 1.8.6_f991c289939c8299bed5e4a6a5a79a62 + react-feather: 2.0.9 + react-highlight-words: 0.17.0 + react-middle-ellipsis: 1.2.1 + react-router: 5.2.0 + react-router-dom: 5.2.0 + react-use: 17.2.4 + react-virtualized-auto-sizer: 1.0.5 + react-window: 1.8.6 remarkable: 2.0.1 scrypt-js: 3.0.1 socket.io-client: 2.4.0 @@ -480,11 +482,11 @@ importers: webextension-polyfill: 0.8.0 z-schema: 5.0.1 devDependencies: - '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d_typescript@4.3.5 + '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d '@pmmmwh/react-refresh-webpack-plugin': 0.5.0-rc.2_0cb17a392999b7da0b5f4263f37b1695 '@sinonjs/text-encoding': 0.7.1 '@swc/core': 1.2.66 - '@testing-library/react-hooks': 7.0.1_1959de3a9153879cff3acd96b46ed70f + '@testing-library/react-hooks': 7.0.1_react-test-renderer@17.0.2 '@types/enzyme': 3.10.9 '@types/enzyme-adapter-react-16': 1.0.6 '@types/expect-puppeteer': 4.4.6 @@ -495,19 +497,19 @@ importers: '@types/rimraf': 3.0.1 '@types/socket.io-client': 1.4.36 '@types/webpack-dev-server': 3.11.5 - '@typescript-eslint/eslint-plugin': 4.28.5_514553717ff968e20f6d1c6e521f8616 - '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 + '@typescript-eslint/eslint-plugin': 4.28.5_@typescript-eslint+parser@4.28.5 + '@typescript-eslint/parser': 4.28.5 babel-loader: 8.2.2_webpack@5.46.0 chrome-launcher: 0.14.0 copy-webpack-plugin: 9.0.1_webpack@5.46.0 dotenv: 10.0.0 enzyme: 3.11.0 - enzyme-adapter-react-16: 1.15.6_f15f970d9b179e8975516dda0497bdea + enzyme-adapter-react-16: 1.15.6_enzyme@3.11.0 expect-puppeteer: 5.0.4 fake-indexeddb: 3.1.3 file-loader: 6.2.0_webpack@5.46.0 html-webpack-plugin: 5.3.2_webpack@5.46.0 - jest: 27.0.6_ts-node@10.1.0 + jest: 27.0.6 jest-environment-jsdom-fourteen: 1.0.1 jest-esm-transformer: 1.0.0 jest-junit: 12.2.0 @@ -516,12 +518,12 @@ importers: openzeppelin-solidity: 3.4.1 react-devtools-core: 4.14.0 react-refresh: 0.10.0 - react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 + react-test-renderer: 17.0.2 rimraf: 3.0.2 source-map-loader: 3.0.0_webpack@5.46.0 swc-loader: 0.1.14_webpack@5.46.0 - ts-jest: 27.0.4_52cc4273aa16028085013af47e479e10 - type-coverage: 2.18.0_typescript@4.3.5 + ts-jest: 27.0.4_@types+jest@26.0.24+jest@27.0.6 + type-coverage: 2.18.0 webpack: 5.46.0_webpack-cli@4.7.2 webpack-cli: 4.7.2_d46d1c9a5e33a01c3500802a2e542ae0 webpack-dev-server: 3.11.2_webpack-cli@4.7.2+webpack@5.46.0 @@ -774,7 +776,7 @@ packages: bintrees: 1.0.2 bn.js: 4.12.0 compare-versions: 3.6.0 - ethereumjs-abi: 0.6.8 + ethereumjs-abi: 0.6.6 ethereumjs-blockstream: 2.0.7 ethereumjs-util: 5.2.1 find-versions: 2.0.0 @@ -3467,7 +3469,7 @@ packages: meow: 7.1.1 dev: false - /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d_typescript@4.3.5: + /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d: resolution: {integrity: sha512-0O0Nc3j2Vxo9Gfvgeq8pWuMHKMSU3tDjRnzE0U5oWvYoY+ZO61NniKp4xf/C+J6Py6lhQFutjd2tqlporqRwlw==, tarball: download/@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d/a2ee1bed40822a7f6b9c60ce4296930c9bab00828e82637aa56060498a135ac7} hasBin: true peerDependencies: @@ -3476,7 +3478,6 @@ packages: async-call-rpc: 4.2.1 buffer: 6.0.3 systemjs: 6.3.2 - typescript: 4.3.5 web-ext-types: 3.2.1 dev: true @@ -4151,7 +4152,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core/27.0.6_ts-node@10.1.0: + /@jest/core/27.0.6: resolution: {integrity: sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -4172,7 +4173,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.6 jest-changed-files: 27.0.6 - jest-config: 27.0.6_ts-node@10.1.0 + jest-config: 27.0.6 jest-haste-map: 27.0.6 jest-message-util: 27.0.6 jest-regex-util: 27.0.6 @@ -6901,7 +6902,7 @@ packages: defer-to-connect: 2.0.1 dev: true - /@testing-library/react-hooks/7.0.1_1959de3a9153879cff3acd96b46ed70f: + /@testing-library/react-hooks/7.0.1_react-test-renderer@17.0.2: resolution: {integrity: sha512-bpEQ2SHSBSzBmfJ437NmnP+oArQ7aVmmULiAp6Ag2rtyLBLPNFSMmgltUbFGmQOJdPWo4Ub31kpUC5T46zXNwQ==} engines: {node: '>=12'} peerDependencies: @@ -6918,10 +6919,8 @@ packages: '@types/react': 17.0.15 '@types/react-dom': 17.0.9 '@types/react-test-renderer': 17.0.1 - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 - react-error-boundary: 3.1.3_react@18.0.0-alpha-aecb3b6d1 - react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 + react-error-boundary: 3.1.3 + react-test-renderer: 17.0.2 dev: true /@tootallnate/once/1.1.2: @@ -7548,6 +7547,10 @@ packages: /@types/node/16.4.3: resolution: {integrity: sha512-GKM4FLMkWDc0sfx7tXqPWkM6NBow1kge0fgQh0bOnlqo4iT1kvTvMEKE0c1RtUGnbLlGRXiAA8SumE//90uKAg==} + /@types/node/16.4.7: + resolution: {integrity: sha512-aDDY54sst8sx47CWT6QQqIZp45yURq4dic0+HCYfYNcY5Ejlb/CLmFnRLfy3wQuYafOeh3lB/DAKaqRKBtcZmA==} + dev: false + /@types/node/8.10.66: resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} dev: false @@ -7887,7 +7890,7 @@ packages: '@types/yargs-parser': 20.2.1 dev: true - /@typescript-eslint/eslint-plugin/4.28.5_514553717ff968e20f6d1c6e521f8616: + /@typescript-eslint/eslint-plugin/4.28.5_@typescript-eslint+parser@4.28.5: resolution: {integrity: sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7898,21 +7901,19 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.28.5_eslint@7.31.0+typescript@4.3.5 - '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 + '@typescript-eslint/experimental-utils': 4.28.5 + '@typescript-eslint/parser': 4.28.5 '@typescript-eslint/scope-manager': 4.28.5 debug: 4.3.2 - eslint: 7.31.0 functional-red-black-tree: 1.0.1 regexpp: 3.2.0 semver: 7.3.5 - tsutils: 3.21.0_typescript@4.3.5 - typescript: 4.3.5 + tsutils: 3.21.0 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils/4.28.5_eslint@7.31.0+typescript@4.3.5: + /@typescript-eslint/experimental-utils/4.28.5: resolution: {integrity: sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7921,16 +7922,15 @@ packages: '@types/json-schema': 7.0.8 '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 - eslint: 7.31.0 + '@typescript-eslint/typescript-estree': 4.28.5 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@7.31.0 + eslint-utils: 3.0.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/4.28.5_eslint@7.31.0+typescript@4.3.5: + /@typescript-eslint/parser/4.28.5: resolution: {integrity: sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7942,10 +7942,8 @@ packages: dependencies: '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 + '@typescript-eslint/typescript-estree': 4.28.5 debug: 4.3.2 - eslint: 7.31.0 - typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true @@ -7963,7 +7961,7 @@ packages: engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} dev: true - /@typescript-eslint/typescript-estree/4.28.5_typescript@4.3.5: + /@typescript-eslint/typescript-estree/4.28.5: resolution: {integrity: sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7978,8 +7976,7 @@ packages: globby: 11.0.4 is-glob: 4.0.1 semver: 7.3.5 - tsutils: 3.21.0_typescript@4.3.5 - typescript: 4.3.5 + tsutils: 3.21.0 transitivePeerDependencies: - supports-color dev: true @@ -8534,7 +8531,7 @@ packages: symbol.prototype.description: 1.0.4 dev: true - /airbnb-prop-types/2.16.0_react@18.0.0-alpha-aecb3b6d1: + /airbnb-prop-types/2.16.0: resolution: {integrity: sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==} peerDependencies: react: ^0.14 || ^15.0.0 || ^16.0.0-alpha @@ -8547,7 +8544,6 @@ packages: object.entries: 1.1.4 prop-types: 15.7.2 prop-types-exact: 1.2.0 - react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 dev: true @@ -10964,6 +10960,13 @@ packages: color-string: 1.6.0 dev: false + /color/4.0.0: + resolution: {integrity: sha512-aVUOa5aYWJSimvei14J5rdxLeljG0EB/uXTovVaaSokW+D4MsAz3MrKsRNaKqPa2KL7Wfvh7PZyIIaaX4lYdzQ==} + dependencies: + color-convert: 2.0.1 + color-string: 1.6.0 + dev: false + /colorette/1.2.2: resolution: {integrity: sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==} dev: true @@ -12525,7 +12528,7 @@ packages: hasBin: true dev: true - /enzyme-adapter-react-16/1.15.6_f15f970d9b179e8975516dda0497bdea: + /enzyme-adapter-react-16/1.15.6_enzyme@3.11.0: resolution: {integrity: sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==} peerDependencies: enzyme: ^3.0.0 @@ -12533,31 +12536,28 @@ packages: react-dom: ^16.0.0-0 dependencies: enzyme: 3.11.0 - enzyme-adapter-utils: 1.14.0_react@18.0.0-alpha-aecb3b6d1 + enzyme-adapter-utils: 1.14.0 enzyme-shallow-equal: 1.0.4 has: 1.0.3 object.assign: 4.1.2 object.values: 1.1.4 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 - react-test-renderer: 16.14.0_react@18.0.0-alpha-aecb3b6d1 + react-test-renderer: 16.14.0 semver: 5.7.1 dev: true - /enzyme-adapter-utils/1.14.0_react@18.0.0-alpha-aecb3b6d1: + /enzyme-adapter-utils/1.14.0: resolution: {integrity: sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==} peerDependencies: react: 0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0 dependencies: - airbnb-prop-types: 2.16.0_react@18.0.0-alpha-aecb3b6d1 + airbnb-prop-types: 2.16.0 function.prototype.name: 1.1.4 has: 1.0.3 object.assign: 4.1.2 object.fromentries: 2.0.4 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 semver: 5.7.1 dev: true @@ -13029,13 +13029,12 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils/3.0.0_eslint@7.31.0: + /eslint-utils/3.0.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 7.31.0 eslint-visitor-keys: 2.1.0 dev: true @@ -13265,11 +13264,11 @@ packages: setimmediate: 1.0.5 dev: false - /ethereumjs-abi/0.6.8: - resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} + /ethereumjs-abi/0.6.6: + resolution: {integrity: sha512-w8KubDsA/+OAuqtIR9RGsMcoZ5nhM8vxwjJAJvEIY+clhxA3BHoLG3+ClYQaQhD0n3mlDt3U5rBrmSVJvI3c8A==} dependencies: bn.js: 4.12.0 - ethereumjs-util: 6.2.1 + ethereumjs-util: 5.2.1 dev: false /ethereumjs-account/2.0.5: @@ -16201,7 +16200,7 @@ packages: - supports-color dev: true - /jest-cli/27.0.6_ts-node@10.1.0: + /jest-cli/27.0.6: resolution: {integrity: sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -16211,14 +16210,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6_ts-node@10.1.0 + '@jest/core': 27.0.6 '@jest/test-result': 27.0.6 '@jest/types': 27.0.6 chalk: 4.1.1 exit: 0.1.2 graceful-fs: 4.2.6 import-local: 3.0.2 - jest-config: 27.0.6_ts-node@10.1.0 + jest-config: 27.0.6 jest-util: 27.0.6 jest-validate: 27.0.6 prompts: 2.4.1 @@ -16231,7 +16230,7 @@ packages: - utf-8-validate dev: true - /jest-config/27.0.6_ts-node@10.1.0: + /jest-config/27.0.6: resolution: {integrity: sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -16261,7 +16260,6 @@ packages: jest-validate: 27.0.6 micromatch: 4.0.4 pretty-format: 27.0.6 - ts-node: 10.1.0_typescript@4.3.5 transitivePeerDependencies: - bufferutil - canvas @@ -16872,7 +16870,7 @@ packages: supports-color: 8.1.1 dev: true - /jest/27.0.6_ts-node@10.1.0: + /jest/27.0.6: resolution: {integrity: sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -16882,9 +16880,9 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6_ts-node@10.1.0 + '@jest/core': 27.0.6 import-local: 3.0.2 - jest-cli: 27.0.6_ts-node@10.1.0 + jest-cli: 27.0.6 transitivePeerDependencies: - bufferutil - canvas @@ -18254,7 +18252,7 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - /mini-create-react-context/0.4.1_d2630f1b5c5d613d08a8af07021f9fe5: + /mini-create-react-context/0.4.1_prop-types@15.7.2: resolution: {integrity: sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==} peerDependencies: prop-types: ^15.0.0 @@ -18262,7 +18260,6 @@ packages: dependencies: '@babel/runtime': 7.14.8 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 tiny-warning: 1.0.3 dev: false @@ -18573,6 +18570,22 @@ packages: /nan/2.14.2: resolution: {integrity: sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==} + /nano-css/5.3.1: + resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + css-tree: 1.1.3 + csstype: 3.0.8 + fastest-stable-stringify: 2.0.2 + inline-style-prefixer: 6.0.0 + rtl-css-js: 1.14.1 + sourcemap-codec: 1.4.8 + stacktrace-js: 2.0.2 + stylis: 4.0.10 + dev: false + /nano-css/5.3.1_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} peerDependencies: @@ -20479,14 +20492,13 @@ packages: react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: true - /react-error-boundary/3.1.3_react@18.0.0-alpha-aecb3b6d1: + /react-error-boundary/3.1.3: resolution: {integrity: sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==} engines: {node: '>=10', npm: '>=6'} peerDependencies: react: '>=16.13.1' dependencies: '@babel/runtime': 7.14.8 - react: 18.0.0-alpha-aecb3b6d1 dev: true /react-error-overlay/6.0.9: @@ -20497,13 +20509,12 @@ packages: resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==} dev: true - /react-feather/2.0.9_react@18.0.0-alpha-aecb3b6d1: + /react-feather/2.0.9: resolution: {integrity: sha512-yMfCGRkZdXwIs23Zw/zIWCJO3m3tlaUvtHiXlW+3FH7cIT6fiK1iJ7RJWugXq7Fso8ZaQyUm92/GOOHXvkiVUw==} peerDependencies: react: ^16.8.6 || ^17 dependencies: prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 dev: false /react-helmet-async/1.0.9_f991c289939c8299bed5e4a6a5a79a62: @@ -20521,7 +20532,7 @@ packages: shallowequal: 1.1.0 dev: true - /react-highlight-words/0.17.0_react@18.0.0-alpha-aecb3b6d1: + /react-highlight-words/0.17.0: resolution: {integrity: sha512-uX1Qh5IGjnLuJT0Zok234QDwRC8h4hcVMnB99Cb7aquB1NlPPDiWKm0XpSZOTdSactvnClCk8LOmVlP+75dgHA==} peerDependencies: react: ^0.14.0 || ^15.0.0 || ^16.0.0-0 || ^17.0.0-0 @@ -20529,7 +20540,6 @@ packages: highlight-words-core: 1.2.2 memoize-one: 4.0.3 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 dev: false /react-hook-form/7.12.0_react@18.0.0-alpha-aecb3b6d1: @@ -20573,15 +20583,12 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: true - /react-middle-ellipsis/1.2.1_f991c289939c8299bed5e4a6a5a79a62: + /react-middle-ellipsis/1.2.1: resolution: {integrity: sha512-BUQWVXIWwkY7qBqZx0qyeCnPIh188t0lLS0ftfBsU41HB6k769HyBwE23eP+qNXr4vEnmKTEmlicrypVdWYs0w==} engines: {node: '>=8', npm: '>=5'} peerDependencies: react: ^17.0.0 react-dom: ^17.0.0 - dependencies: - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: false /react-popper-tooltip/3.1.1_f991c289939c8299bed5e4a6a5a79a62: @@ -20624,7 +20631,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-router-dom/5.2.0_react@18.0.0-alpha-aecb3b6d1: + /react-router-dom/5.2.0: resolution: {integrity: sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==} peerDependencies: react: '>=15' @@ -20633,8 +20640,7 @@ packages: history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 - react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 + react-router: 5.2.0 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 dev: false @@ -20653,7 +20659,7 @@ packages: react-router: 6.0.0-beta.0_dd3df4049b9a65e1e2d003c7940c4871 dev: false - /react-router/5.2.0_react@18.0.0-alpha-aecb3b6d1: + /react-router/5.2.0: resolution: {integrity: sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==} peerDependencies: react: '>=15' @@ -20662,10 +20668,9 @@ packages: history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 - mini-create-react-context: 0.4.1_d2630f1b5c5d613d08a8af07021f9fe5 + mini-create-react-context: 0.4.1_prop-types@15.7.2 path-to-regexp: 1.8.0 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 @@ -20682,13 +20687,12 @@ packages: react: 18.0.0-alpha-aecb3b6d1 dev: false - /react-shallow-renderer/16.14.1_react@18.0.0-alpha-aecb3b6d1: + /react-shallow-renderer/16.14.1: resolution: {integrity: sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==} peerDependencies: react: ^16.0.0 || ^17.0.0 dependencies: object-assign: 4.1.1 - react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 dev: true @@ -20719,27 +20723,25 @@ packages: refractor: 3.4.0 dev: true - /react-test-renderer/16.14.0_react@18.0.0-alpha-aecb3b6d1: + /react-test-renderer/16.14.0: resolution: {integrity: sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==} peerDependencies: react: ^16.14.0 dependencies: object-assign: 4.1.1 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 scheduler: 0.19.1 dev: true - /react-test-renderer/17.0.2_react@18.0.0-alpha-aecb3b6d1: + /react-test-renderer/17.0.2: resolution: {integrity: sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==} peerDependencies: react: 17.0.2 dependencies: object-assign: 4.1.1 - react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 - react-shallow-renderer: 16.14.1_react@18.0.0-alpha-aecb3b6d1 + react-shallow-renderer: 16.14.1 scheduler: 0.20.2 dev: true @@ -20781,6 +20783,37 @@ packages: tslib: 2.3.0 dev: false + /react-universal-interface/0.6.2_tslib@2.3.0: + resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} + peerDependencies: + react: '*' + tslib: '*' + dependencies: + tslib: 2.3.0 + dev: false + + /react-use/17.2.4: + resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + dependencies: + '@types/js-cookie': 2.2.7 + '@xobotyi/scrollbar-width': 1.9.5 + copy-to-clipboard: 3.3.1 + fast-deep-equal: 3.1.3 + fast-shallow-equal: 1.0.0 + js-cookie: 2.2.1 + nano-css: 5.3.1 + react-universal-interface: 0.6.2_tslib@2.3.0 + resize-observer-polyfill: 1.5.1 + screenfull: 5.1.0 + set-harmonic-interval: 1.0.1 + throttle-debounce: 3.0.1 + ts-easing: 0.2.0 + tslib: 2.3.0 + dev: false + /react-use/17.2.4_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} peerDependencies: @@ -20805,15 +20838,23 @@ packages: tslib: 2.3.0 dev: false - /react-virtualized-auto-sizer/1.0.5_f991c289939c8299bed5e4a6a5a79a62: + /react-virtualized-auto-sizer/1.0.5: resolution: {integrity: sha512-kivjYVWX15TX2IUrm8F1jaCEX8EXrpy3DD+u41WGqJ1ZqbljWpiwscV+VxOM1l7sSIM1jwi2LADjhhAJkJ9dxA==} engines: {node: '>8.0.0'} peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 + dev: false + + /react-window/1.8.6: + resolution: {integrity: sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==} + engines: {node: '>8.0.0'} + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 + '@babel/runtime': 7.14.8 + memoize-one: 5.2.1 dev: false /react-window/1.8.6_f991c289939c8299bed5e4a6a5a79a62: @@ -23366,7 +23407,7 @@ packages: typescript: 4.3.5 dev: false - /ts-jest/27.0.4_52cc4273aa16028085013af47e479e10: + /ts-jest/27.0.4_@types+jest@26.0.24+jest@27.0.6: resolution: {integrity: sha512-c4E1ECy9Xz2WGfTMyHbSaArlIva7Wi2p43QOMmCqjSSjHP06KXv+aT+eSY+yZMuqsMi3k7pyGsGj2q5oSl5WfQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -23388,14 +23429,13 @@ packages: bs-logger: 0.2.6 buffer-from: 1.1.1 fast-json-stable-stringify: 2.1.0 - jest: 27.0.6_ts-node@10.1.0 + jest: 27.0.6 jest-util: 27.0.6 json5: 2.2.0 lodash: 4.17.21 make-error: 1.3.6 mkdirp: 1.0.4 semver: 7.3.5 - typescript: 4.3.5 yargs-parser: 20.2.9 dev: true @@ -23525,14 +23565,13 @@ packages: typescript: 2.9.2 dev: false - /tsutils/3.21.0_typescript@4.3.5: + /tsutils/3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.3.5 dev: true /tty-browserify/0.0.0: @@ -23571,7 +23610,7 @@ packages: prelude-ls: 1.2.1 dev: true - /type-coverage-core/2.17.5_typescript@4.3.5: + /type-coverage-core/2.17.5: resolution: {integrity: sha512-FfkH2kIgQkkgC47V2WHJZWBbjYjMw2ZpQRdRGTcMBAnkijmRCp9I1LpOuI+Gv4MDtniRLnkAo8htGGt2iExFgA==} peerDependencies: typescript: 2 || 3 || 4 @@ -23580,16 +23619,15 @@ packages: minimatch: 3.0.4 normalize-path: 3.0.0 tslib: 2.3.0 - tsutils: 3.21.0_typescript@4.3.5 - typescript: 4.3.5 + tsutils: 3.21.0 dev: true - /type-coverage/2.18.0_typescript@4.3.5: + /type-coverage/2.18.0: resolution: {integrity: sha512-SAyrR6Xl7GfHNcXU8Y3wSnJfGftdCvf/b2JlJJtt7gt74T0dCF077/ukhlLjI/MsWmRCxW8k8x/d4AjrFiLSpQ==} hasBin: true dependencies: minimist: 1.2.5 - type-coverage-core: 2.17.5_typescript@4.3.5 + type-coverage-core: 2.17.5 transitivePeerDependencies: - typescript dev: true @@ -24093,6 +24131,14 @@ packages: use-isomorphic-layout-effect: 1.1.1_010541d7fdfc8cbcdd915345c89295c8 dev: true + /use-subscription/1.5.1: + resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 + dependencies: + object-assign: 4.1.1 + dev: false + /use-subscription/1.5.1_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} peerDependencies: From 512c2cbfcd220159809d745a11a382c36ed7cb7f Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Fri, 30 Jul 2021 19:07:21 +0800 Subject: [PATCH 06/60] fix: conflict files --- pnpm-lock.yaml | 303 ++++++++++++++++++++++--------------------------- 1 file changed, 136 insertions(+), 167 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68294a82e4d0..bdf47e63aa8d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -278,7 +278,6 @@ importers: chrome-launcher: ^0.14.0 classnames: ^2.3.1 clipboard-polyfill: ^3.0.3 - color: ^4.0.0 copy-webpack-plugin: ^9.0.1 crypto-browserify: ^3.12.0 d3: ^5.16.0 @@ -424,7 +423,6 @@ importers: buffer: 6.0.3 classnames: 2.3.1 clipboard-polyfill: 3.0.3 - color: 4.0.0 crypto-browserify: 3.12.0 d3: 5.16.0 date-fns: 2.23.0 @@ -450,14 +448,14 @@ importers: pvtsutils: 1.1.7 qrcode: 1.4.4 react-draggable: 4.4.3 - react-feather: 2.0.9 - react-highlight-words: 0.17.0 - react-middle-ellipsis: 1.2.1 - react-router: 5.2.0 - react-router-dom: 5.2.0 - react-use: 17.2.4 - react-virtualized-auto-sizer: 1.0.5 - react-window: 1.8.6 + react-feather: 2.0.9_react@18.0.0-alpha-aecb3b6d1 + react-highlight-words: 0.17.0_react@18.0.0-alpha-aecb3b6d1 + react-middle-ellipsis: 1.2.1_f991c289939c8299bed5e4a6a5a79a62 + react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 + react-router-dom: 5.2.0_react@18.0.0-alpha-aecb3b6d1 + react-use: 17.2.4_f991c289939c8299bed5e4a6a5a79a62 + react-virtualized-auto-sizer: 1.0.5_f991c289939c8299bed5e4a6a5a79a62 + react-window: 1.8.6_f991c289939c8299bed5e4a6a5a79a62 remarkable: 2.0.1 scrypt-js: 3.0.1 socket.io-client: 2.4.0 @@ -482,11 +480,11 @@ importers: webextension-polyfill: 0.8.0 z-schema: 5.0.1 devDependencies: - '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d + '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d_typescript@4.3.5 '@pmmmwh/react-refresh-webpack-plugin': 0.5.0-rc.2_0cb17a392999b7da0b5f4263f37b1695 '@sinonjs/text-encoding': 0.7.1 '@swc/core': 1.2.66 - '@testing-library/react-hooks': 7.0.1_react-test-renderer@17.0.2 + '@testing-library/react-hooks': 7.0.1_1959de3a9153879cff3acd96b46ed70f '@types/enzyme': 3.10.9 '@types/enzyme-adapter-react-16': 1.0.6 '@types/expect-puppeteer': 4.4.6 @@ -497,19 +495,19 @@ importers: '@types/rimraf': 3.0.1 '@types/socket.io-client': 1.4.36 '@types/webpack-dev-server': 3.11.5 - '@typescript-eslint/eslint-plugin': 4.28.5_@typescript-eslint+parser@4.28.5 - '@typescript-eslint/parser': 4.28.5 + '@typescript-eslint/eslint-plugin': 4.28.5_514553717ff968e20f6d1c6e521f8616 + '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 babel-loader: 8.2.2_webpack@5.46.0 chrome-launcher: 0.14.0 copy-webpack-plugin: 9.0.1_webpack@5.46.0 dotenv: 10.0.0 enzyme: 3.11.0 - enzyme-adapter-react-16: 1.15.6_enzyme@3.11.0 + enzyme-adapter-react-16: 1.15.6_f15f970d9b179e8975516dda0497bdea expect-puppeteer: 5.0.4 fake-indexeddb: 3.1.3 file-loader: 6.2.0_webpack@5.46.0 html-webpack-plugin: 5.3.2_webpack@5.46.0 - jest: 27.0.6 + jest: 27.0.6_ts-node@10.1.0 jest-environment-jsdom-fourteen: 1.0.1 jest-esm-transformer: 1.0.0 jest-junit: 12.2.0 @@ -518,12 +516,12 @@ importers: openzeppelin-solidity: 3.4.1 react-devtools-core: 4.14.0 react-refresh: 0.10.0 - react-test-renderer: 17.0.2 + react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 rimraf: 3.0.2 source-map-loader: 3.0.0_webpack@5.46.0 swc-loader: 0.1.14_webpack@5.46.0 - ts-jest: 27.0.4_@types+jest@26.0.24+jest@27.0.6 - type-coverage: 2.18.0 + ts-jest: 27.0.4_52cc4273aa16028085013af47e479e10 + type-coverage: 2.18.0_typescript@4.3.5 webpack: 5.46.0_webpack-cli@4.7.2 webpack-cli: 4.7.2_d46d1c9a5e33a01c3500802a2e542ae0 webpack-dev-server: 3.11.2_webpack-cli@4.7.2+webpack@5.46.0 @@ -776,7 +774,7 @@ packages: bintrees: 1.0.2 bn.js: 4.12.0 compare-versions: 3.6.0 - ethereumjs-abi: 0.6.6 + ethereumjs-abi: 0.6.8 ethereumjs-blockstream: 2.0.7 ethereumjs-util: 5.2.1 find-versions: 2.0.0 @@ -3469,7 +3467,7 @@ packages: meow: 7.1.1 dev: false - /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d: + /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d_typescript@4.3.5: resolution: {integrity: sha512-0O0Nc3j2Vxo9Gfvgeq8pWuMHKMSU3tDjRnzE0U5oWvYoY+ZO61NniKp4xf/C+J6Py6lhQFutjd2tqlporqRwlw==, tarball: download/@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d/a2ee1bed40822a7f6b9c60ce4296930c9bab00828e82637aa56060498a135ac7} hasBin: true peerDependencies: @@ -3478,6 +3476,7 @@ packages: async-call-rpc: 4.2.1 buffer: 6.0.3 systemjs: 6.3.2 + typescript: 4.3.5 web-ext-types: 3.2.1 dev: true @@ -4152,7 +4151,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core/27.0.6: + /@jest/core/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -4173,7 +4172,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.6 jest-changed-files: 27.0.6 - jest-config: 27.0.6 + jest-config: 27.0.6_ts-node@10.1.0 jest-haste-map: 27.0.6 jest-message-util: 27.0.6 jest-regex-util: 27.0.6 @@ -6902,7 +6901,7 @@ packages: defer-to-connect: 2.0.1 dev: true - /@testing-library/react-hooks/7.0.1_react-test-renderer@17.0.2: + /@testing-library/react-hooks/7.0.1_1959de3a9153879cff3acd96b46ed70f: resolution: {integrity: sha512-bpEQ2SHSBSzBmfJ437NmnP+oArQ7aVmmULiAp6Ag2rtyLBLPNFSMmgltUbFGmQOJdPWo4Ub31kpUC5T46zXNwQ==} engines: {node: '>=12'} peerDependencies: @@ -6919,8 +6918,10 @@ packages: '@types/react': 17.0.15 '@types/react-dom': 17.0.9 '@types/react-test-renderer': 17.0.1 - react-error-boundary: 3.1.3 - react-test-renderer: 17.0.2 + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 + react-error-boundary: 3.1.3_react@18.0.0-alpha-aecb3b6d1 + react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 dev: true /@tootallnate/once/1.1.2: @@ -7547,10 +7548,6 @@ packages: /@types/node/16.4.3: resolution: {integrity: sha512-GKM4FLMkWDc0sfx7tXqPWkM6NBow1kge0fgQh0bOnlqo4iT1kvTvMEKE0c1RtUGnbLlGRXiAA8SumE//90uKAg==} - /@types/node/16.4.7: - resolution: {integrity: sha512-aDDY54sst8sx47CWT6QQqIZp45yURq4dic0+HCYfYNcY5Ejlb/CLmFnRLfy3wQuYafOeh3lB/DAKaqRKBtcZmA==} - dev: false - /@types/node/8.10.66: resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} dev: false @@ -7890,7 +7887,7 @@ packages: '@types/yargs-parser': 20.2.1 dev: true - /@typescript-eslint/eslint-plugin/4.28.5_@typescript-eslint+parser@4.28.5: + /@typescript-eslint/eslint-plugin/4.28.5_514553717ff968e20f6d1c6e521f8616: resolution: {integrity: sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7901,19 +7898,21 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.28.5 - '@typescript-eslint/parser': 4.28.5 + '@typescript-eslint/experimental-utils': 4.28.5_eslint@7.31.0+typescript@4.3.5 + '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 '@typescript-eslint/scope-manager': 4.28.5 debug: 4.3.2 + eslint: 7.31.0 functional-red-black-tree: 1.0.1 regexpp: 3.2.0 semver: 7.3.5 - tsutils: 3.21.0 + tsutils: 3.21.0_typescript@4.3.5 + typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils/4.28.5: + /@typescript-eslint/experimental-utils/4.28.5_eslint@7.31.0+typescript@4.3.5: resolution: {integrity: sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7922,15 +7921,16 @@ packages: '@types/json-schema': 7.0.8 '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5 + '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 + eslint: 7.31.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0 + eslint-utils: 3.0.0_eslint@7.31.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/4.28.5: + /@typescript-eslint/parser/4.28.5_eslint@7.31.0+typescript@4.3.5: resolution: {integrity: sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7942,8 +7942,10 @@ packages: dependencies: '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5 + '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 debug: 4.3.2 + eslint: 7.31.0 + typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true @@ -7961,7 +7963,7 @@ packages: engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} dev: true - /@typescript-eslint/typescript-estree/4.28.5: + /@typescript-eslint/typescript-estree/4.28.5_typescript@4.3.5: resolution: {integrity: sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7976,7 +7978,8 @@ packages: globby: 11.0.4 is-glob: 4.0.1 semver: 7.3.5 - tsutils: 3.21.0 + tsutils: 3.21.0_typescript@4.3.5 + typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true @@ -8531,7 +8534,7 @@ packages: symbol.prototype.description: 1.0.4 dev: true - /airbnb-prop-types/2.16.0: + /airbnb-prop-types/2.16.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==} peerDependencies: react: ^0.14 || ^15.0.0 || ^16.0.0-alpha @@ -8544,6 +8547,7 @@ packages: object.entries: 1.1.4 prop-types: 15.7.2 prop-types-exact: 1.2.0 + react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 dev: true @@ -10281,10 +10285,6 @@ packages: /buffer-from/1.1.1: resolution: {integrity: sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==} - /buffer-from/1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: false - /buffer-indexof/1.1.1: resolution: {integrity: sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==} dev: true @@ -10960,13 +10960,6 @@ packages: color-string: 1.6.0 dev: false - /color/4.0.0: - resolution: {integrity: sha512-aVUOa5aYWJSimvei14J5rdxLeljG0EB/uXTovVaaSokW+D4MsAz3MrKsRNaKqPa2KL7Wfvh7PZyIIaaX4lYdzQ==} - dependencies: - color-convert: 2.0.1 - color-string: 1.6.0 - dev: false - /colorette/1.2.2: resolution: {integrity: sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==} dev: true @@ -12528,7 +12521,7 @@ packages: hasBin: true dev: true - /enzyme-adapter-react-16/1.15.6_enzyme@3.11.0: + /enzyme-adapter-react-16/1.15.6_f15f970d9b179e8975516dda0497bdea: resolution: {integrity: sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==} peerDependencies: enzyme: ^3.0.0 @@ -12536,28 +12529,31 @@ packages: react-dom: ^16.0.0-0 dependencies: enzyme: 3.11.0 - enzyme-adapter-utils: 1.14.0 + enzyme-adapter-utils: 1.14.0_react@18.0.0-alpha-aecb3b6d1 enzyme-shallow-equal: 1.0.4 has: 1.0.3 object.assign: 4.1.2 object.values: 1.1.4 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 - react-test-renderer: 16.14.0 + react-test-renderer: 16.14.0_react@18.0.0-alpha-aecb3b6d1 semver: 5.7.1 dev: true - /enzyme-adapter-utils/1.14.0: + /enzyme-adapter-utils/1.14.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==} peerDependencies: react: 0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0 dependencies: - airbnb-prop-types: 2.16.0 + airbnb-prop-types: 2.16.0_react@18.0.0-alpha-aecb3b6d1 function.prototype.name: 1.1.4 has: 1.0.3 object.assign: 4.1.2 object.fromentries: 2.0.4 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 semver: 5.7.1 dev: true @@ -13029,12 +13025,13 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils/3.0.0: + /eslint-utils/3.0.0_eslint@7.31.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: + eslint: 7.31.0 eslint-visitor-keys: 2.1.0 dev: true @@ -13179,7 +13176,7 @@ packages: ethjs-util: 0.1.6 json-rpc-engine: 3.8.0 pify: 2.3.0 - tape: 4.14.0 + tape: 4.13.3 dev: false /eth-ens-namehash/2.0.8: @@ -13264,11 +13261,11 @@ packages: setimmediate: 1.0.5 dev: false - /ethereumjs-abi/0.6.6: - resolution: {integrity: sha512-w8KubDsA/+OAuqtIR9RGsMcoZ5nhM8vxwjJAJvEIY+clhxA3BHoLG3+ClYQaQhD0n3mlDt3U5rBrmSVJvI3c8A==} + /ethereumjs-abi/0.6.8: + resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} dependencies: bn.js: 4.12.0 - ethereumjs-util: 5.2.1 + ethereumjs-util: 6.2.1 dev: false /ethereumjs-account/2.0.5: @@ -14773,7 +14770,7 @@ packages: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.14.1 + uglify-js: 3.14.0 dev: false /har-schema/2.0.0: @@ -15485,6 +15482,7 @@ packages: get-intrinsic: 1.1.1 has: 1.0.3 side-channel: 1.0.4 + dev: true /interpret/1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} @@ -15879,6 +15877,13 @@ packages: '@types/estree': 0.0.50 dev: true + /is-regex/1.0.5: + resolution: {integrity: sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==} + engines: {node: '>= 0.4'} + dependencies: + has: 1.0.3 + dev: false + /is-regex/1.1.3: resolution: {integrity: sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==} engines: {node: '>= 0.4'} @@ -16200,7 +16205,7 @@ packages: - supports-color dev: true - /jest-cli/27.0.6: + /jest-cli/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -16210,14 +16215,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6 + '@jest/core': 27.0.6_ts-node@10.1.0 '@jest/test-result': 27.0.6 '@jest/types': 27.0.6 chalk: 4.1.1 exit: 0.1.2 graceful-fs: 4.2.6 import-local: 3.0.2 - jest-config: 27.0.6 + jest-config: 27.0.6_ts-node@10.1.0 jest-util: 27.0.6 jest-validate: 27.0.6 prompts: 2.4.1 @@ -16230,7 +16235,7 @@ packages: - utf-8-validate dev: true - /jest-config/27.0.6: + /jest-config/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -16260,6 +16265,7 @@ packages: jest-validate: 27.0.6 micromatch: 4.0.4 pretty-format: 27.0.6 + ts-node: 10.1.0_typescript@4.3.5 transitivePeerDependencies: - bufferutil - canvas @@ -16870,7 +16876,7 @@ packages: supports-color: 8.1.1 dev: true - /jest/27.0.6: + /jest/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -16880,9 +16886,9 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6 + '@jest/core': 27.0.6_ts-node@10.1.0 import-local: 3.0.2 - jest-cli: 27.0.6 + jest-cli: 27.0.6_ts-node@10.1.0 transitivePeerDependencies: - bufferutil - canvas @@ -18252,7 +18258,7 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - /mini-create-react-context/0.4.1_prop-types@15.7.2: + /mini-create-react-context/0.4.1_d2630f1b5c5d613d08a8af07021f9fe5: resolution: {integrity: sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==} peerDependencies: prop-types: ^15.0.0 @@ -18260,6 +18266,7 @@ packages: dependencies: '@babel/runtime': 7.14.8 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 tiny-warning: 1.0.3 dev: false @@ -18570,22 +18577,6 @@ packages: /nan/2.14.2: resolution: {integrity: sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==} - /nano-css/5.3.1: - resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} - peerDependencies: - react: '*' - react-dom: '*' - dependencies: - css-tree: 1.1.3 - csstype: 3.0.8 - fastest-stable-stringify: 2.0.2 - inline-style-prefixer: 6.0.0 - rtl-css-js: 1.14.1 - sourcemap-codec: 1.4.8 - stacktrace-js: 2.0.2 - stylis: 4.0.10 - dev: false - /nano-css/5.3.1_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} peerDependencies: @@ -18990,6 +18981,10 @@ packages: /object-inspect/1.11.0: resolution: {integrity: sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==} + /object-inspect/1.7.0: + resolution: {integrity: sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==} + dev: false + /object-is/1.1.5: resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} engines: {node: '>= 0.4'} @@ -20492,13 +20487,14 @@ packages: react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: true - /react-error-boundary/3.1.3: + /react-error-boundary/3.1.3_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==} engines: {node: '>=10', npm: '>=6'} peerDependencies: react: '>=16.13.1' dependencies: '@babel/runtime': 7.14.8 + react: 18.0.0-alpha-aecb3b6d1 dev: true /react-error-overlay/6.0.9: @@ -20509,12 +20505,13 @@ packages: resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==} dev: true - /react-feather/2.0.9: + /react-feather/2.0.9_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-yMfCGRkZdXwIs23Zw/zIWCJO3m3tlaUvtHiXlW+3FH7cIT6fiK1iJ7RJWugXq7Fso8ZaQyUm92/GOOHXvkiVUw==} peerDependencies: react: ^16.8.6 || ^17 dependencies: prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 dev: false /react-helmet-async/1.0.9_f991c289939c8299bed5e4a6a5a79a62: @@ -20532,7 +20529,7 @@ packages: shallowequal: 1.1.0 dev: true - /react-highlight-words/0.17.0: + /react-highlight-words/0.17.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-uX1Qh5IGjnLuJT0Zok234QDwRC8h4hcVMnB99Cb7aquB1NlPPDiWKm0XpSZOTdSactvnClCk8LOmVlP+75dgHA==} peerDependencies: react: ^0.14.0 || ^15.0.0 || ^16.0.0-0 || ^17.0.0-0 @@ -20540,6 +20537,7 @@ packages: highlight-words-core: 1.2.2 memoize-one: 4.0.3 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 dev: false /react-hook-form/7.12.0_react@18.0.0-alpha-aecb3b6d1: @@ -20583,12 +20581,15 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: true - /react-middle-ellipsis/1.2.1: + /react-middle-ellipsis/1.2.1_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-BUQWVXIWwkY7qBqZx0qyeCnPIh188t0lLS0ftfBsU41HB6k769HyBwE23eP+qNXr4vEnmKTEmlicrypVdWYs0w==} engines: {node: '>=8', npm: '>=5'} peerDependencies: react: ^17.0.0 react-dom: ^17.0.0 + dependencies: + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: false /react-popper-tooltip/3.1.1_f991c289939c8299bed5e4a6a5a79a62: @@ -20631,7 +20632,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-router-dom/5.2.0: + /react-router-dom/5.2.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==} peerDependencies: react: '>=15' @@ -20640,7 +20641,8 @@ packages: history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.7.2 - react-router: 5.2.0 + react: 18.0.0-alpha-aecb3b6d1 + react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 dev: false @@ -20659,7 +20661,7 @@ packages: react-router: 6.0.0-beta.0_dd3df4049b9a65e1e2d003c7940c4871 dev: false - /react-router/5.2.0: + /react-router/5.2.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==} peerDependencies: react: '>=15' @@ -20668,9 +20670,10 @@ packages: history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 - mini-create-react-context: 0.4.1_prop-types@15.7.2 + mini-create-react-context: 0.4.1_d2630f1b5c5d613d08a8af07021f9fe5 path-to-regexp: 1.8.0 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 @@ -20687,12 +20690,13 @@ packages: react: 18.0.0-alpha-aecb3b6d1 dev: false - /react-shallow-renderer/16.14.1: + /react-shallow-renderer/16.14.1_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==} peerDependencies: react: ^16.0.0 || ^17.0.0 dependencies: object-assign: 4.1.1 + react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 dev: true @@ -20723,25 +20727,27 @@ packages: refractor: 3.4.0 dev: true - /react-test-renderer/16.14.0: + /react-test-renderer/16.14.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==} peerDependencies: react: ^16.14.0 dependencies: object-assign: 4.1.1 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 scheduler: 0.19.1 dev: true - /react-test-renderer/17.0.2: + /react-test-renderer/17.0.2_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==} peerDependencies: react: 17.0.2 dependencies: object-assign: 4.1.1 + react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 - react-shallow-renderer: 16.14.1 + react-shallow-renderer: 16.14.1_react@18.0.0-alpha-aecb3b6d1 scheduler: 0.20.2 dev: true @@ -20783,37 +20789,6 @@ packages: tslib: 2.3.0 dev: false - /react-universal-interface/0.6.2_tslib@2.3.0: - resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} - peerDependencies: - react: '*' - tslib: '*' - dependencies: - tslib: 2.3.0 - dev: false - - /react-use/17.2.4: - resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - dependencies: - '@types/js-cookie': 2.2.7 - '@xobotyi/scrollbar-width': 1.9.5 - copy-to-clipboard: 3.3.1 - fast-deep-equal: 3.1.3 - fast-shallow-equal: 1.0.0 - js-cookie: 2.2.1 - nano-css: 5.3.1 - react-universal-interface: 0.6.2_tslib@2.3.0 - resize-observer-polyfill: 1.5.1 - screenfull: 5.1.0 - set-harmonic-interval: 1.0.1 - throttle-debounce: 3.0.1 - ts-easing: 0.2.0 - tslib: 2.3.0 - dev: false - /react-use/17.2.4_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} peerDependencies: @@ -20838,23 +20813,15 @@ packages: tslib: 2.3.0 dev: false - /react-virtualized-auto-sizer/1.0.5: + /react-virtualized-auto-sizer/1.0.5_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-kivjYVWX15TX2IUrm8F1jaCEX8EXrpy3DD+u41WGqJ1ZqbljWpiwscV+VxOM1l7sSIM1jwi2LADjhhAJkJ9dxA==} engines: {node: '>8.0.0'} peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 - dev: false - - /react-window/1.8.6: - resolution: {integrity: sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==} - engines: {node: '>8.0.0'} - peerDependencies: - react: ^15.0.0 || ^16.0.0 || ^17.0.0 - react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: - '@babel/runtime': 7.14.8 - memoize-one: 5.2.1 + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: false /react-window/1.8.6_f991c289939c8299bed5e4a6a5a79a62: @@ -21462,6 +21429,12 @@ packages: resolution: {integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=} deprecated: https://github.com/lydell/resolve-url#deprecated + /resolve/1.17.0: + resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + dependencies: + path-parse: 1.0.7 + dev: false + /resolve/1.20.0: resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==} dependencies: @@ -22000,6 +21973,7 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.1.1 object-inspect: 1.11.0 + dev: true /signal-exit/3.0.3: resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==} @@ -22938,22 +22912,22 @@ packages: engines: {node: '>=6'} dev: true - /tape/4.14.0: - resolution: {integrity: sha512-z0+WrUUJuG6wIdWrl4W3rTte2CR26G6qcPOj3w1hfRdcmhF3kHBhOBW9VHsPVAkz08ZmGzp7phVpDupbLzrYKQ==} + /tape/4.13.3: + resolution: {integrity: sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw==} hasBin: true dependencies: - call-bind: 1.0.2 deep-equal: 1.1.1 defined: 1.0.0 dotignore: 0.1.2 for-each: 0.3.3 + function-bind: 1.1.1 glob: 7.1.7 has: 1.0.3 inherits: 2.0.4 - is-regex: 1.1.3 + is-regex: 1.0.5 minimist: 1.2.5 - object-inspect: 1.11.0 - resolve: 1.20.0 + object-inspect: 1.7.0 + resolve: 1.17.0 resumer: 0.0.0 string.prototype.trim: 1.2.4 through: 2.3.8 @@ -23407,7 +23381,7 @@ packages: typescript: 4.3.5 dev: false - /ts-jest/27.0.4_@types+jest@26.0.24+jest@27.0.6: + /ts-jest/27.0.4_52cc4273aa16028085013af47e479e10: resolution: {integrity: sha512-c4E1ECy9Xz2WGfTMyHbSaArlIva7Wi2p43QOMmCqjSSjHP06KXv+aT+eSY+yZMuqsMi3k7pyGsGj2q5oSl5WfQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -23429,13 +23403,14 @@ packages: bs-logger: 0.2.6 buffer-from: 1.1.1 fast-json-stable-stringify: 2.1.0 - jest: 27.0.6 + jest: 27.0.6_ts-node@10.1.0 jest-util: 27.0.6 json5: 2.2.0 lodash: 4.17.21 make-error: 1.3.6 mkdirp: 1.0.4 semver: 7.3.5 + typescript: 4.3.5 yargs-parser: 20.2.9 dev: true @@ -23473,7 +23448,7 @@ packages: hasBin: true dependencies: arrify: 1.0.1 - buffer-from: 1.1.2 + buffer-from: 1.1.1 diff: 3.5.0 make-error: 1.3.6 minimist: 1.2.5 @@ -23565,13 +23540,14 @@ packages: typescript: 2.9.2 dev: false - /tsutils/3.21.0: + /tsutils/3.21.0_typescript@4.3.5: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 + typescript: 4.3.5 dev: true /tty-browserify/0.0.0: @@ -23610,7 +23586,7 @@ packages: prelude-ls: 1.2.1 dev: true - /type-coverage-core/2.17.5: + /type-coverage-core/2.17.5_typescript@4.3.5: resolution: {integrity: sha512-FfkH2kIgQkkgC47V2WHJZWBbjYjMw2ZpQRdRGTcMBAnkijmRCp9I1LpOuI+Gv4MDtniRLnkAo8htGGt2iExFgA==} peerDependencies: typescript: 2 || 3 || 4 @@ -23619,15 +23595,16 @@ packages: minimatch: 3.0.4 normalize-path: 3.0.0 tslib: 2.3.0 - tsutils: 3.21.0 + tsutils: 3.21.0_typescript@4.3.5 + typescript: 4.3.5 dev: true - /type-coverage/2.18.0: + /type-coverage/2.18.0_typescript@4.3.5: resolution: {integrity: sha512-SAyrR6Xl7GfHNcXU8Y3wSnJfGftdCvf/b2JlJJtt7gt74T0dCF077/ukhlLjI/MsWmRCxW8k8x/d4AjrFiLSpQ==} hasBin: true dependencies: minimist: 1.2.5 - type-coverage-core: 2.17.5 + type-coverage-core: 2.17.5_typescript@4.3.5 transitivePeerDependencies: - typescript dev: true @@ -23786,8 +23763,8 @@ packages: uglify-to-browserify: 1.0.2 dev: false - /uglify-js/3.14.1: - resolution: {integrity: sha512-JhS3hmcVaXlp/xSo3PKY5R0JqKs5M3IV+exdLHW99qKvKivPO4Z8qbej6mte17SOPqAOVMjt/XGgWacnFSzM3g==} + /uglify-js/3.14.0: + resolution: {integrity: sha512-R/tiGB1ZXp2BC+TkRGLwj8xUZgdfT2f4UZEgX6aVjJ5uttPrr4fYmwTWDGqVnBCLbOXRMY6nr/BTbwCtVfps0g==} engines: {node: '>=0.8.0'} hasBin: true dev: false @@ -24131,14 +24108,6 @@ packages: use-isomorphic-layout-effect: 1.1.1_010541d7fdfc8cbcdd915345c89295c8 dev: true - /use-subscription/1.5.1: - resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 - dependencies: - object-assign: 4.1.1 - dev: false - /use-subscription/1.5.1_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} peerDependencies: @@ -24874,7 +24843,7 @@ packages: request: 2.88.2 semaphore: 1.1.0 solc: 0.4.26 - tape: 4.14.0 + tape: 4.13.3 xhr: 2.6.0 xtend: 4.0.2 dev: false From 3b4782e86ec4c5c7fad8628c3dd1b3f815050217 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Fri, 30 Jul 2021 22:45:05 +0800 Subject: [PATCH 07/60] fix: tab style --- .../twitter.com/injection/EnhancedProfile.tsx | 7 ++++--- .../social-network-adaptor/twitter.com/utils/selector.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 1a8d07609f39..5e7a15faca8c 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -1,5 +1,4 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { MaskColorVar } from '@masknet/theme' import { useWallet } from '@masknet/web3-shared' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' @@ -44,13 +43,14 @@ export function injectEnhancedProfile(signal: AbortSignal) { const useEnhancedProfileStyles = makeStyles< Theme, - { color: string; font: string; fontSize: string; padding: string; activeColor: string } + { color: string; font: string; fontSize: string; padding: string; height: string; activeColor: string } >((theme) => ({ tab: { '&:hover': { backgroundColor: (props) => new Color(props.activeColor).alpha(0.1).toString(), cursor: 'pointer', }, + height: (props) => props.height, }, button: { display: 'flex', @@ -93,7 +93,8 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { font: style.font, fontSize: style.fontSize, padding: style.paddingBottom, - activeColor: foregroundColorStyle.borderColor, + height: style.height, + activeColor: foregroundColorStyle.color, }) const [active, setActive] = useState(false) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts index 15e3c06f929f..89e42388868a 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts @@ -35,7 +35,7 @@ export const searchProfileActiveTabLabelSelector: () => LiveSelector = export const searchProfileTabListSelector: () => LiveSelector = () => querySelector('[role="tablist"][data-testid="ScrollSnap-List"]') export const searchForegroundColorSelector: () => LiveSelector = () => - querySelector('[data-testid="primaryColumn"] [href="/i/flow/setup_profile"][role="link"]') + querySelector('[data-testid="primaryColumn"] [aria-label="Back"][role="button"] > div') //#endregion export const rootSelector: () => LiveSelector = () => querySelector('#react-root') From 9937bfcef4060b1037c7dd83bb874739caa9ad9b Mon Sep 17 00:00:00 2001 From: unclebill Date: Sun, 1 Aug 2021 18:03:42 +0800 Subject: [PATCH 08/60] feat: get user address from profile page --- .../twitter.com/injection/EnhancedProfile.tsx | 51 ++++++++++++++++--- .../twitter.com/utils/selector.ts | 11 ++++ .../twitter.com/utils/user.ts | 20 +++++++- pnpm-lock.yaml | 9 ++++ 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 5e7a15faca8c..c9ba27987e77 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -2,7 +2,7 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' import { useWallet } from '@masknet/web3-shared' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' -import { useCallback, useState } from 'react' +import { useCallback, useEffect, useMemo, useState } from 'react' import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' import { createReactRootShadowed, startWatch } from '../../../utils' import { @@ -15,7 +15,9 @@ import { searchProfileTabListSelector, searchProfileTabPageSelector, searchProfileTabSelector, + bioCardSelector, } from '../utils/selector' +import { getNickname, getTwitterId, getBioDescription } from '../utils/user' import Color from 'color' function injectEnhancedProfileTab(signal: AbortSignal) { @@ -83,11 +85,15 @@ const useEnhancedProfileStyles = makeStyles< })) export interface EnhancedProfileTabProps {} +const EMPTY_STYLE = {} as CSSStyleDeclaration + export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - const style = window.getComputedStyle(eleTab) + const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE const eleForegroundColorStyle = searchForegroundColorSelector().evaluate() - const foregroundColorStyle = window.getComputedStyle(eleForegroundColorStyle as Element) + const foregroundColorStyle = eleForegroundColorStyle + ? window.getComputedStyle(eleForegroundColorStyle) + : EMPTY_STYLE const classes = useEnhancedProfileStyles({ color: style.color, font: style.font, @@ -100,12 +106,14 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const onOpen = () => setActive(false) const tabList = searchProfileTabListSelector().evaluate()?.querySelectorAll('div') - tabList?.forEach((v, i) => { + tabList?.forEach((v) => { v.addEventListener('click', onOpen, { once: true }) }) const onClick = useCallback(() => { const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + const style = window.getComputedStyle(eleTab) const eleEmpty = searchProfileEmptySelector().evaluate() @@ -140,6 +148,9 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { setActive(true) }, [active]) + + if (!eleTab) return null + return ( <>
@@ -154,10 +165,38 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { export interface EnhancedProfilePageProps {} -export function EnhancedProfileaPage(props: EnhancedProfilePageProps) { +export function EnhancedProfileaPage() { const selectedWallet = useWallet() + const profileEthereumName = useEthereumName() if (!selectedWallet) { return null } - return + return +} + +const ENS_RE = /\w+\.eth/ +const ENS_RE_FULL = /^\w+\.eth$/ + +function useEthereumName() { + const [ethereumName, setEthereumName] = useState('') + const nickname = getNickname() + const twitterId = getTwitterId() + const bioDescription = getBioDescription() + + useEffect(() => { + const matched = bioDescription.match(ENS_RE) + if (matched) { + setEthereumName(matched[0]) + } + }, [bioDescription]) + const name = useMemo(() => { + if (ethereumName) return ethereumName + + if (ENS_RE_FULL.test(nickname)) { + return nickname + } + return `${twitterId}.eth` + }, [ethereumName, nickname, twitterId]) + + return name } diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts index 89e42388868a..43f54e8458e2 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts @@ -36,6 +36,15 @@ export const searchProfileTabListSelector: () => LiveSelector = () => querySelector('[role="tablist"][data-testid="ScrollSnap-List"]') export const searchForegroundColorSelector: () => LiveSelector = () => querySelector('[data-testid="primaryColumn"] [aria-label="Back"][role="button"] > div') +export const bioCardSelector = (singleMode = true) => + querySelector( + [ + '.profile', // legacy twitter + 'a[href*="header_photo"] ~ div', // new twitter + 'div[data-testid="primaryColumn"] > div > div:last-child > div > div > div > div ~ div', // new twitter without header photo + ].join(), + singleMode, + ) //#endregion export const rootSelector: () => LiveSelector = () => querySelector('#react-root') @@ -74,6 +83,8 @@ export const postEditorToolbarSelector: () => LiveSelector = () => export const newPostButtonSelector = () => querySelector('[data-testid="SideNav_NewTweet_Button"]') +export const bioDescriptionSelector = () => querySelector('[data-testid="UserDescription"]') + export const bioPageUserNickNameSelector = () => querySelector('[data-testid="UserDescription"]') .map((x) => x.parentElement?.parentElement?.previousElementSibling) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/user.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/user.ts index ea664a237dee..0a038d109691 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/user.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/user.ts @@ -1,5 +1,6 @@ -import type { SocialNetwork } from '../../../social-network' import { isNull } from 'lodash-es' +import type { SocialNetwork } from '../../../social-network' +import { bioPageUserNickNameSelector, bioPageUserIDSelector, bioDescriptionSelector } from './selector' /** * @link https://help.twitter.com/en/managing-your-account/twitter-username-rules @@ -13,3 +14,20 @@ export const usernameValidator: NonNullable { + const nicknameNode = bioPageUserNickNameSelector().evaluate() + if (!nicknameNode) return '' + return nicknameNode.innerText.trim() +} + +export const getTwitterId = () => { + const twitterIdNode = bioPageUserIDSelector(bioPageUserNickNameSelector).evaluate() + if (!twitterIdNode) return '' + return twitterIdNode +} + +export const getBioDescription = () => { + const node = bioDescriptionSelector().evaluate() + return node?.innerText ?? '' +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bdf47e63aa8d..ddea41e36c83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -278,6 +278,7 @@ importers: chrome-launcher: ^0.14.0 classnames: ^2.3.1 clipboard-polyfill: ^3.0.3 + color: ^4.0.0 copy-webpack-plugin: ^9.0.1 crypto-browserify: ^3.12.0 d3: ^5.16.0 @@ -423,6 +424,7 @@ importers: buffer: 6.0.3 classnames: 2.3.1 clipboard-polyfill: 3.0.3 + color: 4.0.0 crypto-browserify: 3.12.0 d3: 5.16.0 date-fns: 2.23.0 @@ -10960,6 +10962,13 @@ packages: color-string: 1.6.0 dev: false + /color/4.0.0: + resolution: {integrity: sha512-aVUOa5aYWJSimvei14J5rdxLeljG0EB/uXTovVaaSokW+D4MsAz3MrKsRNaKqPa2KL7Wfvh7PZyIIaaX4lYdzQ==} + dependencies: + color-convert: 2.0.1 + color-string: 1.6.0 + dev: false + /colorette/1.2.2: resolution: {integrity: sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==} dev: true From 8af095746fbbece17f4104ce7cc0f74577bbb062 Mon Sep 17 00:00:00 2001 From: unclebill Date: Thu, 29 Jul 2021 10:50:54 +0800 Subject: [PATCH 09/60] feat(web3-shared): add useResolveEns for resolving ens --- packages/web3-shared/src/hooks/index.ts | 1 + packages/web3-shared/src/hooks/useResolveEns.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 packages/web3-shared/src/hooks/useResolveEns.ts diff --git a/packages/web3-shared/src/hooks/index.ts b/packages/web3-shared/src/hooks/index.ts index 4c482e12865f..3fddd6858a4e 100644 --- a/packages/web3-shared/src/hooks/index.ts +++ b/packages/web3-shared/src/hooks/index.ts @@ -55,3 +55,4 @@ export * from './useTransactions' export * from './useMnemonicWordsPuzzle' export * from './useGetPastLogsParams' export * from './useChainColor' +export * from './useResolveEns' diff --git a/packages/web3-shared/src/hooks/useResolveEns.ts b/packages/web3-shared/src/hooks/useResolveEns.ts new file mode 100644 index 000000000000..00995d3afd04 --- /dev/null +++ b/packages/web3-shared/src/hooks/useResolveEns.ts @@ -0,0 +1,15 @@ +import { useEffect, useState } from 'react' +import { useWeb3 } from './useWeb3' + +export function useResolveEns(name: string) { + const web3 = useWeb3() + const [address, setAddress] = useState('') + + useEffect(() => { + web3.eth.ens.getAddress(name, (_: Error, value: string) => { + setAddress(value) + }) + }, [name]) + + return address +} From 9ee2e0c55d3fe4979113aa64b3be6249339c415c Mon Sep 17 00:00:00 2001 From: unclebill Date: Fri, 30 Jul 2021 10:06:02 +0800 Subject: [PATCH 10/60] fixup! feat(web3-shared): add useResolveEns for resolving ens --- packages/web3-shared/src/hooks/useResolveEns.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/web3-shared/src/hooks/useResolveEns.ts b/packages/web3-shared/src/hooks/useResolveEns.ts index 00995d3afd04..6847cd26822d 100644 --- a/packages/web3-shared/src/hooks/useResolveEns.ts +++ b/packages/web3-shared/src/hooks/useResolveEns.ts @@ -1,15 +1,10 @@ -import { useEffect, useState } from 'react' +import { useAsyncRetry } from 'react-use' import { useWeb3 } from './useWeb3' export function useResolveEns(name: string) { const web3 = useWeb3() - const [address, setAddress] = useState('') - useEffect(() => { - web3.eth.ens.getAddress(name, (_: Error, value: string) => { - setAddress(value) - }) + return useAsyncRetry(async () => { + return await web3.eth.ens.getAddress(name) }, [name]) - - return address } From 4b26ae92e3026de9b9e2a3d96b1cfac9182049cf Mon Sep 17 00:00:00 2001 From: unclebill Date: Sun, 1 Aug 2021 18:09:19 +0800 Subject: [PATCH 11/60] feat: resolve ens --- .../twitter.com/injection/EnhancedProfile.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index c9ba27987e77..bb625a96ce06 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -1,5 +1,5 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { useWallet } from '@masknet/web3-shared' +import { useWallet, useResolveEns } from '@masknet/web3-shared' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -168,10 +168,11 @@ export interface EnhancedProfilePageProps {} export function EnhancedProfileaPage() { const selectedWallet = useWallet() const profileEthereumName = useEthereumName() + const resolvedAddress = useResolveEns(profileEthereumName).value if (!selectedWallet) { return null } - return + return } const ENS_RE = /\w+\.eth/ From e3769175b07d80d9273b43e436c0f3f2fb4c344e Mon Sep 17 00:00:00 2001 From: unclebill Date: Mon, 2 Aug 2021 10:48:20 +0800 Subject: [PATCH 12/60] fix: improve layout of CollectiableList --- .../DashboardComponents/CollectibleList/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index 64f1d49b7a03..7f5fb24e4dc0 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -13,14 +13,19 @@ export const CollectibleContext = createContext<{ const useStyles = makeStyles((theme) => ({ root: { - display: 'flex', + display: 'grid', flexWrap: 'wrap', + gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', + gridGap: theme.spacing(1), }, container: { height: 'calc(100% - 52px)', overflow: 'auto', }, card: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', position: 'relative', padding: theme.spacing(1), }, From 89c03d2fee38a75ddbc4991564e8b8748b68737e Mon Sep 17 00:00:00 2001 From: unclebill Date: Mon, 2 Aug 2021 10:52:12 +0800 Subject: [PATCH 13/60] fix: replace auto-fit with auto-fill --- .../options-page/DashboardComponents/CollectibleList/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index 7f5fb24e4dc0..befca9db97f9 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -15,7 +15,7 @@ const useStyles = makeStyles((theme) => ({ root: { display: 'grid', flexWrap: 'wrap', - gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', + gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gridGap: theme.spacing(1), }, container: { From 00a6f7b0207a9e03aee6db2885c824512b368c87 Mon Sep 17 00:00:00 2001 From: UncleBill Date: Mon, 2 Aug 2021 10:58:02 +0800 Subject: [PATCH 14/60] Update packages/maskbook/src/social-network/types.ts Co-authored-by: Jack Works --- packages/maskbook/src/social-network/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/maskbook/src/social-network/types.ts b/packages/maskbook/src/social-network/types.ts index ca8889919ac6..5327b8d95b14 100644 --- a/packages/maskbook/src/social-network/types.ts +++ b/packages/maskbook/src/social-network/types.ts @@ -123,7 +123,7 @@ export namespace SocialNetworkUI { /** Inject UI to the search result */ searchResult?(signal: AbortSignal): void setupWizard?(signal: AbortSignal, for_: PersonaIdentifier): void - + /** Inject UI to the Profile page */ enhancedProfile?(signal: AbortSignal): void } export interface NewPostComposition { From c75d418346ad5aa4d07b3cb06bba9d8d0130c570 Mon Sep 17 00:00:00 2001 From: unclebill Date: Mon, 2 Aug 2021 13:12:46 +0800 Subject: [PATCH 15/60] fix: eslint warning --- .../twitter.com/injection/EnhancedProfile.tsx | 203 ------------------ 1 file changed, 203 deletions(-) delete mode 100644 packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx deleted file mode 100644 index bb625a96ce06..000000000000 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { useWallet, useResolveEns } from '@masknet/web3-shared' -import { makeStyles, Theme } from '@material-ui/core' -import classNames from 'classnames' -import { useCallback, useEffect, useMemo, useState } from 'react' -import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' -import { createReactRootShadowed, startWatch } from '../../../utils' -import { - searchForegroundColorSelector, - searchProfileActiveTabLabelSelector, - searchProfileActiveTabSelector, - searchProfileActiveTabStatusLineSelector, - searchProfileEmptySelector, - searchProfileTabListLastChildSelector, - searchProfileTabListSelector, - searchProfileTabPageSelector, - searchProfileTabSelector, - bioCardSelector, -} from '../utils/selector' -import { getNickname, getTwitterId, getBioDescription } from '../utils/user' -import Color from 'color' - -function injectEnhancedProfileTab(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} - -function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} - -function injectEnhancedProfilePageState(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} -export function injectEnhancedProfile(signal: AbortSignal) { - injectEnhancedProfileTab(signal) - injectEnhancedProfilePageForEmptyState(signal) - injectEnhancedProfilePageState(signal) -} - -const useEnhancedProfileStyles = makeStyles< - Theme, - { color: string; font: string; fontSize: string; padding: string; height: string; activeColor: string } ->((theme) => ({ - tab: { - '&:hover': { - backgroundColor: (props) => new Color(props.activeColor).alpha(0.1).toString(), - cursor: 'pointer', - }, - height: (props) => props.height, - }, - button: { - display: 'flex', - minWidth: 56, - justifyContent: 'center', - alignItems: 'center', - textAlign: 'center', - padding: (props) => props.padding, - fontWeight: 700, - color: (props) => props.color, - font: (props) => props.font, - fontSize: (props) => props.fontSize, - '&:hover': { - color: (props) => props.activeColor, - }, - }, - hot: { - color: (props) => props.activeColor, - }, - active: { - dispaly: 'inline-flex', - borderRadius: 99999, - position: 'absolute', - bottom: 0, - minWidth: 56, - alignSelf: 'center', - height: 4, - backgroundColor: (props) => props.activeColor, - }, -})) -export interface EnhancedProfileTabProps {} - -const EMPTY_STYLE = {} as CSSStyleDeclaration - -export function EnhancedProfileTab(props: EnhancedProfileTabProps) { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE - const eleForegroundColorStyle = searchForegroundColorSelector().evaluate() - const foregroundColorStyle = eleForegroundColorStyle - ? window.getComputedStyle(eleForegroundColorStyle) - : EMPTY_STYLE - const classes = useEnhancedProfileStyles({ - color: style.color, - font: style.font, - fontSize: style.fontSize, - padding: style.paddingBottom, - height: style.height, - activeColor: foregroundColorStyle.color, - }) - const [active, setActive] = useState(false) - - const onOpen = () => setActive(false) - const tabList = searchProfileTabListSelector().evaluate()?.querySelectorAll('div') - tabList?.forEach((v) => { - v.addEventListener('click', onOpen, { once: true }) - }) - - const onClick = useCallback(() => { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - if (!eleTab) return - - const style = window.getComputedStyle(eleTab) - - const eleEmpty = searchProfileEmptySelector().evaluate() - if (eleEmpty) eleEmpty.style.display = 'none' - - const ele = searchProfileTabPageSelector().evaluate() - if (ele) ele.style.display = 'none' - - const line = searchProfileActiveTabStatusLineSelector().evaluate() - if (line) line.style.display = 'none' - - const label = searchProfileActiveTabLabelSelector().evaluate() - if (label) label.style.color = style.color - - const tab = searchProfileActiveTabSelector().evaluate() - if (tab) { - tab.setAttribute('aria-selected', 'false') - tab.addEventListener( - 'click', - () => { - if (eleEmpty) eleEmpty.style.display = 'flex' - if (ele) ele.style.display = 'flex' - if (line) line.style.display = 'inline-flex' - if (label) label.style.color = '' - - setActive(false) - tab.setAttribute('aria-selected', 'true') - }, - { once: true }, - ) - } - - setActive(true) - }, [active]) - - if (!eleTab) return null - - return ( - <> -
-
- NFTs - {active ?
: null} -
-
- - ) -} - -export interface EnhancedProfilePageProps {} - -export function EnhancedProfileaPage() { - const selectedWallet = useWallet() - const profileEthereumName = useEthereumName() - const resolvedAddress = useResolveEns(profileEthereumName).value - if (!selectedWallet) { - return null - } - return -} - -const ENS_RE = /\w+\.eth/ -const ENS_RE_FULL = /^\w+\.eth$/ - -function useEthereumName() { - const [ethereumName, setEthereumName] = useState('') - const nickname = getNickname() - const twitterId = getTwitterId() - const bioDescription = getBioDescription() - - useEffect(() => { - const matched = bioDescription.match(ENS_RE) - if (matched) { - setEthereumName(matched[0]) - } - }, [bioDescription]) - const name = useMemo(() => { - if (ethereumName) return ethereumName - - if (ENS_RE_FULL.test(nickname)) { - return nickname - } - return `${twitterId}.eth` - }, [ethereumName, nickname, twitterId]) - - return name -} From edb80b4b7990a10efb733bd32b33c42d818aaf01 Mon Sep 17 00:00:00 2001 From: unclebill Date: Mon, 2 Aug 2021 13:12:46 +0800 Subject: [PATCH 16/60] fix: eslint warning --- .../twitter.com/injection/EnhancedProfile.tsx | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx new file mode 100644 index 000000000000..3cf938923911 --- /dev/null +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -0,0 +1,202 @@ +import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' +import { useWallet, useResolveEns } from '@masknet/web3-shared' +import { makeStyles, Theme } from '@material-ui/core' +import classNames from 'classnames' +import { useCallback, useEffect, useMemo, useState } from 'react' +import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' +import { createReactRootShadowed, startWatch } from '../../../utils' +import { + searchForegroundColorSelector, + searchProfileActiveTabLabelSelector, + searchProfileActiveTabSelector, + searchProfileActiveTabStatusLineSelector, + searchProfileEmptySelector, + searchProfileTabListLastChildSelector, + searchProfileTabListSelector, + searchProfileTabPageSelector, + searchProfileTabSelector, +} from '../utils/selector' +import { getNickname, getTwitterId, getBioDescription } from '../utils/user' +import Color from 'color' + +function injectEnhancedProfileTab(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +function injectEnhancedProfilePageState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} +export function injectEnhancedProfile(signal: AbortSignal) { + injectEnhancedProfileTab(signal) + injectEnhancedProfilePageForEmptyState(signal) + injectEnhancedProfilePageState(signal) +} + +const useEnhancedProfileStyles = makeStyles< + Theme, + { color: string; font: string; fontSize: string; padding: string; height: string; activeColor: string } +>((theme) => ({ + tab: { + '&:hover': { + backgroundColor: (props) => new Color(props.activeColor).alpha(0.1).toString(), + cursor: 'pointer', + }, + height: (props) => props.height, + }, + button: { + display: 'flex', + minWidth: 56, + justifyContent: 'center', + alignItems: 'center', + textAlign: 'center', + padding: (props) => props.padding, + fontWeight: 700, + color: (props) => props.color, + font: (props) => props.font, + fontSize: (props) => props.fontSize, + '&:hover': { + color: (props) => props.activeColor, + }, + }, + hot: { + color: (props) => props.activeColor, + }, + active: { + dispaly: 'inline-flex', + borderRadius: 99999, + position: 'absolute', + bottom: 0, + minWidth: 56, + alignSelf: 'center', + height: 4, + backgroundColor: (props) => props.activeColor, + }, +})) +export interface EnhancedProfileTabProps {} + +const EMPTY_STYLE = {} as CSSStyleDeclaration + +export function EnhancedProfileTab(props: EnhancedProfileTabProps) { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE + const eleForegroundColorStyle = searchForegroundColorSelector().evaluate() + const foregroundColorStyle = eleForegroundColorStyle + ? window.getComputedStyle(eleForegroundColorStyle) + : EMPTY_STYLE + const classes = useEnhancedProfileStyles({ + color: style.color, + font: style.font, + fontSize: style.fontSize, + padding: style.paddingBottom, + height: style.height, + activeColor: foregroundColorStyle.color, + }) + const [active, setActive] = useState(false) + + const onOpen = () => setActive(false) + const tabList = searchProfileTabListSelector().evaluate()?.querySelectorAll('div') + tabList?.forEach((v) => { + v.addEventListener('click', onOpen, { once: true }) + }) + + const onClick = useCallback(() => { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + + const style = window.getComputedStyle(eleTab) + + const eleEmpty = searchProfileEmptySelector().evaluate() + if (eleEmpty) eleEmpty.style.display = 'none' + + const ele = searchProfileTabPageSelector().evaluate() + if (ele) ele.style.display = 'none' + + const line = searchProfileActiveTabStatusLineSelector().evaluate() + if (line) line.style.display = 'none' + + const label = searchProfileActiveTabLabelSelector().evaluate() + if (label) label.style.color = style.color + + const tab = searchProfileActiveTabSelector().evaluate() + if (tab) { + tab.setAttribute('aria-selected', 'false') + tab.addEventListener( + 'click', + () => { + if (eleEmpty) eleEmpty.style.display = 'flex' + if (ele) ele.style.display = 'flex' + if (line) line.style.display = 'inline-flex' + if (label) label.style.color = '' + + setActive(false) + tab.setAttribute('aria-selected', 'true') + }, + { once: true }, + ) + } + + setActive(true) + }, [active]) + + if (!eleTab) return null + + return ( + <> +
+
+ NFTs + {active ?
: null} +
+
+ + ) +} + +export interface EnhancedProfilePageProps {} + +export function EnhancedProfileaPage() { + const selectedWallet = useWallet() + const profileEthereumName = useEthereumName() + const resolvedAddress = useResolveEns(profileEthereumName).value + if (!selectedWallet) { + return null + } + return +} + +const ENS_RE = /\w+\.eth/ +const ENS_RE_FULL = /^\w+\.eth$/ + +function useEthereumName() { + const [ethereumName, setEthereumName] = useState('') + const nickname = getNickname() + const twitterId = getTwitterId() + const bioDescription = getBioDescription() + + useEffect(() => { + const matched = bioDescription.match(ENS_RE) + if (matched) { + setEthereumName(matched[0]) + } + }, [bioDescription]) + const name = useMemo(() => { + if (ethereumName) return ethereumName + + if (ENS_RE_FULL.test(nickname)) { + return nickname + } + return `${twitterId}.eth` + }, [ethereumName, nickname, twitterId]) + + return name +} From e5499bb455bd7651301d15bbca335f497c269967 Mon Sep 17 00:00:00 2001 From: unclebill Date: Mon, 2 Aug 2021 19:52:32 +0800 Subject: [PATCH 17/60] fix: move useEthereumName to individual file --- .../twitter.com/injection/EnhancedProfile.tsx | 31 ++----------------- .../twitter.com/injection/useEthereumName.ts | 29 +++++++++++++++++ 2 files changed, 31 insertions(+), 29 deletions(-) create mode 100644 packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 3cf938923911..78014a760b7c 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -2,7 +2,7 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' import { useWallet, useResolveEns } from '@masknet/web3-shared' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' -import { useCallback, useEffect, useMemo, useState } from 'react' +import { useCallback } from 'react' import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' import { createReactRootShadowed, startWatch } from '../../../utils' import { @@ -16,7 +16,7 @@ import { searchProfileTabPageSelector, searchProfileTabSelector, } from '../utils/selector' -import { getNickname, getTwitterId, getBioDescription } from '../utils/user' +import { useEthereumName } from './useEthereumName' import Color from 'color' function injectEnhancedProfileTab(signal: AbortSignal) { @@ -173,30 +173,3 @@ export function EnhancedProfileaPage() { } return } - -const ENS_RE = /\w+\.eth/ -const ENS_RE_FULL = /^\w+\.eth$/ - -function useEthereumName() { - const [ethereumName, setEthereumName] = useState('') - const nickname = getNickname() - const twitterId = getTwitterId() - const bioDescription = getBioDescription() - - useEffect(() => { - const matched = bioDescription.match(ENS_RE) - if (matched) { - setEthereumName(matched[0]) - } - }, [bioDescription]) - const name = useMemo(() => { - if (ethereumName) return ethereumName - - if (ENS_RE_FULL.test(nickname)) { - return nickname - } - return `${twitterId}.eth` - }, [ethereumName, nickname, twitterId]) - - return name -} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts new file mode 100644 index 000000000000..1cc9998bfb49 --- /dev/null +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts @@ -0,0 +1,29 @@ +import { useEffect, useMemo, useState } from 'react' +import { getBioDescription, getNickname, getTwitterId } from '../utils/user' + +const ENS_RE = /\w+\.eth/ +const ENS_RE_FULL = /^\w+\.eth$/ + +export function useEthereumName() { + const [ethereumName, setEthereumName] = useState('') + const nickname = getNickname() + const twitterId = getTwitterId() + const bioDescription = getBioDescription() + + useEffect(() => { + const matched = bioDescription.match(ENS_RE) + if (matched) { + setEthereumName(matched[0]) + } + }, [bioDescription]) + const name = useMemo(() => { + if (ethereumName) return ethereumName + + if (ENS_RE_FULL.test(nickname)) { + return nickname + } + return `${twitterId}.eth` + }, [ethereumName, nickname, twitterId]) + + return name +} From 34013d48d443e715396aa8754d7d84146f912fc8 Mon Sep 17 00:00:00 2001 From: unclebill Date: Tue, 3 Aug 2021 10:13:42 +0800 Subject: [PATCH 18/60] fix: missing useState --- .../twitter.com/injection/EnhancedProfile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 78014a760b7c..2e8fa1875cf2 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -2,7 +2,7 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' import { useWallet, useResolveEns } from '@masknet/web3-shared' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' -import { useCallback } from 'react' +import { useCallback, useState } from 'react' import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' import { createReactRootShadowed, startWatch } from '../../../utils' import { From baf1d23da6647497954679700be99e061591bc98 Mon Sep 17 00:00:00 2001 From: unclebill Date: Tue, 3 Aug 2021 10:41:49 +0800 Subject: [PATCH 19/60] fix: eslint warning --- packages/web3-shared/src/hooks/useResolveEns.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web3-shared/src/hooks/useResolveEns.ts b/packages/web3-shared/src/hooks/useResolveEns.ts index 6847cd26822d..004114042fc4 100644 --- a/packages/web3-shared/src/hooks/useResolveEns.ts +++ b/packages/web3-shared/src/hooks/useResolveEns.ts @@ -5,6 +5,7 @@ export function useResolveEns(name: string) { const web3 = useWeb3() return useAsyncRetry(async () => { - return await web3.eth.ens.getAddress(name) + const result = await web3.eth.ens.getAddress(name) + return result }, [name]) } From 9f3224b8b22c0014be2d4d6c0e20e2f4749f5834 Mon Sep 17 00:00:00 2001 From: lelenei Date: Tue, 3 Aug 2021 22:29:46 +0800 Subject: [PATCH 20/60] fix: show nfts list page --- packages/maskbook/package.json | 1 + .../twitter.com/injection/EnhancedProfile.tsx | 98 ++++++++++++------- .../twitter.com/utils/selector.ts | 3 +- 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/packages/maskbook/package.json b/packages/maskbook/package.json index f9c602775d01..0321bbdf31ff 100644 --- a/packages/maskbook/package.json +++ b/packages/maskbook/package.json @@ -71,6 +71,7 @@ "date-fns": "^2.23.0", "elliptic": "^6.5.3", "event-iterator": "^2.0.0", + "events": "^3.3.0", "fuse.js": "^6.4.3", "gun": "0.2020.520", "https-browserify": "^1.0.0", diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 2e8fa1875cf2..f97d2389e4fb 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -1,15 +1,12 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { useWallet, useResolveEns } from '@masknet/web3-shared' +import { useResolveEns, useWallet } from '@masknet/web3-shared' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' -import { useCallback, useState } from 'react' -import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' +import { useState } from 'react' import { createReactRootShadowed, startWatch } from '../../../utils' import { searchForegroundColorSelector, - searchProfileActiveTabLabelSelector, searchProfileActiveTabSelector, - searchProfileActiveTabStatusLineSelector, searchProfileEmptySelector, searchProfileTabListLastChildSelector, searchProfileTabListSelector, @@ -18,7 +15,10 @@ import { } from '../utils/selector' import { useEthereumName } from './useEthereumName' import Color from 'color' +import EventEmitter from 'events' +import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' +const Event = new EventEmitter() function injectEnhancedProfileTab(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) startWatch(watcher, signal) @@ -86,6 +86,37 @@ export interface EnhancedProfileTabProps {} const EMPTY_STYLE = {} as CSSStyleDeclaration +function clearStatus() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + const style = window.getComputedStyle(eleTab) + const tabList = searchProfileTabListSelector().evaluate() + tabList.map((v) => { + const _v = v.querySelector('div') as HTMLDivElement + _v.style.color = style.color + const line = v.querySelector('div > div') as HTMLDivElement + line.style.display = 'none' + }) +} + +const bind = (cb: () => void) => { + const elePage = searchProfileTabPageSelector().evaluate() + const tabList = searchProfileTabListSelector().evaluate() + tabList.map((v) => { + const line = v.querySelector('div > div') as HTMLDivElement + const _v = v.querySelector('div') + _v?.addEventListener( + 'click', + () => { + cb() + if (elePage) elePage.style.display = '' + if (line) line.style.display = '' + }, + { once: true }, + ) + }) +} + export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE @@ -101,64 +132,49 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { height: style.height, activeColor: foregroundColorStyle.color, }) + const [active, setActive] = useState(false) - const onOpen = () => setActive(false) - const tabList = searchProfileTabListSelector().evaluate()?.querySelectorAll('div') - tabList?.forEach((v) => { - v.addEventListener('click', onOpen, { once: true }) + bind(() => { + setActive(false) + Event.emit('event', false) }) - const onClick = useCallback(() => { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - if (!eleTab) return - - const style = window.getComputedStyle(eleTab) - + const onClick = () => { const eleEmpty = searchProfileEmptySelector().evaluate() if (eleEmpty) eleEmpty.style.display = 'none' - const ele = searchProfileTabPageSelector().evaluate() - if (ele) ele.style.display = 'none' - - const line = searchProfileActiveTabStatusLineSelector().evaluate() - if (line) line.style.display = 'none' - - const label = searchProfileActiveTabLabelSelector().evaluate() - if (label) label.style.color = style.color + const elePage = searchProfileTabPageSelector().evaluate() + if (elePage) elePage.style.display = 'none' const tab = searchProfileActiveTabSelector().evaluate() if (tab) { - tab.setAttribute('aria-selected', 'false') tab.addEventListener( 'click', () => { - if (eleEmpty) eleEmpty.style.display = 'flex' - if (ele) ele.style.display = 'flex' - if (line) line.style.display = 'inline-flex' - if (label) label.style.color = '' + if (eleEmpty) eleEmpty.style.display = '' + if (elePage) elePage.style.display = '' setActive(false) - tab.setAttribute('aria-selected', 'true') }, { once: true }, ) } + Event.emit('event', true) setActive(true) - }, [active]) + clearStatus() + } if (!eleTab) return null return ( - <> -
-
- NFTs - {active ?
: null} -
+
+
+ NFTs + {active ?
: null}
- +
) } @@ -167,9 +183,15 @@ export interface EnhancedProfilePageProps {} export function EnhancedProfileaPage() { const selectedWallet = useWallet() const profileEthereumName = useEthereumName() + const [show, setShow] = useState(false) + Event.once('event', (show: boolean) => { + setShow(show) + }) + const resolvedAddress = useResolveEns(profileEthereumName).value if (!selectedWallet) { return null } - return + + return <>{show ? : null} } diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts index 43f54e8458e2..dca471ed24cd 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts @@ -32,8 +32,7 @@ export const searchProfileActiveTabStatusLineSelector: () => LiveSelector('[role="tablist"] [role="tab"][aria-selected="true"] > div > div') export const searchProfileActiveTabLabelSelector: () => LiveSelector = () => querySelector('[role="tablist"] [role="tab"][aria-selected="true"] > div') -export const searchProfileTabListSelector: () => LiveSelector = () => - querySelector('[role="tablist"][data-testid="ScrollSnap-List"]') +export const searchProfileTabListSelector = () => querySelectorAll('[role="tablist"][data-testid="ScrollSnap-List"] a') export const searchForegroundColorSelector: () => LiveSelector = () => querySelector('[data-testid="primaryColumn"] [aria-label="Back"][role="button"] > div') export const bioCardSelector = (singleMode = true) => From 3f47c11cfe12961de7b5f8b0700bd3586abb8279 Mon Sep 17 00:00:00 2001 From: lelenei Date: Wed, 4 Aug 2021 10:43:18 +0800 Subject: [PATCH 21/60] fix: use MaskMessage --- packages/maskbook/package.json | 1 - .../twitter.com/injection/EnhancedProfile.tsx | 13 ++++++------- packages/maskbook/src/utils/messages.ts | 6 ++++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/maskbook/package.json b/packages/maskbook/package.json index 0321bbdf31ff..f9c602775d01 100644 --- a/packages/maskbook/package.json +++ b/packages/maskbook/package.json @@ -71,7 +71,6 @@ "date-fns": "^2.23.0", "elliptic": "^6.5.3", "event-iterator": "^2.0.0", - "events": "^3.3.0", "fuse.js": "^6.4.3", "gun": "0.2020.520", "https-browserify": "^1.0.0", diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index f97d2389e4fb..2881ce9a1bb0 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -3,7 +3,7 @@ import { useResolveEns, useWallet } from '@masknet/web3-shared' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' import { useState } from 'react' -import { createReactRootShadowed, startWatch } from '../../../utils' +import { createReactRootShadowed, MaskMessage, startWatch } from '../../../utils' import { searchForegroundColorSelector, searchProfileActiveTabSelector, @@ -15,10 +15,8 @@ import { } from '../utils/selector' import { useEthereumName } from './useEthereumName' import Color from 'color' -import EventEmitter from 'events' import { CollectibleList } from '../../../extension/options-page/DashboardComponents/CollectibleList' -const Event = new EventEmitter() function injectEnhancedProfileTab(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) startWatch(watcher, signal) @@ -137,7 +135,7 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { bind(() => { setActive(false) - Event.emit('event', false) + MaskMessage.events.profileNFTsPageUpdate.sendToLocal({ show: false }) }) const onClick = () => { @@ -161,7 +159,7 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { ) } - Event.emit('event', true) + MaskMessage.events.profileNFTsPageUpdate.sendToLocal({ show: true }) setActive(true) clearStatus() } @@ -184,8 +182,9 @@ export function EnhancedProfileaPage() { const selectedWallet = useWallet() const profileEthereumName = useEthereumName() const [show, setShow] = useState(false) - Event.once('event', (show: boolean) => { - setShow(show) + + MaskMessage.events.profileNFTsPageUpdate.on((data) => { + setShow(data.show) }) const resolvedAddress = useResolveEns(profileEthereumName).value diff --git a/packages/maskbook/src/utils/messages.ts b/packages/maskbook/src/utils/messages.ts index b53aa33a0759..886d1c89ec2c 100644 --- a/packages/maskbook/src/utils/messages.ts +++ b/packages/maskbook/src/utils/messages.ts @@ -30,6 +30,10 @@ export interface SettingsUpdateEvent { initial: boolean } +export interface ProfileNFTsPageEvent { + show: boolean +} + export interface MaskMessages extends SettingsEvents { // TODO: Maybe in-page UI related messages should use Context instead of messages? autoPasteFailed: { text: string; image?: Blob } @@ -65,6 +69,8 @@ export interface MaskMessages extends SettingsEvents { activatePluginCompositionEntry: string pluginEnabled: string pluginDisabled: string + + profileNFTsPageUpdate: ProfileNFTsPageEvent } export const MaskMessage = new WebExtensionMessage({ domain: 'mask' }) Object.assign(globalThis, { MaskMessage }) From f539985b78162efc7385c1488ed19c5d084942c2 Mon Sep 17 00:00:00 2001 From: UncleBill Date: Wed, 4 Aug 2021 11:15:16 +0800 Subject: [PATCH 22/60] Update packages/web3-shared/src/hooks/useResolveEns.ts Co-authored-by: guanbinrui <52657989+guanbinrui@users.noreply.github.com> --- packages/web3-shared/src/hooks/useResolveEns.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-shared/src/hooks/useResolveEns.ts b/packages/web3-shared/src/hooks/useResolveEns.ts index 004114042fc4..c517f26840b5 100644 --- a/packages/web3-shared/src/hooks/useResolveEns.ts +++ b/packages/web3-shared/src/hooks/useResolveEns.ts @@ -7,5 +7,5 @@ export function useResolveEns(name: string) { return useAsyncRetry(async () => { const result = await web3.eth.ens.getAddress(name) return result - }, [name]) + }, [web3, name]) } From 33ed78a0ddac07178e233802127535454e920ef4 Mon Sep 17 00:00:00 2001 From: unclebill Date: Wed, 4 Aug 2021 17:24:14 +0800 Subject: [PATCH 23/60] fix: useEthereumName check twitterId --- .../twitter.com/injection/useEthereumName.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts index 1cc9998bfb49..80a95b4274cf 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts @@ -22,7 +22,7 @@ export function useEthereumName() { if (ENS_RE_FULL.test(nickname)) { return nickname } - return `${twitterId}.eth` + return twitterId ? `${twitterId}.eth` : '' }, [ethereumName, nickname, twitterId]) return name From d4db2d7a0b8a0a67ad1f7c6d4a83ed0c2b4bc893 Mon Sep 17 00:00:00 2001 From: lelenei Date: Wed, 4 Aug 2021 20:36:23 +0800 Subject: [PATCH 24/60] fix: style in My Wallets --- .../options-page/DashboardComponents/CollectibleList/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index befca9db97f9..8f21551b46f0 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -121,7 +121,7 @@ export function CollectibleList({ wallet, owner, readonly }: CollectibleListProp flexDirection: 'column', alignItems: 'center', justifyContent: 'center', - height: '100%', + height: 'auto', }}> {t('dashboard_no_collectible_found')} @@ -174,14 +170,20 @@ function CollectibleListUI({ ) } -export interface CollectibleListAddressProps { +const useCollectibleListAddressStyles = makeStyles((theme) => ({ + empty: {}, + button: {}, +})) +export interface CollectibleListAddressProps extends withClasses<'empty' | 'button'> { address: string } -export function CollectibleListAddress({ address }: CollectibleListAddressProps) { +export function CollectibleListAddress(props: CollectibleListAddressProps) { + const { address } = props const provider = useValueRef(currentCollectibleDataProviderSettings) const chainId = ChainId.Mainnet const [page, setPage] = useState(0) + const classes = useStylesExtends(useCollectibleListAddressStyles(), props) const { value = { collectibles: [], hasNextPage: false }, @@ -197,6 +199,7 @@ export function CollectibleListAddress({ address }: CollectibleListAddressProps) return ( ((theme) => ({ + empty: { + paddingTop: 36, + paddingBottom: 36, + '& > p': { + fontSize: 18, + fontFamily: 'inherit', + fontWeight: 700, + color: 'black', + }, + }, + button: { + backgroundColor: (props: StyleProps) => props.activeColor, + color: 'white', + marginTop: 18, + '&:hover': { + backgroundColor: (props: StyleProps) => props.activeColor, + }, + }, +})) + export function EnhancedProfileaPage() { const [show, setShow] = useState(false) + const style = getStyle() + const classes = EnhancedProfileaPageStyles(style) useEffect(() => { MaskMessage.events.profileNFTsPageUpdate.on((data) => { setShow(data.show) }) - return () => - MaskMessage.events.profileNFTsPageUpdate.off((data) => { - setShow(false) - }) }, []) const resolvedAddress = useEthereumAddress() - return <>{show ? : null} + return <>{show ? : null} } From 5e1c1bd055c854a2cc5c99563aec7f39e79bb9a2 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Mon, 9 Aug 2021 22:31:11 +0800 Subject: [PATCH 36/60] fix: improve code --- .../CollectibleList/index.tsx | 2 +- .../twitter.com/injection/EnhancedProfile.tsx | 31 +++++++------------ 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index 25f0376af0ef..10f49df2d063 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -103,7 +103,7 @@ function CollectibleListUI(props: CollectibleListUIProps) { if (loading) return ( - {Array.from({ length: 4 }) + {Array.from({ length: 6 }) .fill(0) .map((_, i) => ( diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index eb73f5c56f21..0ef456d6f2dd 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -107,37 +107,28 @@ function clearStatus() { } function resetStatus() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + const eleEmpty = searchProfileEmptySelector().evaluate() if (eleEmpty) eleEmpty.style.display = '' const elePage = searchProfileTabPageSelector().evaluate() if (elePage) elePage.style.display = '' -} - -const onEvent = (parent: HTMLElement, handler: () => void) => { - const elePage = searchProfileTabPageSelector().evaluate() - if (elePage) elePage.style.display = '' - const line = parent.querySelector('div > div') as HTMLDivElement - if (line) line.style.display = '' - handler() -} -const addEventListener = (tabList: HTMLElement[], handler: () => void) => { + const tabList = searchProfileTabListSelector().evaluate() tabList.map((v) => { - v.addEventListener('click', () => onEvent(v, handler), { once: true }) + const _v = v.querySelector('div') as HTMLDivElement + _v.style.color = '' + const line = v.querySelector('div > div') as HTMLDivElement + line.style.display = '' }) } -const removeEventListener = (tabList: HTMLElement[], handler: () => void) => { - tabList.map((v) => { - v.removeEventListener('click', () => onEvent(v, handler)) - }) -} const useBind = (handler: () => void) => { - const tabList = searchProfileTabListSelector().evaluate() useEffect(() => { - addEventListener(tabList, handler) - return () => removeEventListener(tabList, handler) - }, [tabList, addEventListener, removeEventListener, handler]) + window.addEventListener('replacestate', handler) + return () => window.removeEventListener('replacestate', handler) + }, [handler]) } function getStyle() { From d71b65ca38ebaedb8c0ede0683b78f7cbc0996cf Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Tue, 10 Aug 2021 10:42:34 +0800 Subject: [PATCH 37/60] fix: apply review --- .../DashboardComponents/CollectibleList/index.tsx | 6 +----- .../twitter.com/injection/EnhancedProfile.tsx | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index 10f49df2d063..e5533e44b4ee 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -170,10 +170,6 @@ function CollectibleListUI(props: CollectibleListUIProps) { ) } -const useCollectibleListAddressStyles = makeStyles((theme) => ({ - empty: {}, - button: {}, -})) export interface CollectibleListAddressProps extends withClasses<'empty' | 'button'> { address: string } @@ -183,7 +179,7 @@ export function CollectibleListAddress(props: CollectibleListAddressProps) { const provider = useValueRef(currentCollectibleDataProviderSettings) const chainId = ChainId.Mainnet const [page, setPage] = useState(0) - const classes = useStylesExtends(useCollectibleListAddressStyles(), props) + const classes = props.classes ?? {} const { value = { collectibles: [], hasNextPage: false }, diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 0ef456d6f2dd..e20765ff5557 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -124,7 +124,7 @@ function resetStatus() { }) } -const useBind = (handler: () => void) => { +function useRepaceState(handler: () => void) { useEffect(() => { window.addEventListener('replacestate', handler) return () => window.removeEventListener('replacestate', handler) @@ -164,7 +164,7 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { setActive(true) } - useBind(onClose) + useRepaceState(onClose) const onClick = useCallback(() => { onOpen() @@ -208,7 +208,7 @@ export function EnhancedProfileaPage() { const classes = EnhancedProfileaPageStyles(style) useEffect(() => { - MaskMessage.events.profileNFTsPageUpdate.on((data) => { + return MaskMessage.events.profileNFTsPageUpdate.on((data) => { setShow(data.show) }) }, []) From 7c8394df518febb673b3f7c6b97628d8d89cebf2 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Tue, 10 Aug 2021 12:20:19 +0800 Subject: [PATCH 38/60] refactor: useLocationChange --- .../twitter.com/injection/EnhancedProfile.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index e20765ff5557..9601d70fe495 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -148,6 +148,20 @@ function getStyle() { activeColor: foregroundColorStyle.color, } as StyleProps } + +function useLocationChange() { + const onLocationChange = useCallback(() => { + console.log(location.href) + }, []) + + useEffect(() => { + onLocationChange() + window.addEventListener('locationchange', onLocationChange) + return () => window.removeEventListener('locationchange', onLocationChange) + }, [onLocationChange]) +} + + export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const style = getStyle() const classes = useEnhancedProfileStyles(style) @@ -207,6 +221,8 @@ export function EnhancedProfileaPage() { const style = getStyle() const classes = EnhancedProfileaPageStyles(style) + useLocationChange() + useEffect(() => { return MaskMessage.events.profileNFTsPageUpdate.on((data) => { setShow(data.show) From 81306e3baa74cd93d585a150ea07d79f6f374b7f Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Tue, 10 Aug 2021 12:22:44 +0800 Subject: [PATCH 39/60] fix: prettier --- .../twitter.com/injection/EnhancedProfile.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 9601d70fe495..5ed9a6de1134 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -161,7 +161,6 @@ function useLocationChange() { }, [onLocationChange]) } - export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const style = getStyle() const classes = useEnhancedProfileStyles(style) From 0379c478f53c2f9eb8e318d62cebeb8181e03480 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Tue, 10 Aug 2021 14:30:50 +0800 Subject: [PATCH 40/60] fix: add profileNFTTabUpdated event --- .../twitter.com/injection/EnhancedProfile.tsx | 31 +++++++++---------- packages/maskbook/src/utils/messages.ts | 3 +- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 5ed9a6de1134..71ee3dd54923 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -14,6 +14,7 @@ import { import { useEthereumAddress } from './useEthereumName' import Color from 'color' import { CollectibleListAddress } from '../../../extension/options-page/DashboardComponents/CollectibleList' +import { getMaskColor } from '@masknet/theme' function injectEnhancedProfileTab(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) @@ -124,13 +125,6 @@ function resetStatus() { }) } -function useRepaceState(handler: () => void) { - useEffect(() => { - window.addEventListener('replacestate', handler) - return () => window.removeEventListener('replacestate', handler) - }, [handler]) -} - function getStyle() { const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE @@ -149,13 +143,12 @@ function getStyle() { } as StyleProps } -function useLocationChange() { +function useLocationChange(handler: () => void) { const onLocationChange = useCallback(() => { - console.log(location.href) - }, []) + handler() + }, [handler]) useEffect(() => { - onLocationChange() window.addEventListener('locationchange', onLocationChange) return () => window.removeEventListener('locationchange', onLocationChange) }, [onLocationChange]) @@ -169,15 +162,17 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const onClose = () => { setActive(false) - MaskMessage.events.profileNFTsPageUpdate.sendToLocal({ show: false }) + MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: false }) resetStatus() } const onOpen = () => { - MaskMessage.events.profileNFTsPageUpdate.sendToLocal({ show: true }) + MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: true }) setActive(true) } - useRepaceState(onClose) + useEffect(() => { + return MaskMessage.events.profileNFTsTabUpdated.on(onClose) + }, []) const onClick = useCallback(() => { onOpen() @@ -202,7 +197,7 @@ const EnhancedProfileaPageStyles = makeStyles((theme) => ({ fontSize: 18, fontFamily: 'inherit', fontWeight: 700, - color: 'black', + color: getMaskColor(theme).textPrimary, }, }, button: { @@ -220,10 +215,12 @@ export function EnhancedProfileaPage() { const style = getStyle() const classes = EnhancedProfileaPageStyles(style) - useLocationChange() + useLocationChange(() => { + MaskMessage.events.profileNFTsTabUpdated.sendToLocal('reset') + }) useEffect(() => { - return MaskMessage.events.profileNFTsPageUpdate.on((data) => { + return MaskMessage.events.profileNFTsPageUpdated.on((data) => { setShow(data.show) }) }, []) diff --git a/packages/maskbook/src/utils/messages.ts b/packages/maskbook/src/utils/messages.ts index 886d1c89ec2c..81406bbec194 100644 --- a/packages/maskbook/src/utils/messages.ts +++ b/packages/maskbook/src/utils/messages.ts @@ -70,7 +70,8 @@ export interface MaskMessages extends SettingsEvents { pluginEnabled: string pluginDisabled: string - profileNFTsPageUpdate: ProfileNFTsPageEvent + profileNFTsPageUpdated: ProfileNFTsPageEvent + profileNFTsTabUpdated: 'reset' } export const MaskMessage = new WebExtensionMessage({ domain: 'mask' }) Object.assign(globalThis, { MaskMessage }) From 17135732a422a32e2f7c958603824d01d3c1bf74 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Tue, 10 Aug 2021 20:54:44 +0800 Subject: [PATCH 41/60] fix: eslint error --- .../twitter.com/injection/useEthereumName.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts index 6647136df24a..1e950e2136e0 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts @@ -4,7 +4,7 @@ import { getBioDescription, getNickname, getTwitterId } from '../utils/user' const ENS_RE = /\w+\.eth/ const ENS_RE_FULL = /^\w+\.eth$/ -const ADDRESS = /0x[a-fA-F0-9]{40}/ +const ADDRESS = /0x[\dA-Fa-f]{40}/ export function useEthereumName() { const [ethereumName, setEthereumName] = useState('') From 1b11e8575f8384c02acec9eecb88efdd8504c2cc Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Wed, 11 Aug 2021 12:43:19 +0800 Subject: [PATCH 42/60] refactor: code style --- .../InjectedComponents}/EnhancedProfile.tsx | 37 +++---------------- .../injection/EnhancedProfileTab.tsx | 31 ++++++++++++++++ .../twitter.com/ui-provider.ts | 2 +- 3 files changed, 38 insertions(+), 32 deletions(-) rename packages/maskbook/src/{social-network-adaptor/twitter.com/injection => components/InjectedComponents}/EnhancedProfile.tsx (81%) create mode 100644 packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx similarity index 81% rename from packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx rename to packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx index 71ee3dd54923..85bef18c3d35 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx @@ -1,43 +1,18 @@ -import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' +import { getMaskColor } from '@masknet/theme' import { makeStyles, Theme } from '@material-ui/core' import classNames from 'classnames' +import Color from 'color' import { useCallback, useEffect, useState } from 'react' -import { createReactRootShadowed, MaskMessage, startWatch } from '../../../utils' +import { CollectibleListAddress } from '../../extension/options-page/DashboardComponents/CollectibleList' +import { useEthereumAddress } from '../../social-network-adaptor/twitter.com/injection/useEthereumName' import { searchForegroundColorSelector, searchProfileEmptySelector, - searchProfileTabListLastChildSelector, searchProfileTabListSelector, searchProfileTabPageSelector, searchProfileTabSelector, -} from '../utils/selector' -import { useEthereumAddress } from './useEthereumName' -import Color from 'color' -import { CollectibleListAddress } from '../../../extension/options-page/DashboardComponents/CollectibleList' -import { getMaskColor } from '@masknet/theme' - -function injectEnhancedProfileTab(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} - -function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} - -function injectEnhancedProfilePageState(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} -export function injectEnhancedProfile(signal: AbortSignal) { - injectEnhancedProfileTab(signal) - injectEnhancedProfilePageForEmptyState(signal) - injectEnhancedProfilePageState(signal) -} +} from '../../social-network-adaptor/twitter.com/utils/selector' +import { MaskMessage } from '../../utils' interface StyleProps { color: string diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx new file mode 100644 index 000000000000..001a9691c8ee --- /dev/null +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx @@ -0,0 +1,31 @@ +import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' +import { EnhancedProfileaPage, EnhancedProfileTab } from '../../../components/InjectedComponents/EnhancedProfile' +import { createReactRootShadowed, startWatch } from '../../../utils' +import { + searchProfileEmptySelector, + searchProfileTabListLastChildSelector, + searchProfileTabPageSelector, +} from '../utils/selector' + +function injectEnhancedProfileTab(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +function injectEnhancedProfilePageState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} +export function injectEnhancedProfile(signal: AbortSignal) { + injectEnhancedProfileTab(signal) + injectEnhancedProfilePageForEmptyState(signal) + injectEnhancedProfilePageState(signal) +} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts index 3a6999996bd1..084471377f7a 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts @@ -29,7 +29,7 @@ import { currentSelectedIdentity } from '../../settings/settings' import { injectPostInspectorAtTwitter } from './injection/PostInspector' import { ProfileIdentifier } from '../../database/type' import { unreachable } from '@dimensiondev/kit' -import { injectEnhancedProfile } from './injection/EnhancedProfile' +import { injectEnhancedProfile } from './injection/EnhancedProfileTab' const twitterUI: SocialNetworkUI.Definition = { ...twitterBase, From 6eeafc01a48485762fa5387015d723d024a6fed7 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Wed, 11 Aug 2021 17:45:06 +0800 Subject: [PATCH 43/60] fix: broken lockfile --- pnpm-lock.yaml | 237 +++++++++++++++++++++---------------------------- 1 file changed, 102 insertions(+), 135 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bbd3daf3d707..72d8ad8153d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -454,14 +454,14 @@ importers: pvtsutils: 1.1.7 qrcode: 1.4.4 react-draggable: 4.4.3 - react-feather: 2.0.9 - react-highlight-words: 0.17.0 - react-middle-ellipsis: 1.2.1 - react-router: 5.2.0 - react-router-dom: 5.2.0 - react-use: 17.2.4 - react-virtualized-auto-sizer: 1.0.5 - react-window: 1.8.6 + react-feather: 2.0.9_react@18.0.0-alpha-aecb3b6d1 + react-highlight-words: 0.17.0_react@18.0.0-alpha-aecb3b6d1 + react-middle-ellipsis: 1.2.1_f991c289939c8299bed5e4a6a5a79a62 + react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 + react-router-dom: 5.2.0_react@18.0.0-alpha-aecb3b6d1 + react-use: 17.2.4_f991c289939c8299bed5e4a6a5a79a62 + react-virtualized-auto-sizer: 1.0.5_f991c289939c8299bed5e4a6a5a79a62 + react-window: 1.8.6_f991c289939c8299bed5e4a6a5a79a62 remarkable: 2.0.1 scrypt-js: 3.0.1 socket.io-client: 2.4.0 @@ -471,7 +471,7 @@ importers: ts-results: 3.3.0 unstated-next: 1.1.0 urlcat: 2.0.4 - use-subscription: 1.5.1 + use-subscription: 1.5.1_react@18.0.0-alpha-aecb3b6d1 uuid: 8.3.2 wallet.ts: 1.0.1 web-ext-types: 3.2.1 @@ -486,11 +486,11 @@ importers: webextension-polyfill: 0.8.0 z-schema: 5.0.1 devDependencies: - '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d + '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d_typescript@4.3.5 '@pmmmwh/react-refresh-webpack-plugin': 0.5.0-rc.2_0cb17a392999b7da0b5f4263f37b1695 '@sinonjs/text-encoding': 0.7.1 '@swc/core': 1.2.66 - '@testing-library/react-hooks': 7.0.1_react-test-renderer@17.0.2 + '@testing-library/react-hooks': 7.0.1_1959de3a9153879cff3acd96b46ed70f '@types/enzyme': 3.10.9 '@types/enzyme-adapter-react-16': 1.0.6 '@types/expect-puppeteer': 4.4.6 @@ -501,19 +501,19 @@ importers: '@types/rimraf': 3.0.1 '@types/socket.io-client': 1.4.36 '@types/webpack-dev-server': 3.11.5 - '@typescript-eslint/eslint-plugin': 4.28.5_@typescript-eslint+parser@4.28.5 - '@typescript-eslint/parser': 4.28.5 + '@typescript-eslint/eslint-plugin': 4.28.5_514553717ff968e20f6d1c6e521f8616 + '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 babel-loader: 8.2.2_webpack@5.46.0 chrome-launcher: 0.14.0 copy-webpack-plugin: 9.0.1_webpack@5.46.0 dotenv: 10.0.0 enzyme: 3.11.0 - enzyme-adapter-react-16: 1.15.6_enzyme@3.11.0 + enzyme-adapter-react-16: 1.15.6_f15f970d9b179e8975516dda0497bdea expect-puppeteer: 5.0.4 fake-indexeddb: 3.1.3 file-loader: 6.2.0_webpack@5.46.0 html-webpack-plugin: 5.3.2_webpack@5.46.0 - jest: 27.0.6 + jest: 27.0.6_ts-node@10.1.0 jest-environment-jsdom-fourteen: 1.0.1 jest-esm-transformer: 1.0.0 jest-junit: 12.2.0 @@ -522,12 +522,12 @@ importers: openzeppelin-solidity: 3.4.1 react-devtools-core: 4.14.0 react-refresh: 0.10.0 - react-test-renderer: 17.0.2 + react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 rimraf: 3.0.2 source-map-loader: 3.0.0_webpack@5.46.0 swc-loader: 0.1.14_webpack@5.46.0 - ts-jest: 27.0.4_@types+jest@26.0.24+jest@27.0.6 - type-coverage: 2.18.0 + ts-jest: 27.0.4_52cc4273aa16028085013af47e479e10 + type-coverage: 2.18.0_typescript@4.3.5 webpack: 5.46.0_webpack-cli@4.7.2 webpack-cli: 4.7.2_d46d1c9a5e33a01c3500802a2e542ae0 webpack-dev-server: 3.11.2_webpack-cli@4.7.2+webpack@5.46.0 @@ -3475,7 +3475,7 @@ packages: meow: 7.1.1 dev: false - /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d: + /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d_typescript@4.3.5: resolution: {integrity: sha512-0O0Nc3j2Vxo9Gfvgeq8pWuMHKMSU3tDjRnzE0U5oWvYoY+ZO61NniKp4xf/C+J6Py6lhQFutjd2tqlporqRwlw==, tarball: download/@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d/a2ee1bed40822a7f6b9c60ce4296930c9bab00828e82637aa56060498a135ac7} hasBin: true peerDependencies: @@ -3484,6 +3484,7 @@ packages: async-call-rpc: 4.2.1 buffer: 6.0.3 systemjs: 6.3.2 + typescript: 4.3.5 web-ext-types: 3.2.1 dev: true @@ -4172,7 +4173,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core/27.0.6: + /@jest/core/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -4193,7 +4194,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.6 jest-changed-files: 27.0.6 - jest-config: 27.0.6 + jest-config: 27.0.6_ts-node@10.1.0 jest-haste-map: 27.0.6 jest-message-util: 27.0.6 jest-regex-util: 27.0.6 @@ -6922,7 +6923,7 @@ packages: defer-to-connect: 2.0.1 dev: true - /@testing-library/react-hooks/7.0.1_react-test-renderer@17.0.2: + /@testing-library/react-hooks/7.0.1_1959de3a9153879cff3acd96b46ed70f: resolution: {integrity: sha512-bpEQ2SHSBSzBmfJ437NmnP+oArQ7aVmmULiAp6Ag2rtyLBLPNFSMmgltUbFGmQOJdPWo4Ub31kpUC5T46zXNwQ==} engines: {node: '>=12'} peerDependencies: @@ -6939,8 +6940,10 @@ packages: '@types/react': 17.0.15 '@types/react-dom': 17.0.9 '@types/react-test-renderer': 17.0.1 - react-error-boundary: 3.1.3 - react-test-renderer: 17.0.2 + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 + react-error-boundary: 3.1.3_react@18.0.0-alpha-aecb3b6d1 + react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 dev: true /@tootallnate/once/1.1.2: @@ -7906,7 +7909,7 @@ packages: '@types/yargs-parser': 20.2.1 dev: true - /@typescript-eslint/eslint-plugin/4.28.5_@typescript-eslint+parser@4.28.5: + /@typescript-eslint/eslint-plugin/4.28.5_514553717ff968e20f6d1c6e521f8616: resolution: {integrity: sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7917,19 +7920,21 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.28.5 - '@typescript-eslint/parser': 4.28.5 + '@typescript-eslint/experimental-utils': 4.28.5_eslint@7.31.0+typescript@4.3.5 + '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 '@typescript-eslint/scope-manager': 4.28.5 debug: 4.3.2 + eslint: 7.31.0 functional-red-black-tree: 1.0.1 regexpp: 3.2.0 semver: 7.3.5 - tsutils: 3.21.0 + tsutils: 3.21.0_typescript@4.3.5 + typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils/4.28.5: + /@typescript-eslint/experimental-utils/4.28.5_eslint@7.31.0+typescript@4.3.5: resolution: {integrity: sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7938,15 +7943,16 @@ packages: '@types/json-schema': 7.0.8 '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5 + '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 + eslint: 7.31.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0 + eslint-utils: 3.0.0_eslint@7.31.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/4.28.5: + /@typescript-eslint/parser/4.28.5_eslint@7.31.0+typescript@4.3.5: resolution: {integrity: sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7958,8 +7964,10 @@ packages: dependencies: '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5 + '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 debug: 4.3.2 + eslint: 7.31.0 + typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true @@ -7977,7 +7985,7 @@ packages: engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} dev: true - /@typescript-eslint/typescript-estree/4.28.5: + /@typescript-eslint/typescript-estree/4.28.5_typescript@4.3.5: resolution: {integrity: sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7992,7 +8000,8 @@ packages: globby: 11.0.4 is-glob: 4.0.1 semver: 7.3.5 - tsutils: 3.21.0 + tsutils: 3.21.0_typescript@4.3.5 + typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true @@ -8547,7 +8556,7 @@ packages: symbol.prototype.description: 1.0.4 dev: true - /airbnb-prop-types/2.16.0: + /airbnb-prop-types/2.16.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==} peerDependencies: react: ^0.14 || ^15.0.0 || ^16.0.0-alpha @@ -8560,6 +8569,7 @@ packages: object.entries: 1.1.4 prop-types: 15.7.2 prop-types-exact: 1.2.0 + react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 dev: true @@ -12542,7 +12552,7 @@ packages: hasBin: true dev: true - /enzyme-adapter-react-16/1.15.6_enzyme@3.11.0: + /enzyme-adapter-react-16/1.15.6_f15f970d9b179e8975516dda0497bdea: resolution: {integrity: sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==} peerDependencies: enzyme: ^3.0.0 @@ -12550,28 +12560,31 @@ packages: react-dom: ^16.0.0-0 dependencies: enzyme: 3.11.0 - enzyme-adapter-utils: 1.14.0 + enzyme-adapter-utils: 1.14.0_react@18.0.0-alpha-aecb3b6d1 enzyme-shallow-equal: 1.0.4 has: 1.0.3 object.assign: 4.1.2 object.values: 1.1.4 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 - react-test-renderer: 16.14.0 + react-test-renderer: 16.14.0_react@18.0.0-alpha-aecb3b6d1 semver: 5.7.1 dev: true - /enzyme-adapter-utils/1.14.0: + /enzyme-adapter-utils/1.14.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==} peerDependencies: react: 0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0 dependencies: - airbnb-prop-types: 2.16.0 + airbnb-prop-types: 2.16.0_react@18.0.0-alpha-aecb3b6d1 function.prototype.name: 1.1.4 has: 1.0.3 object.assign: 4.1.2 object.fromentries: 2.0.4 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 semver: 5.7.1 dev: true @@ -13043,12 +13056,13 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils/3.0.0: + /eslint-utils/3.0.0_eslint@7.31.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: + eslint: 7.31.0 eslint-visitor-keys: 2.1.0 dev: true @@ -16242,7 +16256,7 @@ packages: - supports-color dev: true - /jest-cli/27.0.6: + /jest-cli/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -16252,14 +16266,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6 + '@jest/core': 27.0.6_ts-node@10.1.0 '@jest/test-result': 27.0.6 '@jest/types': 27.0.6 chalk: 4.1.1 exit: 0.1.2 graceful-fs: 4.2.6 import-local: 3.0.2 - jest-config: 27.0.6 + jest-config: 27.0.6_ts-node@10.1.0 jest-util: 27.0.6 jest-validate: 27.0.6 prompts: 2.4.1 @@ -16272,7 +16286,7 @@ packages: - utf-8-validate dev: true - /jest-config/27.0.6: + /jest-config/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -16302,6 +16316,7 @@ packages: jest-validate: 27.0.6 micromatch: 4.0.4 pretty-format: 27.0.6 + ts-node: 10.1.0_typescript@4.3.5 transitivePeerDependencies: - bufferutil - canvas @@ -16912,7 +16927,7 @@ packages: supports-color: 8.1.1 dev: true - /jest/27.0.6: + /jest/27.0.6_ts-node@10.1.0: resolution: {integrity: sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -16922,9 +16937,9 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6 + '@jest/core': 27.0.6_ts-node@10.1.0 import-local: 3.0.2 - jest-cli: 27.0.6 + jest-cli: 27.0.6_ts-node@10.1.0 transitivePeerDependencies: - bufferutil - canvas @@ -18294,7 +18309,7 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - /mini-create-react-context/0.4.1_prop-types@15.7.2: + /mini-create-react-context/0.4.1_d2630f1b5c5d613d08a8af07021f9fe5: resolution: {integrity: sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==} peerDependencies: prop-types: ^15.0.0 @@ -18302,6 +18317,7 @@ packages: dependencies: '@babel/runtime': 7.14.8 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 tiny-warning: 1.0.3 dev: false @@ -18619,22 +18635,6 @@ packages: /nan/2.14.2: resolution: {integrity: sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==} - /nano-css/5.3.1: - resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} - peerDependencies: - react: '*' - react-dom: '*' - dependencies: - css-tree: 1.1.3 - csstype: 3.0.8 - fastest-stable-stringify: 2.0.2 - inline-style-prefixer: 6.0.0 - rtl-css-js: 1.14.1 - sourcemap-codec: 1.4.8 - stacktrace-js: 2.0.2 - stylis: 4.0.10 - dev: false - /nano-css/5.3.1_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} peerDependencies: @@ -20541,13 +20541,14 @@ packages: react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: true - /react-error-boundary/3.1.3: + /react-error-boundary/3.1.3_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==} engines: {node: '>=10', npm: '>=6'} peerDependencies: react: '>=16.13.1' dependencies: '@babel/runtime': 7.14.8 + react: 18.0.0-alpha-aecb3b6d1 dev: true /react-error-overlay/6.0.9: @@ -20558,12 +20559,13 @@ packages: resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==} dev: true - /react-feather/2.0.9: + /react-feather/2.0.9_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-yMfCGRkZdXwIs23Zw/zIWCJO3m3tlaUvtHiXlW+3FH7cIT6fiK1iJ7RJWugXq7Fso8ZaQyUm92/GOOHXvkiVUw==} peerDependencies: react: ^16.8.6 || ^17 dependencies: prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 dev: false /react-helmet-async/1.0.9_f991c289939c8299bed5e4a6a5a79a62: @@ -20581,7 +20583,7 @@ packages: shallowequal: 1.1.0 dev: true - /react-highlight-words/0.17.0: + /react-highlight-words/0.17.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-uX1Qh5IGjnLuJT0Zok234QDwRC8h4hcVMnB99Cb7aquB1NlPPDiWKm0XpSZOTdSactvnClCk8LOmVlP+75dgHA==} peerDependencies: react: ^0.14.0 || ^15.0.0 || ^16.0.0-0 || ^17.0.0-0 @@ -20589,6 +20591,7 @@ packages: highlight-words-core: 1.2.2 memoize-one: 4.0.3 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 dev: false /react-hook-form/7.12.0_react@18.0.0-alpha-aecb3b6d1: @@ -20632,12 +20635,15 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: true - /react-middle-ellipsis/1.2.1: + /react-middle-ellipsis/1.2.1_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-BUQWVXIWwkY7qBqZx0qyeCnPIh188t0lLS0ftfBsU41HB6k769HyBwE23eP+qNXr4vEnmKTEmlicrypVdWYs0w==} engines: {node: '>=8', npm: '>=5'} peerDependencies: react: ^17.0.0 react-dom: ^17.0.0 + dependencies: + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: false /react-popper-tooltip/3.1.1_f991c289939c8299bed5e4a6a5a79a62: @@ -20684,7 +20690,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-router-dom/5.2.0: + /react-router-dom/5.2.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==} peerDependencies: react: '>=15' @@ -20693,7 +20699,8 @@ packages: history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.7.2 - react-router: 5.2.0 + react: 18.0.0-alpha-aecb3b6d1 + react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 dev: false @@ -20712,7 +20719,7 @@ packages: react-router: 6.0.0-beta.0_dd3df4049b9a65e1e2d003c7940c4871 dev: false - /react-router/5.2.0: + /react-router/5.2.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==} peerDependencies: react: '>=15' @@ -20721,9 +20728,10 @@ packages: history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 - mini-create-react-context: 0.4.1_prop-types@15.7.2 + mini-create-react-context: 0.4.1_d2630f1b5c5d613d08a8af07021f9fe5 path-to-regexp: 1.8.0 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 @@ -20740,12 +20748,13 @@ packages: react: 18.0.0-alpha-aecb3b6d1 dev: false - /react-shallow-renderer/16.14.1: + /react-shallow-renderer/16.14.1_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==} peerDependencies: react: ^16.0.0 || ^17.0.0 dependencies: object-assign: 4.1.1 + react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 dev: true @@ -20776,25 +20785,27 @@ packages: refractor: 3.4.0 dev: true - /react-test-renderer/16.14.0: + /react-test-renderer/16.14.0_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==} peerDependencies: react: ^16.14.0 dependencies: object-assign: 4.1.1 prop-types: 15.7.2 + react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 scheduler: 0.19.1 dev: true - /react-test-renderer/17.0.2: + /react-test-renderer/17.0.2_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==} peerDependencies: react: 17.0.2 dependencies: object-assign: 4.1.1 + react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 - react-shallow-renderer: 16.14.1 + react-shallow-renderer: 16.14.1_react@18.0.0-alpha-aecb3b6d1 scheduler: 0.20.2 dev: true @@ -20836,37 +20847,6 @@ packages: tslib: 2.3.0 dev: false - /react-universal-interface/0.6.2_tslib@2.3.0: - resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} - peerDependencies: - react: '*' - tslib: '*' - dependencies: - tslib: 2.3.0 - dev: false - - /react-use/17.2.4: - resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - dependencies: - '@types/js-cookie': 2.2.7 - '@xobotyi/scrollbar-width': 1.9.5 - copy-to-clipboard: 3.3.1 - fast-deep-equal: 3.1.3 - fast-shallow-equal: 1.0.0 - js-cookie: 2.2.1 - nano-css: 5.3.1 - react-universal-interface: 0.6.2_tslib@2.3.0 - resize-observer-polyfill: 1.5.1 - screenfull: 5.1.0 - set-harmonic-interval: 1.0.1 - throttle-debounce: 3.0.1 - ts-easing: 0.2.0 - tslib: 2.3.0 - dev: false - /react-use/17.2.4_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} peerDependencies: @@ -20891,23 +20871,15 @@ packages: tslib: 2.3.0 dev: false - /react-virtualized-auto-sizer/1.0.5: + /react-virtualized-auto-sizer/1.0.5_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-kivjYVWX15TX2IUrm8F1jaCEX8EXrpy3DD+u41WGqJ1ZqbljWpiwscV+VxOM1l7sSIM1jwi2LADjhhAJkJ9dxA==} engines: {node: '>8.0.0'} peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 - dev: false - - /react-window/1.8.6: - resolution: {integrity: sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==} - engines: {node: '>8.0.0'} - peerDependencies: - react: ^15.0.0 || ^16.0.0 || ^17.0.0 - react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: - '@babel/runtime': 7.14.8 - memoize-one: 5.2.1 + react: 18.0.0-alpha-aecb3b6d1 + react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: false /react-window/1.8.6_f991c289939c8299bed5e4a6a5a79a62: @@ -23472,7 +23444,7 @@ packages: typescript: 4.3.5 dev: false - /ts-jest/27.0.4_@types+jest@26.0.24+jest@27.0.6: + /ts-jest/27.0.4_52cc4273aa16028085013af47e479e10: resolution: {integrity: sha512-c4E1ECy9Xz2WGfTMyHbSaArlIva7Wi2p43QOMmCqjSSjHP06KXv+aT+eSY+yZMuqsMi3k7pyGsGj2q5oSl5WfQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -23494,13 +23466,14 @@ packages: bs-logger: 0.2.6 buffer-from: 1.1.1 fast-json-stable-stringify: 2.1.0 - jest: 27.0.6 + jest: 27.0.6_ts-node@10.1.0 jest-util: 27.0.6 json5: 2.2.0 lodash: 4.17.21 make-error: 1.3.6 mkdirp: 1.0.4 semver: 7.3.5 + typescript: 4.3.5 yargs-parser: 20.2.9 dev: true @@ -23649,13 +23622,14 @@ packages: typescript: 2.9.2 dev: false - /tsutils/3.21.0: + /tsutils/3.21.0_typescript@4.3.5: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 + typescript: 4.3.5 dev: true /tty-browserify/0.0.0: @@ -23694,7 +23668,7 @@ packages: prelude-ls: 1.2.1 dev: true - /type-coverage-core/2.17.5: + /type-coverage-core/2.17.5_typescript@4.3.5: resolution: {integrity: sha512-FfkH2kIgQkkgC47V2WHJZWBbjYjMw2ZpQRdRGTcMBAnkijmRCp9I1LpOuI+Gv4MDtniRLnkAo8htGGt2iExFgA==} peerDependencies: typescript: 2 || 3 || 4 @@ -23703,15 +23677,16 @@ packages: minimatch: 3.0.4 normalize-path: 3.0.0 tslib: 2.3.0 - tsutils: 3.21.0 + tsutils: 3.21.0_typescript@4.3.5 + typescript: 4.3.5 dev: true - /type-coverage/2.18.0: + /type-coverage/2.18.0_typescript@4.3.5: resolution: {integrity: sha512-SAyrR6Xl7GfHNcXU8Y3wSnJfGftdCvf/b2JlJJtt7gt74T0dCF077/ukhlLjI/MsWmRCxW8k8x/d4AjrFiLSpQ==} hasBin: true dependencies: minimist: 1.2.5 - type-coverage-core: 2.17.5 + type-coverage-core: 2.17.5_typescript@4.3.5 transitivePeerDependencies: - typescript dev: true @@ -24215,14 +24190,6 @@ packages: use-isomorphic-layout-effect: 1.1.1_010541d7fdfc8cbcdd915345c89295c8 dev: true - /use-subscription/1.5.1: - resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 - dependencies: - object-assign: 4.1.1 - dev: false - /use-subscription/1.5.1_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} peerDependencies: From 6cec77abd9b2f39cd2d04ef5ada095ae5ace637b Mon Sep 17 00:00:00 2001 From: Jack Works Date: Wed, 11 Aug 2021 18:05:51 +0800 Subject: [PATCH 44/60] chore: migrate enhanced profile tab to new makeStyles --- .../InjectedComponents/EnhancedProfile.tsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx index 85bef18c3d35..ad5c7083ef35 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx @@ -1,5 +1,5 @@ import { getMaskColor } from '@masknet/theme' -import { makeStyles, Theme } from '@material-ui/core' +import { makeStyles } from '@masknet/theme' import classNames from 'classnames' import Color from 'color' import { useCallback, useEffect, useState } from 'react' @@ -23,13 +23,13 @@ interface StyleProps { activeColor: string } -const useEnhancedProfileStyles = makeStyles((theme) => ({ +const useEnhancedProfileStyles = makeStyles()((theme, props) => ({ tab: { '&:hover': { - backgroundColor: (props: StyleProps) => new Color(props.activeColor).alpha(0.1).toString(), + backgroundColor: new Color(props.activeColor).alpha(0.1).toString(), cursor: 'pointer', }, - height: (props: StyleProps) => props.height, + height: props.height, }, button: { display: 'flex', @@ -37,17 +37,17 @@ const useEnhancedProfileStyles = makeStyles((theme) => ({ justifyContent: 'center', alignItems: 'center', textAlign: 'center', - padding: (props: StyleProps) => props.padding, + padding: props.padding, fontWeight: 700, - color: (props: StyleProps) => props.color, - font: (props: StyleProps) => props.font, - fontSize: (props: StyleProps) => props.fontSize, + color: props.color, + font: props.font, + fontSize: props.fontSize, '&:hover': { - color: (props: StyleProps) => props.activeColor, + color: props.activeColor, }, }, hot: { - color: (props: StyleProps) => props.activeColor, + color: props.activeColor, }, active: { dispaly: 'inline-flex', @@ -57,7 +57,7 @@ const useEnhancedProfileStyles = makeStyles((theme) => ({ minWidth: 56, alignSelf: 'center', height: 4, - backgroundColor: (props: StyleProps) => props.activeColor, + backgroundColor: props.activeColor, }, })) export interface EnhancedProfileTabProps {} @@ -131,8 +131,7 @@ function useLocationChange(handler: () => void) { export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const style = getStyle() - const classes = useEnhancedProfileStyles(style) - + const { classes } = useEnhancedProfileStyles(style) const [active, setActive] = useState(false) const onClose = () => { @@ -163,8 +162,7 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) {
) } - -const EnhancedProfileaPageStyles = makeStyles((theme) => ({ +const useEnhancedProfileaPageStyles = makeStyles()((theme, props) => ({ empty: { paddingTop: 36, paddingBottom: 36, @@ -176,11 +174,11 @@ const EnhancedProfileaPageStyles = makeStyles((theme) => ({ }, }, button: { - backgroundColor: (props: StyleProps) => props.activeColor, + backgroundColor: props.activeColor, color: 'white', marginTop: 18, '&:hover': { - backgroundColor: (props: StyleProps) => props.activeColor, + backgroundColor: props.activeColor, }, }, })) @@ -188,7 +186,7 @@ const EnhancedProfileaPageStyles = makeStyles((theme) => ({ export function EnhancedProfileaPage() { const [show, setShow] = useState(false) const style = getStyle() - const classes = EnhancedProfileaPageStyles(style) + const { classes } = useEnhancedProfileaPageStyles(style) useLocationChange(() => { MaskMessage.events.profileNFTsTabUpdated.sendToLocal('reset') From 285f69458a306b9e3f62e4b8ab9c08d7c19569d2 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Thu, 12 Aug 2021 12:09:02 +0800 Subject: [PATCH 45/60] fix: refresh nft list --- .../InjectedComponents/EnhancedProfile.tsx | 195 +++--------------- .../InjectedComponents/EnhancedProfileTab.tsx | 153 ++++++++++++++ .../twitter.com/injection/EnhancedProfile.tsx | 20 ++ .../injection/EnhancedProfileTab.tsx | 27 +-- .../twitter.com/injection/useEthereumName.ts | 19 +- .../twitter.com/ui-provider.ts | 6 +- .../twitter.com/utils/selector.ts | 3 +- packages/maskbook/src/social-network/types.ts | 1 + packages/maskbook/src/social-network/ui.ts | 2 + .../src/utils/hooks/useLocationChange.ts | 8 + pnpm-lock.yaml | 2 - 11 files changed, 232 insertions(+), 204 deletions(-) create mode 100644 packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx create mode 100644 packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx create mode 100644 packages/maskbook/src/utils/hooks/useLocationChange.ts diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx index ad5c7083ef35..b5f382a015d7 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx @@ -1,168 +1,19 @@ -import { getMaskColor } from '@masknet/theme' -import { makeStyles } from '@masknet/theme' -import classNames from 'classnames' -import Color from 'color' -import { useCallback, useEffect, useState } from 'react' +import { getMaskColor, makeStyles } from '@masknet/theme' +import { useState, useEffect } from 'react' import { CollectibleListAddress } from '../../extension/options-page/DashboardComponents/CollectibleList' import { useEthereumAddress } from '../../social-network-adaptor/twitter.com/injection/useEthereumName' -import { - searchForegroundColorSelector, - searchProfileEmptySelector, - searchProfileTabListSelector, - searchProfileTabPageSelector, - searchProfileTabSelector, -} from '../../social-network-adaptor/twitter.com/utils/selector' +import { searchNewTweetButtonSelector } from '../../social-network-adaptor/twitter.com/utils/selector' +import { getBioDescription, getNickname, getTwitterId } from '../../social-network-adaptor/twitter.com/utils/user' import { MaskMessage } from '../../utils' +import { useLocationChange } from '../../utils/hooks/useLocationChange' interface StyleProps { - color: string - font: string - fontSize: string - padding: string - height: string - activeColor: string + backgroundColor: string } -const useEnhancedProfileStyles = makeStyles()((theme, props) => ({ - tab: { - '&:hover': { - backgroundColor: new Color(props.activeColor).alpha(0.1).toString(), - cursor: 'pointer', - }, - height: props.height, - }, - button: { - display: 'flex', - minWidth: 56, - justifyContent: 'center', - alignItems: 'center', - textAlign: 'center', - padding: props.padding, - fontWeight: 700, - color: props.color, - font: props.font, - fontSize: props.fontSize, - '&:hover': { - color: props.activeColor, - }, - }, - hot: { - color: props.activeColor, - }, - active: { - dispaly: 'inline-flex', - borderRadius: 99999, - position: 'absolute', - bottom: 0, - minWidth: 56, - alignSelf: 'center', - height: 4, - backgroundColor: props.activeColor, - }, -})) -export interface EnhancedProfileTabProps {} - const EMPTY_STYLE = {} as CSSStyleDeclaration -function clearStatus() { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - if (!eleTab) return - const style = window.getComputedStyle(eleTab) - const tabList = searchProfileTabListSelector().evaluate() - tabList.map((v) => { - const _v = v.querySelector('div') as HTMLDivElement - _v.style.color = style.color - const line = v.querySelector('div > div') as HTMLDivElement - line.style.display = 'none' - }) - - const eleEmpty = searchProfileEmptySelector().evaluate() - if (eleEmpty) eleEmpty.style.display = 'none' - const elePage = searchProfileTabPageSelector().evaluate() - if (elePage) elePage.style.display = 'none' -} - -function resetStatus() { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - if (!eleTab) return - - const eleEmpty = searchProfileEmptySelector().evaluate() - if (eleEmpty) eleEmpty.style.display = '' - const elePage = searchProfileTabPageSelector().evaluate() - if (elePage) elePage.style.display = '' - - const tabList = searchProfileTabListSelector().evaluate() - tabList.map((v) => { - const _v = v.querySelector('div') as HTMLDivElement - _v.style.color = '' - const line = v.querySelector('div > div') as HTMLDivElement - line.style.display = '' - }) -} - -function getStyle() { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE - const eleForegroundColorStyle = searchForegroundColorSelector().evaluate() - const foregroundColorStyle = eleForegroundColorStyle - ? window.getComputedStyle(eleForegroundColorStyle) - : EMPTY_STYLE - - return { - color: style.color, - font: style.font, - fontSize: style.fontSize, - padding: style.paddingBottom, - height: style.height, - activeColor: foregroundColorStyle.color, - } as StyleProps -} - -function useLocationChange(handler: () => void) { - const onLocationChange = useCallback(() => { - handler() - }, [handler]) - - useEffect(() => { - window.addEventListener('locationchange', onLocationChange) - return () => window.removeEventListener('locationchange', onLocationChange) - }, [onLocationChange]) -} - -export function EnhancedProfileTab(props: EnhancedProfileTabProps) { - const style = getStyle() - const { classes } = useEnhancedProfileStyles(style) - const [active, setActive] = useState(false) - - const onClose = () => { - setActive(false) - MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: false }) - resetStatus() - } - const onOpen = () => { - MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: true }) - setActive(true) - } - - useEffect(() => { - return MaskMessage.events.profileNFTsTabUpdated.on(onClose) - }, []) - - const onClick = useCallback(() => { - onOpen() - clearStatus() - }, [clearStatus, onOpen]) - - return ( -
-
- NFTs - {active ?
: null} -
-
- ) -} -const useEnhancedProfileaPageStyles = makeStyles()((theme, props) => ({ +const useStyles = makeStyles()((theme, props) => ({ empty: { paddingTop: 36, paddingBottom: 36, @@ -174,23 +25,41 @@ const useEnhancedProfileaPageStyles = makeStyles()((theme, props) => }, }, button: { - backgroundColor: props.activeColor, + backgroundColor: props.backgroundColor, color: 'white', marginTop: 18, '&:hover': { - backgroundColor: props.activeColor, + backgroundColor: props.backgroundColor, }, }, })) export function EnhancedProfileaPage() { const [show, setShow] = useState(false) - const style = getStyle() - const { classes } = useEnhancedProfileaPageStyles(style) + const newTweetButton = searchNewTweetButtonSelector().evaluate() + const style = newTweetButton ? window.getComputedStyle(newTweetButton) : EMPTY_STYLE + const { classes } = useStyles({ backgroundColor: style.backgroundColor }) - useLocationChange(() => { + const [bio, setBio] = useState(getBioDescription()) + const [nickname, setNickname] = useState(getNickname()) + const [twitterId, setTwitterId] = useState(getTwitterId()) + + const onLocalChange = () => { MaskMessage.events.profileNFTsTabUpdated.sendToLocal('reset') - }) + } + + useEffect(() => { + return MaskMessage.events.profileNFTsTabUpdated.on((data) => { + const _bioDescription = getBioDescription() + setBio(_bioDescription) + const _nickname = getNickname() + setNickname(_nickname) + const _twitterId = getTwitterId() + setTwitterId(_twitterId) + }) + }, []) + + useLocationChange(onLocalChange) useEffect(() => { return MaskMessage.events.profileNFTsPageUpdated.on((data) => { @@ -198,6 +67,6 @@ export function EnhancedProfileaPage() { }) }, []) - const resolvedAddress = useEthereumAddress() + const resolvedAddress = useEthereumAddress(nickname, twitterId, bio) return <>{show ? : null} } diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx new file mode 100644 index 000000000000..51fac7089a3c --- /dev/null +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx @@ -0,0 +1,153 @@ +import { makeStyles } from '@masknet/theme' +import classNames from 'classnames' +import Color from 'color' +import { useCallback, useEffect, useState } from 'react' +import { + searchForegroundColorSelector, + searchNewTweetButtonSelector, + searchProfileEmptySelector, + searchProfileTabListSelector, + searchProfileTabPageSelector, + searchProfileTabSelector, +} from '../../social-network-adaptor/twitter.com/utils/selector' +import { MaskMessage } from '../../utils' + +interface StyleProps { + color: string + font: string + fontSize: string + padding: string + height: string + hover: string + line: string +} + +const useEnhancedProfileStyles = makeStyles()((theme, props) => ({ + tab: { + '&:hover': { + backgroundColor: new Color(props.hover).alpha(0.1).toString(), + cursor: 'pointer', + }, + height: props.height, + }, + button: { + display: 'flex', + minWidth: 56, + justifyContent: 'center', + alignItems: 'center', + textAlign: 'center', + padding: props.padding, + fontWeight: 700, + color: props.color, + font: props.font, + fontSize: props.fontSize, + '&:hover': { + color: props.hover, + }, + }, + hot: { + color: props.hover, + }, + line: { + dispaly: 'inline-flex', + borderRadius: 99999, + position: 'absolute', + bottom: 0, + minWidth: 56, + alignSelf: 'center', + height: 4, + backgroundColor: props.line, + }, +})) +export interface EnhancedProfileTabProps {} + +const EMPTY_STYLE = {} as CSSStyleDeclaration + +function clearStatus() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + const style = window.getComputedStyle(eleTab) + const tabList = searchProfileTabListSelector().evaluate() + tabList.map((v) => { + const _v = v.querySelector('div') as HTMLDivElement + _v.style.color = style.color + const line = v.querySelector('div > div') as HTMLDivElement + line.style.display = 'none' + }) + + const eleEmpty = searchProfileEmptySelector().evaluate() + if (eleEmpty) eleEmpty.style.display = 'none' + const elePage = searchProfileTabPageSelector().evaluate() + if (elePage) elePage.style.display = 'none' +} + +function resetStatus() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + + const eleEmpty = searchProfileEmptySelector().evaluate() + if (eleEmpty) eleEmpty.style.display = '' + const elePage = searchProfileTabPageSelector().evaluate() + if (elePage) elePage.style.display = '' + + const tabList = searchProfileTabListSelector().evaluate() + tabList.map((v) => { + const _v = v.querySelector('div') as HTMLDivElement + _v.style.color = '' + const line = v.querySelector('div > div') as HTMLDivElement + line.style.display = '' + }) +} + +function getStyle() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE + const eleNewTweetButton = searchNewTweetButtonSelector().evaluate() + const newTweetButtonColorStyle = eleNewTweetButton ? window.getComputedStyle(eleNewTweetButton) : EMPTY_STYLE + const eleBackButton = searchForegroundColorSelector().evaluate() + const backButtonColorStyle = eleBackButton ? window.getComputedStyle(eleBackButton) : EMPTY_STYLE + + return { + color: style.color, + font: style.font, + fontSize: style.fontSize, + padding: style.paddingBottom, + height: style.height, + hover: backButtonColorStyle.color, + line: newTweetButtonColorStyle.backgroundColor, + } as StyleProps +} + +export function EnhancedProfileTab(props: EnhancedProfileTabProps) { + const style = getStyle() + const { classes } = useEnhancedProfileStyles(style) + const [active, setActive] = useState(false) + + const onClose = () => { + setActive(false) + MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: false }) + resetStatus() + } + const onOpen = () => { + MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: true }) + setActive(true) + } + + useEffect(() => { + return MaskMessage.events.profileNFTsTabUpdated.on(onClose) + }, []) + + const onClick = useCallback(() => { + onOpen() + clearStatus() + }, [clearStatus, onOpen]) + + return ( +
+
+ NFTs + {active ?
: null} +
+
+ ) +} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx new file mode 100644 index 000000000000..678801728273 --- /dev/null +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -0,0 +1,20 @@ +import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' +import { EnhancedProfileaPage } from '../../../components/InjectedComponents/EnhancedProfile' +import { createReactRootShadowed, startWatch } from '../../../utils' +import { searchProfileEmptySelector, searchProfileTabPageSelector } from '../utils/selector' + +function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +function injectEnhancedProfilePageState(signal: AbortSignal) { + const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) + startWatch(watcher, signal) + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} +export function injectEnhancedProfileAtTwitter(signal: AbortSignal) { + injectEnhancedProfilePageForEmptyState(signal) + injectEnhancedProfilePageState(signal) +} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx index 001a9691c8ee..7cda72c9dfad 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx @@ -1,31 +1,10 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { EnhancedProfileaPage, EnhancedProfileTab } from '../../../components/InjectedComponents/EnhancedProfile' +import { EnhancedProfileTab } from '../../../components/InjectedComponents/EnhancedProfileTab' import { createReactRootShadowed, startWatch } from '../../../utils' -import { - searchProfileEmptySelector, - searchProfileTabListLastChildSelector, - searchProfileTabPageSelector, -} from '../utils/selector' +import { searchProfileTabListLastChildSelector } from '../utils/selector' -function injectEnhancedProfileTab(signal: AbortSignal) { +export function injectEnhancedProfileTabAtTwitter(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) startWatch(watcher, signal) createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() } - -function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} - -function injectEnhancedProfilePageState(signal: AbortSignal) { - const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) - startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() -} -export function injectEnhancedProfile(signal: AbortSignal) { - injectEnhancedProfileTab(signal) - injectEnhancedProfilePageForEmptyState(signal) - injectEnhancedProfilePageState(signal) -} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts index 1e950e2136e0..2decaadaee25 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts @@ -1,23 +1,19 @@ import { useResolveEns } from '@masknet/web3-shared' import { useEffect, useMemo, useState } from 'react' -import { getBioDescription, getNickname, getTwitterId } from '../utils/user' const ENS_RE = /\w+\.eth/ const ENS_RE_FULL = /^\w+\.eth$/ const ADDRESS = /0x[\dA-Fa-f]{40}/ -export function useEthereumName() { +export function useEthereumName(nickname: string, twitterId: string, bio: string) { const [ethereumName, setEthereumName] = useState('') - const nickname = getNickname() - const twitterId = getTwitterId() - const bioDescription = getBioDescription() useEffect(() => { - const matched = bioDescription.match(ENS_RE) + const matched = bio.match(ENS_RE) if (matched) { setEthereumName(matched[0]) } - }, [bioDescription]) + }, [bio]) const name = useMemo(() => { if (ENS_RE_FULL.test(nickname)) { return nickname @@ -29,16 +25,15 @@ export function useEthereumName() { return name } -export function useEthereumAddress() { - const bioDescription = getBioDescription() +export function useEthereumAddress(nickanme: string, twitterId: string, bio: string) { const [addr, setAddr] = useState() - const name = useEthereumName() + const name = useEthereumName(nickanme, twitterId, bio) const ens_addr = useResolveEns(name).value useEffect(() => { - const matched = bioDescription.match(ADDRESS) + const matched = bio.match(ADDRESS) if (matched) setAddr(matched[0]) - }, [bioDescription]) + }, [bio]) return ens_addr ?? addr } diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts index 084471377f7a..ef6c1dbd4dc4 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/ui-provider.ts @@ -29,7 +29,8 @@ import { currentSelectedIdentity } from '../../settings/settings' import { injectPostInspectorAtTwitter } from './injection/PostInspector' import { ProfileIdentifier } from '../../database/type' import { unreachable } from '@dimensiondev/kit' -import { injectEnhancedProfile } from './injection/EnhancedProfileTab' +import { injectEnhancedProfileTabAtTwitter } from './injection/EnhancedProfileTab' +import { injectEnhancedProfileAtTwitter } from './injection/EnhancedProfile' const twitterUI: SocialNetworkUI.Definition = { ...twitterBase, @@ -78,7 +79,8 @@ const twitterUI: SocialNetworkUI.Definition = { pageInspector: injectPageInspectorDefault(), postInspector: injectPostInspectorAtTwitter, setupPrompt: injectSetupPromptAtTwitter, - enhancedProfile: injectEnhancedProfile, + enhancedProfile: injectEnhancedProfileAtTwitter, + enhancedProfileTab: injectEnhancedProfileTabAtTwitter, newPostComposition: { start: injectPostBoxComposed, supportedInputTypes: { diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts index ca06a25f1278..bf5435121701 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/utils/selector.ts @@ -36,7 +36,8 @@ export const searchProfileTabListSelector = () => querySelectorAll('[aria-label="Profile timelines"] [role="tablist"][data-testid="ScrollSnap-List"] a') export const searchForegroundColorSelector: () => LiveSelector = () => querySelector('[data-testid="primaryColumn"] [aria-label="Back"][role="button"] > div') - +export const searchNewTweetButtonSelector: () => LiveSelector = () => + querySelector('[data-testid="SideNav_NewTweet_Button"]') export const searchNickNameSelector: () => LiveSelector = () => querySelector('[data-testid="UserProfileHeader_Items"]') export const bioCardSelector = (singleMode = true) => diff --git a/packages/maskbook/src/social-network/types.ts b/packages/maskbook/src/social-network/types.ts index 5327b8d95b14..6cd1687cdc98 100644 --- a/packages/maskbook/src/social-network/types.ts +++ b/packages/maskbook/src/social-network/types.ts @@ -124,6 +124,7 @@ export namespace SocialNetworkUI { searchResult?(signal: AbortSignal): void setupWizard?(signal: AbortSignal, for_: PersonaIdentifier): void /** Inject UI to the Profile page */ + enhancedProfileTab?(signal: AbortSignal): void enhancedProfile?(signal: AbortSignal): void } export interface NewPostComposition { diff --git a/packages/maskbook/src/social-network/ui.ts b/packages/maskbook/src/social-network/ui.ts index 9171470e9f2a..984773209f74 100644 --- a/packages/maskbook/src/social-network/ui.ts +++ b/packages/maskbook/src/social-network/ui.ts @@ -80,7 +80,9 @@ export async function activateSocialNetworkUIInner(ui_deferred: SocialNetworkUI. ui.injection.userBadge?.(signal) setTimeout(activateSNSAdaptorPluginOnStart, 1000) + ui.injection.enhancedProfile?.(signal) + ui.injection.enhancedProfileTab?.(signal) startPluginSNSAdaptor(getCurrentSNSNetwork(ui.networkIdentifier), createPluginHost(signal)) diff --git a/packages/maskbook/src/utils/hooks/useLocationChange.ts b/packages/maskbook/src/utils/hooks/useLocationChange.ts new file mode 100644 index 000000000000..20da711e0fc8 --- /dev/null +++ b/packages/maskbook/src/utils/hooks/useLocationChange.ts @@ -0,0 +1,8 @@ +import { useEffect } from 'react' + +export const useLocationChange = (handler: () => void) => { + useEffect(() => { + window.addEventListener('locationchange', handler) + return () => window.removeEventListener('locationchange', handler) + }, [handler]) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fea8266b5382..2fd111eae148 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15546,7 +15546,6 @@ packages: get-intrinsic: 1.1.1 has: 1.0.3 side-channel: 1.0.4 - dev: true /interpret/1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} @@ -22048,7 +22047,6 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.1.1 object-inspect: 1.11.0 - dev: true /signal-exit/3.0.3: resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==} From 95782d9efbf3b3e42d060199da47060037fa2947 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Thu, 12 Aug 2021 14:41:37 +0800 Subject: [PATCH 46/60] refactor: improve code --- .../InjectedComponents/EnhancedProfile.tsx | 50 +++---- .../InjectedComponents/EnhancedProfileTab.tsx | 117 +++------------- .../twitter.com/injection/EnhancedProfile.tsx | 65 ++++++++- .../injection/EnhancedProfileTab.tsx | 125 +++++++++++++++++- .../twitter.com/injection/useEthereumName.ts | 1 + 5 files changed, 224 insertions(+), 134 deletions(-) diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx index b5f382a015d7..6bdcfa92d317 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx @@ -1,19 +1,13 @@ -import { getMaskColor, makeStyles } from '@masknet/theme' +import { useStylesExtends } from '@masknet/shared' +import { getMaskColor } from '@masknet/theme' +import { makeStyles } from '@material-ui/core' import { useState, useEffect } from 'react' import { CollectibleListAddress } from '../../extension/options-page/DashboardComponents/CollectibleList' import { useEthereumAddress } from '../../social-network-adaptor/twitter.com/injection/useEthereumName' -import { searchNewTweetButtonSelector } from '../../social-network-adaptor/twitter.com/utils/selector' -import { getBioDescription, getNickname, getTwitterId } from '../../social-network-adaptor/twitter.com/utils/user' import { MaskMessage } from '../../utils' import { useLocationChange } from '../../utils/hooks/useLocationChange' -interface StyleProps { - backgroundColor: string -} - -const EMPTY_STYLE = {} as CSSStyleDeclaration - -const useStyles = makeStyles()((theme, props) => ({ +const useStyles = makeStyles((theme) => ({ empty: { paddingTop: 36, paddingBottom: 36, @@ -24,25 +18,20 @@ const useStyles = makeStyles()((theme, props) => ({ color: getMaskColor(theme).textPrimary, }, }, - button: { - backgroundColor: props.backgroundColor, - color: 'white', - marginTop: 18, - '&:hover': { - backgroundColor: props.backgroundColor, - }, - }, + button: {}, })) -export function EnhancedProfileaPage() { - const [show, setShow] = useState(false) - const newTweetButton = searchNewTweetButtonSelector().evaluate() - const style = newTweetButton ? window.getComputedStyle(newTweetButton) : EMPTY_STYLE - const { classes } = useStyles({ backgroundColor: style.backgroundColor }) +interface EnhancedProfileaPageProps extends withClasses<'empty' | 'button'> { + bioDescription: string + nickname: string + twitterId: string + onUpdated: () => void +} - const [bio, setBio] = useState(getBioDescription()) - const [nickname, setNickname] = useState(getNickname()) - const [twitterId, setTwitterId] = useState(getTwitterId()) +export function EnhancedProfileaPage(props: EnhancedProfileaPageProps) { + const [show, setShow] = useState(false) + const classes = useStylesExtends(useStyles(), props) + const { bioDescription, nickname, twitterId, onUpdated } = props const onLocalChange = () => { MaskMessage.events.profileNFTsTabUpdated.sendToLocal('reset') @@ -50,12 +39,7 @@ export function EnhancedProfileaPage() { useEffect(() => { return MaskMessage.events.profileNFTsTabUpdated.on((data) => { - const _bioDescription = getBioDescription() - setBio(_bioDescription) - const _nickname = getNickname() - setNickname(_nickname) - const _twitterId = getTwitterId() - setTwitterId(_twitterId) + onUpdated() }) }, []) @@ -67,6 +51,6 @@ export function EnhancedProfileaPage() { }) }, []) - const resolvedAddress = useEthereumAddress(nickname, twitterId, bio) + const resolvedAddress = useEthereumAddress(nickname, twitterId, bioDescription) return <>{show ? : null} } diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx index 51fac7089a3c..f3b3f21344da 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx @@ -1,34 +1,17 @@ -import { makeStyles } from '@masknet/theme' +import { useStylesExtends } from '@masknet/shared' +import { getMaskColor, makeStyles } from '@masknet/theme' import classNames from 'classnames' import Color from 'color' import { useCallback, useEffect, useState } from 'react' -import { - searchForegroundColorSelector, - searchNewTweetButtonSelector, - searchProfileEmptySelector, - searchProfileTabListSelector, - searchProfileTabPageSelector, - searchProfileTabSelector, -} from '../../social-network-adaptor/twitter.com/utils/selector' -import { MaskMessage } from '../../utils' -interface StyleProps { - color: string - font: string - fontSize: string - padding: string - height: string - hover: string - line: string -} +import { MaskMessage } from '../../utils' -const useEnhancedProfileStyles = makeStyles()((theme, props) => ({ +const useStyles = makeStyles()((theme) => ({ tab: { '&:hover': { - backgroundColor: new Color(props.hover).alpha(0.1).toString(), + backgroundColor: new Color(getMaskColor(theme).blue).alpha(0.1).toString(), cursor: 'pointer', }, - height: props.height, }, button: { display: 'flex', @@ -36,17 +19,12 @@ const useEnhancedProfileStyles = makeStyles()((theme, props) => ({ justifyContent: 'center', alignItems: 'center', textAlign: 'center', - padding: props.padding, + padding: theme.spacing(1), fontWeight: 700, - color: props.color, - font: props.font, - fontSize: props.fontSize, - '&:hover': { - color: props.hover, - }, + color: getMaskColor(theme).blue, }, hot: { - color: props.hover, + color: 'black', }, line: { dispaly: 'inline-flex', @@ -56,77 +34,24 @@ const useEnhancedProfileStyles = makeStyles()((theme, props) => ({ minWidth: 56, alignSelf: 'center', height: 4, - backgroundColor: props.line, + backgroundColor: getMaskColor(theme).blue, }, })) -export interface EnhancedProfileTabProps {} - -const EMPTY_STYLE = {} as CSSStyleDeclaration - -function clearStatus() { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - if (!eleTab) return - const style = window.getComputedStyle(eleTab) - const tabList = searchProfileTabListSelector().evaluate() - tabList.map((v) => { - const _v = v.querySelector('div') as HTMLDivElement - _v.style.color = style.color - const line = v.querySelector('div > div') as HTMLDivElement - line.style.display = 'none' - }) - - const eleEmpty = searchProfileEmptySelector().evaluate() - if (eleEmpty) eleEmpty.style.display = 'none' - const elePage = searchProfileTabPageSelector().evaluate() - if (elePage) elePage.style.display = 'none' -} - -function resetStatus() { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - if (!eleTab) return - - const eleEmpty = searchProfileEmptySelector().evaluate() - if (eleEmpty) eleEmpty.style.display = '' - const elePage = searchProfileTabPageSelector().evaluate() - if (elePage) elePage.style.display = '' - - const tabList = searchProfileTabListSelector().evaluate() - tabList.map((v) => { - const _v = v.querySelector('div') as HTMLDivElement - _v.style.color = '' - const line = v.querySelector('div > div') as HTMLDivElement - line.style.display = '' - }) -} - -function getStyle() { - const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element - const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE - const eleNewTweetButton = searchNewTweetButtonSelector().evaluate() - const newTweetButtonColorStyle = eleNewTweetButton ? window.getComputedStyle(eleNewTweetButton) : EMPTY_STYLE - const eleBackButton = searchForegroundColorSelector().evaluate() - const backButtonColorStyle = eleBackButton ? window.getComputedStyle(eleBackButton) : EMPTY_STYLE - - return { - color: style.color, - font: style.font, - fontSize: style.fontSize, - padding: style.paddingBottom, - height: style.height, - hover: backButtonColorStyle.color, - line: newTweetButtonColorStyle.backgroundColor, - } as StyleProps +export interface EnhancedProfileTabProps extends withClasses<'tab' | 'button' | 'hot' | 'line'> { + clear(): void + reset(): void } export function EnhancedProfileTab(props: EnhancedProfileTabProps) { - const style = getStyle() - const { classes } = useEnhancedProfileStyles(style) + const { reset, clear } = props + const { classes } = useStyles() + const styles = useStylesExtends(classes, props) const [active, setActive] = useState(false) const onClose = () => { setActive(false) MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: false }) - resetStatus() + reset() } const onOpen = () => { MaskMessage.events.profileNFTsPageUpdated.sendToLocal({ show: true }) @@ -139,14 +64,14 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { const onClick = useCallback(() => { onOpen() - clearStatus() - }, [clearStatus, onOpen]) + clear() + }, [clear, onOpen]) return ( -
-
+
+
NFTs - {active ?
: null} + {active ?
: null}
) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 678801728273..5659219fa94d 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -1,20 +1,79 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' +import { getMaskColor } from '@masknet/theme' +import { makeStyles, Theme } from '@material-ui/core' +import { useState } from 'react' import { EnhancedProfileaPage } from '../../../components/InjectedComponents/EnhancedProfile' import { createReactRootShadowed, startWatch } from '../../../utils' -import { searchProfileEmptySelector, searchProfileTabPageSelector } from '../utils/selector' +import { + searchNewTweetButtonSelector, + searchProfileEmptySelector, + searchProfileTabPageSelector, +} from '../utils/selector' +import { getBioDescription, getNickname, getTwitterId } from '../utils/user' function injectEnhancedProfilePageForEmptyState(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileEmptySelector()) startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() } function injectEnhancedProfilePageState(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabPageSelector()) startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() } export function injectEnhancedProfileAtTwitter(signal: AbortSignal) { injectEnhancedProfilePageForEmptyState(signal) injectEnhancedProfilePageState(signal) } + +const EMPTY_STYLE = {} as CSSStyleDeclaration +interface StyleProps { + backgroundColor: string +} + +const useStyles = makeStyles((theme) => ({ + empty: { + paddingTop: 36, + paddingBottom: 36, + '& > p': { + fontSize: 18, + fontFamily: 'inherit', + fontWeight: 700, + color: getMaskColor(theme).textPrimary, + }, + }, + button: { + backgroundColor: (props: StyleProps) => props.backgroundColor, + color: 'white', + marginTop: 18, + '&:hover': { + backgroundColor: (props: StyleProps) => props.backgroundColor, + }, + }, +})) + +export function EnhancedProfileaPageAtTwitter() { + const newTweetButton = searchNewTweetButtonSelector().evaluate() + const style = newTweetButton ? window.getComputedStyle(newTweetButton) : EMPTY_STYLE + const classes = useStyles({ backgroundColor: style.backgroundColor }) + + const [bio, setBio] = useState(getBioDescription()) + const [nickname, setNickname] = useState(getNickname()) + const [twitterId, setTwitterId] = useState(getTwitterId()) + + const onUpdated = () => { + setBio(getBioDescription()) + setNickname(getNickname()) + setTwitterId(getTwitterId()) + } + return ( + + ) +} diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx index 7cda72c9dfad..36e2ec88fb58 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx @@ -1,10 +1,131 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' import { EnhancedProfileTab } from '../../../components/InjectedComponents/EnhancedProfileTab' import { createReactRootShadowed, startWatch } from '../../../utils' -import { searchProfileTabListLastChildSelector } from '../utils/selector' +import { + searchForegroundColorSelector, + searchNewTweetButtonSelector, + searchProfileEmptySelector, + searchProfileTabListLastChildSelector, + searchProfileTabListSelector, + searchProfileTabPageSelector, + searchProfileTabSelector, +} from '../utils/selector' +import Color from 'color' +import { makeStyles, Theme } from '@material-ui/core' export function injectEnhancedProfileTabAtTwitter(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) startWatch(watcher, signal) - createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() + createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render() +} + +interface StyleProps { + color: string + font: string + fontSize: string + padding: string + height: string + hover: string + line: string +} + +const useStyles = makeStyles((theme) => ({ + tab: { + '&:hover': { + backgroundColor: (props: StyleProps) => new Color(props.hover).alpha(0.1).toString(), + cursor: 'pointer', + }, + height: (props: StyleProps) => props.height, + }, + button: { + display: 'flex', + minWidth: 56, + justifyContent: 'center', + alignItems: 'center', + textAlign: 'center', + padding: (props: StyleProps) => props.padding, + fontWeight: 700, + color: (props: StyleProps) => props.color, + font: (props: StyleProps) => props.font, + fontSize: (props: StyleProps) => props.fontSize, + '&:hover': { + color: (props: StyleProps) => props.hover, + }, + }, + hot: { + color: (props: StyleProps) => props.hover, + }, + line: { + dispaly: 'inline-flex', + borderRadius: 99999, + position: 'absolute', + bottom: 0, + minWidth: 56, + alignSelf: 'center', + height: 4, + backgroundColor: (props: StyleProps) => props.line, + }, +})) + +const EMPTY_STYLE = {} as CSSStyleDeclaration + +function clear() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + const style = window.getComputedStyle(eleTab) + const tabList = searchProfileTabListSelector().evaluate() + tabList.map((v) => { + const _v = v.querySelector('div') as HTMLDivElement + _v.style.color = style.color + const line = v.querySelector('div > div') as HTMLDivElement + line.style.display = 'none' + }) + + const eleEmpty = searchProfileEmptySelector().evaluate() + if (eleEmpty) eleEmpty.style.display = 'none' + const elePage = searchProfileTabPageSelector().evaluate() + if (elePage) elePage.style.display = 'none' +} + +function reset() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + if (!eleTab) return + + const eleEmpty = searchProfileEmptySelector().evaluate() + if (eleEmpty) eleEmpty.style.display = '' + const elePage = searchProfileTabPageSelector().evaluate() + if (elePage) elePage.style.display = '' + + const tabList = searchProfileTabListSelector().evaluate() + tabList.map((v) => { + const _v = v.querySelector('div') as HTMLDivElement + _v.style.color = '' + const line = v.querySelector('div > div') as HTMLDivElement + line.style.display = '' + }) +} + +function getStyle() { + const eleTab = searchProfileTabSelector().evaluate()?.querySelector('div') as Element + const style = eleTab ? window.getComputedStyle(eleTab) : EMPTY_STYLE + const eleNewTweetButton = searchNewTweetButtonSelector().evaluate() + const newTweetButtonColorStyle = eleNewTweetButton ? window.getComputedStyle(eleNewTweetButton) : EMPTY_STYLE + const eleBackButton = searchForegroundColorSelector().evaluate() + const backButtonColorStyle = eleBackButton ? window.getComputedStyle(eleBackButton) : EMPTY_STYLE + + return { + color: style.color, + font: style.font, + fontSize: style.fontSize, + padding: style.paddingBottom, + height: style.height, + hover: backButtonColorStyle.color, + line: newTweetButtonColorStyle.backgroundColor, + } as StyleProps +} + +export function EnhancedProfileTabAtTwitter() { + const style = getStyle() + const classes = useStyles(style) + return } diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts index 2decaadaee25..f1127692e082 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts @@ -31,6 +31,7 @@ export function useEthereumAddress(nickanme: string, twitterId: string, bio: str const ens_addr = useResolveEns(name).value useEffect(() => { + setAddr('') const matched = bio.match(ADDRESS) if (matched) setAddr(matched[0]) }, [bio]) From 3135f370b409e580e8ca1614684fa010ea0d7011 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Thu, 12 Aug 2021 16:40:18 +0800 Subject: [PATCH 47/60] fix: change the chainnet, not update the nft list --- .../InjectedComponents/EnhancedProfileTab.tsx | 23 ++++++------------- .../injection/EnhancedProfileTab.tsx | 2 +- .../web3-shared/src/hooks/useResolveEns.ts | 4 +++- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx index f3b3f21344da..6126fcc0739e 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx @@ -2,7 +2,7 @@ import { useStylesExtends } from '@masknet/shared' import { getMaskColor, makeStyles } from '@masknet/theme' import classNames from 'classnames' import Color from 'color' -import { useCallback, useEffect, useState } from 'react' +import { ReactElement, useCallback, useEffect, useState } from 'react' import { MaskMessage } from '../../utils' @@ -23,27 +23,18 @@ const useStyles = makeStyles()((theme) => ({ fontWeight: 700, color: getMaskColor(theme).blue, }, - hot: { + selected: { color: 'black', }, - line: { - dispaly: 'inline-flex', - borderRadius: 99999, - position: 'absolute', - bottom: 0, - minWidth: 56, - alignSelf: 'center', - height: 4, - backgroundColor: getMaskColor(theme).blue, - }, })) -export interface EnhancedProfileTabProps extends withClasses<'tab' | 'button' | 'hot' | 'line'> { +export interface EnhancedProfileTabProps extends withClasses<'tab' | 'button' | 'selected'> { clear(): void reset(): void + hot?: ReactElement } export function EnhancedProfileTab(props: EnhancedProfileTabProps) { - const { reset, clear } = props + const { reset, clear, hot } = props const { classes } = useStyles() const styles = useStylesExtends(classes, props) const [active, setActive] = useState(false) @@ -69,9 +60,9 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { return (
-
+
NFTs - {active ?
: null} + {active && hot ? hot : null}
) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx index 36e2ec88fb58..f77a79979cc3 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx @@ -52,7 +52,7 @@ const useStyles = makeStyles((theme) => ({ color: (props: StyleProps) => props.hover, }, }, - hot: { + selected: { color: (props: StyleProps) => props.hover, }, line: { diff --git a/packages/web3-shared/src/hooks/useResolveEns.ts b/packages/web3-shared/src/hooks/useResolveEns.ts index c517f26840b5..656eed4c10ed 100644 --- a/packages/web3-shared/src/hooks/useResolveEns.ts +++ b/packages/web3-shared/src/hooks/useResolveEns.ts @@ -1,11 +1,13 @@ import { useAsyncRetry } from 'react-use' +import { useChainId } from '.' import { useWeb3 } from './useWeb3' export function useResolveEns(name: string) { const web3 = useWeb3() + const chainId = useChainId() return useAsyncRetry(async () => { const result = await web3.eth.ens.getAddress(name) return result - }, [web3, name]) + }, [web3, name, chainId]) } From 1e00ffd18b3d95925d4e1032b2e399ed6e1b9037 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Thu, 12 Aug 2021 16:44:19 +0800 Subject: [PATCH 48/60] fix: recovery code --- .../twitter.com/injection/EnhancedProfileTab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx index f77a79979cc3..8bc89482c851 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx @@ -127,5 +127,5 @@ function getStyle() { export function EnhancedProfileTabAtTwitter() { const style = getStyle() const classes = useStyles(style) - return + return } /> } From a37b6237d25d293dd9161fa0c8e5ff7142ba2075 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Thu, 12 Aug 2021 18:29:11 +0800 Subject: [PATCH 49/60] fix: ens resolve --- .../twitter.com/injection/useEthereumName.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts index f1127692e082..05bd97328c9d 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/useEthereumName.ts @@ -9,6 +9,7 @@ export function useEthereumName(nickname: string, twitterId: string, bio: string const [ethereumName, setEthereumName] = useState('') useEffect(() => { + setEthereumName('') const matched = bio.match(ENS_RE) if (matched) { setEthereumName(matched[0]) From 342dd4296ce12846661b958c763681aff3670c22 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Thu, 12 Aug 2021 19:14:08 +0800 Subject: [PATCH 50/60] fix: css breaks --- packages/theme/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/theme/package.json b/packages/theme/package.json index 100929db7bb1..a516b82f9a7e 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -21,7 +21,7 @@ "notistack": "1.0.6-next.1", "react-window": "^1.8.6", "tinycolor2": "^1.4.2", - "tss-react": "^0.6.0-beta.1", + "tss-react": "^0.6.0", "use-subscription": "^1.5.1" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72d8ad8153d4..1146840d057e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -687,7 +687,7 @@ importers: react-window: ^1.8.6 storybook-addon-matrix: ^1.6.0 tinycolor2: ^1.4.2 - tss-react: ^0.6.0-beta.1 + tss-react: ^0.6.0 use-subscription: ^1.5.1 dependencies: '@masknet/storybook-shared': link:../storybook-shared @@ -697,7 +697,7 @@ importers: notistack: 1.0.6-next.1_132ff92e0fd7328580f6380de259b809 react-window: 1.8.6_f991c289939c8299bed5e4a6a5a79a62 tinycolor2: 1.4.2 - tss-react: 0.6.0-beta.1_c6fea8dcaf6b764ffb1999acad870c8e + tss-react: 0.6.0_bef0d66e98e8cc6f9687bc5bf9034690 use-subscription: 1.5.1_react@18.0.0-alpha-aecb3b6d1 devDependencies: '@babel/core': 7.14.8 @@ -18524,6 +18524,7 @@ packages: /multibase/2.0.0: resolution: {integrity: sha512-xIrqUVsinSlFjqj+OtEgCJ6MRl5hXjHMBPWsUt1ZGSRMx8rzm+7hCLE4wDeSA3COomlUC9zHCoUlvWjvAMtfDg==} engines: {node: '>=10.0.0', npm: '>=6.0.0'} + deprecated: This module has been superseded by the multiformats module dependencies: base-x: 3.0.8 buffer: 5.7.1 @@ -18533,6 +18534,7 @@ packages: /multibase/3.1.2: resolution: {integrity: sha512-bpklWHs70LO3smJUHOjcnzGceJJvn9ui0Vau6Za0B/GBepaXswmW8Ufea0uD9pROf/qCQ4N4lZ3sf3U+SNf0tw==} engines: {node: '>=10.0.0', npm: '>=6.0.0'} + deprecated: This module has been superseded by the multiformats module dependencies: '@multiformats/base-x': 4.0.1 web-encoding: 1.1.5 @@ -18541,6 +18543,7 @@ packages: /multibase/4.0.4: resolution: {integrity: sha512-8/JmrdSGzlw6KTgAJCOqUBSGd1V6186i/X8dDCGy/lbCKrQ+1QB6f3HE+wPr7Tpdj4U3gutaj9jG2rNX6UpiJg==} engines: {node: '>=12.0.0', npm: '>=6.0.0'} + deprecated: This module has been superseded by the multiformats module dependencies: '@multiformats/base-x': 4.0.1 dev: false @@ -23586,13 +23589,10 @@ packages: typescript: 2.9.2 dev: false - /tss-react/0.6.0-beta.1_c6fea8dcaf6b764ffb1999acad870c8e: - resolution: {integrity: sha512-2RtMNR5KQoZIixu+osV2tJJxIT0KBdW+sKTS2LCuz4WpULUFj5e5BUNpV4RFZj7Fmt/+mImpDHVATCx73+qLyQ==} + /tss-react/0.6.0_bef0d66e98e8cc6f9687bc5bf9034690: + resolution: {integrity: sha512-9AiMS/P30X3xPk7VMj14WBsZ/erb/Tr/Z/m07Va84E/tPy1GqVFnixx42XYwzDehaVOQQ9ap+bUNxdpBI98+uQ==} peerDependencies: - '@emotion/cache': ^11.4.0 '@emotion/react': ^11.4.1 - '@emotion/serialize': ^1.0.2 - '@emotion/utils': ^1.0.0 dependencies: '@emotion/cache': 11.4.0 '@emotion/react': 11.4.1_010541d7fdfc8cbcdd915345c89295c8 From c54300c6a7da4a9e52b7007166031566d08bc173 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Thu, 12 Aug 2021 19:22:41 +0800 Subject: [PATCH 51/60] fix: hide retry button --- .../InjectedComponents/EnhancedProfile.tsx | 11 ++++---- .../InjectedComponents/EnhancedProfileTab.tsx | 15 +++++----- .../CollectibleList/index.tsx | 11 ++++++-- .../twitter.com/injection/EnhancedProfile.tsx | 11 ++++---- .../injection/EnhancedProfileTab.tsx | 28 ++++++++++--------- 5 files changed, 40 insertions(+), 36 deletions(-) diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx index 6bdcfa92d317..03927b4f871a 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx @@ -1,18 +1,17 @@ import { useStylesExtends } from '@masknet/shared' -import { getMaskColor } from '@masknet/theme' -import { makeStyles } from '@material-ui/core' +import { getMaskColor, makeStyles } from '@masknet/theme' import { useState, useEffect } from 'react' import { CollectibleListAddress } from '../../extension/options-page/DashboardComponents/CollectibleList' import { useEthereumAddress } from '../../social-network-adaptor/twitter.com/injection/useEthereumName' import { MaskMessage } from '../../utils' import { useLocationChange } from '../../utils/hooks/useLocationChange' -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles()((theme) => ({ empty: { paddingTop: 36, paddingBottom: 36, '& > p': { - fontSize: 18, + fontSize: 28, fontFamily: 'inherit', fontWeight: 700, color: getMaskColor(theme).textPrimary, @@ -37,14 +36,14 @@ export function EnhancedProfileaPage(props: EnhancedProfileaPageProps) { MaskMessage.events.profileNFTsTabUpdated.sendToLocal('reset') } + useLocationChange(onLocalChange) + useEffect(() => { return MaskMessage.events.profileNFTsTabUpdated.on((data) => { onUpdated() }) }, []) - useLocationChange(onLocalChange) - useEffect(() => { return MaskMessage.events.profileNFTsPageUpdated.on((data) => { setShow(data.show) diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx index 6126fcc0739e..a34ed58d7a13 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx @@ -1,6 +1,6 @@ import { useStylesExtends } from '@masknet/shared' import { getMaskColor, makeStyles } from '@masknet/theme' -import classNames from 'classnames' +import classnames from 'classnames' import Color from 'color' import { ReactElement, useCallback, useEffect, useState } from 'react' @@ -30,13 +30,12 @@ const useStyles = makeStyles()((theme) => ({ export interface EnhancedProfileTabProps extends withClasses<'tab' | 'button' | 'selected'> { clear(): void reset(): void - hot?: ReactElement + children?: ReactElement } export function EnhancedProfileTab(props: EnhancedProfileTabProps) { - const { reset, clear, hot } = props - const { classes } = useStyles() - const styles = useStylesExtends(classes, props) + const { reset, clear, children } = props + const classes = useStylesExtends(useStyles(), props) const [active, setActive] = useState(false) const onClose = () => { @@ -59,10 +58,10 @@ export function EnhancedProfileTab(props: EnhancedProfileTabProps) { }, [clear, onOpen]) return ( -
-
+
+
NFTs - {active && hot ? hot : null} + {active && children ? children : null}
) diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index e5533e44b4ee..d0648cb3314c 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -80,6 +80,7 @@ interface CollectibleListUIProps extends withClasses<'empty' | 'button'> { hasNextPage: boolean readonly?: boolean page: number + hasRetry?: boolean onNextPage: () => void onPrevPage: () => void } @@ -94,6 +95,7 @@ function CollectibleListUI(props: CollectibleListUIProps) { error, readonly, page, + hasRetry = true, onNextPage, onPrevPage, } = props @@ -126,9 +128,11 @@ function CollectibleListUI(props: CollectibleListUIProps) { {error || collectibles.length === 0 ? ( {t('dashboard_no_collectible_found')} - + {hasRetry ? ( + + ) : null} ) : ( @@ -204,6 +208,7 @@ export function CollectibleListAddress(props: CollectibleListAddressProps) { readonly={true} page={page} hasNextPage={hasNextPage} + hasRetry={!!address} onPrevPage={() => setPage((prev) => prev - 1)} onNextPage={() => setPage((next) => next + 1)} /> diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx index 5659219fa94d..6ca94b89f6d5 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfile.tsx @@ -1,6 +1,5 @@ import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit' -import { getMaskColor } from '@masknet/theme' -import { makeStyles, Theme } from '@material-ui/core' +import { getMaskColor, makeStyles } from '@masknet/theme' import { useState } from 'react' import { EnhancedProfileaPage } from '../../../components/InjectedComponents/EnhancedProfile' import { createReactRootShadowed, startWatch } from '../../../utils' @@ -32,7 +31,7 @@ interface StyleProps { backgroundColor: string } -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles()((theme, props) => ({ empty: { paddingTop: 36, paddingBottom: 36, @@ -44,11 +43,11 @@ const useStyles = makeStyles((theme) => ({ }, }, button: { - backgroundColor: (props: StyleProps) => props.backgroundColor, + backgroundColor: props.backgroundColor, color: 'white', marginTop: 18, '&:hover': { - backgroundColor: (props: StyleProps) => props.backgroundColor, + backgroundColor: props.backgroundColor, }, }, })) @@ -56,7 +55,7 @@ const useStyles = makeStyles((theme) => ({ export function EnhancedProfileaPageAtTwitter() { const newTweetButton = searchNewTweetButtonSelector().evaluate() const style = newTweetButton ? window.getComputedStyle(newTweetButton) : EMPTY_STYLE - const classes = useStyles({ backgroundColor: style.backgroundColor }) + const { classes } = useStyles({ backgroundColor: style.backgroundColor }) const [bio, setBio] = useState(getBioDescription()) const [nickname, setNickname] = useState(getNickname()) diff --git a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx index 8bc89482c851..56c7c7c4c58d 100644 --- a/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/social-network-adaptor/twitter.com/injection/EnhancedProfileTab.tsx @@ -11,7 +11,7 @@ import { searchProfileTabSelector, } from '../utils/selector' import Color from 'color' -import { makeStyles, Theme } from '@material-ui/core' +import { makeStyles } from '@masknet/theme' export function injectEnhancedProfileTabAtTwitter(signal: AbortSignal) { const watcher = new MutationObserverWatcher(searchProfileTabListLastChildSelector()) @@ -29,13 +29,13 @@ interface StyleProps { line: string } -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles()((theme, props) => ({ tab: { '&:hover': { - backgroundColor: (props: StyleProps) => new Color(props.hover).alpha(0.1).toString(), + backgroundColor: new Color(props.hover).alpha(0.1).toString(), cursor: 'pointer', }, - height: (props: StyleProps) => props.height, + height: props.height, }, button: { display: 'flex', @@ -43,17 +43,17 @@ const useStyles = makeStyles((theme) => ({ justifyContent: 'center', alignItems: 'center', textAlign: 'center', - padding: (props: StyleProps) => props.padding, + padding: props.padding, fontWeight: 700, - color: (props: StyleProps) => props.color, - font: (props: StyleProps) => props.font, - fontSize: (props: StyleProps) => props.fontSize, + color: props.color, + font: props.font, + fontSize: props.fontSize, '&:hover': { - color: (props: StyleProps) => props.hover, + color: props.hover, }, }, selected: { - color: (props: StyleProps) => props.hover, + color: props.hover, }, line: { dispaly: 'inline-flex', @@ -63,7 +63,7 @@ const useStyles = makeStyles((theme) => ({ minWidth: 56, alignSelf: 'center', height: 4, - backgroundColor: (props: StyleProps) => props.line, + backgroundColor: props.line, }, })) @@ -126,6 +126,8 @@ function getStyle() { export function EnhancedProfileTabAtTwitter() { const style = getStyle() - const classes = useStyles(style) - return } /> + const { classes } = useStyles(style) + return ( + } /> + ) } From 0ca51c6616739df47beb7eea436b36e6c1762c70 Mon Sep 17 00:00:00 2001 From: lelenei <72531217+lelenei@users.noreply.github.com> Date: Thu, 12 Aug 2021 21:12:19 +0800 Subject: [PATCH 52/60] refactor: use makeStyles --- .../src/components/InjectedComponents/EnhancedProfile.tsx | 7 ++----- .../components/InjectedComponents/EnhancedProfileTab.tsx | 4 +++- .../DashboardComponents/CollectibleList/index.tsx | 4 ++-- .../twitter.com/injection/EnhancedProfile.tsx | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx index 03927b4f871a..b6ba0e49d906 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfile.tsx @@ -7,20 +7,17 @@ import { MaskMessage } from '../../utils' import { useLocationChange } from '../../utils/hooks/useLocationChange' const useStyles = makeStyles()((theme) => ({ - empty: { + text: { paddingTop: 36, paddingBottom: 36, '& > p': { - fontSize: 28, - fontFamily: 'inherit', - fontWeight: 700, color: getMaskColor(theme).textPrimary, }, }, button: {}, })) -interface EnhancedProfileaPageProps extends withClasses<'empty' | 'button'> { +interface EnhancedProfileaPageProps extends withClasses<'text' | 'button'> { bioDescription: string nickname: string twitterId: string diff --git a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx index a34ed58d7a13..29c9cc9081b3 100644 --- a/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx +++ b/packages/maskbook/src/components/InjectedComponents/EnhancedProfileTab.tsx @@ -19,9 +19,11 @@ const useStyles = makeStyles()((theme) => ({ justifyContent: 'center', alignItems: 'center', textAlign: 'center', - padding: theme.spacing(1), fontWeight: 700, color: getMaskColor(theme).blue, + '&:hover': { + color: getMaskColor(theme).blue, + }, }, selected: { color: 'black', diff --git a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx index d0648cb3314c..dec58584fa0d 100644 --- a/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx +++ b/packages/maskbook/src/extension/options-page/DashboardComponents/CollectibleList/index.tsx @@ -29,7 +29,7 @@ const useStyles = makeStyles((theme) => ({ gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gridGap: theme.spacing(1), }, - empty: { + text: { display: 'flex', flexDirection: 'column', alignItems: 'center', @@ -126,7 +126,7 @@ function CollectibleListUI(props: CollectibleListUIProps) { {error || collectibles.length === 0 ? ( - + {t('dashboard_no_collectible_found')} {hasRetry ? (