From 15393c7ed5076e86757e4829d6c3f60dde9eac1b Mon Sep 17 00:00:00 2001 From: Jack Works Date: Mon, 7 Feb 2022 22:02:27 +0800 Subject: [PATCH 1/9] refactor: move plugin-infra i18n to its package --- .../mask/src/components/CompositionDialog/BadgeRenderer.tsx | 3 +-- .../src/components/CompositionDialog/PluginEntryRender.tsx | 3 ++- packages/plugin-infra/package.json | 6 ++++++ packages/plugin-infra/src/hooks/index.ts | 1 + .../src/hooks/useI18N.tsx} | 2 +- pnpm-lock.yaml | 6 +++--- 6 files changed, 14 insertions(+), 7 deletions(-) rename packages/{mask/src/plugin-infra/I18NFieldRender.tsx => plugin-infra/src/hooks/useI18N.tsx} (95%) diff --git a/packages/mask/src/components/CompositionDialog/BadgeRenderer.tsx b/packages/mask/src/components/CompositionDialog/BadgeRenderer.tsx index b7870dfb4910..c80ac97b4958 100644 --- a/packages/mask/src/components/CompositionDialog/BadgeRenderer.tsx +++ b/packages/mask/src/components/CompositionDialog/BadgeRenderer.tsx @@ -1,8 +1,7 @@ -import { useActivatedPluginsSNSAdaptor, Plugin } from '@masknet/plugin-infra' +import { useActivatedPluginsSNSAdaptor, Plugin, usePluginI18NField } from '@masknet/plugin-infra' import { makeStyles } from '@masknet/theme' import type { TypedMessage } from '@masknet/shared-base' import { Box, Chip } from '@mui/material' -import { usePluginI18NField } from '../../plugin-infra/I18NFieldRender' import { ShadowRootTooltip, useI18N } from '../../utils' const useStyles = makeStyles()((theme) => ({ diff --git a/packages/mask/src/components/CompositionDialog/PluginEntryRender.tsx b/packages/mask/src/components/CompositionDialog/PluginEntryRender.tsx index 4ec9176689ec..33f3b5495d1b 100644 --- a/packages/mask/src/components/CompositionDialog/PluginEntryRender.tsx +++ b/packages/mask/src/components/CompositionDialog/PluginEntryRender.tsx @@ -3,10 +3,11 @@ import { useActivatedPluginSNSAdaptor_Web3Supported, useActivatedPluginsSNSAdaptor, Plugin, + PluginI18NFieldRender, + usePluginI18NField, } from '@masknet/plugin-infra' import { ErrorBoundary } from '@masknet/shared' import { Result } from 'ts-results' -import { PluginI18NFieldRender, usePluginI18NField } from '../../plugin-infra/I18NFieldRender' import { RedPacketPluginID } from '../../plugins/RedPacket/constants' import { ITO_PluginID } from '../../plugins/ITO/constants' import { ClickableChip } from '../shared/SelectRecipients/ClickableChip' diff --git a/packages/plugin-infra/package.json b/packages/plugin-infra/package.json index 3489a4fb2d3c..67f1c3085906 100644 --- a/packages/plugin-infra/package.json +++ b/packages/plugin-infra/package.json @@ -18,5 +18,11 @@ "react-use": "^17.3.2", "unstated-next": "^1.1.0", "use-subscription": "^1.5.1" + }, + "devDependencies": { + "react-i18next": "^11.15.3" + }, + "peerDependencies": { + "react-i18next": "^11.15.3" } } diff --git a/packages/plugin-infra/src/hooks/index.ts b/packages/plugin-infra/src/hooks/index.ts index e18c0691aa98..6bf304a8cc5d 100644 --- a/packages/plugin-infra/src/hooks/index.ts +++ b/packages/plugin-infra/src/hooks/index.ts @@ -4,3 +4,4 @@ export * from './useActivatedPluginWeb3State' export * from './useAllPluginsWeb3State' export * from './useLookupDomain' export * from './useReverseAddress' +export * from './useI18N' diff --git a/packages/mask/src/plugin-infra/I18NFieldRender.tsx b/packages/plugin-infra/src/hooks/useI18N.tsx similarity index 95% rename from packages/mask/src/plugin-infra/I18NFieldRender.tsx rename to packages/plugin-infra/src/hooks/useI18N.tsx index 33996c7cab31..523a46569658 100644 --- a/packages/mask/src/plugin-infra/I18NFieldRender.tsx +++ b/packages/plugin-infra/src/hooks/useI18N.tsx @@ -1,5 +1,5 @@ -import type { I18NFieldOrReactNode, I18NStringField } from '@masknet/plugin-infra' import { useTranslation } from 'react-i18next' +import type { I18NFieldOrReactNode, I18NStringField } from '../types' export interface PluginI18NFieldRenderProps { field: I18NFieldOrReactNode diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92663eed3ce5..24fb087f686a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -581,6 +581,7 @@ importers: '@types/use-subscription': ^1.0.0 async-call-rpc: ^6.0.1 bignumber.js: ^9.0.2 + react-i18next: ^11.15.3 react-use: ^17.3.2 unstated-next: ^1.1.0 use-subscription: ^1.5.1 @@ -597,6 +598,8 @@ importers: react-use: 17.3.2_757a802188413a36d4f24237d13b8e90 unstated-next: 1.1.0 use-subscription: 1.5.1_react@18.0.0-rc.0 + devDependencies: + react-i18next: 11.15.3_5f1f718baae1643018ff61bbe4484af0 packages/plugins/DAO: specifiers: @@ -15613,7 +15616,6 @@ packages: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} dependencies: void-elements: 3.1.0 - dev: false /html-tags/3.1.0: resolution: {integrity: sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==} @@ -20293,7 +20295,6 @@ packages: i18next: 21.6.9 react: 18.0.0-rc.0 react-dom: 18.0.0-rc.0_react@18.0.0-rc.0 - dev: false /react-inspector/5.1.1_react@18.0.0-rc.0: resolution: {integrity: sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==} @@ -23965,7 +23966,6 @@ packages: /void-elements/3.1.0: resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} engines: {node: '>=0.10.0'} - dev: false /vscode-uri/3.0.3: resolution: {integrity: sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==} From a5f250fc153b36ed1690eff5961e1282627b5a5d Mon Sep 17 00:00:00 2001 From: Jack Works Date: Mon, 7 Feb 2022 22:32:00 +0800 Subject: [PATCH 2/9] refactor: move plugin wrapper to plugin-infra --- .../DecryptedPost/DecryptedPostSuccess.tsx | 2 + .../InjectedComponents/PostInspector.tsx | 2 + .../mask/src/plugins/MaskPluginWrapper.tsx | 9 ++- packages/plugin-infra/src/hooks/index.ts | 1 + .../src/hooks/usePluginWrapper.tsx | 13 +++++ .../src/utils/createInjectHooksRenderer.tsx | 55 ++++++++++++------- 6 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 packages/plugin-infra/src/hooks/usePluginWrapper.tsx diff --git a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx index 40ae0dd9c48a..538afc7f7236 100644 --- a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx +++ b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx @@ -15,10 +15,12 @@ import { useDisabledPluginSuggestionFromPost, PossiblePluginSuggestionUI, } from '../DisabledPluginSuggestion' +import { generatePluginWrapper } from '../../../plugins/MaskPluginWrapper' const PluginRenderer = createInjectHooksRenderer( useActivatedPluginsSNSAdaptor.visibility.useNotMinimalMode, (x) => x.DecryptedInspector, + (x) => generatePluginWrapper(x.ID, x.name), ) function PluginRendererWithSuggestion(props: MetadataRendererProps) { const a = useDisabledPluginSuggestionFromMeta(props.metadata || new Map()) diff --git a/packages/mask/src/components/InjectedComponents/PostInspector.tsx b/packages/mask/src/components/InjectedComponents/PostInspector.tsx index 15667c9b1eb0..0001815cb813 100644 --- a/packages/mask/src/components/InjectedComponents/PostInspector.tsx +++ b/packages/mask/src/components/InjectedComponents/PostInspector.tsx @@ -18,10 +18,12 @@ import { usePostInfoDetails } from '../DataSource/usePostInfo' import { decodePublicKeyUI } from '../../social-network/utils/text-payload-ui' import { createInjectHooksRenderer, useActivatedPluginsSNSAdaptor } from '@masknet/plugin-infra' import { PossiblePluginSuggestionPostInspector } from './DisabledPluginSuggestion' +import { generatePluginWrapper } from '../../plugins/MaskPluginWrapper' const PluginHooksRenderer = createInjectHooksRenderer( useActivatedPluginsSNSAdaptor.visibility.useNotMinimalMode, (plugin) => plugin.PostInspector, + (x) => generatePluginWrapper(x.ID, x.name), ) export interface PostInspectorProps { diff --git a/packages/mask/src/plugins/MaskPluginWrapper.tsx b/packages/mask/src/plugins/MaskPluginWrapper.tsx index 2131a7558a53..a2b88e50c86e 100644 --- a/packages/mask/src/plugins/MaskPluginWrapper.tsx +++ b/packages/mask/src/plugins/MaskPluginWrapper.tsx @@ -7,7 +7,7 @@ import { isTwitter } from '../social-network-adaptor/twitter.com/base' import { usePersonaConnectStatus } from '../components/DataSource/usePersonaConnectStatus' import { useI18N } from '../utils' import { Box } from '@mui/system' -import type { Plugin } from '@masknet/plugin-infra' +import { Plugin, I18NStringField, usePluginI18NField } from '@masknet/plugin-infra' interface PluginWrapperProps extends React.PropsWithChildren<{}> { pluginName: string @@ -120,3 +120,10 @@ export default function MaskPluginWrapper(props: PluginWrapperProps) { ) return } children={inner} /> } + +export function generatePluginWrapper(pluginID: string, pluginName: I18NStringField) { + return function PluginWrapper(props: React.PropsWithChildren<{}>) { + const t = usePluginI18NField() + return + } +} diff --git a/packages/plugin-infra/src/hooks/index.ts b/packages/plugin-infra/src/hooks/index.ts index 6bf304a8cc5d..7f08794c5879 100644 --- a/packages/plugin-infra/src/hooks/index.ts +++ b/packages/plugin-infra/src/hooks/index.ts @@ -5,3 +5,4 @@ export * from './useAllPluginsWeb3State' export * from './useLookupDomain' export * from './useReverseAddress' export * from './useI18N' +export * from './usePluginWrapper' diff --git a/packages/plugin-infra/src/hooks/usePluginWrapper.tsx b/packages/plugin-infra/src/hooks/usePluginWrapper.tsx new file mode 100644 index 000000000000..a748174efd55 --- /dev/null +++ b/packages/plugin-infra/src/hooks/usePluginWrapper.tsx @@ -0,0 +1,13 @@ +import { createContext, useContext } from 'react' + +const PluginWrapperContext = createContext>>(DefaultWrapper) +function DefaultWrapper(props: React.PropsWithChildren<{}>) { + return <>{props.children} +} + +export function usePluginWrapper() { + return useContext(PluginWrapperContext) +} + +/** @internal */ +export const PluginWrapperProvider = PluginWrapperContext.Provider diff --git a/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx b/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx index 20c5f56b376c..2b9bc0e4b288 100644 --- a/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx +++ b/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx @@ -1,37 +1,54 @@ import type { Plugin } from '../types' -import { useEffect, useState, useRef } from 'react' +import React, { useEffect, useState, useRef, memo, createContext, useContext } from 'react' import { ErrorBoundary } from '@masknet/shared' +import { usePluginI18NField, PluginWrapperProvider } from '../hooks' type Inject = Plugin.InjectUI type Raw = Plugin.InjectUIRaw +const PropsContext = createContext(null) export function createInjectHooksRenderer( usePlugins: () => PluginDefinition[], - pickInjector: (plugin: PluginDefinition) => undefined | Inject, -): React.FunctionComponent { - const picker = (plugin: PluginDefinition) => ({ - key: plugin.ID, - name: plugin.name, - ui: pickInjector(plugin), - }) - function InjectHooksRenderer(props: PropsType) { - const all = usePlugins() - .map(picker) - .filter((x) => x.ui) - .map(({ key, name, ui }) => ( - // TODO: i18n - -
+ pickInjectorHook: (plugin: PluginDefinition) => undefined | Inject, + maskWrapperProvider?: (plugin: PluginDefinition) => React.ComponentType>, +) { + function usePluginWrapperProvider(element: JSX.Element | null, plugin: PluginDefinition) { + const Wrapper = useRef | false>() + if (Wrapper.current === undefined || Wrapper.current === null) { + Wrapper.current = maskWrapperProvider?.(plugin) || false + } + if (Wrapper.current) return {element} + return element + } + function SinglePluginWithinErrorBoundary({ plugin }: { plugin: PluginDefinition }) { + const t = usePluginI18NField() + const props = useContext(PropsContext) + const ui = pickInjectorHook(plugin) + return usePluginWrapperProvider( + ui ? ( + +
+ ) : null, + plugin, + ) + } + function PluginsInjectionHookRender(props: PropsType) { + const all = usePlugins() + .filter(pickInjectorHook) + .map((plugin) => ( + + + )) return <>{all} } - return function (props: PropsType) { + return memo(function PluginsInjectionHookRenderErrorBoundary(props: PropsType) { return ( - + ) - } + }) } function Main(props: { data: T; UI: Inject }) { From 968f8fe3f6bea2b5b914fa91b945ba00099583c9 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Mon, 7 Feb 2022 22:43:48 +0800 Subject: [PATCH 3/9] chore: add publisher to wrapper --- .../DecryptedPost/DecryptedPostSuccess.tsx | 2 +- .../components/InjectedComponents/PostInspector.tsx | 2 +- packages/mask/src/plugins/MaskPluginWrapper.tsx | 12 +++++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx index 538afc7f7236..d6111889ada1 100644 --- a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx +++ b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPostSuccess.tsx @@ -20,7 +20,7 @@ import { generatePluginWrapper } from '../../../plugins/MaskPluginWrapper' const PluginRenderer = createInjectHooksRenderer( useActivatedPluginsSNSAdaptor.visibility.useNotMinimalMode, (x) => x.DecryptedInspector, - (x) => generatePluginWrapper(x.ID, x.name), + generatePluginWrapper, ) function PluginRendererWithSuggestion(props: MetadataRendererProps) { const a = useDisabledPluginSuggestionFromMeta(props.metadata || new Map()) diff --git a/packages/mask/src/components/InjectedComponents/PostInspector.tsx b/packages/mask/src/components/InjectedComponents/PostInspector.tsx index 0001815cb813..e6b0e104a71a 100644 --- a/packages/mask/src/components/InjectedComponents/PostInspector.tsx +++ b/packages/mask/src/components/InjectedComponents/PostInspector.tsx @@ -23,7 +23,7 @@ import { generatePluginWrapper } from '../../plugins/MaskPluginWrapper' const PluginHooksRenderer = createInjectHooksRenderer( useActivatedPluginsSNSAdaptor.visibility.useNotMinimalMode, (plugin) => plugin.PostInspector, - (x) => generatePluginWrapper(x.ID, x.name), + generatePluginWrapper, ) export interface PostInspectorProps { diff --git a/packages/mask/src/plugins/MaskPluginWrapper.tsx b/packages/mask/src/plugins/MaskPluginWrapper.tsx index a2b88e50c86e..f2e3c7110594 100644 --- a/packages/mask/src/plugins/MaskPluginWrapper.tsx +++ b/packages/mask/src/plugins/MaskPluginWrapper.tsx @@ -7,7 +7,7 @@ import { isTwitter } from '../social-network-adaptor/twitter.com/base' import { usePersonaConnectStatus } from '../components/DataSource/usePersonaConnectStatus' import { useI18N } from '../utils' import { Box } from '@mui/system' -import { Plugin, I18NStringField, usePluginI18NField } from '@masknet/plugin-infra' +import { Plugin, usePluginI18NField } from '@masknet/plugin-infra' interface PluginWrapperProps extends React.PropsWithChildren<{}> { pluginName: string @@ -121,9 +121,15 @@ export default function MaskPluginWrapper(props: PluginWrapperProps) { return } children={inner} /> } -export function generatePluginWrapper(pluginID: string, pluginName: I18NStringField) { +export function generatePluginWrapper(plugin: Plugin.Shared.Definition) { return function PluginWrapper(props: React.PropsWithChildren<{}>) { const t = usePluginI18NField() - return + return ( + + ) } } From b8a6a0032337bbeb2ea0c00fead670e226989648 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Mon, 7 Feb 2022 22:49:28 +0800 Subject: [PATCH 4/9] refactor: remove unnecessary suspense --- .../src/plugins/Furucombo/SNSAdaptor/index.tsx | 11 ++++------- .../mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx | 11 ++++------- .../mask/src/plugins/MaskBox/SNSAdaptor/index.tsx | 15 ++++++--------- packages/mask/src/plugins/MaskPluginWrapper.tsx | 10 ++++++++-- .../src/plugins/PoolTogether/SNSAdaptor/index.tsx | 15 ++++++--------- .../mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx | 7 ++----- 6 files changed, 30 insertions(+), 39 deletions(-) diff --git a/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx b/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx index a927b6dbe652..0e7939b86451 100644 --- a/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx @@ -1,6 +1,5 @@ -import { Suspense, useMemo } from 'react' +import { useMemo } from 'react' import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' -import { SnackbarContent } from '@mui/material' import { base } from '../base' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import MaskPluginWrapper from '../../MaskPluginWrapper' @@ -34,11 +33,9 @@ function Renderer(props: React.PropsWithChildren<{ url: string }>) { return ( - }> - - - - + + + ) } diff --git a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx index 9d21abb9cc52..8b74f6555d22 100644 --- a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx @@ -1,7 +1,6 @@ -import { Suspense, useMemo } from 'react' +import { useMemo } from 'react' import { ChainId } from '@masknet/web3-shared-evm' import { NetworkPluginID, Plugin, useChainId } from '@masknet/plugin-infra' -import { SnackbarContent } from '@mui/material' import MaskPluginWrapper from '../../MaskPluginWrapper' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { usePostInfoDetails } from '../../../components/DataSource/usePostInfo' @@ -44,11 +43,9 @@ function Renderer(props: React.PropsWithChildren<{ url: string }>) { const chainId = useChainId(NetworkPluginID.PLUGIN_EVM) return ( - }> - - - - + + + ) } diff --git a/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx b/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx index e1d10b384dbd..042725c29a81 100644 --- a/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx @@ -1,6 +1,5 @@ -import { Suspense, useMemo } from 'react' +import { useMemo } from 'react' import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' -import { SnackbarContent } from '@mui/material' import { base } from '../base' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { EthereumChainBoundary } from '../../../web3/UI/EthereumChainBoundary' @@ -39,13 +38,11 @@ function Renderer(props: React.PropsWithChildren<{ url: string }>) { return ( - }> - - - - - - + + + + + ) } diff --git a/packages/mask/src/plugins/MaskPluginWrapper.tsx b/packages/mask/src/plugins/MaskPluginWrapper.tsx index f2e3c7110594..683cd61fc2d3 100644 --- a/packages/mask/src/plugins/MaskPluginWrapper.tsx +++ b/packages/mask/src/plugins/MaskPluginWrapper.tsx @@ -7,9 +7,10 @@ import { isTwitter } from '../social-network-adaptor/twitter.com/base' import { usePersonaConnectStatus } from '../components/DataSource/usePersonaConnectStatus' import { useI18N } from '../utils' import { Box } from '@mui/system' -import { Plugin, usePluginI18NField } from '@masknet/plugin-infra' +import { Plugin, usePluginI18NField, PluginI18NFieldRender } from '@masknet/plugin-infra' interface PluginWrapperProps extends React.PropsWithChildren<{}> { + pluginID?: string pluginName: string width?: number action?: ReactNode @@ -94,7 +95,11 @@ export default function MaskPluginWrapper(props: PluginWrapperProps) { - {publisher.name.fallback} + {props.pluginID ? ( + + ) : ( + publisher.name.fallback + )} @@ -128,6 +133,7 @@ export function generatePluginWrapper(plugin: Plugin.Shared.Definition) { ) diff --git a/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx b/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx index 3afd64bb8b58..c22c67355656 100644 --- a/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx @@ -1,8 +1,7 @@ -import { Suspense, useMemo } from 'react' +import { useMemo } from 'react' import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { ChainId } from '@masknet/web3-shared-evm' -import { SnackbarContent } from '@mui/material' import { base } from '../base' import MaskPluginWrapper from '../../MaskPluginWrapper' import { DepositDialog } from '../UI/DepositDialog' @@ -41,13 +40,11 @@ export default sns function Renderer(props: React.PropsWithChildren<{ url: string }>) { return ( - }> - [ChainId.Mainnet, ChainId.Matic].includes(chainId)}> - - - + [ChainId.Mainnet, ChainId.Matic].includes(chainId)}> + + ) } diff --git a/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx b/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx index 017740a03739..29c510a3a67b 100644 --- a/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx @@ -1,7 +1,6 @@ -import { Suspense, useMemo } from 'react' +import { useMemo } from 'react' import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' -import { SnackbarContent } from '@mui/material' import { base } from '../base' import MaskPluginWrapper from '../../MaskPluginWrapper' import { PoolView } from '../UI/PoolView' @@ -51,9 +50,7 @@ export default sns function Renderer(props: React.PropsWithChildren<{ link: string; address: string }>) { return ( - }> - - + ) } From 0569bbc58d488229176505c5fbb2ac4e16786642 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Thu, 10 Feb 2022 12:22:46 +0800 Subject: [PATCH 5/9] chore: move it out --- .../DecryptedPost/DecryptPostFailed.tsx | 4 +- .../DecryptedPost/DecryptedPostSuccess.tsx | 4 +- .../DisabledPluginSuggestion.tsx | 6 +- .../InjectedComponents/PostInspector.tsx | 4 +- .../plugins/Collectible/SNSAdaptor/index.tsx | 21 ++---- .../plugins/CryptoartAI/SNSAdaptor/index.tsx | 21 ++---- .../plugins/FindTruman/SNSAdaptor/index.tsx | 37 +++++----- .../plugins/Furucombo/SNSAdaptor/index.tsx | 13 ++-- .../src/plugins/Gitcoin/SNSAdaptor/index.tsx | 12 ++- .../plugins/GoodGhosting/SNSAdaptor/index.tsx | 17 ++--- .../mask/src/plugins/ITO/SNSAdaptor/index.tsx | 12 ++- .../src/plugins/MaskBox/SNSAdaptor/index.tsx | 19 +++-- .../mask/src/plugins/MaskPluginWrapper.tsx | 74 ++++++++++++------- .../plugins/Polls/SNSAdaptor/PollsInPost.tsx | 26 +++---- .../plugins/PoolTogether/SNSAdaptor/index.tsx | 16 ++-- .../plugins/RedPacket/SNSAdaptor/index.tsx | 15 ++-- .../src/plugins/Snapshot/SNSAdaptor/index.tsx | 36 +++++---- .../SNSAdaptor/UnlockProtocolInPost.tsx | 29 ++++---- .../src/plugins/dHEDGE/SNSAdaptor/index.tsx | 10 +-- packages/plugin-infra/src/hooks/index.ts | 2 +- .../src/hooks/usePluginWrapper.tsx | 38 +++++++--- .../src/utils/createInjectHooksRenderer.tsx | 21 ++++-- 22 files changed, 221 insertions(+), 216 deletions(-) diff --git a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx index 849d15a05539..860f5b03a5a6 100644 --- a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx +++ b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx @@ -4,7 +4,7 @@ import { AdditionalContent } from '../AdditionalPostContent' import { DecryptFailedReason } from '../../../utils/constants' import type { ProfileIdentifier } from '@masknet/shared-base' import { wrapAuthorDifferentMessage } from './authorDifferentMessage' -import MaskPluginWrapper from '../../../plugins/MaskPluginWrapper' +import MaskPostExtraInfoWrapper from '../../../plugins/MaskPluginWrapper' export interface DecryptPostFailedProps { error: Error @@ -18,7 +18,7 @@ export const DecryptPostFailed = memo(function DecryptPostFailed(props: DecryptP const { t } = useI18N() if (error?.message === DecryptFailedReason.MyCryptoKeyNotFound) { - return + return } return ( x.DecryptedInspector, - generatePluginWrapper, + MaskPostExtraPluginWrapper, ) function PluginRendererWithSuggestion(props: MetadataRendererProps) { const a = useDisabledPluginSuggestionFromMeta(props.metadata || new Map()) diff --git a/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx b/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx index 59ec3d778954..a0578c535e13 100644 --- a/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx +++ b/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx @@ -8,7 +8,7 @@ import { import { extractTextFromTypedMessage } from '@masknet/shared-base' import { Switch } from '@mui/material' import Services from '../../extension/service' -import MaskPluginWrapper from '../../plugins/MaskPluginWrapper' +import MaskPostExtraInfoWrapper from '../../plugins/MaskPluginWrapper' import { useI18N } from '../../utils' function useDisabledPlugins() { @@ -56,9 +56,9 @@ export function PossiblePluginSuggestionUI(props: { plugins: Plugin.DeferredDefi return ( <> {plugins.map((x) => ( - plugin.PostInspector, - generatePluginWrapper, + MaskPostExtraPluginWrapper, ) export interface PostInspectorProps { diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx index be67a0935d55..171a280e2fa5 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/index.tsx @@ -1,11 +1,9 @@ import { uniq, first } from 'lodash-unified' -import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' -import MaskPluginWrapper from '../../MaskPluginWrapper' +import { Plugin, usePostInfoDetails, usePluginWrapper } from '@masknet/plugin-infra' import { PostInspector } from './PostInspector' import { base } from '../base' -import type { CollectibleJSON_Payload } from '../types' import { checkUrl, getAssetInfoFromURL, getRelevantUrl } from '../utils' -import { PLUGIN_NAME, PLUGIN_ID } from '../constants' +import { PLUGIN_ID } from '../constants' import { getTypedMessageContent } from '../../../protocols/typed-message' import { NFTPage } from './NFTPage' import { AddressName, AddressNameType } from '@masknet/web3-shared-evm' @@ -17,13 +15,14 @@ const sns: Plugin.SNSAdaptor.Definition = { const links = usePostInfoDetails.mentionedLinks() const link = uniq(links).find(checkUrl) const asset = getAssetInfoFromURL(link) - - return asset ? renderPostInspector(asset) : null + usePluginWrapper(!!asset) + return asset ? : null }, DecryptedInspector: function Component(props) { const collectibleUrl = getRelevantUrl(getTypedMessageContent(props.message)) const asset = getAssetInfoFromURL(collectibleUrl) - return asset ? renderPostInspector(asset) : null + usePluginWrapper(!!asset) + return asset ? : null }, ProfileTabs: [ { @@ -69,11 +68,3 @@ const sns: Plugin.SNSAdaptor.Definition = { } export default sns - -function renderPostInspector(payload: CollectibleJSON_Payload) { - return ( - - - - ) -} diff --git a/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/index.tsx b/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/index.tsx index cdf689f9f321..77d47b296fad 100644 --- a/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/index.tsx @@ -1,11 +1,8 @@ import { uniq } from 'lodash-unified' -import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' -import MaskPluginWrapper from '../../MaskPluginWrapper' +import { Plugin, usePostInfoDetails, usePluginWrapper } from '@masknet/plugin-infra' import { PostInspector } from './PostInspector' import { base } from '../base' import { checkUrl, getAssetInfoFromURL, getRelevantUrl } from '../utils' -import { PLUGIN_NAME } from '../constants' -import type { PayloadType } from '../types' import { getTypedMessageContent } from '../../../protocols/typed-message' const sns: Plugin.SNSAdaptor.Definition = { @@ -14,24 +11,16 @@ const sns: Plugin.SNSAdaptor.Definition = { PostInspector: function Component() { const links = usePostInfoDetails.mentionedLinks() const link = uniq(links).find(checkUrl) - const asset = getAssetInfoFromURL(link) - - return asset ? renderPostInspector(asset) : null + usePluginWrapper(!!asset) + return asset ? : null }, DecryptedInspector: function Component(props) { const collectibleUrl = getRelevantUrl(getTypedMessageContent(props.message)) const asset = getAssetInfoFromURL(collectibleUrl) - return asset ? renderPostInspector(asset) : null + usePluginWrapper(!!asset) + return asset ? : null }, } export default sns - -function renderPostInspector(payload: PayloadType) { - return ( - - - - ) -} diff --git a/packages/mask/src/plugins/FindTruman/SNSAdaptor/index.tsx b/packages/mask/src/plugins/FindTruman/SNSAdaptor/index.tsx index 9b918545dc64..990776f889c7 100644 --- a/packages/mask/src/plugins/FindTruman/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/FindTruman/SNSAdaptor/index.tsx @@ -1,10 +1,8 @@ -import type { Plugin } from '@masknet/plugin-infra' import { base } from '../base' import { useMemo, Suspense } from 'react' import { Skeleton } from '@mui/material' import { makeStyles } from '@masknet/theme' -import MaskPluginWrapper from '../../MaskPluginWrapper' -import { usePostInfoDetails } from '@masknet/plugin-infra' +import { type Plugin, usePostInfoDetails, usePluginWrapper } from '@masknet/plugin-infra' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { PostInspector } from './PostInspector' @@ -46,24 +44,23 @@ const isFindTrumanURL = (input: string): boolean => { function Renderer({ url }: { url: string }) { const { classes } = useStyles() + usePluginWrapper(true) + const fallbackUI = Array.from({ length: 2 }) + .fill(0) + .map((_, i) => ( + + )) return ( - - ( - - ))}> - - - + + + ) } diff --git a/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx b/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx index 0e7939b86451..500bc0944c02 100644 --- a/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/Furucombo/SNSAdaptor/index.tsx @@ -1,8 +1,7 @@ import { useMemo } from 'react' -import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' +import { Plugin, usePluginWrapper, usePostInfoDetails } from '@masknet/plugin-infra' import { base } from '../base' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { FurucomboView } from '../UI/FurucomboView' import { EthereumChainBoundary } from '../../../web3/UI/EthereumChainBoundary' @@ -30,13 +29,11 @@ const sns: Plugin.SNSAdaptor.Definition = { function Renderer(props: React.PropsWithChildren<{ url: string }>) { const [, category, chainId, address] = props.url.match(matchLink) ?? [] - + usePluginWrapper(true) return ( - - - - - + + + ) } diff --git a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx index 8b74f6555d22..9f08826461d5 100644 --- a/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/Gitcoin/SNSAdaptor/index.tsx @@ -1,7 +1,6 @@ import { useMemo } from 'react' import { ChainId } from '@masknet/web3-shared-evm' -import { NetworkPluginID, Plugin, useChainId } from '@masknet/plugin-infra' -import MaskPluginWrapper from '../../MaskPluginWrapper' +import { NetworkPluginID, Plugin, useChainId, usePluginWrapper } from '@masknet/plugin-infra' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { usePostInfoDetails } from '../../../components/DataSource/usePostInfo' import { PreviewCard } from './PreviewCard' @@ -41,12 +40,11 @@ const sns: Plugin.SNSAdaptor.Definition = { function Renderer(props: React.PropsWithChildren<{ url: string }>) { const [id = ''] = props.url.match(/\d+/) ?? [] const chainId = useChainId(NetworkPluginID.PLUGIN_EVM) + usePluginWrapper(true) return ( - - - - - + + + ) } diff --git a/packages/mask/src/plugins/GoodGhosting/SNSAdaptor/index.tsx b/packages/mask/src/plugins/GoodGhosting/SNSAdaptor/index.tsx index 64be79561831..c490ee7945af 100644 --- a/packages/mask/src/plugins/GoodGhosting/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/GoodGhosting/SNSAdaptor/index.tsx @@ -1,7 +1,5 @@ -import { Suspense, useMemo } from 'react' -import type { Plugin } from '@masknet/plugin-infra' -import { SnackbarContent } from '@mui/material' -import MaskPluginWrapper from '../../MaskPluginWrapper' +import { useMemo } from 'react' +import { Plugin, usePluginWrapper } from '@masknet/plugin-infra' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { usePostInfoDetails } from '../../../components/DataSource/usePostInfo' import { PreviewCard } from '../UI/PreviewCard' @@ -37,15 +35,12 @@ function Renderer(props: React.PropsWithChildren<{ url: string }>) { if (id) { id = id.replace('pools/', '') } + usePluginWrapper(true) return ( - - }> - - - - - + + + ) } diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/index.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/index.tsx index c342c02a36e6..a1e82a69ff96 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/index.tsx @@ -1,4 +1,4 @@ -import type { Plugin } from '@masknet/plugin-infra' +import { Plugin, usePluginWrapper } from '@masknet/plugin-infra' import { ItoLabelIcon } from '../assets/ItoLabelIcon' import { makeStyles } from '@masknet/theme' import { @@ -12,7 +12,6 @@ import { base } from '../base' import { ITO_MetaKey_1, ITO_MetaKey_2, MSG_DELIMITER } from '../constants' import type { JSON_PayloadComposeMask } from '../types' import { ITO_MetadataReader, payloadIntoMask } from './helpers' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { CompositionDialog } from './CompositionDialog' import { set } from 'lodash-unified' import { EthereumChainBoundary } from '../../../web3/UI/EthereumChainBoundary' @@ -33,13 +32,12 @@ const sns: Plugin.SNSAdaptor.Definition = { init(signal) {}, DecryptedInspector(props) { const payload = ITO_MetadataReader(props.message.meta) + usePluginWrapper(payload.ok) if (!payload.ok) return null return ( - - - - - + + + ) }, CompositionDialogMetadataBadgeRender: new Map([ diff --git a/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx b/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx index 042725c29a81..bcdc72943447 100644 --- a/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/MaskBox/SNSAdaptor/index.tsx @@ -1,10 +1,9 @@ import { useMemo } from 'react' -import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' +import { Plugin, usePluginWrapper, usePostInfoDetails } from '@masknet/plugin-infra' import { base } from '../base' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { EthereumChainBoundary } from '../../../web3/UI/EthereumChainBoundary' import { PreviewCard } from './components/PreviewCard' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { Context } from '../hooks/useContext' const isMaskBox = (x: string) => x.startsWith('https://box-beta.mask.io') || x.startsWith('https://box.mask.io') @@ -34,15 +33,15 @@ function Renderer(props: React.PropsWithChildren<{ url: string }>) { const [, chainId] = props.url.match(/chain=(\d+)/i) ?? [] const [, boxId] = props.url.match(/box=(\d+)/i) ?? [] - if (!chainId || !boxId) return null + const shouldNotRender = !chainId || !boxId + usePluginWrapper(!shouldNotRender) + if (shouldNotRender) return null return ( - - - - - - - + + + + + ) } diff --git a/packages/mask/src/plugins/MaskPluginWrapper.tsx b/packages/mask/src/plugins/MaskPluginWrapper.tsx index 683cd61fc2d3..3042b6713fdb 100644 --- a/packages/mask/src/plugins/MaskPluginWrapper.tsx +++ b/packages/mask/src/plugins/MaskPluginWrapper.tsx @@ -2,19 +2,19 @@ import { Typography, SnackbarContent, Button, Link } from '@mui/material' import { makeStyles, MaskColorVar } from '@masknet/theme' import { activatedSocialNetworkUI } from '../social-network' import { MaskIcon } from '../resources/MaskIcon' -import { Suspense, ReactNode, useMemo } from 'react' +import { Suspense, ReactNode, useMemo, forwardRef, useImperativeHandle, useState } from 'react' import { isTwitter } from '../social-network-adaptor/twitter.com/base' import { usePersonaConnectStatus } from '../components/DataSource/usePersonaConnectStatus' import { useI18N } from '../utils' import { Box } from '@mui/system' -import { Plugin, usePluginI18NField, PluginI18NFieldRender } from '@masknet/plugin-infra' +import { usePluginI18NField, PluginI18NFieldRender, PluginWrapperComponent, Plugin } from '@masknet/plugin-infra' interface PluginWrapperProps extends React.PropsWithChildren<{}> { - pluginID?: string - pluginName: string + title: string width?: number action?: ReactNode - publisher?: Plugin.Shared.Publisher + publisher?: JSX.Element + publisherLink?: string } const useStyles = makeStyles()((theme) => { @@ -63,9 +63,9 @@ const useStyles = makeStyles()((theme) => { } }) -export default function MaskPluginWrapper(props: PluginWrapperProps) { +export default function MaskPostExtraInfoWrapper(props: PluginWrapperProps) { const { classes } = useStyles() - const { pluginName, children, action, publisher } = props + const { title, children, action, publisher, publisherLink } = props const personaConnectStatus = usePersonaConnectStatus() const { t } = useI18N() @@ -73,7 +73,7 @@ export default function MaskPluginWrapper(props: PluginWrapperProps) { ? t('please_create_persona') : !personaConnectStatus.connected ? t('please_connect_persona') - : pluginName + : title const actionButton = useMemo(() => { if (!personaConnectStatus.action) return null @@ -88,23 +88,26 @@ export default function MaskPluginWrapper(props: PluginWrapperProps) { const publisherInfo = useMemo(() => { if (!publisher) return null + const main = ( + + {publisher} + + ) return ( Provided by - - - {props.pluginID ? ( - - ) : ( - publisher.name.fallback - )} - - + {publisherLink ? ( + + {main} + + ) : ( + main + )} ) - }, [publisher]) + }, [publisher, publisherLink]) const inner = (
ev.stopPropagation()}> @@ -112,7 +115,7 @@ export default function MaskPluginWrapper(props: PluginWrapperProps) {
- Mask Plugin {!personaConnectStatus.connected && pluginName ? `(${pluginName})` : ''} + Mask Plugin {!personaConnectStatus.connected && title ? `(${title})` : ''} {name} @@ -123,19 +126,34 @@ export default function MaskPluginWrapper(props: PluginWrapperProps) { {personaConnectStatus.connected && children ?
{children}
: null}
) - return } children={inner} /> + return } children={inner} /> } -export function generatePluginWrapper(plugin: Plugin.Shared.Definition) { - return function PluginWrapper(props: React.PropsWithChildren<{}>) { +export const MaskPostExtraPluginWrapper: PluginWrapperComponent = forwardRef( + (props, ref) => { + const { ID, name, publisher } = props.definition const t = usePluginI18NField() + const [width, setWidth] = useState(undefined) + const [open, setOpen] = useState(false) + const [title, setTitle] = useState(undefined) + + useImperativeHandle(ref, () => ({ setWidth, setWrap: setOpen, setWrapperName: setTitle }), []) + + if (!open) return <>{props.children} return ( - + + + ) : undefined + } + publisherLink={publisher?.link} children={props.children} /> ) - } -} + }, +) diff --git a/packages/mask/src/plugins/Polls/SNSAdaptor/PollsInPost.tsx b/packages/mask/src/plugins/Polls/SNSAdaptor/PollsInPost.tsx index 635998a92bf2..0d7b57543361 100644 --- a/packages/mask/src/plugins/Polls/SNSAdaptor/PollsInPost.tsx +++ b/packages/mask/src/plugins/Polls/SNSAdaptor/PollsInPost.tsx @@ -1,18 +1,17 @@ import { useEffect, useState } from 'react' -import MaskPluginWrapper from '../../MaskPluginWrapper' import type { TypedMessage } from '@masknet/shared-base' import { PluginPollRPC } from '../messages' import { renderWithPollMetadata, PollMetadataReader } from '../helpers' import type { PollGunDB } from '../Services' import { PollCardUI } from './Polls' import { PollMetaData, PollStatus } from '../types' +import { usePluginWrapper } from '@masknet/plugin-infra' interface PollsInPostProps { message: TypedMessage } export default function PollsInPost(props: PollsInPostProps) { - const { message } = props const [status, setStatus] = useState(PollStatus.Inactive) const [updatedPoll, setUpdatedPoll] = useState(undefined) @@ -41,16 +40,15 @@ export default function PollsInPost(props: PollsInPostProps) { } }, [props.message.meta]) - const jsx = message - ? renderWithPollMetadata(props.message.meta, (r) => { - return ( -
- - - -
- ) - }) - : null - return <>{jsx} + return renderWithPollMetadata(props.message.meta, (r) => { + return + }) +} +const C: typeof PollCardUI = (props) => { + usePluginWrapper(true, { width: 400 }) + return ( +
+ +
+ ) } diff --git a/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx b/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx index c22c67355656..c642cb0d0ccd 100644 --- a/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/PoolTogether/SNSAdaptor/index.tsx @@ -1,9 +1,8 @@ import { useMemo } from 'react' -import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' +import { Plugin, usePluginWrapper, usePostInfoDetails } from '@masknet/plugin-infra' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { ChainId } from '@masknet/web3-shared-evm' import { base } from '../base' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { DepositDialog } from '../UI/DepositDialog' import { URL_PATTERN } from '../constants' import { PoolTogetherView } from '../UI/PoolTogetherView' @@ -38,13 +37,12 @@ const sns: Plugin.SNSAdaptor.Definition = { export default sns function Renderer(props: React.PropsWithChildren<{ url: string }>) { + usePluginWrapper(true) return ( - - [ChainId.Mainnet, ChainId.Matic].includes(chainId)}> - - - + [ChainId.Mainnet, ChainId.Matic].includes(chainId)}> + + ) } diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/index.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/index.tsx index acdb3910cf82..acc345e78511 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/index.tsx @@ -1,4 +1,4 @@ -import type { Plugin } from '@masknet/plugin-infra' +import { Plugin, usePluginWrapper } from '@masknet/plugin-infra' import { ChainId, EthereumTokenType, @@ -7,7 +7,6 @@ import { getChainIdFromName, useERC20TokenDetailed, } from '@masknet/web3-shared-evm' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { base } from '../base' import { RedPacketMetaKey, RedPacketNftMetaKey } from '../constants' import { @@ -22,26 +21,30 @@ import { RedPacketInPost } from './RedPacketInPost' import { RedPacketNftInPost } from './RedPacketNftInPost' import { RedPacketIcon } from '@masknet/icons' +function Render(props: React.PropsWithChildren<{ name: string }>) { + usePluginWrapper(true, { name: props.name }) + return <>{props.children} +} const sns: Plugin.SNSAdaptor.Definition = { ...base, init(signal) {}, DecryptedInspector(props) { if (RedPacketMetadataReader(props.message.meta).ok) return ( - + {renderWithRedPacketMetadata(props.message.meta, (r) => ( ))} - + ) if (RedPacketNftMetadataReader(props.message.meta).ok) return ( - + {renderWithRedPacketNftMetadata(props.message.meta, (r) => ( ))} - + ) return null }, diff --git a/packages/mask/src/plugins/Snapshot/SNSAdaptor/index.tsx b/packages/mask/src/plugins/Snapshot/SNSAdaptor/index.tsx index 0324b7d1d693..a01dc5eaea71 100644 --- a/packages/mask/src/plugins/Snapshot/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/Snapshot/SNSAdaptor/index.tsx @@ -1,9 +1,8 @@ -import type { Plugin } from '@masknet/plugin-infra' +import { Plugin, usePluginWrapper } from '@masknet/plugin-infra' import { base } from '../base' import { useMemo, Suspense } from 'react' import { Skeleton } from '@mui/material' import { makeStyles } from '@masknet/theme' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { PostInspector } from './PostInspector' import { usePostInfoDetails } from '../../../components/DataSource/usePostInfo' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' @@ -24,24 +23,23 @@ const isSnapshotURL = (x: string): boolean => function Renderer({ url }: { url: string }) { const { classes } = useStyles() + usePluginWrapper(true) + const fallbackUI = Array.from({ length: 2 }) + .fill(0) + .map((_, i) => ( + + )) return ( - - ( - - ))}> - - - + + + ) } diff --git a/packages/mask/src/plugins/UnlockProtocol/SNSAdaptor/UnlockProtocolInPost.tsx b/packages/mask/src/plugins/UnlockProtocol/SNSAdaptor/UnlockProtocolInPost.tsx index 38062c903aa6..55e5d8f836e4 100644 --- a/packages/mask/src/plugins/UnlockProtocol/SNSAdaptor/UnlockProtocolInPost.tsx +++ b/packages/mask/src/plugins/UnlockProtocol/SNSAdaptor/UnlockProtocolInPost.tsx @@ -1,13 +1,13 @@ import type { TypedMessage } from '@masknet/shared-base' import { Button, Typography } from '@mui/material' -import { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import { useI18N } from '../../../utils' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { paywallUrl } from '../constants' import { renderWithUnlockProtocolMetadata, UnlockProtocolMetadataReader } from '../helpers' import { useAccount, useChainId } from '@masknet/web3-shared-evm' import { PluginUnlockProtocolRPC } from '../messages' import { EthereumChainBoundary } from '../../../web3/UI/EthereumChainBoundary' +import { usePluginWrapper } from '@masknet/plugin-infra' interface UnlockProtocolInPostProps { message: TypedMessage @@ -62,13 +62,11 @@ export default function UnlockProtocolInPost(props: UnlockProtocolInPostProps) { const jsx = message ? renderWithUnlockProtocolMetadata(props.message.meta, (r) => { return ( - <> - - - {content} - - - + + + {content} + + ) }) : null @@ -78,7 +76,7 @@ export default function UnlockProtocolInPost(props: UnlockProtocolInPostProps) { const jsx = message ? renderWithUnlockProtocolMetadata(props.message.meta, (r) => { return ( - + "{t('plugin_unlockprotocol_no_access')}"
"{t('plugin_unlockprotocol_buy_lock_alert')}" @@ -86,7 +84,7 @@ export default function UnlockProtocolInPost(props: UnlockProtocolInPostProps) { -
+ ) }) : null @@ -96,12 +94,12 @@ export default function UnlockProtocolInPost(props: UnlockProtocolInPostProps) { const jsx = message ? renderWithUnlockProtocolMetadata(props.message.meta, (r) => { return ( - + "{t('loading')}"
-
+ ) }) : null @@ -109,3 +107,8 @@ export default function UnlockProtocolInPost(props: UnlockProtocolInPostProps) { return <>{jsx} } } + +function Render(props: React.PropsWithChildren<{}>) { + usePluginWrapper(true, { width: 300 }) + return <>{props.children} +} diff --git a/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx b/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx index 29c510a3a67b..44ce0c781396 100644 --- a/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx +++ b/packages/mask/src/plugins/dHEDGE/SNSAdaptor/index.tsx @@ -1,8 +1,7 @@ import { useMemo } from 'react' -import { Plugin, usePostInfoDetails } from '@masknet/plugin-infra' +import { Plugin, usePostInfoDetails, usePluginWrapper } from '@masknet/plugin-infra' import { extractTextFromTypedMessage, parseURL } from '@masknet/shared-base' import { base } from '../base' -import MaskPluginWrapper from '../../MaskPluginWrapper' import { PoolView } from '../UI/PoolView' import { InvestDialog } from '../UI/InvestDialog' import { createMatchLink } from '../constants' @@ -48,9 +47,6 @@ const sns: Plugin.SNSAdaptor.Definition = { export default sns function Renderer(props: React.PropsWithChildren<{ link: string; address: string }>) { - return ( - - - - ) + usePluginWrapper(true) + return } diff --git a/packages/plugin-infra/src/hooks/index.ts b/packages/plugin-infra/src/hooks/index.ts index 7f08794c5879..e9272b78222b 100644 --- a/packages/plugin-infra/src/hooks/index.ts +++ b/packages/plugin-infra/src/hooks/index.ts @@ -5,4 +5,4 @@ export * from './useAllPluginsWeb3State' export * from './useLookupDomain' export * from './useReverseAddress' export * from './useI18N' -export * from './usePluginWrapper' +export { type PluginWrapperMethods, type PluginWrapperComponent, usePluginWrapper } from './usePluginWrapper' diff --git a/packages/plugin-infra/src/hooks/usePluginWrapper.tsx b/packages/plugin-infra/src/hooks/usePluginWrapper.tsx index a748174efd55..5948d64ef3eb 100644 --- a/packages/plugin-infra/src/hooks/usePluginWrapper.tsx +++ b/packages/plugin-infra/src/hooks/usePluginWrapper.tsx @@ -1,13 +1,33 @@ -import { createContext, useContext } from 'react' +import { noop } from 'lodash-unified' +import { createContext, useEffect, useRef, useContext, ForwardRefExoticComponent, RefAttributes } from 'react' +import type { Plugin } from '../types' +export type PluginWrapperComponent = + ForwardRefExoticComponent & { definition: T }>> -const PluginWrapperContext = createContext>>(DefaultWrapper) -function DefaultWrapper(props: React.PropsWithChildren<{}>) { - return <>{props.children} +/** @internal */ +export const emptyPluginWrapperMethods = { + setWrap: noop, + setWrapperName: noop, + setWidth: noop, } - -export function usePluginWrapper() { - return useContext(PluginWrapperContext) +/** @internal */ +export const PluginWrapperMethodsContext = createContext(emptyPluginWrapperMethods) +export interface PluginWrapperMethods { + setWrap(open: boolean): void + setWrapperName(name: string | undefined): void + setWidth(width: number | undefined): void } -/** @internal */ -export const PluginWrapperProvider = PluginWrapperContext.Provider +export function usePluginWrapper(open: boolean, options?: { width?: number; name?: string }) { + const { setWidth, setWrap, setWrapperName } = useContext(PluginWrapperMethodsContext) + const { width, name } = options || {} + + useEffect(() => setWrap(open), [open, setWrap]) + useEffect(() => setWidth(width), [width, setWidth]) + useEffect(() => setWrapperName(name), [name, setWrapperName]) + + // unwrap when the component is unmounted + const setWrapRef = useRef(setWrap) + setWrapRef.current = setWrap + useEffect(() => () => setWrapRef.current(false), []) +} diff --git a/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx b/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx index 2b9bc0e4b288..2db9e5a7369b 100644 --- a/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx +++ b/packages/plugin-infra/src/utils/createInjectHooksRenderer.tsx @@ -1,7 +1,9 @@ import type { Plugin } from '../types' -import React, { useEffect, useState, useRef, memo, createContext, useContext } from 'react' +import { useEffect, useState, useRef, memo, createContext, useContext } from 'react' import { ErrorBoundary } from '@masknet/shared' -import { usePluginI18NField, PluginWrapperProvider } from '../hooks' +import { usePluginI18NField, PluginWrapperComponent, PluginWrapperMethods } from '../hooks' +import { emptyPluginWrapperMethods, PluginWrapperMethodsContext } from '../hooks/usePluginWrapper' + type Inject = Plugin.InjectUI type Raw = Plugin.InjectUIRaw @@ -9,14 +11,19 @@ const PropsContext = createContext(null) export function createInjectHooksRenderer( usePlugins: () => PluginDefinition[], pickInjectorHook: (plugin: PluginDefinition) => undefined | Inject, - maskWrapperProvider?: (plugin: PluginDefinition) => React.ComponentType>, + PluginWrapperComponent?: PluginWrapperComponent, ) { function usePluginWrapperProvider(element: JSX.Element | null, plugin: PluginDefinition) { - const Wrapper = useRef | false>() - if (Wrapper.current === undefined || Wrapper.current === null) { - Wrapper.current = maskWrapperProvider?.(plugin) || false + const ref = useRef(emptyPluginWrapperMethods) + if (PluginWrapperComponent) { + return ( + + + {element} + + + ) } - if (Wrapper.current) return {element} return element } function SinglePluginWithinErrorBoundary({ plugin }: { plugin: PluginDefinition }) { From 89125696bca7f2597444a641ffb56dd5ce78bbbf Mon Sep 17 00:00:00 2001 From: Jack Works Date: Thu, 10 Feb 2022 12:26:45 +0800 Subject: [PATCH 6/9] chore: i18n a field --- .../InjectedComponents/DisabledPluginSuggestion.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx b/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx index a0578c535e13..a57c0b413ac8 100644 --- a/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx +++ b/packages/mask/src/components/InjectedComponents/DisabledPluginSuggestion.tsx @@ -4,6 +4,7 @@ import { usePostInfoDetails, Option, Plugin, + usePluginI18NField, } from '@masknet/plugin-infra' import { extractTextFromTypedMessage } from '@masknet/shared-base' import { Switch } from '@mui/material' @@ -51,6 +52,7 @@ export function PossiblePluginSuggestionPostInspector() { } export function PossiblePluginSuggestionUI(props: { plugins: Plugin.DeferredDefinition[] }) { const { t } = useI18N() + const t2 = usePluginI18NField() const { plugins } = props if (!plugins.length) return null return ( @@ -58,7 +60,7 @@ export function PossiblePluginSuggestionUI(props: { plugins: Plugin.DeferredDefi {plugins.map((x) => ( Date: Thu, 10 Feb 2022 13:01:23 +0800 Subject: [PATCH 7/9] chore: remove extra link --- packages/mask/src/plugins/MaskPluginWrapper.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/mask/src/plugins/MaskPluginWrapper.tsx b/packages/mask/src/plugins/MaskPluginWrapper.tsx index 3042b6713fdb..e193ca16bf5c 100644 --- a/packages/mask/src/plugins/MaskPluginWrapper.tsx +++ b/packages/mask/src/plugins/MaskPluginWrapper.tsx @@ -144,13 +144,7 @@ export const MaskPostExtraPluginWrapper: PluginWrapperComponent - - - ) : undefined - } + publisher={publisher ? : undefined} publisherLink={publisher?.link} children={props.children} /> From 386e38a25baf1f9192fd39aa0e3803c1025d2003 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Thu, 10 Feb 2022 18:19:22 +0800 Subject: [PATCH 8/9] chore: remove old provider information --- packages/mask/shared-ui/locales/en-US.json | 5 - packages/mask/shared-ui/locales/ko-KR.json | 5 - packages/mask/shared-ui/locales/qya-AA.json | 5 - packages/mask/shared-ui/locales/zh-CN.json | 3 - packages/mask/shared-ui/locales/zh-TW.json | 1 - .../Collectible/SNSAdaptor/Collectible.tsx | 81 +---------------- .../CryptoartAI/SNSAdaptor/Collectible.tsx | 72 +-------------- .../plugins/Furucombo/UI/FurucomboView.tsx | 68 +------------- .../PoolTogether/UI/PoolTogetherView.tsx | 65 +------------ .../Trader/SNSAdaptor/trader/TradeFooter.tsx | 91 ------------------- .../Trader/SNSAdaptor/trending/TraderView.tsx | 2 - .../SNSAdaptor/trending/TrendingViewDeck.tsx | 34 +------ .../mask/src/plugins/dHEDGE/UI/PoolView.tsx | 69 +------------- 13 files changed, 13 insertions(+), 488 deletions(-) delete mode 100644 packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx diff --git a/packages/mask/shared-ui/locales/en-US.json b/packages/mask/shared-ui/locales/en-US.json index 379135e29f9a..6f73c92908be 100644 --- a/packages/mask/shared-ui/locales/en-US.json +++ b/packages/mask/shared-ui/locales/en-US.json @@ -18,7 +18,6 @@ "reload": "Reload", "load": "Load", "load_all": "Load All", - "supported_by": "Supported by", "no_data": "No Data", "tip": "Tip", "tags": "Tags", @@ -258,7 +257,6 @@ "relative_time_seconds_ago": "{{seconds}} seconds ago", "relative_time_years_ago": "{{years}} years ago", "plugin_chain_not_supported": "Not supported on {{chain}} yet.", - "plugin_powered_by": "Powered by", "plugin_wallet_snackbar_wait_for_confirming": "Confirm this transaction in your wallet", "plugin_wallet_snackbar_hash": "Transaction Submitted", "plugin_wallet_snackbar_confirmed": "Transaction Confirmed", @@ -423,7 +421,6 @@ "plugin_trader_circulating_supply": "Circulating Supply", "plugin_trader_volume_24": "Volume (24h)", "plugin_trader_market_cap": "Market Cap", - "plugin_trader_data_source": "Data Source", "plugin_trader_price_updated": "Price Updated", "plugin_trader_view_pair_analytics": "View pair analytics", "plugin_savings": "Savings", @@ -777,7 +774,6 @@ "plugin_find_truman_buy_nft_tip": "At least {{count}} copy of this NFT is required.", "plugin_find_truman_connect_wallet_tip": "Please connect to a wallet.", "plugin_find_truman_no_participation_tip": "You have not participated in any vote yet.", - "plugin_dhedge_dhedge": "dHEDGE", "plugin_dhedge_managed_by": "Managed by {{managerName}}", "plugin_dhedge_manager_share": "Holds {{managerShare}}% of the pool", "plugin_dhedge_manager_share_more_than_50": "Holds more than 50% of the pool", @@ -884,7 +880,6 @@ "plugin_unlockprotocol_submit_post": "Submit Post", "plugin_unlockprotocol_title": "Unlock Protocol", "plugin_unlockprotocol_server_error": "Some Server error occured, Please try again later.", - "plugin_furucombo_name": "Furucombo", "plugin_furucombo_tab_pool": "Pool", "plugin_furucombo_tab_investments": "All investments", "plugin_furucombo_liquidity": "Liquidity", diff --git a/packages/mask/shared-ui/locales/ko-KR.json b/packages/mask/shared-ui/locales/ko-KR.json index 1f2129f9d0ea..94e039b6ed8e 100644 --- a/packages/mask/shared-ui/locales/ko-KR.json +++ b/packages/mask/shared-ui/locales/ko-KR.json @@ -18,7 +18,6 @@ "reload": "다시 로드", "load": "로드", "load_all": "모두 로드하기", - "supported_by": "Supported by", "no_data": "데이터 없음", "tip": "팁", "tags": "태그", @@ -215,7 +214,6 @@ "relative_time_months_ago": "{{months}} 월 전", "relative_time_seconds_ago": "{{seconds}} 초 전", "relative_time_years_ago": "{{years}} 년 전", - "plugin_powered_by": "기술 지원", "plugin_wallet_collections": "컬렉션", "plugin_wallet_select_a_token": "토큰을 선택하기", "plugin_wallet_select_a_nft_contract": "NFT 컨트렉트를 선택하세요.", @@ -339,7 +337,6 @@ "plugin_trader_circulating_supply": "유통량", "plugin_trader_volume_24": "거래량 (24시간)", "plugin_trader_market_cap": "시가 총액", - "plugin_trader_data_source": "데이터 소스", "plugin_trader_price_updated": "가격은 업데이트뒤었습니다", "plugin_trader_view_pair_analytics": "페어 분석 보기", "plugin_trader_swap": "스왑", @@ -628,7 +625,6 @@ "plugin_snapshot_current_result_title": "현재 결과", "plugin_snapshot_download_report": "다운로드 리포트", "plugin_find_truman_no_participation_tip": "아직 아무 투표에 참여하지 않았습니다.", - "plugin_dhedge_dhedge": "dHEDGE", "plugin_dhedge_managed_by": "관리자: {{managerName}}", "plugin_dhedge_manager_share": "풀의 {{managerShare}}% 홀드합니다.", "plugin_dhedge_manager_share_more_than_50": "이 풀의 50% 이상을 보유합니다", @@ -733,7 +729,6 @@ "plugin_unlockprotocol_submit_post": "포스트 제출", "plugin_unlockprotocol_title": "언락 프로토콜", "plugin_unlockprotocol_server_error": "서버 오류 발생했습니다. 다시 시도 하세요.", - "plugin_furucombo_name": "Furucombo", "plugin_furucombo_tab_pool": "풀", "plugin_furucombo_tab_investments": "전체 투자", "plugin_furucombo_liquidity": "유동성", diff --git a/packages/mask/shared-ui/locales/qya-AA.json b/packages/mask/shared-ui/locales/qya-AA.json index 602de2bb512a..0e65326e31b0 100644 --- a/packages/mask/shared-ui/locales/qya-AA.json +++ b/packages/mask/shared-ui/locales/qya-AA.json @@ -18,7 +18,6 @@ "reload": "crwdns10087:0crwdne10087:0", "load": "crwdns10089:0crwdne10089:0", "load_all": "crwdns10093:0crwdne10093:0", - "supported_by": "crwdns10095:0crwdne10095:0", "no_data": "crwdns10097:0crwdne10097:0", "tip": "crwdns10105:0crwdne10105:0", "tags": "crwdns10107:0crwdne10107:0", @@ -258,7 +257,6 @@ "relative_time_seconds_ago": "crwdns4583:0{{seconds}}crwdne4583:0", "relative_time_years_ago": "crwdns4585:0{{years}}crwdne4585:0", "plugin_chain_not_supported": "crwdns10689:0{{chain}}crwdne10689:0", - "plugin_powered_by": "crwdns4587:0crwdne4587:0", "plugin_wallet_snackbar_wait_for_confirming": "crwdns10629:0crwdne10629:0", "plugin_wallet_snackbar_hash": "crwdns10631:0crwdne10631:0", "plugin_wallet_snackbar_confirmed": "crwdns10633:0crwdne10633:0", @@ -423,7 +421,6 @@ "plugin_trader_circulating_supply": "crwdns10229:0crwdne10229:0", "plugin_trader_volume_24": "crwdns10231:0crwdne10231:0", "plugin_trader_market_cap": "crwdns10233:0crwdne10233:0", - "plugin_trader_data_source": "crwdns10235:0crwdne10235:0", "plugin_trader_price_updated": "crwdns10237:0crwdne10237:0", "plugin_trader_view_pair_analytics": "crwdns10239:0crwdne10239:0", "plugin_trader_swap": "crwdns4881:0crwdne4881:0", @@ -766,7 +763,6 @@ "plugin_find_truman_buy_nft_tip": "crwdns10407:0{{count}}crwdne10407:0", "plugin_find_truman_connect_wallet_tip": "crwdns10411:0crwdne10411:0", "plugin_find_truman_no_participation_tip": "crwdns10413:0crwdne10413:0", - "plugin_dhedge_dhedge": "crwdns10251:0crwdne10251:0", "plugin_dhedge_managed_by": "crwdns5393:0{{managerName}}crwdne5393:0", "plugin_dhedge_manager_share": "crwdns5395:0{{managerShare}}crwdne5395:0", "plugin_dhedge_manager_share_more_than_50": "crwdns5397:0crwdne5397:0", @@ -873,7 +869,6 @@ "plugin_unlockprotocol_submit_post": "crwdns7987:0crwdne7987:0", "plugin_unlockprotocol_title": "crwdns7989:0crwdne7989:0", "plugin_unlockprotocol_server_error": "crwdns7991:0crwdne7991:0", - "plugin_furucombo_name": "crwdns10263:0crwdne10263:0", "plugin_furucombo_tab_pool": "crwdns9113:0crwdne9113:0", "plugin_furucombo_tab_investments": "crwdns9115:0crwdne9115:0", "plugin_furucombo_liquidity": "crwdns9117:0crwdne9117:0", diff --git a/packages/mask/shared-ui/locales/zh-CN.json b/packages/mask/shared-ui/locales/zh-CN.json index 52c85661e757..4cdf90ac2795 100644 --- a/packages/mask/shared-ui/locales/zh-CN.json +++ b/packages/mask/shared-ui/locales/zh-CN.json @@ -18,7 +18,6 @@ "reload": "重新加载", "load": "加载", "load_all": "加载全部", - "supported_by": "技术支持:", "no_data": "暂无数据", "tip": "小费", "tags": "标签", @@ -243,7 +242,6 @@ "relative_time_seconds_ago": "{{seconds}} 秒前", "relative_time_years_ago": "{{years}} 年前", "plugin_chain_not_supported": "尚未在 {{chain}} 上支持。", - "plugin_powered_by": "技术支持:", "plugin_wallet_snackbar_wait_for_confirming": "请在您的钱包中确认这笔交易", "plugin_wallet_snackbar_hash": "交易已提交", "plugin_wallet_snackbar_confirmed": "交易已确认", @@ -400,7 +398,6 @@ "plugin_trader_circulating_supply": "流通总量", "plugin_trader_volume_24": "交易量 (24h)", "plugin_trader_market_cap": "市值", - "plugin_trader_data_source": "数据源", "plugin_trader_price_updated": "价格已更新", "plugin_trader_view_pair_analytics": "查看交易对分析", "plugin_trader_swap": "兑换", diff --git a/packages/mask/shared-ui/locales/zh-TW.json b/packages/mask/shared-ui/locales/zh-TW.json index ca93794f9a4a..56fb91626a62 100644 --- a/packages/mask/shared-ui/locales/zh-TW.json +++ b/packages/mask/shared-ui/locales/zh-TW.json @@ -189,7 +189,6 @@ "relative_time_months_ago": "{{months}} 月前", "relative_time_seconds_ago": "{{seconds}} 秒前", "relative_time_years_ago": "{{years}} 年前", - "plugin_powered_by": "提供者為 ", "plugin_wallet_guiding_step_1": "1. 選擇網路", "plugin_wallet_guiding_step_2": "2. 選擇錢包", "plugin_wallet_collections": "收藏", diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx index 7a57cb450c7b..6824fbd4b70a 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx @@ -1,13 +1,11 @@ -import { ReactElement, useCallback } from 'react' -import { Box, Button, CardActions, CardContent, CardHeader, Link, Paper, Tab, Tabs, Typography } from '@mui/material' +import type { ReactElement } from 'react' +import { Box, Button, CardContent, CardHeader, Link, Paper, Tab, Tabs, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import { Trans } from 'react-i18next' -import { findIndex } from 'lodash-unified' import formatDateTime from 'date-fns/format' import isValidDate from 'date-fns/isValid' import isAfter from 'date-fns/isAfter' import VerifiedUserIcon from '@mui/icons-material/VerifiedUser' -import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' import { useI18N, useSettingsSwitcher } from '../../../utils' import { ArticleTab } from './ArticleTab' import { TokenTab } from './TokenTab' @@ -17,14 +15,11 @@ import { HistoryTab } from './HistoryTab' import { LinkingAvatar } from './LinkingAvatar' import { CollectibleState } from '../hooks/useCollectibleState' import { CollectibleCard } from './CollectibleCard' -import { CollectibleProviderIcon } from './CollectibleProviderIcon' import { CollectibleTab } from '../types' -import { MaskTextIcon } from '../../../resources/MaskIcon' import { resolveAssetLinkOnCurrentProvider, resolveCollectibleProviderName } from '../pipes' import { ActionBar } from './ActionBar' import { NonFungibleAssetProvider, useChainId } from '@masknet/web3-shared-evm' import { getEnumAsArray } from '@dimensiondev/kit' -import { FootnoteMenu, FootnoteMenuOption } from '../../Trader/SNSAdaptor/trader/FootnoteMenu' import { LoadingAnimation } from '@masknet/shared' import { Markdown } from '../../Snapshot/SNSAdaptor/Markdown' import { currentNonFungibleAssetProviderSettings } from '../settings' @@ -53,13 +48,6 @@ const useStyles = makeStyles()((theme) => { display: 'none', }, }, - footer: { - marginTop: -1, // merge duplicate borders - zIndex: 1, - position: 'relative', - borderTop: `solid 1px ${theme.palette.divider}`, - justifyContent: 'space-between', - }, tabs: { height: 'var(--tabHeight)', width: '100%', @@ -87,30 +75,6 @@ const useStyles = makeStyles()((theme) => { fontWeight: 300, }, }, - footnote: { - fontSize: 10, - marginRight: theme.spacing(1), - }, - footLink: { - cursor: 'pointer', - marginRight: theme.spacing(0.5), - '&:last-child': { - marginRight: 0, - }, - }, - footMenu: { - color: theme.palette.text.secondary, - fontSize: 10, - display: 'flex', - alignItems: 'center', - }, - footName: { - marginLeft: theme.spacing(0.5), - }, - mask: { - width: 40, - height: 10, - }, countdown: { fontSize: 12, borderRadius: 8, @@ -144,13 +108,6 @@ export function Collectible(props: CollectibleProps) { const chainId = useChainId() const { token, asset, provider, tabIndex, setTabIndex } = CollectibleState.useContainer() - // #region sync with settings - const collectibleProviderOptions = getEnumAsArray(NonFungibleAssetProvider) - const onDataProviderChange = useCallback((option: FootnoteMenuOption) => { - currentNonFungibleAssetProviderSettings.value = option.value as NonFungibleAssetProvider - }, []) - // #endregion - // #region provider switcher const CollectibleProviderSwitcher = useSettingsSwitcher( currentNonFungibleAssetProviderSettings, @@ -200,7 +157,7 @@ export function Collectible(props: CollectibleProps) { const endDate = _asset.end_time return ( <> - + {renderTab(tabIndex)}} - - - {t('plugin_powered_by')} - - - - -
- ({ - name: ( - <> - - - {resolveCollectibleProviderName(x.value)} - - - ), - value: x.value, - }))} - selectedIndex={findIndex(collectibleProviderOptions, (x) => x.value === provider)} - onChange={onDataProviderChange} - /> - -
-
{endDate && isValidDate(endDate) && isAfter(endDate, Date.now()) && ( diff --git a/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/Collectible.tsx b/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/Collectible.tsx index 048c1bcca337..05d78c75ae9d 100644 --- a/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/Collectible.tsx +++ b/packages/mask/src/plugins/CryptoartAI/SNSAdaptor/Collectible.tsx @@ -1,17 +1,5 @@ import { useState, useEffect, useMemo } from 'react' -import { - Avatar, - Box, - Button, - CardActions, - CardContent, - CardHeader, - Link, - Paper, - Tab, - Tabs, - Typography, -} from '@mui/material' +import { Avatar, Box, Button, CardContent, CardHeader, Link, Paper, Tab, Tabs, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import { Trans } from 'react-i18next' import VerifiedUserIcon from '@mui/icons-material/VerifiedUser' @@ -24,7 +12,6 @@ import { CollectibleState } from '../hooks/useCollectibleState' import { CollectibleCard } from './CollectibleCard' import { PluginSkeleton } from './PluginSkeleton' import { TabState, TransactionType } from '../types' -import { MaskTextIcon } from '../../../resources/MaskIcon' import { resolveAssetLinkOnCryptoartAI, resolveWebLinkOnCryptoartAI } from '../pipes' import { Markdown } from '../../Snapshot/SNSAdaptor/Markdown' import { ActionBar } from './ActionBar' @@ -54,13 +41,6 @@ const useStyles = makeStyles()((theme) => { display: 'none', }, }, - footer: { - marginTop: -1, // merge duplicate borders - zIndex: 1, - position: 'relative', - borderTop: `solid 1px ${theme.palette.divider}`, - justifyContent: 'space-between', - }, tabs: { height: 'var(--tabHeight)', width: '100%', @@ -88,39 +68,6 @@ const useStyles = makeStyles()((theme) => { fontWeight: 300, }, }, - footnote: { - fontSize: 10, - marginRight: theme.spacing(1), - }, - footLink: { - cursor: 'pointer', - marginRight: theme.spacing(0.5), - '&:last-child': { - marginRight: 0, - }, - }, - footMenu: { - color: theme.palette.text.secondary, - fontSize: 10, - display: 'flex', - alignItems: 'center', - }, - footName: { - marginLeft: theme.spacing(0.5), - }, - mask: { - width: 40, - height: 10, - }, - countdown: { - fontSize: 12, - borderRadius: 8, - display: 'block', - white: '100%', - color: theme.palette.common.white, - backgroundColor: '#eb5757', - padding: theme.spacing(0.5, 2), - }, } }) @@ -175,7 +122,7 @@ export function Collectible(props: CollectibleProps) { return ( <> - + : null} - - - {t('plugin_powered_by')} - - - - -
- diff --git a/packages/mask/src/plugins/Furucombo/UI/FurucomboView.tsx b/packages/mask/src/plugins/Furucombo/UI/FurucomboView.tsx index 7cc60bba3167..3f3411e84c74 100644 --- a/packages/mask/src/plugins/Furucombo/UI/FurucomboView.tsx +++ b/packages/mask/src/plugins/Furucombo/UI/FurucomboView.tsx @@ -1,9 +1,7 @@ import { makeStyles } from '@masknet/theme' import { isSameAddress, useChainId } from '@masknet/web3-shared-evm' -import { Card, CardContent, CardActions, Tabs, Tab, Typography, Link, Paper } from '@mui/material' +import { Card, CardContent, Tabs, Tab, Typography, Paper } from '@mui/material' import { useState } from 'react' -import { FurucomboIcon } from '../../../resources/FurucomboIcon' -import { MaskTextIcon } from '../../../resources/MaskIcon' import { useI18N } from '../../../utils/i18n-next-ui' import { useFetchPools } from '../hooks/usePool' import type { Investable } from '../types' @@ -35,41 +33,6 @@ const useStyles = makeStyles()((theme) => ({ fontFamily: 'inherit', color: 'white', }, - footer: { - marginTop: -1, // merge duplicate borders - zIndex: 1, - position: 'relative', - borderTop: `solid 1px ${theme.palette.divider}`, - justifyContent: 'space-between', - }, - footnote: { - fontSize: 10, - marginRight: theme.spacing(1), - }, - footLink: { - cursor: 'pointer', - marginRight: theme.spacing(0.5), - '&:last-child': { - marginRight: 0, - }, - }, - footMenu: { - color: theme.palette.text.secondary, - fontSize: 10, - display: 'flex', - alignItems: 'center', - }, - footName: { - marginLeft: theme.spacing(0.5), - }, - mask: { - width: 40, - height: 10, - }, - furucombo: { - height: 16, - margin: theme.spacing(-0.5, 0.25), - }, })) interface PoolViewProps { @@ -119,7 +82,7 @@ export function FurucomboView(props: PoolViewProps) { variant="fullWidth" indicatorColor="primary" textColor="secondary" - onChange={(event: React.SyntheticEvent, newValue: number) => setTabIndex(newValue)}> + onChange={(_, newValue: number) => setTabIndex(newValue)}> , , @@ -128,33 +91,6 @@ export function FurucomboView(props: PoolViewProps) { {tabIndex === 1 ? : null} - - - {t('plugin_powered_by')} - - - - - - {t('supported_by')} - - - {t('plugin_furucombo_name')} - - - ) } diff --git a/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx b/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx index 56bb70cd82d1..270adbb042bb 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx @@ -1,11 +1,9 @@ import { RefreshIcon } from '@masknet/icons' import { DarkColor } from '@masknet/theme/constants' import { usePoolTogetherConstants } from '@masknet/web3-shared-evm' -import { Card, CardActions, CardContent, CircularProgress, Link, Paper, Tab, Tabs, Typography } from '@mui/material' +import { Card, CardContent, CircularProgress, Paper, Tab, Tabs, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import React, { useState, useEffect } from 'react' -import { MaskTextIcon } from '../../../resources/MaskIcon' -import { PoolTogetherIcon } from '../../../resources/PoolTogetherIcon' import { useI18N } from '../../../utils/i18n-next-ui' import { usePool, usePools } from '../hooks/usePools' import type { Pool } from '../types' @@ -60,42 +58,6 @@ const useStyles = makeStyles()((theme) => ({ minHeight: 'unset', minWidth: 'unset', }, - footer: { - marginTop: -1, // merge duplicate borders - zIndex: 1, - position: 'relative', - borderTop: `solid 1px ${theme.palette.divider}`, - justifyContent: 'space-between', - }, - footnote: { - fontSize: 10, - marginRight: theme.spacing(1), - }, - footLink: { - cursor: 'pointer', - marginRight: theme.spacing(0.5), - '&:last-child': { - marginRight: 0, - }, - }, - footMenu: { - color: theme.palette.text.secondary, - fontSize: 10, - display: 'flex', - alignItems: 'center', - }, - footName: { - marginLeft: theme.spacing(0.5), - }, - mask: { - width: 40, - height: 10, - }, - pooltogether: { - height: 10, - width: 10, - marginLeft: theme.spacing(0.5), - }, progress: { bottom: theme.spacing(1), right: theme.spacing(1), @@ -175,31 +137,6 @@ export function PoolTogetherView(props: PoolTogetherViewProps) { {tabIndex === 1 ? : null} - - - {t('plugin_powered_by')} - - - - - - {t('supported_by')} - - - oolTogether - - - ) } diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx deleted file mode 100644 index f7d5d3407af5..000000000000 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import type { DataProvider } from '@masknet/public-api' -import { makeStyles, useStylesExtends } from '@masknet/theme' -import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' -import { CardActions, Link, Typography } from '@mui/material' -import type { FC } from 'react' -import { MaskTextIcon } from '../../../../resources/MaskIcon' -import { useI18N } from '../../../../utils' -import { resolveDataProviderName } from '../../pipes' -import { DataProviderIcon } from './DataProviderIcon' -import { FootnoteMenu, FootnoteMenuOption } from './FootnoteMenu' - -const useStyles = makeStyles()((theme) => { - return { - footer: { - justifyContent: 'space-between', - }, - footnote: { - color: theme.palette.text.secondary, - fontSize: 10, - marginRight: theme.spacing(0.5), - }, - footLink: { - cursor: 'pointer', - marginRight: theme.spacing(0.5), - '&:last-child': { - marginRight: 0, - }, - }, - footMenu: { - color: theme.palette.text.secondary, - fontSize: 10, - display: 'flex', - alignItems: 'center', - }, - footName: { - marginLeft: theme.spacing(0.5), - }, - mask: { - width: 40, - height: 10, - }, - } -}) - -export interface TradeFooterProps extends withClasses<'footer'> { - showDataProviderIcon?: boolean - dataProvider?: DataProvider - dataProviders?: DataProvider[] - onDataProviderChange?: (option: FootnoteMenuOption) => void -} - -export const TradeFooter: FC = (props) => { - const { showDataProviderIcon = false, dataProvider, dataProviders = [], onDataProviderChange } = props - const { t } = useI18N() - const classes = useStylesExtends(useStyles(), props) - return ( - - - {t('plugin_powered_by')} - - - - - {showDataProviderIcon ? ( -
- {t('plugin_trader_data_source')} - ({ - name: ( - <> - - {resolveDataProviderName(x)} - - ), - value: x, - }))} - selectedIndex={typeof dataProvider !== 'undefined' ? dataProviders.indexOf(dataProvider) : -1} - onChange={onDataProviderChange} - /> - -
- ) : null} -
- ) -} diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx index cf0fa4e9049f..0527f0597bb3 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx @@ -233,8 +233,6 @@ export function TraderView(props: TraderViewProps) { currency={currency} trending={trending} dataProvider={dataProvider} - showDataProviderIcon={tabIndex < 3} - dataProviders={dataProviders} TrendingCardProps={{ classes: { root: classes.root } }}> - dataProviders: DataProvider[] } export function TrendingViewDeck(props: TrendingViewDeckProps) { - const { - coins, - currency, - trending, - dataProvider, - stats, - children, - showDataProviderIcon = false, - TrendingCardProps, - dataProviders = [], - } = props + const { coins, currency, trending, dataProvider, stats, children, TrendingCardProps } = props const { coin, market } = trending const { t } = useI18N() @@ -130,12 +116,6 @@ export function TrendingViewDeck(props: TrendingViewDeckProps) { }, [account, trending?.coin?.symbol]) // #endregion - // #region sync with settings - const onDataProviderChange = useCallback((option: FootnoteMenuOption) => { - currentDataProviderSettings.value = option.value as DataProvider - }, []) - // #endregion - // #region switch between coins with the same symbol const currentPreferredCoinIdSettings = useValueRef(getCurrentPreferredCoinIdSettings(dataProvider)) const onCoinMenuChange = useCallback( @@ -240,16 +220,6 @@ export function TrendingViewDeck(props: TrendingViewDeckProps) { {children} - - ) } diff --git a/packages/mask/src/plugins/dHEDGE/UI/PoolView.tsx b/packages/mask/src/plugins/dHEDGE/UI/PoolView.tsx index 7d0e0d4663ef..b134d31ee75d 100644 --- a/packages/mask/src/plugins/dHEDGE/UI/PoolView.tsx +++ b/packages/mask/src/plugins/dHEDGE/UI/PoolView.tsx @@ -1,9 +1,8 @@ import { RefreshIcon } from '@masknet/icons' import { useChainId } from '@masknet/web3-shared-evm' -import { Card, CardActions, CardContent, CardHeader, Link, Paper, Tab, Tabs, Typography } from '@mui/material' +import { Card, CardContent, CardHeader, Paper, Tab, Tabs, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' -import React, { useState } from 'react' -import { MaskTextIcon } from '../../../resources/MaskIcon' +import { useState } from 'react' import { useI18N } from '../../../utils/i18n-next-ui' import { EthereumChainBoundary } from '../../../web3/UI/EthereumChainBoundary' import { useFetchPool, usePoolDepositAssets } from '../hooks/usePool' @@ -53,41 +52,6 @@ const useStyles = makeStyles()((theme) => ({ minHeight: 'unset', minWidth: 'unset', }, - footer: { - marginTop: -1, // merge duplicate borders - zIndex: 1, - position: 'relative', - borderTop: `solid 1px ${theme.palette.divider}`, - justifyContent: 'space-between', - }, - footnote: { - fontSize: 10, - marginRight: theme.spacing(1), - }, - footLink: { - cursor: 'pointer', - marginRight: theme.spacing(0.5), - '&:last-child': { - marginRight: 0, - }, - }, - footMenu: { - color: theme.palette.text.secondary, - fontSize: 10, - display: 'flex', - alignItems: 'center', - }, - footName: { - marginLeft: theme.spacing(0.5), - }, - mask: { - width: 40, - height: 10, - }, - dhedge: { - height: 10, - margin: theme.spacing(0, 0.5), - }, })) interface PoolViewProps { @@ -154,7 +118,7 @@ export function PoolView(props: PoolViewProps) { textColor="primary" variant="fullWidth" value={tabIndex} - onChange={(ev: React.ChangeEvent<{}>, newValue: number) => setTabIndex(newValue)} + onChange={(_, newValue: number) => setTabIndex(newValue)} TabIndicatorProps={{ style: { display: 'none', @@ -167,33 +131,6 @@ export function PoolView(props: PoolViewProps) { {tabIndex === 1 ? : null} - - - {t('plugin_powered_by')} - - - - - - {t('supported_by')} - - - {t('plugin_dhedge_dhedge')} - - - ) From 4344bcd51c1d8f2ae377a8b72c09d7c61c1a3418 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Fri, 11 Feb 2022 17:01:15 +0800 Subject: [PATCH 9/9] chore: revert change --- packages/mask/shared-ui/locales/en-US.json | 1 + packages/mask/shared-ui/locales/ko-KR.json | 1 + packages/mask/shared-ui/locales/qya-AA.json | 1 + packages/mask/shared-ui/locales/zh-CN.json | 1 + .../Collectible/SNSAdaptor/Collectible.tsx | 54 ++++++++++++++- .../Trader/SNSAdaptor/trader/TradeFooter.tsx | 69 +++++++++++++++++++ .../Trader/SNSAdaptor/trending/TraderView.tsx | 2 + .../SNSAdaptor/trending/TrendingViewDeck.tsx | 34 ++++++++- .../mask/src/plugins/dHEDGE/UI/PoolStats.tsx | 48 ++++++------- 9 files changed, 184 insertions(+), 27 deletions(-) create mode 100644 packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx diff --git a/packages/mask/shared-ui/locales/en-US.json b/packages/mask/shared-ui/locales/en-US.json index fde1b04c3b43..d9e3f301a1fb 100644 --- a/packages/mask/shared-ui/locales/en-US.json +++ b/packages/mask/shared-ui/locales/en-US.json @@ -421,6 +421,7 @@ "plugin_trader_circulating_supply": "Circulating Supply", "plugin_trader_volume_24": "Volume (24h)", "plugin_trader_market_cap": "Market Cap", + "plugin_trader_data_source": "Data Source", "plugin_trader_price_updated": "Price Updated", "plugin_trader_view_pair_analytics": "View pair analytics", "plugin_savings": "Savings", diff --git a/packages/mask/shared-ui/locales/ko-KR.json b/packages/mask/shared-ui/locales/ko-KR.json index 94e039b6ed8e..c3c6345e49df 100644 --- a/packages/mask/shared-ui/locales/ko-KR.json +++ b/packages/mask/shared-ui/locales/ko-KR.json @@ -337,6 +337,7 @@ "plugin_trader_circulating_supply": "유통량", "plugin_trader_volume_24": "거래량 (24시간)", "plugin_trader_market_cap": "시가 총액", + "plugin_trader_data_source": "데이터 소스", "plugin_trader_price_updated": "가격은 업데이트뒤었습니다", "plugin_trader_view_pair_analytics": "페어 분석 보기", "plugin_trader_swap": "스왑", diff --git a/packages/mask/shared-ui/locales/qya-AA.json b/packages/mask/shared-ui/locales/qya-AA.json index 136e6e5ee2f1..81c7caae1388 100644 --- a/packages/mask/shared-ui/locales/qya-AA.json +++ b/packages/mask/shared-ui/locales/qya-AA.json @@ -421,6 +421,7 @@ "plugin_trader_circulating_supply": "crwdns10229:0crwdne10229:0", "plugin_trader_volume_24": "crwdns10231:0crwdne10231:0", "plugin_trader_market_cap": "crwdns10233:0crwdne10233:0", + "plugin_trader_data_source": "crwdns10235:0crwdne10235:0", "plugin_trader_price_updated": "crwdns10237:0crwdne10237:0", "plugin_trader_view_pair_analytics": "crwdns10239:0crwdne10239:0", "plugin_savings": "crwdns13250:0crwdne13250:0", diff --git a/packages/mask/shared-ui/locales/zh-CN.json b/packages/mask/shared-ui/locales/zh-CN.json index fa2e60050902..9ed9571c3d11 100644 --- a/packages/mask/shared-ui/locales/zh-CN.json +++ b/packages/mask/shared-ui/locales/zh-CN.json @@ -419,6 +419,7 @@ "plugin_trader_circulating_supply": "流通总量", "plugin_trader_volume_24": "交易量 (24h)", "plugin_trader_market_cap": "市值", + "plugin_trader_data_source": "数据源", "plugin_trader_price_updated": "价格已更新", "plugin_trader_view_pair_analytics": "查看交易对分析", "plugin_trader_swap": "兑换", diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx index 6824fbd4b70a..564b3b5df7f3 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/Collectible.tsx @@ -1,11 +1,13 @@ -import type { ReactElement } from 'react' -import { Box, Button, CardContent, CardHeader, Link, Paper, Tab, Tabs, Typography } from '@mui/material' +import { ReactElement, useCallback } from 'react' +import { Box, Button, CardActions, CardContent, CardHeader, Link, Paper, Tab, Tabs, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' import { Trans } from 'react-i18next' +import { findIndex } from 'lodash-unified' import formatDateTime from 'date-fns/format' import isValidDate from 'date-fns/isValid' import isAfter from 'date-fns/isAfter' import VerifiedUserIcon from '@mui/icons-material/VerifiedUser' +import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' import { useI18N, useSettingsSwitcher } from '../../../utils' import { ArticleTab } from './ArticleTab' import { TokenTab } from './TokenTab' @@ -15,11 +17,13 @@ import { HistoryTab } from './HistoryTab' import { LinkingAvatar } from './LinkingAvatar' import { CollectibleState } from '../hooks/useCollectibleState' import { CollectibleCard } from './CollectibleCard' +import { CollectibleProviderIcon } from './CollectibleProviderIcon' import { CollectibleTab } from '../types' import { resolveAssetLinkOnCurrentProvider, resolveCollectibleProviderName } from '../pipes' import { ActionBar } from './ActionBar' import { NonFungibleAssetProvider, useChainId } from '@masknet/web3-shared-evm' import { getEnumAsArray } from '@dimensiondev/kit' +import { FootnoteMenu, FootnoteMenuOption } from '../../Trader/SNSAdaptor/trader/FootnoteMenu' import { LoadingAnimation } from '@masknet/shared' import { Markdown } from '../../Snapshot/SNSAdaptor/Markdown' import { currentNonFungibleAssetProviderSettings } from '../settings' @@ -30,6 +34,7 @@ const useStyles = makeStyles()((theme) => { width: '100%', border: `solid 1px ${theme.palette.divider}`, padding: 0, + marginBottom: 12, }, content: { width: '100%', @@ -48,6 +53,13 @@ const useStyles = makeStyles()((theme) => { display: 'none', }, }, + footer: { + marginTop: -1, // merge duplicate borders + zIndex: 1, + position: 'relative', + borderTop: `solid 1px ${theme.palette.divider}`, + justifyContent: 'space-between', + }, tabs: { height: 'var(--tabHeight)', width: '100%', @@ -75,6 +87,15 @@ const useStyles = makeStyles()((theme) => { fontWeight: 300, }, }, + footMenu: { + color: theme.palette.text.secondary, + fontSize: 10, + display: 'flex', + alignItems: 'center', + }, + footName: { + marginLeft: theme.spacing(0.5), + }, countdown: { fontSize: 12, borderRadius: 8, @@ -108,6 +129,13 @@ export function Collectible(props: CollectibleProps) { const chainId = useChainId() const { token, asset, provider, tabIndex, setTabIndex } = CollectibleState.useContainer() + // #region sync with settings + const collectibleProviderOptions = getEnumAsArray(NonFungibleAssetProvider) + const onDataProviderChange = useCallback((option: FootnoteMenuOption) => { + currentNonFungibleAssetProviderSettings.value = option.value as NonFungibleAssetProvider + }, []) + // #endregion + // #region provider switcher const CollectibleProviderSwitcher = useSettingsSwitcher( currentNonFungibleAssetProviderSettings, @@ -243,6 +271,28 @@ export function Collectible(props: CollectibleProps) { )) || <>{renderTab(tabIndex)}} + + {/* flex to make foot menu right */} +
+
+ ({ + name: ( + <> + + + {resolveCollectibleProviderName(x.value)} + + + ), + value: x.value, + }))} + selectedIndex={findIndex(collectibleProviderOptions, (x) => x.value === provider)} + onChange={onDataProviderChange} + /> + +
+ {endDate && isValidDate(endDate) && isAfter(endDate, Date.now()) && ( diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx new file mode 100644 index 000000000000..d28894bb2c06 --- /dev/null +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TradeFooter.tsx @@ -0,0 +1,69 @@ +import type { DataProvider } from '@masknet/public-api' +import { makeStyles, useStylesExtends } from '@masknet/theme' +import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' +import { CardActions, Typography } from '@mui/material' +import type { FC } from 'react' +import { useI18N } from '../../../../utils' +import { resolveDataProviderName } from '../../pipes' +import { DataProviderIcon } from './DataProviderIcon' +import { FootnoteMenu, FootnoteMenuOption } from './FootnoteMenu' + +const useStyles = makeStyles()((theme) => { + return { + footer: { + justifyContent: 'space-between', + }, + footnote: { + color: theme.palette.text.secondary, + fontSize: 10, + marginRight: theme.spacing(0.5), + }, + footMenu: { + color: theme.palette.text.secondary, + fontSize: 10, + display: 'flex', + alignItems: 'center', + }, + footName: { + marginLeft: theme.spacing(0.5), + }, + } +}) + +export interface TradeFooterProps extends withClasses<'footer'> { + showDataProviderIcon?: boolean + dataProvider?: DataProvider + dataProviders?: DataProvider[] + onDataProviderChange?: (option: FootnoteMenuOption) => void +} + +export const TradeFooter: FC = (props) => { + const { showDataProviderIcon = false, dataProvider, dataProviders = [], onDataProviderChange } = props + const { t } = useI18N() + const classes = useStylesExtends(useStyles(), props) + return ( + +
+ {/* actions on the */} + {showDataProviderIcon ? ( +
+ {t('plugin_trader_data_source')} + ({ + name: ( + <> + + {resolveDataProviderName(x)} + + ), + value: x, + }))} + selectedIndex={typeof dataProvider !== 'undefined' ? dataProviders.indexOf(dataProvider) : -1} + onChange={onDataProviderChange} + /> + +
+ ) : null} + + ) +} diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx index 0527f0597bb3..cf0fa4e9049f 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trending/TraderView.tsx @@ -233,6 +233,8 @@ export function TraderView(props: TraderViewProps) { currency={currency} trending={trending} dataProvider={dataProvider} + showDataProviderIcon={tabIndex < 3} + dataProviders={dataProviders} TrendingCardProps={{ classes: { root: classes.root } }}> + dataProviders: DataProvider[] } export function TrendingViewDeck(props: TrendingViewDeckProps) { - const { coins, currency, trending, dataProvider, stats, children, TrendingCardProps } = props + const { + coins, + currency, + trending, + dataProvider, + stats, + children, + showDataProviderIcon = false, + TrendingCardProps, + dataProviders = [], + } = props const { coin, market } = trending const { t } = useI18N() @@ -116,6 +130,12 @@ export function TrendingViewDeck(props: TrendingViewDeckProps) { }, [account, trending?.coin?.symbol]) // #endregion + // #region sync with settings + const onDataProviderChange = useCallback((option: FootnoteMenuOption) => { + currentDataProviderSettings.value = option.value as DataProvider + }, []) + // #endregion + // #region switch between coins with the same symbol const currentPreferredCoinIdSettings = useValueRef(getCurrentPreferredCoinIdSettings(dataProvider)) const onCoinMenuChange = useCallback( @@ -220,6 +240,16 @@ export function TrendingViewDeck(props: TrendingViewDeckProps) { {children} + + ) } diff --git a/packages/mask/src/plugins/dHEDGE/UI/PoolStats.tsx b/packages/mask/src/plugins/dHEDGE/UI/PoolStats.tsx index 0f72a67fc443..ad79a113f30a 100644 --- a/packages/mask/src/plugins/dHEDGE/UI/PoolStats.tsx +++ b/packages/mask/src/plugins/dHEDGE/UI/PoolStats.tsx @@ -114,31 +114,33 @@ export function PoolStats(props: PoolStatsProps) {
- {cleanDescription ? ( -
- - - - - - - {cleanDescription.length > POOL_DESCRIPTION_LIMIT ? ( - setExpanded(!expanded)}> - {expanded ? ( - - ) : ( - - )} + <> + +
+ + - ) : null} -
+ + + + {cleanDescription.length > POOL_DESCRIPTION_LIMIT ? ( + setExpanded(!expanded)}> + {expanded ? ( + + ) : ( + + )} + + ) : null} +
+ ) : null}
)