From 62661fa71b9c2d278ac80584588e0895ebabeabe Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:23:23 +0700 Subject: [PATCH 01/19] feat(donation): allow to support authors w/o ETH address --- lang/default.json | 3 - lang/en.json | 3 - lang/zh-Hans.json | 7 +- lang/zh-Hant.json | 7 +- package-lock.json | 4 +- src/common/enums/contract.ts | 26 +- src/common/utils/abis/curationVault.ts | 243 ++++++++++++++++++ src/common/utils/abis/index.ts | 1 + .../PaymentForm/PayTo/Complete/index.tsx | 2 +- .../Forms/PaymentForm/PayTo/Confirm/index.tsx | 4 +- .../PaymentForm/PayTo/SetAmount/index.tsx | 4 +- .../Forms/PaymentForm/Processing/index.tsx | 43 +++- .../Forms/PaymentForm/SwitchNetwork/index.tsx | 1 - src/components/Hook/index.ts | 1 - src/components/Hook/useCuration.ts | 14 - src/components/Hook/useERC20.ts | 18 +- .../SupportAuthor/DisableSupport/index.tsx | 7 - .../Support/SupportAuthor/index.tsx | 5 +- 18 files changed, 319 insertions(+), 74 deletions(-) create mode 100644 src/common/utils/abis/curationVault.ts delete mode 100644 src/components/Hook/useCuration.ts diff --git a/lang/default.json b/lang/default.json index 784c113eba..1fc650e546 100644 --- a/lang/default.json +++ b/lang/default.json @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "Applied successfully" }, - "4tqFCR": { - "defaultMessage": "The author has not bound the USDT wallet yet" - }, "4wOWfp": { "defaultMessage": "What's this?", "description": "src/components/Billboard/index.tsx" diff --git a/lang/en.json b/lang/en.json index 2fcbe0300c..9fe60683ba 100644 --- a/lang/en.json +++ b/lang/en.json @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "Applied successfully" }, - "4tqFCR": { - "defaultMessage": "The author has not bound the USDT wallet yet" - }, "4wOWfp": { "defaultMessage": "What's this?", "description": "src/components/Billboard/index.tsx" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 82a99d37af..309209eeb4 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -87,7 +87,7 @@ "defaultMessage": "支持排行榜" }, "/NX9L+": { - "defaultMessage": "确认授权", + "defaultMessage": "去钱包确认", "description": "src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx" }, "/TXBJR": { @@ -95,7 +95,7 @@ "description": "UNKNOWN_ERROR" }, "/cyuh2": { - "defaultMessage": "前往授权" + "defaultMessage": "去钱包授权" }, "/dKzfc": { "defaultMessage": "该作品因违反社区约章,已被站方强制封存。" @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "报名成功" }, - "4tqFCR": { - "defaultMessage": "作者尚未启用 USDT 钱包" - }, "4wOWfp": { "defaultMessage": "这是什么?", "description": "src/components/Billboard/index.tsx" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 4d31476398..3808917ac8 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -87,7 +87,7 @@ "defaultMessage": "支持排行榜" }, "/NX9L+": { - "defaultMessage": "確認授權", + "defaultMessage": "去錢包確認", "description": "src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx" }, "/TXBJR": { @@ -95,7 +95,7 @@ "description": "UNKNOWN_ERROR" }, "/cyuh2": { - "defaultMessage": "前往授權" + "defaultMessage": "去錢包授權" }, "/dKzfc": { "defaultMessage": "該作品因違反社區約章,已被站方強制歸檔。" @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "報名成功" }, - "4tqFCR": { - "defaultMessage": "作者尚未啓用 USDT 錢包" - }, "4wOWfp": { "defaultMessage": "這是什麼?", "description": "src/components/Billboard/index.tsx" diff --git a/package-lock.json b/package-lock.json index 1746b77ffd..fd1b6dbb00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "matters-web", - "version": "5.6.2", + "version": "5.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "matters-web", - "version": "5.6.2", + "version": "5.7.0", "license": "Apache-2.0", "dependencies": { "@apollo/react-common": "^3.1.3", diff --git a/src/common/enums/contract.ts b/src/common/enums/contract.ts index 10202e5403..1dbec7183e 100644 --- a/src/common/enums/contract.ts +++ b/src/common/enums/contract.ts @@ -15,37 +15,43 @@ export const contract = { logbookAddress: '0xcdf8D568EC808de5fCBb35849B5bAFB5d444D4c0' as `0x${string}`, curationAddress: - '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8' as `0x${string}`, + '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8'.toLowerCase() as `0x${string}`, curationBlockNum: '34564355', tokenAddress: - '0xc2132D05D31c914a87C6611C10748AEb04B58e8F' as `0x${string}`, + '0xc2132D05D31c914a87C6611C10748AEb04B58e8F'.toLowerCase() as `0x${string}`, tokenDecimals: 6, } : { logbookAddress: '0x203197e074b7a2f4ff6890815e4657a9c47c68b1' as `0x${string}`, curationAddress: - '0xa219C6722008aa22828B31A13ab9Ba93bB91222c' as `0x${string}`, - curationBlockNum: '28675517' as `0x${string}`, + '0xa219C6722008aa22828B31A13ab9Ba93bB91222c'.toLowerCase() as `0x${string}`, + curationBlockNum: '28675517', tokenAddress: - '0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1' as `0x${string}`, + '0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1'.toLowerCase() as `0x${string}`, tokenDecimals: 6, }, Optimism: isProd ? { curationAddress: - '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8' as `0x${string}`, - curationBlockNum: '117058632' as `0x${string}`, + '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8'.toLowerCase() as `0x${string}`, + curationBlockNum: '117058632', tokenAddress: - '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58' as `0x${string}`, + '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58'.toLowerCase() as `0x${string}`, tokenDecimals: 6, + curationVaultAddress: + '0x7CC566aa9488a9990977Cb31D856C47e67b35465'.toLowerCase() as `0x${string}`, + curationVaultBlockNum: '128886733', } : { curationAddress: - '0x92a117aeA74963Cd0CEdF9C50f99435451a291F7' as `0x${string}`, + '0x92a117aeA74963Cd0CEdF9C50f99435451a291F7'.toLowerCase() as `0x${string}`, curationBlockNum: '8438904', tokenAddress: - '0x5fd84259d66Cd46123540766Be93DFE6D43130D7' as `0x${string}`, + '0x5fd84259d66Cd46123540766Be93DFE6D43130D7'.toLowerCase() as `0x${string}`, tokenDecimals: 6, + curationVaultAddress: + '0x891060263b8397cB3c69F01E3383e7f8838Fd8a8'.toLowerCase() as `0x${string}`, + curationVaultBlockNum: '20457192', }, } diff --git a/src/common/utils/abis/curationVault.ts b/src/common/utils/abis/curationVault.ts new file mode 100644 index 0000000000..6ef9baac2d --- /dev/null +++ b/src/common/utils/abis/curationVault.ts @@ -0,0 +1,243 @@ +export const CurationVaultABI = [ + { + inputs: [ + { internalType: 'address', name: 'signer_', type: 'address' }, + { internalType: 'address', name: 'owner_', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AlreadyWithdrawn', type: 'error' }, + { inputs: [], name: 'Expired', type: 'error' }, + { inputs: [], name: 'InvalidSignature', type: 'error' }, + { inputs: [], name: 'InvalidURI', type: 'error' }, + { inputs: [], name: 'TransferFailed', type: 'error' }, + { inputs: [], name: 'ZeroAddress', type: 'error' }, + { inputs: [], name: 'ZeroAmount', type: 'error' }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { indexed: false, internalType: 'string', name: 'uri', type: 'string' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Curation', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { indexed: false, internalType: 'string', name: 'uri', type: 'string' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Curation', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'signer', + type: 'address', + }, + ], + name: 'SignerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [ + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'contract IERC20', name: 'token_', type: 'address' }, + { internalType: 'uint256', name: 'amount_', type: 'uint256' }, + { internalType: 'string', name: 'uri_', type: 'string' }, + ], + name: 'curate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'string', name: 'uri_', type: 'string' }, + ], + name: 'curate', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: '', type: 'string' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'erc20Balances', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'string', name: '', type: 'string' }], + name: 'nativeBalances', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'signer_', type: 'address' }], + name: 'setSigner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'signer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId_', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to_', type: 'address' }, + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'uint256', name: 'expiredAt_', type: 'uint256' }, + { internalType: 'uint8', name: 'v_', type: 'uint8' }, + { internalType: 'bytes32', name: 'r_', type: 'bytes32' }, + { internalType: 'bytes32', name: 's_', type: 'bytes32' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to_', type: 'address' }, + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'contract IERC20', name: 'token_', type: 'address' }, + { internalType: 'uint256', name: 'expiredAt_', type: 'uint256' }, + { internalType: 'uint8', name: 'v_', type: 'uint8' }, + { internalType: 'bytes32', name: 'r_', type: 'bytes32' }, + { internalType: 'bytes32', name: 's_', type: 'bytes32' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: '', type: 'string' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'withdrawals', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, +] as const diff --git a/src/common/utils/abis/index.ts b/src/common/utils/abis/index.ts index 567fa47105..6023b3ac6f 100644 --- a/src/common/utils/abis/index.ts +++ b/src/common/utils/abis/index.ts @@ -1,3 +1,4 @@ export * from './billboard' export * from './curation' +export * from './curationVault' export * from './ensPublicResolver' diff --git a/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx b/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx index eb8fa03e60..3e2f5cfcfc 100644 --- a/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx @@ -83,7 +83,7 @@ const Complete: React.FC = ({ currency={currency} recipient={recipient} showLikerID={isLikecoin} - showEthAddress={isUSDT} + showEthAddress={isUSDT && !!recipient.info.ethAddress} > <> diff --git a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx index d55e4757d4..2b0e69c69d 100644 --- a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx @@ -205,7 +205,9 @@ const Confirm: React.FC = ({ currency={currency} recipient={recipient} showLikerID={currency === CURRENCY.LIKE} - showEthAddress={currency === CURRENCY.USDT} + showEthAddress={ + currency === CURRENCY.USDT && !!recipient.info.ethAddress + } /> {isSubmitting && ( diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index ed65c74e11..2966a5f65b 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -149,13 +149,13 @@ const SetAmount: React.FC = ({ refetch: refetchAllowanceData, isLoading: allowanceLoading, error: allowanceError, - } = useAllowanceUSDT() + } = useAllowanceUSDT(!recipient.info.ethAddress) const { data: approveData, isLoading: approving, write: approveWrite, error: approveError, - } = useApproveUSDT() + } = useApproveUSDT(!recipient.info.ethAddress) const { data: balanceUSDTData, error: balanceUSDTError } = useBalanceUSDT({ address, }) diff --git a/src/components/Forms/PaymentForm/Processing/index.tsx b/src/components/Forms/PaymentForm/Processing/index.tsx index a2078d8e42..bfd4128e60 100644 --- a/src/components/Forms/PaymentForm/Processing/index.tsx +++ b/src/components/Forms/PaymentForm/Processing/index.tsx @@ -14,7 +14,7 @@ import { PAYMENT_CURRENCY as CURRENCY, SUPPORT_SUCCESS_USDT_VISITOR, } from '~/common/enums' -import { CurationABI } from '~/common/utils' +import { CurationABI, CurationVaultABI } from '~/common/utils' import { Dialog, Icon, @@ -217,11 +217,30 @@ const USDTProcessingForm: React.FC = ({ const [draftTxId, setDraftTxId] = useState() + const useCurationVault = !recipient.info.ethAddress + const normalizedAmount = parseUnits( + amount.toString() as `${number}`, + contract.Optimism.tokenDecimals + ) + const uri = `ipfs://${article?.dataHash}` + + const { + data: vaultData, + error: vaultError, + isError: isVaultError, + write: curateVault, + } = useContractWrite({ + address: contract.Optimism.curationVaultAddress, + abi: CurationVaultABI, + functionName: 'curate', + args: [recipient.id, contract.Optimism.tokenAddress, normalizedAmount, uri], + }) + const { - data, - error, - isError, - write: curate, + data: curationData, + error: curationError, + isError: isCurationError, + write: curateDirect, } = useContractWrite({ address: contract.Optimism.curationAddress, abi: CurationABI, @@ -229,14 +248,16 @@ const USDTProcessingForm: React.FC = ({ args: [ recipient.info.ethAddress as `0x${string}`, contract.Optimism.tokenAddress, - parseUnits( - amount.toString() as `${number}`, - contract.Optimism.tokenDecimals - ), - `ipfs://${article?.dataHash}`, + normalizedAmount, + uri, ], }) + const data = useCurationVault ? vaultData : curationData + const error = useCurationVault ? vaultError : curationError + const isError = useCurationVault ? isVaultError : isCurationError + const curate = useCurationVault ? curateVault : curateDirect + const payToData = { amount, currency, @@ -327,7 +348,7 @@ const USDTProcessingForm: React.FC = ({ amount={amount} currency={currency} recipient={recipient} - showEthAddress={true} + showEthAddress={!!recipient.info.ethAddress} > {!isError && ( <> diff --git a/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx b/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx index 914747cd2c..2df6549b9c 100644 --- a/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx +++ b/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx @@ -22,7 +22,6 @@ interface SwitchNetworkProps { const SwitchNetwork: React.FC = ({ submitCallback }) => { const { lang } = useContext(LanguageContext) - // TODO: support multiple networks const targetNetork = featureSupportedChains.curation[0] const { isUnsupportedNetwork, switchToTargetNetwork, isSwitchingNetwork } = useTargetNetwork(targetNetork) diff --git a/src/components/Hook/index.ts b/src/components/Hook/index.ts index 0c40be308d..1e5f2f1696 100644 --- a/src/components/Hook/index.ts +++ b/src/components/Hook/index.ts @@ -2,7 +2,6 @@ export * from './useBillboard' export * from './useCarousel' export * from './useColorThief' export * from './useCountdown' -export * from './useCuration' export * from './useDialogSwitch' export * from './useDirectImageUpload' export * from './useERC20' diff --git a/src/components/Hook/useCuration.ts b/src/components/Hook/useCuration.ts deleted file mode 100644 index b158cb370c..0000000000 --- a/src/components/Hook/useCuration.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useContractWrite, usePrepareContractWrite } from 'wagmi' - -import { contract } from '~/common/enums' -import { CurationABI } from '~/common/utils' - -export const useCurate = () => { - const { config } = usePrepareContractWrite({ - address: contract.Optimism.curationAddress, - abi: CurationABI, - functionName: 'curate', - }) - - return useContractWrite(config) -} diff --git a/src/components/Hook/useERC20.ts b/src/components/Hook/useERC20.ts index 28d36ad35d..9d4d37a41d 100644 --- a/src/components/Hook/useERC20.ts +++ b/src/components/Hook/useERC20.ts @@ -12,14 +12,19 @@ import { contract } from '~/common/enums' import { featureSupportedChains, MaxApprovedUSDTAmount } from '~/common/utils' import { ViewerContext } from '~/components' -export const useAllowanceUSDT = () => { +export const useAllowanceUSDT = (useCurationVault: boolean) => { const { address } = useAccount() return useContractRead({ address: contract.Optimism.tokenAddress, abi: erc20ABI, functionName: 'allowance', - args: [address as `0x${string}`, contract.Optimism.curationAddress], + args: [ + address as `0x${string}`, + useCurationVault + ? contract.Optimism.curationVaultAddress + : contract.Optimism.curationAddress, + ], }) } @@ -56,12 +61,17 @@ export const useBalanceEther = ({ }) } -export const useApproveUSDT = () => { +export const useApproveUSDT = (useCurationVault: boolean) => { const { config } = usePrepareContractWrite({ address: contract.Optimism.tokenAddress, abi: erc20ABI, functionName: 'approve', - args: [contract.Optimism.curationAddress, MaxApprovedUSDTAmount], + args: [ + useCurationVault + ? contract.Optimism.curationVaultAddress + : contract.Optimism.curationAddress, + MaxApprovedUSDTAmount, + ], }) return useContractWrite(config) diff --git a/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx b/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx index ad112a57aa..31543f89c2 100644 --- a/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx +++ b/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx @@ -20,7 +20,6 @@ export const DisableSupport = ({ recipient, onClose, }: Props) => { - const isUSDT = currency === CURRENCY.USDT const isLikecoin = currency === CURRENCY.LIKE return ( @@ -33,12 +32,6 @@ export const DisableSupport = ({
- {isUSDT && ( - - )} {isLikecoin && ( { const viewer = useContext(ViewerContext) const [windowRef, setWindowRef] = useState(undefined) const { currStep, forward: _forward } = useStep('setAmount') - const hasAuthorAddress = recipient.info.ethAddress const hasAuthorLikeID = !!recipient.liker.likerId const supportCurrency = storage.get(SUPPORT_TAB_PREFERENCE_KEY) const { address } = useAccount() - // TODO: support multiple networks const targetNetork = featureSupportedChains.curation[0] const { isUnsupportedNetwork } = useTargetNetwork(targetNetork) @@ -104,7 +102,6 @@ const SupportAuthor = (props: SupportAuthorProps) => { forward('setAmount') } - const isUSDT = currency === CURRENCY.USDT const isLikecoin = currency === CURRENCY.LIKE const [payToTx, setPayToTx] = @@ -177,7 +174,7 @@ const SupportAuthor = (props: SupportAuthorProps) => { const showTabs = isSetAmount || isWalletSelect || isNetworkSelect - if ((!hasAuthorAddress && isUSDT) || (!hasAuthorLikeID && isLikecoin)) { + if (!hasAuthorLikeID && isLikecoin) { return ( Date: Thu, 5 Dec 2024 15:44:27 +0700 Subject: [PATCH 02/19] feat(donation): add WithdrewLockedTokens notice --- lang/default.json | 3 + lang/en.json | 3 + lang/zh-Hans.json | 3 + lang/zh-Hant.json | 3 + src/common/enums/test.ts | 1 + .../WithdrewLockedTokensNotice.tsx | 74 +++++++++++++++++++ .../Notice/TransactionNotice/index.tsx | 5 ++ src/stories/components/Notices/mock.ts | 11 +++ src/stories/mocks/index.ts | 6 ++ 9 files changed, 109 insertions(+) create mode 100644 src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx diff --git a/lang/default.json b/lang/default.json index 1fc650e546..9939beb6df 100644 --- a/lang/default.json +++ b/lang/default.json @@ -1265,6 +1265,9 @@ "defaultMessage": "New followers", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "The vault contract has sent {amount} USDT to the linked wallet. Click here for details." + }, "Jmg5do": { "defaultMessage": "Archived Work" }, diff --git a/lang/en.json b/lang/en.json index 9fe60683ba..7650708501 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1265,6 +1265,9 @@ "defaultMessage": "New followers", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "The vault contract has sent {amount} USDT to the linked wallet. Click here for details." + }, "Jmg5do": { "defaultMessage": "Archived Work" }, diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 309209eeb4..9a4f77662e 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -1265,6 +1265,9 @@ "defaultMessage": "被关注", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "交易合约已将金额 {amount} USDT 发送至绑定钱包,点此查看详情" + }, "Jmg5do": { "defaultMessage": "作品已归档" }, diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 3808917ac8..e6f8717518 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -1265,6 +1265,9 @@ "defaultMessage": "被追蹤", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "交易合約已將金額 {amount} USDT 發送至綁定錢包,點此查看詳情" + }, "Jmg5do": { "defaultMessage": "作品已封存" }, diff --git a/src/common/enums/test.ts b/src/common/enums/test.ts index 3cb983ce83..04553f177c 100644 --- a/src/common/enums/test.ts +++ b/src/common/enums/test.ts @@ -127,6 +127,7 @@ export enum TEST_ID { NOTICE_TAG_LEAVE_EDITOR = 'notice/tag-leave-editor', NOTICE_PAYMENT_PAYOUT = 'notice/payment-payout', NOTICE_PAYMENT_RECEIVE_DONATION = 'notice/payment-receive-donation', + NOTICE_WITHDREW_LOCKED_TOKENS = 'notice/withdrew-locked-tokens', NOTICE_CIRCLE_NEW_FOLLOWER = 'notice/circle-new-follower', NOTICE_CIRCLE_NEW_SUBSCRIBER = 'notice/circle-new-subscriber', NOTICE_CIRCLE_NEW_UNSUBSCRIBER = 'notice/circle-new-unsubscriber', diff --git a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx new file mode 100644 index 0000000000..f183776f1d --- /dev/null +++ b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx @@ -0,0 +1,74 @@ +import gql from 'graphql-tag' +import { FormattedMessage } from 'react-intl' +import { parseUnits } from 'viem' + +import { contract, TEST_ID } from '~/common/enums' +import { explorers } from '~/common/utils/wallet' +import { WithdrewLockedTokensNoticeFragment } from '~/gql/graphql' + +import NoticeActorAvatar from '../NoticeActorAvatar' +import NoticeActorName from '../NoticeActorName' +import NoticeDate from '../NoticeDate' +import styles from '../styles.module.css' + +const WithdrewLockedTokensNotice = ({ + notice, +}: { + notice: WithdrewLockedTokensNoticeFragment +}) => { + const tx = notice.tx + const blockchainTx = tx.blockchainTx + + if (!notice.actors || !blockchainTx) { + return null + } + + const link = `${explorers[blockchainTx.chain].url}/tx/${blockchainTx.txHash}` + + return ( +
+
+ + + +
+
+ +
+
+ ) +} + +WithdrewLockedTokensNotice.fragments = { + notice: gql` + fragment WithdrewLockedTokensNotice on TransactionNotice { + id + ...NoticeDate + actors { + ...NoticeActorAvatarUser + ...NoticeActorNameUser + } + tx: target { + id + amount + currency + blockchainTx { + chain + txHash + } + } + } + ${NoticeDate.fragments.notice} + ${NoticeActorAvatar.fragments.user} + ${NoticeActorName.fragments.user} + `, +} + +export default WithdrewLockedTokensNotice diff --git a/src/components/Notice/TransactionNotice/index.tsx b/src/components/Notice/TransactionNotice/index.tsx index 5c7f189862..0c0b618433 100644 --- a/src/components/Notice/TransactionNotice/index.tsx +++ b/src/components/Notice/TransactionNotice/index.tsx @@ -3,6 +3,7 @@ import gql from 'graphql-tag' import { TransactionNoticeFragment } from '~/gql/graphql' import PaymentReceivedDonationNotice from './PaymentReceivedDonationNotice' +import WithdrewLockedTokensNotice from './WithdrewLockedTokensNotice' const TransactionNotice = ({ notice, @@ -12,6 +13,8 @@ const TransactionNotice = ({ switch (notice.txNoticeType) { case 'PaymentReceivedDonation': return + case 'WithdrewLockedTokens': + return default: return null } @@ -25,8 +28,10 @@ TransactionNotice.fragments = { __typename txNoticeType: type ...PaymentReceivedDonationNotice + ...WithdrewLockedTokensNotice } ${PaymentReceivedDonationNotice.fragments.notice} + ${WithdrewLockedTokensNotice.fragments.notice} `, } diff --git a/src/stories/components/Notices/mock.ts b/src/stories/components/Notices/mock.ts index 6ea0d8336b..79e5a40c32 100644 --- a/src/stories/components/Notices/mock.ts +++ b/src/stories/components/Notices/mock.ts @@ -1,5 +1,6 @@ import { MOCK_ARTILCE, + MOCK_BLOCKCHAIN_TRANSACTION, MOCK_CIRCLE, MOCK_CIRCLE_ARTICLE, MOCK_CIRCLE_COMMENT, @@ -323,6 +324,16 @@ export const MOCK_NOTICE_LIST = [ txNoticeType: 'PaymentReceivedDonation' as any, tx: MOCK_TRANSACTION, }, + // WithdrewLockedTokens + { + __typename: 'TransactionNotice' as any, + id: 'WithdrewLockedTokens', + unread: false, + createdAt: '2020-12-24T07:29:17.682Z', + actors: [MOCK_USER], + txNoticeType: 'WithdrewLockedTokens' as any, + tx: { ...MOCK_TRANSACTION, blockchainTx: MOCK_BLOCKCHAIN_TRANSACTION }, + }, /** * Circle diff --git a/src/stories/mocks/index.ts b/src/stories/mocks/index.ts index d4e02d4997..e00f9011d9 100644 --- a/src/stories/mocks/index.ts +++ b/src/stories/mocks/index.ts @@ -279,6 +279,12 @@ export const MOCK_TRANSACTION = { target: MOCK_ARTILCE, } +export const MOCK_BLOCKCHAIN_TRANSACTION = { + __typename: 'BlockchainTransaction' as any, + chain: 'Optimism' as any, + txHash: '0x1234567890abcdef', +} + // Crypto wallet export const MOCK_CRYPTO_WALLET = { __typename: 'CryptoWallet' as any, From 10ad7f7f67bb940ad5786f535d2fa35c65dbaee5 Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:33:38 +0700 Subject: [PATCH 03/19] feat(donation): revise PaymentReceivedDonationNotice --- lang/default.json | 3 +++ lang/en.json | 3 +++ lang/zh-Hans.json | 3 +++ lang/zh-Hant.json | 3 +++ .../PaymentReceivedDonationNotice.tsx | 11 +++++++++++ .../TransactionNotice/WithdrewLockedTokensNotice.tsx | 3 +-- 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lang/default.json b/lang/default.json index 9939beb6df..5750a0a095 100644 --- a/lang/default.json +++ b/lang/default.json @@ -869,6 +869,9 @@ "defaultMessage": "Copy comment", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ", connect your wallet to claim" + }, "Ci7dxf": { "defaultMessage": "Comment deleted", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/lang/en.json b/lang/en.json index 7650708501..0205359d4b 100644 --- a/lang/en.json +++ b/lang/en.json @@ -869,6 +869,9 @@ "defaultMessage": "Copy comment", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ", connect your wallet to claim" + }, "Ci7dxf": { "defaultMessage": "Comment deleted", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 9a4f77662e..acc34265b0 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -869,6 +869,9 @@ "defaultMessage": "复制留言", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ",绑定钱包后可领取" + }, "Ci7dxf": { "defaultMessage": "留言已删除", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index e6f8717518..9bcf8756ca 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -869,6 +869,9 @@ "defaultMessage": "複製留言", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ",連接錢包領取" + }, "Ci7dxf": { "defaultMessage": "留言已刪除", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx b/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx index 41d89f7411..ece92363cb 100644 --- a/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx +++ b/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx @@ -1,7 +1,9 @@ import gql from 'graphql-tag' +import { useContext } from 'react' import { FormattedMessage } from 'react-intl' import { TEST_ID } from '~/common/enums' +import { ViewerContext } from '~/components/Context' import { PaymentReceivedDonationNoticeFragment } from '~/gql/graphql' import NoticeActorAvatar from '../NoticeActorAvatar' @@ -16,11 +18,14 @@ const PaymentReceivedDonationNotice = ({ }: { notice: PaymentReceivedDonationNoticeFragment }) => { + const viewer = useContext(ViewerContext) + if (!notice.actors) { return null } const tx = notice.tx + const hasEthAddress = !!viewer?.info?.ethAddress return ( {tx.amount} {tx.currency} + {!hasEthAddress && ( + + )} )) || '' diff --git a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx index f183776f1d..54d7283e2e 100644 --- a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx +++ b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx @@ -1,8 +1,7 @@ import gql from 'graphql-tag' import { FormattedMessage } from 'react-intl' -import { parseUnits } from 'viem' -import { contract, TEST_ID } from '~/common/enums' +import { TEST_ID } from '~/common/enums' import { explorers } from '~/common/utils/wallet' import { WithdrewLockedTokensNoticeFragment } from '~/gql/graphql' From c8a4cba52c9f0684b9fc52dfd00d5ab8bea08250 Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:41:40 +0700 Subject: [PATCH 04/19] feat(settings): show claim button for viewer hasn't connected a wallet but has balance in vault --- lang/default.json | 3 +++ lang/en.json | 3 +++ lang/zh-Hans.json | 3 +++ lang/zh-Hant.json | 3 +++ src/common/utils/contract.ts | 11 +++++++++ src/common/utils/index.ts | 1 + .../Forms/PaymentForm/Processing/index.tsx | 14 +++++++++-- src/components/Hook/useERC20.ts | 24 ++++++++++++++++++- .../Me/Settings/Account/Wallet/index.tsx | 19 +++++++++++---- 9 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 src/common/utils/contract.ts diff --git a/lang/default.json b/lang/default.json index 5750a0a095..bf57dae841 100644 --- a/lang/default.json +++ b/lang/default.json @@ -500,6 +500,9 @@ "defaultMessage": "subscribers_empty", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, + "6Sj2lN": { + "defaultMessage": "Claim" + }, "6Vznnt": { "defaultMessage": "left a comment in your circle", "description": "src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx" diff --git a/lang/en.json b/lang/en.json index 0205359d4b..56dd960aac 100644 --- a/lang/en.json +++ b/lang/en.json @@ -500,6 +500,9 @@ "defaultMessage": "subscribers_empty", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, + "6Sj2lN": { + "defaultMessage": "Claim" + }, "6Vznnt": { "defaultMessage": "left a comment in your circle", "description": "src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index acc34265b0..b04c30a4c1 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -500,6 +500,9 @@ "defaultMessage": "目前总订阅人数", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, + "6Sj2lN": { + "defaultMessage": "提领支持" + }, "6Vznnt": { "defaultMessage": "在你的围炉中留言", "description": "src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 9bcf8756ca..8e38536882 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -500,6 +500,9 @@ "defaultMessage": "目前總訂閱人數", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, + "6Sj2lN": { + "defaultMessage": "提領支持" + }, "6Vznnt": { "defaultMessage": "在你的圍爐中留言", "description": "src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx" diff --git a/src/common/utils/contract.ts b/src/common/utils/contract.ts new file mode 100644 index 0000000000..24623b4880 --- /dev/null +++ b/src/common/utils/contract.ts @@ -0,0 +1,11 @@ +export const toCurationVaultUID = (userId: string) => { + return `matters:${userId}` +} + +export const parseCurationVaultUID = (uid: string) => { + const match = uid.match(/^matters:(\d+)$/) + if (!match) { + return null + } + return match[1] +} diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts index 9fe9be7425..def7f2824f 100644 --- a/src/common/utils/index.ts +++ b/src/common/utils/index.ts @@ -3,6 +3,7 @@ export * from './analytics' export * from './audioPlayer' export * from './comment' export * from './connections' +export * from './contract' export * from './cookie' export * from './crypto' export * from './datetime' diff --git a/src/components/Forms/PaymentForm/Processing/index.tsx b/src/components/Forms/PaymentForm/Processing/index.tsx index bfd4128e60..406368deb4 100644 --- a/src/components/Forms/PaymentForm/Processing/index.tsx +++ b/src/components/Forms/PaymentForm/Processing/index.tsx @@ -14,7 +14,12 @@ import { PAYMENT_CURRENCY as CURRENCY, SUPPORT_SUCCESS_USDT_VISITOR, } from '~/common/enums' -import { CurationABI, CurationVaultABI } from '~/common/utils' +import { + CurationABI, + CurationVaultABI, + fromGlobalId, + toCurationVaultUID, +} from '~/common/utils' import { Dialog, Icon, @@ -233,7 +238,12 @@ const USDTProcessingForm: React.FC = ({ address: contract.Optimism.curationVaultAddress, abi: CurationVaultABI, functionName: 'curate', - args: [recipient.id, contract.Optimism.tokenAddress, normalizedAmount, uri], + args: [ + toCurationVaultUID(fromGlobalId(recipient.id).id), + contract.Optimism.tokenAddress, + normalizedAmount, + uri, + ], }) const { diff --git a/src/components/Hook/useERC20.ts b/src/components/Hook/useERC20.ts index 9d4d37a41d..e183644088 100644 --- a/src/components/Hook/useERC20.ts +++ b/src/components/Hook/useERC20.ts @@ -9,7 +9,13 @@ import { } from 'wagmi' import { contract } from '~/common/enums' -import { featureSupportedChains, MaxApprovedUSDTAmount } from '~/common/utils' +import { + CurationVaultABI, + featureSupportedChains, + fromGlobalId, + MaxApprovedUSDTAmount, + toCurationVaultUID, +} from '~/common/utils' import { ViewerContext } from '~/components' export const useAllowanceUSDT = (useCurationVault: boolean) => { @@ -61,6 +67,22 @@ export const useBalanceEther = ({ }) } +export const useVaultBalanceUSDT = () => { + const viewer = useContext(ViewerContext) + const viewerId = viewer.id + const uid = toCurationVaultUID(fromGlobalId(viewerId).id) + const targetNetwork = featureSupportedChains.curation[0] + + return useContractRead({ + address: contract.Optimism.curationVaultAddress, + abi: CurationVaultABI, + functionName: 'erc20Balances', + args: [uid, contract.Optimism.tokenAddress], + chainId: targetNetwork.id, + cacheTime: 5_000, + }) +} + export const useApproveUSDT = (useCurationVault: boolean) => { const { config } = usePrepareContractWrite({ address: contract.Optimism.tokenAddress, diff --git a/src/views/Me/Settings/Account/Wallet/index.tsx b/src/views/Me/Settings/Account/Wallet/index.tsx index 9ac16a588d..70b54daf45 100644 --- a/src/views/Me/Settings/Account/Wallet/index.tsx +++ b/src/views/Me/Settings/Account/Wallet/index.tsx @@ -8,6 +8,7 @@ import { Icon, RemoveWalletLoginDialog, TableView, + useVaultBalanceUSDT, ViewerContext, } from '~/components' import { SocialAccountType } from '~/gql/graphql' @@ -30,6 +31,9 @@ const Wallet = () => { const canRemoveNonFacebookLogins = +canEmailLogin + +canWalletLogin + nonFacebookSocials.length > 1 + const { data: vaultBalanceUSDT } = useVaultBalanceUSDT() + const hasVaultBalanceUSDT = vaultBalanceUSDT && vaultBalanceUSDT > 0 + return ( {({ openDialog: openAddWalletLoginDialog }) => { @@ -61,10 +65,17 @@ const Wallet = () => { right={ ethAddress ? undefined : ( - + {hasVaultBalanceUSDT ? ( + + ) : ( + + )} ) } From 61ff081a7c21f3e57abb49a462f775f3f524dfaa Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:28:13 +0700 Subject: [PATCH 05/19] feat(wallet): revise USDT balance button; retire payment pointer; --- lang/default.json | 31 +---- lang/en.json | 31 +---- lang/zh-Hans.json | 31 +---- lang/zh-Hant.json | 31 +---- src/common/utils/form/validate.test.ts | 13 -- src/common/utils/form/validate.ts | 16 +-- src/common/utils/validator.test.ts | 13 -- src/common/utils/validator.ts | 2 - src/components/Context/Viewer/index.tsx | 1 - src/components/CurrencyFormatter/index.tsx | 12 +- .../CurrencyFormatter/styles.module.css | 14 +- .../PaymentPointerDialog/Explainer/index.tsx | 70 ---------- .../Explainer/styles.module.css | 5 - .../SetPaymentPointerForm.tsx | 129 ------------------ .../Dialogs/PaymentPointerDialog/index.tsx | 71 ---------- src/components/Dialogs/index.tsx | 1 - src/components/Head/index.tsx | 5 +- src/views/ArticleDetail/gql.ts | 1 - src/views/ArticleDetail/index.tsx | 2 - src/views/Me/Wallet/Balance/FiatCurrency.tsx | 1 + src/views/Me/Wallet/Balance/LikeCoin.tsx | 12 +- src/views/Me/Wallet/Balance/USDT.tsx | 37 +++-- src/views/Me/Wallet/PaymentPointer/index.tsx | 20 --- src/views/Me/Wallet/index.tsx | 14 +- 24 files changed, 98 insertions(+), 465 deletions(-) delete mode 100644 src/components/Dialogs/PaymentPointerDialog/Explainer/index.tsx delete mode 100644 src/components/Dialogs/PaymentPointerDialog/Explainer/styles.module.css delete mode 100644 src/components/Dialogs/PaymentPointerDialog/SetPaymentPointerForm.tsx delete mode 100644 src/components/Dialogs/PaymentPointerDialog/index.tsx delete mode 100644 src/views/Me/Wallet/PaymentPointer/index.tsx diff --git a/lang/default.json b/lang/default.json index bf57dae841..051ebff536 100644 --- a/lang/default.json +++ b/lang/default.json @@ -134,9 +134,6 @@ "defaultMessage": "Matters ID has been set up. More account info can be found in Settings", "description": "src/components/Dialogs/SetUserNameDialog/ConfirmStep.tsx" }, - "0HdNPs": { - "defaultMessage": "{link1}: In order to increase the sources of income for creators, Matters introduced {link2} and {link3}, enabling the payer and the payee to conduct transactions in different currencies. Through {link4}, and other services you can acqure a {link6}, and receive payments from {link7}, applicable on both Matters website and IPFS." - }, "0JlaP1": { "defaultMessage": "Oops!This link has expired", "description": "src/views/Callback/UI.tsx" @@ -702,6 +699,10 @@ "9Vkz9W": { "defaultMessage": "Maximum image area is limited to 100 megapixels (for example, 10,000×10,000 pixels)." }, + "9WMs5q": { + "defaultMessage": "Connect", + "description": "src/views/Me/Wallet/Balance" + }, "9WRlF4": { "defaultMessage": "Send" }, @@ -1232,9 +1233,6 @@ "IpMWC4": { "defaultMessage": "You’ve posted several times in a short period. Please take a break." }, - "Is5PqP": { - "defaultMessage": "Interledger Protocol" - }, "ItUuuX": { "defaultMessage": "invites you to join the circle {circleName} , and you can experience it for {freePeriod} days for free", "description": "src/components/Notice/CircleNotice/CircleInvitationNotice.tsx" @@ -1388,9 +1386,6 @@ "defaultMessage": "Article published", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" }, - "LklXfd": { - "defaultMessage": "Payment Pointer" - }, "LmiUWG": { "defaultMessage": "You do not have permissionn to perform this operation", "description": "FORBIDDEN_BY_TARGET_STATE" @@ -1958,16 +1953,10 @@ "WQT8ZA": { "defaultMessage": "Edit collection" }, - "WiGHyF": { - "defaultMessage": "Web Monetization standard" - }, "WpvsPu": { "defaultMessage": "Subscribe", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, - "WrQjnc": { - "defaultMessage": "Payment pointer updated" - }, "WsPbZT": { "defaultMessage": "Continue payout" }, @@ -2321,6 +2310,9 @@ "defaultMessage": "No blocked users yet", "description": "src/views/Me/Settings/Blocked/SettingsBlocked.tsx" }, + "dK7Dnj": { + "defaultMessage": "🔥 Claim for free" + }, "dQhNbF": { "defaultMessage": "Payment will be processed by Stripe, allowing your support to be unrestricted by region.", "description": "src/components/Forms/PaymentForm/StripeCheckout/index.tsx" @@ -2544,9 +2536,6 @@ "i4OBEw": { "defaultMessage": "\"{name}\" is invalid." }, - "i7cXnf": { - "defaultMessage": "The wallet address starts with \"$\"." - }, "iEJeQH": { "defaultMessage": "Liker ID" }, @@ -2890,9 +2879,6 @@ "defaultMessage": "liked", "description": "src/components/Notice/ArticleNotice/ArticleNewAppreciationNotice.tsx" }, - "p6D+Uc": { - "defaultMessage": "Enter Payment Pointer" - }, "p9gEZh": { "defaultMessage": "Up to 3 images can be uploaded" }, @@ -3252,9 +3238,6 @@ "defaultMessage": "reset your login password", "description": "src/components/Dialogs/SetEmailDialog/Content.tsx" }, - "vyG38g": { - "defaultMessage": "wallet address" - }, "w+6UiO": { "defaultMessage": "Add Invitation" }, diff --git a/lang/en.json b/lang/en.json index 56dd960aac..a67050ba68 100644 --- a/lang/en.json +++ b/lang/en.json @@ -134,9 +134,6 @@ "defaultMessage": "Matters ID has been set up. More account info can be found in Settings", "description": "src/components/Dialogs/SetUserNameDialog/ConfirmStep.tsx" }, - "0HdNPs": { - "defaultMessage": "{link1}: In order to increase the sources of income for creators, Matters introduced {link2} and {link3}, enabling the payer and the payee to conduct transactions in different currencies. Through {link4}, and other services you can acqure a {link6}, and receive payments from {link7}, applicable on both Matters website and IPFS." - }, "0JlaP1": { "defaultMessage": "Oops!This link has expired", "description": "src/views/Callback/UI.tsx" @@ -702,6 +699,10 @@ "9Vkz9W": { "defaultMessage": "Maximum image area is limited to 100 megapixels (for example, 10,000×10,000 pixels)." }, + "9WMs5q": { + "defaultMessage": "Connect", + "description": "src/views/Me/Wallet/Balance" + }, "9WRlF4": { "defaultMessage": "Send" }, @@ -1232,9 +1233,6 @@ "IpMWC4": { "defaultMessage": "You’ve posted several times in a short period. Please take a break." }, - "Is5PqP": { - "defaultMessage": "Interledger Protocol" - }, "ItUuuX": { "defaultMessage": "invites you to join the circle {circleName} , and you can experience it for {freePeriod} days for free", "description": "src/components/Notice/CircleNotice/CircleInvitationNotice.tsx" @@ -1388,9 +1386,6 @@ "defaultMessage": "Article published", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" }, - "LklXfd": { - "defaultMessage": "Payment Pointer" - }, "LmiUWG": { "defaultMessage": "You do not have permissionn to perform this operation", "description": "FORBIDDEN_BY_TARGET_STATE" @@ -1958,16 +1953,10 @@ "WQT8ZA": { "defaultMessage": "Edit collection" }, - "WiGHyF": { - "defaultMessage": "Web Monetization standard" - }, "WpvsPu": { "defaultMessage": "Subscribe", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, - "WrQjnc": { - "defaultMessage": "Payment pointer updated" - }, "WsPbZT": { "defaultMessage": "Continue payout" }, @@ -2321,6 +2310,9 @@ "defaultMessage": "No blocked users yet", "description": "src/views/Me/Settings/Blocked/SettingsBlocked.tsx" }, + "dK7Dnj": { + "defaultMessage": "🔥 Claim for free" + }, "dQhNbF": { "defaultMessage": "Payment will be processed by Stripe, allowing your support to be unrestricted by region.", "description": "src/components/Forms/PaymentForm/StripeCheckout/index.tsx" @@ -2544,9 +2536,6 @@ "i4OBEw": { "defaultMessage": "\"{name}\" is invalid." }, - "i7cXnf": { - "defaultMessage": "The wallet address starts with \"$\"." - }, "iEJeQH": { "defaultMessage": "Liker ID" }, @@ -2890,9 +2879,6 @@ "defaultMessage": "liked", "description": "src/components/Notice/ArticleNotice/ArticleNewAppreciationNotice.tsx" }, - "p6D+Uc": { - "defaultMessage": "Enter Payment Pointer" - }, "p9gEZh": { "defaultMessage": "Up to 3 images can be uploaded" }, @@ -3252,9 +3238,6 @@ "defaultMessage": "reset your login password", "description": "src/components/Dialogs/SetEmailDialog/Content.tsx" }, - "vyG38g": { - "defaultMessage": "wallet address" - }, "w+6UiO": { "defaultMessage": "Add Invitation" }, diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index b04c30a4c1..ff4a5f7eed 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -134,9 +134,6 @@ "defaultMessage": "Matters ID 已设置,更多帐号相关设置可前往设置页修改", "description": "src/components/Dialogs/SetUserNameDialog/ConfirmStep.tsx" }, - "0HdNPs": { - "defaultMessage": "{link1}:为增加创作者的收入来源,Matters 引入了 {link2} 与 {link3},实现付款方与收款方即使使用不同的货币进行交易,也可以对交易进行自动币种转换。你可以通过 {link4}等服务配置 {link6},获得来自 {link7} 平台的收入,在 Matters 网站与 IPFS 网络中均可使用。" - }, "0JlaP1": { "defaultMessage": "Oops!链接已失效", "description": "src/views/Callback/UI.tsx" @@ -702,6 +699,10 @@ "9Vkz9W": { "defaultMessage": "图片面积不得超过 1 亿像素(如 10,000 x 10,000 像素)" }, + "9WMs5q": { + "defaultMessage": "绑定钱包", + "description": "src/views/Me/Wallet/Balance" + }, "9WRlF4": { "defaultMessage": "送出" }, @@ -1232,9 +1233,6 @@ "IpMWC4": { "defaultMessage": "短时间内已发布多条动态,请先休息一会吧~" }, - "Is5PqP": { - "defaultMessage": "跨账本协议" - }, "ItUuuX": { "defaultMessage": "邀你加入围炉 {circleName} ,你可以免费体验 {freePeriod} 天", "description": "src/components/Notice/CircleNotice/CircleInvitationNotice.tsx" @@ -1388,9 +1386,6 @@ "defaultMessage": "作品已发布", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" }, - "LklXfd": { - "defaultMessage": "跨链收款地址" - }, "LmiUWG": { "defaultMessage": "你无法对此对象进行该操作", "description": "FORBIDDEN_BY_TARGET_STATE" @@ -1958,16 +1953,10 @@ "WQT8ZA": { "defaultMessage": "编辑选集" }, - "WiGHyF": { - "defaultMessage": "Web Monetization 标准" - }, "WpvsPu": { "defaultMessage": "订阅", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, - "WrQjnc": { - "defaultMessage": "收款地址已更新" - }, "WsPbZT": { "defaultMessage": "继续提现" }, @@ -2321,6 +2310,9 @@ "defaultMessage": "尚无屏蔽记录", "description": "src/views/Me/Settings/Blocked/SettingsBlocked.tsx" }, + "dK7Dnj": { + "defaultMessage": "🔥 免费提领" + }, "dQhNbF": { "defaultMessage": "付款将由 Stripe 处理,让你的支持不受地域限制", "description": "src/components/Forms/PaymentForm/StripeCheckout/index.tsx" @@ -2544,9 +2536,6 @@ "i4OBEw": { "defaultMessage": "不能使用 “{name}”" }, - "i7cXnf": { - "defaultMessage": "钱包地址以“$”开头" - }, "iEJeQH": { "defaultMessage": "设置 Liker ID" }, @@ -2890,9 +2879,6 @@ "defaultMessage": "赞赏了", "description": "src/components/Notice/ArticleNotice/ArticleNewAppreciationNotice.tsx" }, - "p6D+Uc": { - "defaultMessage": "请输入地址" - }, "p9gEZh": { "defaultMessage": "动态最多支持 3 张图片" }, @@ -3252,9 +3238,6 @@ "defaultMessage": "重置你的登录密码", "description": "src/components/Dialogs/SetEmailDialog/Content.tsx" }, - "vyG38g": { - "defaultMessage": "钱包地址" - }, "w+6UiO": { "defaultMessage": "新增邀请" }, diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 8e38536882..644f7abff9 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -134,9 +134,6 @@ "defaultMessage": "Matters ID 已設置,更多帳號相關設置可前往設定頁修改", "description": "src/components/Dialogs/SetUserNameDialog/ConfirmStep.tsx" }, - "0HdNPs": { - "defaultMessage": "{link1}:為增加創作者的收入來源,Matters 引入了 {link2} 與 {link3},實現付款方與收款方即使使用不同的貨幣進行交易,也可以對交易進行自動幣種轉換。你可以通過 {link4}等服務配置 {link6},獲得來自 {link7} 平臺的收入,在 Matters 網站與 IPFS 網絡中均可使用。" - }, "0JlaP1": { "defaultMessage": "Oops!連結已失效", "description": "src/views/Callback/UI.tsx" @@ -702,6 +699,10 @@ "9Vkz9W": { "defaultMessage": "圖片面積不得超過 1 億像素(如 10,000x10,000 像素)" }, + "9WMs5q": { + "defaultMessage": "綁定錢包", + "description": "src/views/Me/Wallet/Balance" + }, "9WRlF4": { "defaultMessage": "送出" }, @@ -1232,9 +1233,6 @@ "IpMWC4": { "defaultMessage": "短時間內已發布多條動態,請先休息一會吧~" }, - "Is5PqP": { - "defaultMessage": "跨賬本協議" - }, "ItUuuX": { "defaultMessage": "邀你加入圍爐 {circleName} ,你可以免費體驗 {freePeriod} 天", "description": "src/components/Notice/CircleNotice/CircleInvitationNotice.tsx" @@ -1388,9 +1386,6 @@ "defaultMessage": "作品已發布", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" }, - "LklXfd": { - "defaultMessage": "跨鏈收款地址" - }, "LmiUWG": { "defaultMessage": "你無法對此對象進行該操作", "description": "FORBIDDEN_BY_TARGET_STATE" @@ -1958,16 +1953,10 @@ "WQT8ZA": { "defaultMessage": "編輯選集" }, - "WiGHyF": { - "defaultMessage": "Web Monetization 標準" - }, "WpvsPu": { "defaultMessage": "訂閱", "description": "src/views/Circle/Analytics/SubscriberAnalytics/index.tsx" }, - "WrQjnc": { - "defaultMessage": "收款地址已更新" - }, "WsPbZT": { "defaultMessage": "繼續提現" }, @@ -2321,6 +2310,9 @@ "defaultMessage": "尚無封鎖紀錄", "description": "src/views/Me/Settings/Blocked/SettingsBlocked.tsx" }, + "dK7Dnj": { + "defaultMessage": "🔥 免費提領" + }, "dQhNbF": { "defaultMessage": "付款將由 Stripe 處理,讓你的支持不受地域限制", "description": "src/components/Forms/PaymentForm/StripeCheckout/index.tsx" @@ -2544,9 +2536,6 @@ "i4OBEw": { "defaultMessage": "不能使用「{name}」" }, - "i7cXnf": { - "defaultMessage": "錢包地址以「$」開頭" - }, "iEJeQH": { "defaultMessage": "設置 Liker ID" }, @@ -2890,9 +2879,6 @@ "defaultMessage": "讚賞了", "description": "src/components/Notice/ArticleNotice/ArticleNewAppreciationNotice.tsx" }, - "p6D+Uc": { - "defaultMessage": "請輸入地址" - }, "p9gEZh": { "defaultMessage": "動態最多支持 3 張圖片" }, @@ -3252,9 +3238,6 @@ "defaultMessage": "重置你的登入密碼", "description": "src/components/Dialogs/SetEmailDialog/Content.tsx" }, - "vyG38g": { - "defaultMessage": "錢包地址" - }, "w+6UiO": { "defaultMessage": "新增邀請" }, diff --git a/src/common/utils/form/validate.test.ts b/src/common/utils/form/validate.test.ts index c4afbefb90..0cd066783a 100644 --- a/src/common/utils/form/validate.test.ts +++ b/src/common/utils/form/validate.test.ts @@ -37,7 +37,6 @@ import { validateEmail, validatePassword, validatePaymentPassword, - validatePaymentPointer, validatePayoutAmount, validateTagName, validateUserName, @@ -297,18 +296,6 @@ describe('utils/form/validate/validatePaymentPassword', () => { }) }) -describe('utils/form/validate/validatePaymentPointer', () => { - it('should validate payment pointer correctly', () => { - expect(validatePaymentPointer('', intl)).toBe('Required') - expect(validatePaymentPointer('$123456', intl)).toBeUndefined() - - const error = 'The wallet address starts with "$".' - expect(validatePaymentPointer('你好世界🌍', intl)).toBe(error) - expect(validatePaymentPointer('1234', intl)).toBe(error) - expect(validatePaymentPointer('abcd', intl)).toBe(error) - }) -}) - describe('utils/form/validate/validatePayoutAmount', () => { it('should validate payout amount correctly', () => { const min = 100 diff --git a/src/common/utils/form/validate.ts b/src/common/utils/form/validate.ts index 7ac71cc36c..66042e36b7 100644 --- a/src/common/utils/form/validate.ts +++ b/src/common/utils/form/validate.ts @@ -26,7 +26,7 @@ import { ValidEmailOptions, } from '~/common/utils' -import { hasUpperCase, isValidPaymentPointer } from '../validator' +import { hasUpperCase } from '../validator' export const PUNCTUATION_CHINESE = '\u3002\uff1f\uff01\uff0c\u3001\uff1b\uff1a\u201c\u201d\u2018\u2019\uff08\uff09\u300a\u300b\u3008\u3009\u3010\u3011\u300e\u300f\u300c\u300d\ufe43\ufe44\u3014\u3015\u2026\u2014\uff5e\ufe4f\uffe5' @@ -132,20 +132,6 @@ export const validatePaymentPassword = (value: string, intl: IntlShape) => { } } -export const validatePaymentPointer = (value: string, intl: IntlShape) => { - if (!value) { - return intl.formatMessage({ - defaultMessage: 'Required', - id: 'Seanpx', - }) - } else if (!isValidPaymentPointer(value)) { - return intl.formatMessage({ - defaultMessage: 'The wallet address starts with "$".', - id: 'i7cXnf', - }) - } -} - export const validateUserName = (value: string, intl: IntlShape) => { if (value.length > MAX_USER_NAME_LENGTH) { return intl.formatMessage( diff --git a/src/common/utils/validator.test.ts b/src/common/utils/validator.test.ts index 4d915bdf9b..42eb1430ca 100644 --- a/src/common/utils/validator.test.ts +++ b/src/common/utils/validator.test.ts @@ -4,7 +4,6 @@ import { isValidEmail, isValidPassword, isValidPaymentPassword, - isValidPaymentPointer, } from './validator' describe('utils/validator/isValidEmail', () => { @@ -50,15 +49,3 @@ describe('utils/validator/isValidPaymentPassword', () => { expect(isValidPassword('你好世界你你')).toBe(false) }) }) - -describe('utils/validator/isValidPaymentPointer', () => { - it('should return true for valid payment pointers', () => { - expect(isValidPaymentPointer('$example.com')).toBe(true) - expect(isValidPaymentPointer('$www.example.com')).toBe(true) - }) - - it('should return false for invalid payment pointers', () => { - expect(isValidPaymentPointer('example.com')).toBe(false) - expect(isValidPaymentPointer('www.example.com')).toBe(false) - }) -}) diff --git a/src/common/utils/validator.ts b/src/common/utils/validator.ts index 54c75b00c4..c966010870 100644 --- a/src/common/utils/validator.ts +++ b/src/common/utils/validator.ts @@ -49,8 +49,6 @@ export const isValidPaymentPassword = (password: string): boolean => { /** * Validate payment pointer. */ -export const isValidPaymentPointer = (paymentPointer: string): boolean => - paymentPointer.startsWith('$') export const hasUpperCase = (str: string) => str.toLowerCase() !== str diff --git a/src/components/Context/Viewer/index.tsx b/src/components/Context/Viewer/index.tsx index fcf44623b2..8dfa48de64 100644 --- a/src/components/Context/Viewer/index.tsx +++ b/src/components/Context/Viewer/index.tsx @@ -16,7 +16,6 @@ const ViewerFragments = { userName displayName avatar - paymentPointer liker { likerId civicLiker diff --git a/src/components/CurrencyFormatter/index.tsx b/src/components/CurrencyFormatter/index.tsx index 75323f66ee..53db34381b 100644 --- a/src/components/CurrencyFormatter/index.tsx +++ b/src/components/CurrencyFormatter/index.tsx @@ -5,6 +5,8 @@ interface Props { currency: string subValue?: number | string subCurrency?: string + subtitle?: React.ReactNode + weight?: 'normal' | 'medium' } export const CurrencyFormatter: React.FC = ({ @@ -12,15 +14,21 @@ export const CurrencyFormatter: React.FC = ({ currency, subValue, subCurrency, + subtitle, + weight = 'medium', }) => { return ( - + {currency} {value} + {subtitle && {subtitle}} + {subCurrency && ( - + ≈ {subCurrency} {subValue} )} diff --git a/src/components/CurrencyFormatter/styles.module.css b/src/components/CurrencyFormatter/styles.module.css index f888329756..f81932872a 100644 --- a/src/components/CurrencyFormatter/styles.module.css +++ b/src/components/CurrencyFormatter/styles.module.css @@ -6,8 +6,15 @@ & .currency { font-size: var(--text16); - font-weight: var(--font-medium); color: black; + + &.currency-medium { + font-weight: var(--font-medium); + } + + &.currency-normal { + font-weight: var(--font-normal); + } } & .subCurrency { @@ -15,4 +22,9 @@ font-size: var(--text12); color: var(--color-grey); } + + & .subtitle { + padding-top: var(--sp8); + font-size: var(--text12); + } } diff --git a/src/components/Dialogs/PaymentPointerDialog/Explainer/index.tsx b/src/components/Dialogs/PaymentPointerDialog/Explainer/index.tsx deleted file mode 100644 index 102c08ea5d..0000000000 --- a/src/components/Dialogs/PaymentPointerDialog/Explainer/index.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { FormattedMessage } from 'react-intl' - -import styles from './styles.module.css' - -const PaymentPointerExplainer = () => ( - <> -

- - - - ), - link2: ( - - - - ), - link3: ( - - - - ), - link4: ( - - Uphold - - ), - link5: ( - - GateHub - - ), - link6: ( - - - - ), - link7: ( - - Coil - - ), - }} - /> -

- -) - -export default PaymentPointerExplainer diff --git a/src/components/Dialogs/PaymentPointerDialog/Explainer/styles.module.css b/src/components/Dialogs/PaymentPointerDialog/Explainer/styles.module.css deleted file mode 100644 index 54b0bf0522..0000000000 --- a/src/components/Dialogs/PaymentPointerDialog/Explainer/styles.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.content { - & a { - text-decoration: underline; - } -} diff --git a/src/components/Dialogs/PaymentPointerDialog/SetPaymentPointerForm.tsx b/src/components/Dialogs/PaymentPointerDialog/SetPaymentPointerForm.tsx deleted file mode 100644 index 2175cb4b0d..0000000000 --- a/src/components/Dialogs/PaymentPointerDialog/SetPaymentPointerForm.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import { useFormik } from 'formik' -import gql from 'graphql-tag' -import _pickBy from 'lodash/pickBy' -import { useContext, useState } from 'react' -import { FormattedMessage, useIntl } from 'react-intl' - -import { parseFormSubmitErrors, validatePaymentPointer } from '~/common/utils' -import { Dialog, Form, toast, ViewerContext } from '~/components' -import { useMutation } from '~/components/GQL' -import { UpdatePaymentPointerMutation } from '~/gql/graphql' - -import Explainer from './Explainer' - -interface FormProps { - setIsSubmitting: (submitting: boolean) => void - setIsValid: (valid: boolean) => void - closeDialog: () => void - formId?: string -} - -interface FormValues { - paymentPointer: string -} - -const UPDATE_PAYMENT_POINTER = gql` - mutation UpdatePaymentPointer($input: UpdateUserInfoInput!) { - updateUserInfo(input: $input) { - paymentPointer - } - } -` - -const SetPaymentPointerForm: React.FC = ({ - setIsValid, - setIsSubmitting, - closeDialog, - formId = `set-payment-pointer-form`, -}) => { - const intl = useIntl() - const [submitPaymentPointer] = useMutation( - UPDATE_PAYMENT_POINTER - ) - const viewer = useContext(ViewerContext) - - const [defaultPaymentPointer, setDefaultPaymentPointer] = useState( - viewer.paymentPointer || '' - ) - - const { - values, - errors, - touched, - handleBlur, - handleChange, - handleSubmit, - isValid, - } = useFormik({ - initialValues: { - paymentPointer: defaultPaymentPointer, - }, - validateOnBlur: false, - validateOnChange: false, - validate: ({ paymentPointer }) => - _pickBy({ - paymentPointer: validatePaymentPointer(paymentPointer, intl), - }), - onSubmit: async ({ paymentPointer }, { setFieldError }) => { - try { - setIsSubmitting(true) - await submitPaymentPointer({ - variables: { input: { paymentPointer } }, - }) - - toast.success({ - message: ( - - ), - }) - - setDefaultPaymentPointer(paymentPointer) - setIsSubmitting(false) - closeDialog() - } catch (error) { - setIsSubmitting(false) - - const [messages, codes] = parseFormSubmitErrors(error as any) - codes.forEach((code) => { - setFieldError('paymentPointer', intl.formatMessage(messages[code])) - }) - } - }, - }) - - const updateValidity = () => - setIsValid(isValid && values.paymentPointer !== defaultPaymentPointer) - - return ( - - - - -
- { - handleChange(e) - updateValidity() - }} - spacingTop="base" - /> - -
-
- ) -} - -export default SetPaymentPointerForm diff --git a/src/components/Dialogs/PaymentPointerDialog/index.tsx b/src/components/Dialogs/PaymentPointerDialog/index.tsx deleted file mode 100644 index 69de601515..0000000000 --- a/src/components/Dialogs/PaymentPointerDialog/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { useState } from 'react' -import { FormattedMessage } from 'react-intl' - -import { Dialog, useDialogSwitch } from '~/components' - -import SetPaymentPointerForm from './SetPaymentPointerForm' - -interface PaymentPointerProps { - children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode -} - -const BasePaymentPointerDialog: React.FC = ({ - children, -}) => { - const formId = `set-payment-pointer-form` - const [isSubmitting, setIsSubmitting] = useState(false) - const [isValid, setIsValid] = useState(false) - const { show, openDialog, closeDialog } = useDialogSwitch(true) - - const SubmitButton = ( - } - loading={isSubmitting} - /> - ) - - return ( - <> - {children({ openDialog })} - - - - } - closeDialog={closeDialog} - rightBtn={SubmitButton} - /> - - - - - } - color="greyDarker" - onClick={closeDialog} - /> - {SubmitButton} - - } - /> - - - ) -} - -export const PaymentPointerDialog = (props: PaymentPointerProps) => ( - }> - {({ openDialog }) => <>{props.children({ openDialog })}} - -) diff --git a/src/components/Dialogs/index.tsx b/src/components/Dialogs/index.tsx index 629e2215c0..2513050cf7 100644 --- a/src/components/Dialogs/index.tsx +++ b/src/components/Dialogs/index.tsx @@ -49,4 +49,3 @@ export * from './UnsubscribeCircleDialog' // Misc export * from './BillboardDialog' -export * from './PaymentPointerDialog' diff --git a/src/components/Head/index.tsx b/src/components/Head/index.tsx index b78b2aad02..95dbb57285 100644 --- a/src/components/Head/index.tsx +++ b/src/components/Head/index.tsx @@ -29,7 +29,6 @@ interface HeadProps { path?: string image?: string | null noSuffix?: boolean - paymentPointer?: string | null jsonLdData?: Record | null availableLanguages?: UserLanguage[] } @@ -224,9 +223,7 @@ export const Head: React.FC = (props) => { key="ld-json-data" /> )} - {props.paymentPointer && ( - - )} + {/* noindex for non-production enviroment */} {!isProdServingCanonical && ( diff --git a/src/views/ArticleDetail/gql.ts b/src/views/ArticleDetail/gql.ts index 338c82fc2c..1b4c37b3ab 100644 --- a/src/views/ArticleDetail/gql.ts +++ b/src/views/ArticleDetail/gql.ts @@ -28,7 +28,6 @@ const articlePublicFragment = gql` language author { id - paymentPointer ...UserDigestRichUserPublic ...UserDigestRichUserPrivate } diff --git a/src/views/ArticleDetail/index.tsx b/src/views/ArticleDetail/index.tsx index 17fba58490..0505babfca 100644 --- a/src/views/ArticleDetail/index.tsx +++ b/src/views/ArticleDetail/index.tsx @@ -151,7 +151,6 @@ const BaseArticleDetail = ({ } const authorId = article.author?.id - const paymentPointer = article.author?.paymentPointer const collectionCount = article.collection?.totalCount || 0 const isAuthor = viewer.id === authorId const circle = article.access.circle @@ -274,7 +273,6 @@ const BaseArticleDetail = ({ description={summary} keywords={keywords} image={article.cover} - paymentPointer={paymentPointer} jsonLdData={{ '@context': 'https://schema.org', '@type': 'Article', diff --git a/src/views/Me/Wallet/Balance/FiatCurrency.tsx b/src/views/Me/Wallet/Balance/FiatCurrency.tsx index f16288b6ed..1361ae0a51 100644 --- a/src/views/Me/Wallet/Balance/FiatCurrency.tsx +++ b/src/views/Me/Wallet/Balance/FiatCurrency.tsx @@ -177,6 +177,7 @@ export const FiatCurrencyBalance: React.FC = ({ balanceHKD * exchangeRate, 2 )} + weight="normal" />
diff --git a/src/views/Me/Wallet/Balance/LikeCoin.tsx b/src/views/Me/Wallet/Balance/LikeCoin.tsx index 8415ffa359..5c6f42eeb0 100644 --- a/src/views/Me/Wallet/Balance/LikeCoin.tsx +++ b/src/views/Me/Wallet/Balance/LikeCoin.tsx @@ -2,6 +2,7 @@ import { useQuery } from '@apollo/react-hooks' import classNames from 'classnames' import gql from 'graphql-tag' import React, { useContext } from 'react' +import { FormattedMessage } from 'react-intl' import { ReactComponent as IconLikeCoin } from '@/public/static/icons/24px/likecoin.svg' import { PATHS } from '~/common/enums' @@ -115,6 +116,7 @@ export const LikeCoinBalance = ({ currency="LIKE" subValue={formatAmount(total * exchangeRate, 2)} subCurrency={currency} + weight="normal" /> ) @@ -125,11 +127,15 @@ export const LikeCoinBalance = ({ diff --git a/src/views/Me/Wallet/Balance/USDT.tsx b/src/views/Me/Wallet/Balance/USDT.tsx index a3c75d33de..e7e42ef235 100644 --- a/src/views/Me/Wallet/Balance/USDT.tsx +++ b/src/views/Me/Wallet/Balance/USDT.tsx @@ -1,8 +1,10 @@ import classNames from 'classnames' import { useContext } from 'react' +import { FormattedMessage } from 'react-intl' +import { formatUnits } from 'viem' import { ReactComponent as IconTether } from '@/public/static/icons/24px/tether.svg' -import { PATHS } from '~/common/enums' +import { contract, PATHS } from '~/common/enums' import { formatAmount } from '~/common/utils' import { Button, @@ -11,6 +13,7 @@ import { TextIcon, Translate, useBalanceUSDT, + useVaultBalanceUSDT, ViewerContext, } from '~/components' import { QuoteCurrency } from '~/gql/graphql' @@ -26,14 +29,22 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { const viewer = useContext(ViewerContext) const address = viewer.info.ethAddress const { data: balanceUSDTData } = useBalanceUSDT({}) + const { data: vaultBalanceUSDTData } = useVaultBalanceUSDT() const balanceUSDT = parseFloat(balanceUSDTData?.formatted || '0') + const vaultBalanceUSDT = parseFloat( + formatUnits( + BigInt(vaultBalanceUSDTData || '0'), + contract.Optimism.tokenDecimals + ) + ) + const balance = address ? balanceUSDT : vaultBalanceUSDT const classes = classNames({ [styles.assetsItem]: true, assetsItem: true, // global selector for overriding }) - if (!address) { + if (!address && !vaultBalanceUSDT) { return (
{
@@ -69,10 +84,16 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { + ) + } + weight="normal" />
) diff --git a/src/views/Me/Wallet/PaymentPointer/index.tsx b/src/views/Me/Wallet/PaymentPointer/index.tsx deleted file mode 100644 index 42145a4a8a..0000000000 --- a/src/views/Me/Wallet/PaymentPointer/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { FormattedMessage } from 'react-intl' - -import { PaymentPointerDialog, TableView } from '~/components' - -const PaymentPointer = () => ( - - {({ openDialog }) => ( - - } - onClick={openDialog} - role="button" - ariaHasPopup="dialog" - /> - )} - -) - -export default PaymentPointer diff --git a/src/views/Me/Wallet/index.tsx b/src/views/Me/Wallet/index.tsx index 25e3247a22..4444f55c08 100644 --- a/src/views/Me/Wallet/index.tsx +++ b/src/views/Me/Wallet/index.tsx @@ -24,7 +24,6 @@ import { ExchangeRatesQuery, WalletBalanceQuery } from '~/gql/graphql' import { FiatCurrencyBalance, LikeCoinBalance, USDTBalance } from './Balance' import PaymentPassword from './PaymentPassword' -import PaymentPointer from './PaymentPointer' import styles from './styles.module.css' import ViewStripeAccount from './ViewStripeAccount' import ViewStripeCustomerPortal from './ViewStripeCustomerPortal' @@ -96,10 +95,10 @@ const Wallet = () => { @@ -119,14 +118,14 @@ const Wallet = () => { currency={currency} exchangeRate={exchangeRateHKD?.rate || 0} /> - +
@@ -134,7 +133,6 @@ const Wallet = () => { {hasPaymentPassword && } {hasStripeAccount && } - From 69fd1f706e4bfee70bb3be5b75e12c7f8d40d4cd Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:23:23 +0700 Subject: [PATCH 06/19] feat(donation): allow to support authors w/o ETH address --- lang/default.json | 3 - lang/en.json | 3 - lang/zh-Hans.json | 7 +- lang/zh-Hant.json | 7 +- package-lock.json | 4 +- src/common/enums/contract.ts | 26 +- src/common/utils/abis/curationVault.ts | 243 ++++++++++++++++++ src/common/utils/abis/index.ts | 1 + .../PaymentForm/PayTo/Complete/index.tsx | 2 +- .../Forms/PaymentForm/PayTo/Confirm/index.tsx | 4 +- .../PaymentForm/PayTo/SetAmount/index.tsx | 4 +- .../Forms/PaymentForm/Processing/index.tsx | 43 +++- .../Forms/PaymentForm/SwitchNetwork/index.tsx | 1 - src/components/Hook/index.ts | 1 - src/components/Hook/useCuration.ts | 14 - src/components/Hook/useERC20.ts | 18 +- .../SupportAuthor/DisableSupport/index.tsx | 7 - .../Support/SupportAuthor/index.tsx | 5 +- 18 files changed, 319 insertions(+), 74 deletions(-) create mode 100644 src/common/utils/abis/curationVault.ts delete mode 100644 src/components/Hook/useCuration.ts diff --git a/lang/default.json b/lang/default.json index ec07a834b3..c991a270c7 100644 --- a/lang/default.json +++ b/lang/default.json @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "Applied successfully" }, - "4tqFCR": { - "defaultMessage": "The author has not bound the USDT wallet yet" - }, "4wOWfp": { "defaultMessage": "What's this?", "description": "src/components/Billboard/index.tsx" diff --git a/lang/en.json b/lang/en.json index 828e86a159..27d674b4bd 100644 --- a/lang/en.json +++ b/lang/en.json @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "Applied successfully" }, - "4tqFCR": { - "defaultMessage": "The author has not bound the USDT wallet yet" - }, "4wOWfp": { "defaultMessage": "What's this?", "description": "src/components/Billboard/index.tsx" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 377a667420..6edbbfc9b0 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -87,7 +87,7 @@ "defaultMessage": "支持排行榜" }, "/NX9L+": { - "defaultMessage": "确认授权", + "defaultMessage": "去钱包确认", "description": "src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx" }, "/TXBJR": { @@ -95,7 +95,7 @@ "description": "UNKNOWN_ERROR" }, "/cyuh2": { - "defaultMessage": "前往授权" + "defaultMessage": "去钱包授权" }, "/dKzfc": { "defaultMessage": "该作品因违反社区约章,已被站方强制封存。" @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "报名成功" }, - "4tqFCR": { - "defaultMessage": "作者尚未启用 USDT 钱包" - }, "4wOWfp": { "defaultMessage": "这是什么?", "description": "src/components/Billboard/index.tsx" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index d08e228708..63c66f133e 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -87,7 +87,7 @@ "defaultMessage": "支持排行榜" }, "/NX9L+": { - "defaultMessage": "確認授權", + "defaultMessage": "去錢包確認", "description": "src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx" }, "/TXBJR": { @@ -95,7 +95,7 @@ "description": "UNKNOWN_ERROR" }, "/cyuh2": { - "defaultMessage": "前往授權" + "defaultMessage": "去錢包授權" }, "/dKzfc": { "defaultMessage": "該作品因違反社區約章,已被站方強制歸檔。" @@ -389,9 +389,6 @@ "4nHH2x": { "defaultMessage": "報名成功" }, - "4tqFCR": { - "defaultMessage": "作者尚未啓用 USDT 錢包" - }, "4wOWfp": { "defaultMessage": "這是什麼?", "description": "src/components/Billboard/index.tsx" diff --git a/package-lock.json b/package-lock.json index 1746b77ffd..fd1b6dbb00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "matters-web", - "version": "5.6.2", + "version": "5.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "matters-web", - "version": "5.6.2", + "version": "5.7.0", "license": "Apache-2.0", "dependencies": { "@apollo/react-common": "^3.1.3", diff --git a/src/common/enums/contract.ts b/src/common/enums/contract.ts index 10202e5403..1dbec7183e 100644 --- a/src/common/enums/contract.ts +++ b/src/common/enums/contract.ts @@ -15,37 +15,43 @@ export const contract = { logbookAddress: '0xcdf8D568EC808de5fCBb35849B5bAFB5d444D4c0' as `0x${string}`, curationAddress: - '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8' as `0x${string}`, + '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8'.toLowerCase() as `0x${string}`, curationBlockNum: '34564355', tokenAddress: - '0xc2132D05D31c914a87C6611C10748AEb04B58e8F' as `0x${string}`, + '0xc2132D05D31c914a87C6611C10748AEb04B58e8F'.toLowerCase() as `0x${string}`, tokenDecimals: 6, } : { logbookAddress: '0x203197e074b7a2f4ff6890815e4657a9c47c68b1' as `0x${string}`, curationAddress: - '0xa219C6722008aa22828B31A13ab9Ba93bB91222c' as `0x${string}`, - curationBlockNum: '28675517' as `0x${string}`, + '0xa219C6722008aa22828B31A13ab9Ba93bB91222c'.toLowerCase() as `0x${string}`, + curationBlockNum: '28675517', tokenAddress: - '0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1' as `0x${string}`, + '0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1'.toLowerCase() as `0x${string}`, tokenDecimals: 6, }, Optimism: isProd ? { curationAddress: - '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8' as `0x${string}`, - curationBlockNum: '117058632' as `0x${string}`, + '0x5edebbdae7B5C79a69AaCF7873796bb1Ec664DB8'.toLowerCase() as `0x${string}`, + curationBlockNum: '117058632', tokenAddress: - '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58' as `0x${string}`, + '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58'.toLowerCase() as `0x${string}`, tokenDecimals: 6, + curationVaultAddress: + '0x7CC566aa9488a9990977Cb31D856C47e67b35465'.toLowerCase() as `0x${string}`, + curationVaultBlockNum: '128886733', } : { curationAddress: - '0x92a117aeA74963Cd0CEdF9C50f99435451a291F7' as `0x${string}`, + '0x92a117aeA74963Cd0CEdF9C50f99435451a291F7'.toLowerCase() as `0x${string}`, curationBlockNum: '8438904', tokenAddress: - '0x5fd84259d66Cd46123540766Be93DFE6D43130D7' as `0x${string}`, + '0x5fd84259d66Cd46123540766Be93DFE6D43130D7'.toLowerCase() as `0x${string}`, tokenDecimals: 6, + curationVaultAddress: + '0x891060263b8397cB3c69F01E3383e7f8838Fd8a8'.toLowerCase() as `0x${string}`, + curationVaultBlockNum: '20457192', }, } diff --git a/src/common/utils/abis/curationVault.ts b/src/common/utils/abis/curationVault.ts new file mode 100644 index 0000000000..6ef9baac2d --- /dev/null +++ b/src/common/utils/abis/curationVault.ts @@ -0,0 +1,243 @@ +export const CurationVaultABI = [ + { + inputs: [ + { internalType: 'address', name: 'signer_', type: 'address' }, + { internalType: 'address', name: 'owner_', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AlreadyWithdrawn', type: 'error' }, + { inputs: [], name: 'Expired', type: 'error' }, + { inputs: [], name: 'InvalidSignature', type: 'error' }, + { inputs: [], name: 'InvalidURI', type: 'error' }, + { inputs: [], name: 'TransferFailed', type: 'error' }, + { inputs: [], name: 'ZeroAddress', type: 'error' }, + { inputs: [], name: 'ZeroAmount', type: 'error' }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { indexed: false, internalType: 'string', name: 'uri', type: 'string' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Curation', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { indexed: false, internalType: 'string', name: 'uri', type: 'string' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Curation', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'signer', + type: 'address', + }, + ], + name: 'SignerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: true, internalType: 'string', name: 'uid', type: 'string' }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Withdraw', + type: 'event', + }, + { + inputs: [ + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'contract IERC20', name: 'token_', type: 'address' }, + { internalType: 'uint256', name: 'amount_', type: 'uint256' }, + { internalType: 'string', name: 'uri_', type: 'string' }, + ], + name: 'curate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'string', name: 'uri_', type: 'string' }, + ], + name: 'curate', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: '', type: 'string' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'erc20Balances', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'string', name: '', type: 'string' }], + name: 'nativeBalances', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'signer_', type: 'address' }], + name: 'setSigner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'signer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId_', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to_', type: 'address' }, + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'uint256', name: 'expiredAt_', type: 'uint256' }, + { internalType: 'uint8', name: 'v_', type: 'uint8' }, + { internalType: 'bytes32', name: 'r_', type: 'bytes32' }, + { internalType: 'bytes32', name: 's_', type: 'bytes32' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'to_', type: 'address' }, + { internalType: 'string', name: 'uid_', type: 'string' }, + { internalType: 'contract IERC20', name: 'token_', type: 'address' }, + { internalType: 'uint256', name: 'expiredAt_', type: 'uint256' }, + { internalType: 'uint8', name: 'v_', type: 'uint8' }, + { internalType: 'bytes32', name: 'r_', type: 'bytes32' }, + { internalType: 'bytes32', name: 's_', type: 'bytes32' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'string', name: '', type: 'string' }, + { internalType: 'uint256', name: '', type: 'uint256' }, + ], + name: 'withdrawals', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, +] as const diff --git a/src/common/utils/abis/index.ts b/src/common/utils/abis/index.ts index 567fa47105..6023b3ac6f 100644 --- a/src/common/utils/abis/index.ts +++ b/src/common/utils/abis/index.ts @@ -1,3 +1,4 @@ export * from './billboard' export * from './curation' +export * from './curationVault' export * from './ensPublicResolver' diff --git a/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx b/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx index eb8fa03e60..3e2f5cfcfc 100644 --- a/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/Complete/index.tsx @@ -83,7 +83,7 @@ const Complete: React.FC = ({ currency={currency} recipient={recipient} showLikerID={isLikecoin} - showEthAddress={isUSDT} + showEthAddress={isUSDT && !!recipient.info.ethAddress} > <> diff --git a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx index d55e4757d4..2b0e69c69d 100644 --- a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx @@ -205,7 +205,9 @@ const Confirm: React.FC = ({ currency={currency} recipient={recipient} showLikerID={currency === CURRENCY.LIKE} - showEthAddress={currency === CURRENCY.USDT} + showEthAddress={ + currency === CURRENCY.USDT && !!recipient.info.ethAddress + } /> {isSubmitting && ( diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index ed65c74e11..2966a5f65b 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -149,13 +149,13 @@ const SetAmount: React.FC = ({ refetch: refetchAllowanceData, isLoading: allowanceLoading, error: allowanceError, - } = useAllowanceUSDT() + } = useAllowanceUSDT(!recipient.info.ethAddress) const { data: approveData, isLoading: approving, write: approveWrite, error: approveError, - } = useApproveUSDT() + } = useApproveUSDT(!recipient.info.ethAddress) const { data: balanceUSDTData, error: balanceUSDTError } = useBalanceUSDT({ address, }) diff --git a/src/components/Forms/PaymentForm/Processing/index.tsx b/src/components/Forms/PaymentForm/Processing/index.tsx index a2078d8e42..bfd4128e60 100644 --- a/src/components/Forms/PaymentForm/Processing/index.tsx +++ b/src/components/Forms/PaymentForm/Processing/index.tsx @@ -14,7 +14,7 @@ import { PAYMENT_CURRENCY as CURRENCY, SUPPORT_SUCCESS_USDT_VISITOR, } from '~/common/enums' -import { CurationABI } from '~/common/utils' +import { CurationABI, CurationVaultABI } from '~/common/utils' import { Dialog, Icon, @@ -217,11 +217,30 @@ const USDTProcessingForm: React.FC = ({ const [draftTxId, setDraftTxId] = useState() + const useCurationVault = !recipient.info.ethAddress + const normalizedAmount = parseUnits( + amount.toString() as `${number}`, + contract.Optimism.tokenDecimals + ) + const uri = `ipfs://${article?.dataHash}` + + const { + data: vaultData, + error: vaultError, + isError: isVaultError, + write: curateVault, + } = useContractWrite({ + address: contract.Optimism.curationVaultAddress, + abi: CurationVaultABI, + functionName: 'curate', + args: [recipient.id, contract.Optimism.tokenAddress, normalizedAmount, uri], + }) + const { - data, - error, - isError, - write: curate, + data: curationData, + error: curationError, + isError: isCurationError, + write: curateDirect, } = useContractWrite({ address: contract.Optimism.curationAddress, abi: CurationABI, @@ -229,14 +248,16 @@ const USDTProcessingForm: React.FC = ({ args: [ recipient.info.ethAddress as `0x${string}`, contract.Optimism.tokenAddress, - parseUnits( - amount.toString() as `${number}`, - contract.Optimism.tokenDecimals - ), - `ipfs://${article?.dataHash}`, + normalizedAmount, + uri, ], }) + const data = useCurationVault ? vaultData : curationData + const error = useCurationVault ? vaultError : curationError + const isError = useCurationVault ? isVaultError : isCurationError + const curate = useCurationVault ? curateVault : curateDirect + const payToData = { amount, currency, @@ -327,7 +348,7 @@ const USDTProcessingForm: React.FC = ({ amount={amount} currency={currency} recipient={recipient} - showEthAddress={true} + showEthAddress={!!recipient.info.ethAddress} > {!isError && ( <> diff --git a/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx b/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx index 914747cd2c..2df6549b9c 100644 --- a/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx +++ b/src/components/Forms/PaymentForm/SwitchNetwork/index.tsx @@ -22,7 +22,6 @@ interface SwitchNetworkProps { const SwitchNetwork: React.FC = ({ submitCallback }) => { const { lang } = useContext(LanguageContext) - // TODO: support multiple networks const targetNetork = featureSupportedChains.curation[0] const { isUnsupportedNetwork, switchToTargetNetwork, isSwitchingNetwork } = useTargetNetwork(targetNetork) diff --git a/src/components/Hook/index.ts b/src/components/Hook/index.ts index 0c40be308d..1e5f2f1696 100644 --- a/src/components/Hook/index.ts +++ b/src/components/Hook/index.ts @@ -2,7 +2,6 @@ export * from './useBillboard' export * from './useCarousel' export * from './useColorThief' export * from './useCountdown' -export * from './useCuration' export * from './useDialogSwitch' export * from './useDirectImageUpload' export * from './useERC20' diff --git a/src/components/Hook/useCuration.ts b/src/components/Hook/useCuration.ts deleted file mode 100644 index b158cb370c..0000000000 --- a/src/components/Hook/useCuration.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useContractWrite, usePrepareContractWrite } from 'wagmi' - -import { contract } from '~/common/enums' -import { CurationABI } from '~/common/utils' - -export const useCurate = () => { - const { config } = usePrepareContractWrite({ - address: contract.Optimism.curationAddress, - abi: CurationABI, - functionName: 'curate', - }) - - return useContractWrite(config) -} diff --git a/src/components/Hook/useERC20.ts b/src/components/Hook/useERC20.ts index 28d36ad35d..9d4d37a41d 100644 --- a/src/components/Hook/useERC20.ts +++ b/src/components/Hook/useERC20.ts @@ -12,14 +12,19 @@ import { contract } from '~/common/enums' import { featureSupportedChains, MaxApprovedUSDTAmount } from '~/common/utils' import { ViewerContext } from '~/components' -export const useAllowanceUSDT = () => { +export const useAllowanceUSDT = (useCurationVault: boolean) => { const { address } = useAccount() return useContractRead({ address: contract.Optimism.tokenAddress, abi: erc20ABI, functionName: 'allowance', - args: [address as `0x${string}`, contract.Optimism.curationAddress], + args: [ + address as `0x${string}`, + useCurationVault + ? contract.Optimism.curationVaultAddress + : contract.Optimism.curationAddress, + ], }) } @@ -56,12 +61,17 @@ export const useBalanceEther = ({ }) } -export const useApproveUSDT = () => { +export const useApproveUSDT = (useCurationVault: boolean) => { const { config } = usePrepareContractWrite({ address: contract.Optimism.tokenAddress, abi: erc20ABI, functionName: 'approve', - args: [contract.Optimism.curationAddress, MaxApprovedUSDTAmount], + args: [ + useCurationVault + ? contract.Optimism.curationVaultAddress + : contract.Optimism.curationAddress, + MaxApprovedUSDTAmount, + ], }) return useContractWrite(config) diff --git a/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx b/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx index ad112a57aa..31543f89c2 100644 --- a/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx +++ b/src/views/ArticleDetail/Support/SupportAuthor/DisableSupport/index.tsx @@ -20,7 +20,6 @@ export const DisableSupport = ({ recipient, onClose, }: Props) => { - const isUSDT = currency === CURRENCY.USDT const isLikecoin = currency === CURRENCY.LIKE return ( @@ -33,12 +32,6 @@ export const DisableSupport = ({
- {isUSDT && ( - - )} {isLikecoin && ( { const viewer = useContext(ViewerContext) const [windowRef, setWindowRef] = useState(undefined) const { currStep, forward: _forward } = useStep('setAmount') - const hasAuthorAddress = recipient.info.ethAddress const hasAuthorLikeID = !!recipient.liker.likerId const supportCurrency = storage.get(SUPPORT_TAB_PREFERENCE_KEY) const { address } = useAccount() - // TODO: support multiple networks const targetNetork = featureSupportedChains.curation[0] const { isUnsupportedNetwork } = useTargetNetwork(targetNetork) @@ -104,7 +102,6 @@ const SupportAuthor = (props: SupportAuthorProps) => { forward('setAmount') } - const isUSDT = currency === CURRENCY.USDT const isLikecoin = currency === CURRENCY.LIKE const [payToTx, setPayToTx] = @@ -177,7 +174,7 @@ const SupportAuthor = (props: SupportAuthorProps) => { const showTabs = isSetAmount || isWalletSelect || isNetworkSelect - if ((!hasAuthorAddress && isUSDT) || (!hasAuthorLikeID && isLikecoin)) { + if (!hasAuthorLikeID && isLikecoin) { return ( Date: Thu, 5 Dec 2024 15:44:27 +0700 Subject: [PATCH 07/19] feat(donation): add WithdrewLockedTokens notice --- lang/default.json | 3 + lang/en.json | 3 + lang/zh-Hans.json | 3 + lang/zh-Hant.json | 3 + src/common/enums/test.ts | 1 + .../WithdrewLockedTokensNotice.tsx | 74 +++++++++++++++++++ .../Notice/TransactionNotice/index.tsx | 5 ++ src/stories/components/Notices/mock.ts | 11 +++ src/stories/mocks/index.ts | 6 ++ 9 files changed, 109 insertions(+) create mode 100644 src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx diff --git a/lang/default.json b/lang/default.json index c991a270c7..2e6cec99cf 100644 --- a/lang/default.json +++ b/lang/default.json @@ -1268,6 +1268,9 @@ "defaultMessage": "New followers", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "The vault contract has sent {amount} USDT to the linked wallet. Click here for details." + }, "Jmg5do": { "defaultMessage": "Archived Work" }, diff --git a/lang/en.json b/lang/en.json index 27d674b4bd..a5abd97bec 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1268,6 +1268,9 @@ "defaultMessage": "New followers", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "The vault contract has sent {amount} USDT to the linked wallet. Click here for details." + }, "Jmg5do": { "defaultMessage": "Archived Work" }, diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 6edbbfc9b0..54f19dd150 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -1268,6 +1268,9 @@ "defaultMessage": "被关注", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "交易合约已将金额 {amount} USDT 发送至绑定钱包,点此查看详情" + }, "Jmg5do": { "defaultMessage": "作品已归档" }, diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 63c66f133e..df91ee37bf 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -1268,6 +1268,9 @@ "defaultMessage": "被追蹤", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "JlpeDH": { + "defaultMessage": "交易合約已將金額 {amount} USDT 發送至綁定錢包,點此查看詳情" + }, "Jmg5do": { "defaultMessage": "作品已封存" }, diff --git a/src/common/enums/test.ts b/src/common/enums/test.ts index 3cb983ce83..04553f177c 100644 --- a/src/common/enums/test.ts +++ b/src/common/enums/test.ts @@ -127,6 +127,7 @@ export enum TEST_ID { NOTICE_TAG_LEAVE_EDITOR = 'notice/tag-leave-editor', NOTICE_PAYMENT_PAYOUT = 'notice/payment-payout', NOTICE_PAYMENT_RECEIVE_DONATION = 'notice/payment-receive-donation', + NOTICE_WITHDREW_LOCKED_TOKENS = 'notice/withdrew-locked-tokens', NOTICE_CIRCLE_NEW_FOLLOWER = 'notice/circle-new-follower', NOTICE_CIRCLE_NEW_SUBSCRIBER = 'notice/circle-new-subscriber', NOTICE_CIRCLE_NEW_UNSUBSCRIBER = 'notice/circle-new-unsubscriber', diff --git a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx new file mode 100644 index 0000000000..f183776f1d --- /dev/null +++ b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx @@ -0,0 +1,74 @@ +import gql from 'graphql-tag' +import { FormattedMessage } from 'react-intl' +import { parseUnits } from 'viem' + +import { contract, TEST_ID } from '~/common/enums' +import { explorers } from '~/common/utils/wallet' +import { WithdrewLockedTokensNoticeFragment } from '~/gql/graphql' + +import NoticeActorAvatar from '../NoticeActorAvatar' +import NoticeActorName from '../NoticeActorName' +import NoticeDate from '../NoticeDate' +import styles from '../styles.module.css' + +const WithdrewLockedTokensNotice = ({ + notice, +}: { + notice: WithdrewLockedTokensNoticeFragment +}) => { + const tx = notice.tx + const blockchainTx = tx.blockchainTx + + if (!notice.actors || !blockchainTx) { + return null + } + + const link = `${explorers[blockchainTx.chain].url}/tx/${blockchainTx.txHash}` + + return ( +
+
+ + + +
+
+ +
+
+ ) +} + +WithdrewLockedTokensNotice.fragments = { + notice: gql` + fragment WithdrewLockedTokensNotice on TransactionNotice { + id + ...NoticeDate + actors { + ...NoticeActorAvatarUser + ...NoticeActorNameUser + } + tx: target { + id + amount + currency + blockchainTx { + chain + txHash + } + } + } + ${NoticeDate.fragments.notice} + ${NoticeActorAvatar.fragments.user} + ${NoticeActorName.fragments.user} + `, +} + +export default WithdrewLockedTokensNotice diff --git a/src/components/Notice/TransactionNotice/index.tsx b/src/components/Notice/TransactionNotice/index.tsx index 5c7f189862..0c0b618433 100644 --- a/src/components/Notice/TransactionNotice/index.tsx +++ b/src/components/Notice/TransactionNotice/index.tsx @@ -3,6 +3,7 @@ import gql from 'graphql-tag' import { TransactionNoticeFragment } from '~/gql/graphql' import PaymentReceivedDonationNotice from './PaymentReceivedDonationNotice' +import WithdrewLockedTokensNotice from './WithdrewLockedTokensNotice' const TransactionNotice = ({ notice, @@ -12,6 +13,8 @@ const TransactionNotice = ({ switch (notice.txNoticeType) { case 'PaymentReceivedDonation': return + case 'WithdrewLockedTokens': + return default: return null } @@ -25,8 +28,10 @@ TransactionNotice.fragments = { __typename txNoticeType: type ...PaymentReceivedDonationNotice + ...WithdrewLockedTokensNotice } ${PaymentReceivedDonationNotice.fragments.notice} + ${WithdrewLockedTokensNotice.fragments.notice} `, } diff --git a/src/stories/components/Notices/mock.ts b/src/stories/components/Notices/mock.ts index 6ea0d8336b..79e5a40c32 100644 --- a/src/stories/components/Notices/mock.ts +++ b/src/stories/components/Notices/mock.ts @@ -1,5 +1,6 @@ import { MOCK_ARTILCE, + MOCK_BLOCKCHAIN_TRANSACTION, MOCK_CIRCLE, MOCK_CIRCLE_ARTICLE, MOCK_CIRCLE_COMMENT, @@ -323,6 +324,16 @@ export const MOCK_NOTICE_LIST = [ txNoticeType: 'PaymentReceivedDonation' as any, tx: MOCK_TRANSACTION, }, + // WithdrewLockedTokens + { + __typename: 'TransactionNotice' as any, + id: 'WithdrewLockedTokens', + unread: false, + createdAt: '2020-12-24T07:29:17.682Z', + actors: [MOCK_USER], + txNoticeType: 'WithdrewLockedTokens' as any, + tx: { ...MOCK_TRANSACTION, blockchainTx: MOCK_BLOCKCHAIN_TRANSACTION }, + }, /** * Circle diff --git a/src/stories/mocks/index.ts b/src/stories/mocks/index.ts index d4e02d4997..e00f9011d9 100644 --- a/src/stories/mocks/index.ts +++ b/src/stories/mocks/index.ts @@ -279,6 +279,12 @@ export const MOCK_TRANSACTION = { target: MOCK_ARTILCE, } +export const MOCK_BLOCKCHAIN_TRANSACTION = { + __typename: 'BlockchainTransaction' as any, + chain: 'Optimism' as any, + txHash: '0x1234567890abcdef', +} + // Crypto wallet export const MOCK_CRYPTO_WALLET = { __typename: 'CryptoWallet' as any, From 4922172f4b1f0de4e611822e4b2f39f1c45b687a Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:33:38 +0700 Subject: [PATCH 08/19] feat(donation): revise PaymentReceivedDonationNotice --- lang/default.json | 3 +++ lang/en.json | 3 +++ lang/zh-Hans.json | 3 +++ lang/zh-Hant.json | 3 +++ .../PaymentReceivedDonationNotice.tsx | 11 +++++++++++ .../TransactionNotice/WithdrewLockedTokensNotice.tsx | 3 +-- 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lang/default.json b/lang/default.json index 2e6cec99cf..f831700c6c 100644 --- a/lang/default.json +++ b/lang/default.json @@ -869,6 +869,9 @@ "defaultMessage": "Copy comment", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ", connect your wallet to claim" + }, "Ci7dxf": { "defaultMessage": "Comment deleted", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/lang/en.json b/lang/en.json index a5abd97bec..466f1dc5eb 100644 --- a/lang/en.json +++ b/lang/en.json @@ -869,6 +869,9 @@ "defaultMessage": "Copy comment", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ", connect your wallet to claim" + }, "Ci7dxf": { "defaultMessage": "Comment deleted", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 54f19dd150..a4e6f53f38 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -869,6 +869,9 @@ "defaultMessage": "复制留言", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ",绑定钱包后可领取" + }, "Ci7dxf": { "defaultMessage": "留言已删除", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index df91ee37bf..a9a6846fc7 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -869,6 +869,9 @@ "defaultMessage": "複製留言", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CgPGAu": { + "defaultMessage": ",連接錢包領取" + }, "Ci7dxf": { "defaultMessage": "留言已刪除", "description": "src/components/Notice/NoticeComment.tsx/moment" diff --git a/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx b/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx index 41d89f7411..ece92363cb 100644 --- a/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx +++ b/src/components/Notice/TransactionNotice/PaymentReceivedDonationNotice.tsx @@ -1,7 +1,9 @@ import gql from 'graphql-tag' +import { useContext } from 'react' import { FormattedMessage } from 'react-intl' import { TEST_ID } from '~/common/enums' +import { ViewerContext } from '~/components/Context' import { PaymentReceivedDonationNoticeFragment } from '~/gql/graphql' import NoticeActorAvatar from '../NoticeActorAvatar' @@ -16,11 +18,14 @@ const PaymentReceivedDonationNotice = ({ }: { notice: PaymentReceivedDonationNoticeFragment }) => { + const viewer = useContext(ViewerContext) + if (!notice.actors) { return null } const tx = notice.tx + const hasEthAddress = !!viewer?.info?.ethAddress return ( {tx.amount} {tx.currency} + {!hasEthAddress && ( + + )} )) || '' diff --git a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx index f183776f1d..54d7283e2e 100644 --- a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx +++ b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx @@ -1,8 +1,7 @@ import gql from 'graphql-tag' import { FormattedMessage } from 'react-intl' -import { parseUnits } from 'viem' -import { contract, TEST_ID } from '~/common/enums' +import { TEST_ID } from '~/common/enums' import { explorers } from '~/common/utils/wallet' import { WithdrewLockedTokensNoticeFragment } from '~/gql/graphql' From 531811ae2e1495a8d7509c6c221ab1599e24d2b7 Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:40:40 +0700 Subject: [PATCH 09/19] feat(wallet): withdraw entry for USDT button --- .../WithdrawLockedTokensDialog/index.tsx | 47 +++++++++++++ .../WithdrawLockedTokensDialog/types.d.ts | 1 + src/components/Dialogs/index.tsx | 1 + src/views/Me/Wallet/Balance/USDT.tsx | 67 +++++++++++++------ 4 files changed, 95 insertions(+), 21 deletions(-) create mode 100644 src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx create mode 100644 src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts diff --git a/src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx b/src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx new file mode 100644 index 0000000000..541305b3a0 --- /dev/null +++ b/src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx @@ -0,0 +1,47 @@ +// import dynamic from 'next/dynamic' + +import { + Dialog, + // SpinnerBlock, + useDialogSwitch, + // useStep +} from '~/components' + +// import { Step } from './types' + +interface WithdrawLockedTokensDialogProps { + children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode +} + +const BaseWithdrawLockedTokensDialog = ({ + children, +}: WithdrawLockedTokensDialogProps) => { + const { + show, + openDialog: baseOpenDialog, + closeDialog, + } = useDialogSwitch(true) + // const { currStep, prevStep, forward, back } = useStep('confirm') + + const openDialog = () => { + baseOpenDialog() + } + + return ( + <> + {children({ openDialog })} + + + TODO + + + ) +} + +export const WithdrawLockedTokensDialog = ( + props: WithdrawLockedTokensDialogProps +) => ( + }> + {({ openDialog }) => <>{props.children({ openDialog })}} + +) diff --git a/src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts b/src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts new file mode 100644 index 0000000000..92dee5063c --- /dev/null +++ b/src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts @@ -0,0 +1 @@ +export type Step = 'connectWallet' | 'confirm' diff --git a/src/components/Dialogs/index.tsx b/src/components/Dialogs/index.tsx index 2513050cf7..31cb83190b 100644 --- a/src/components/Dialogs/index.tsx +++ b/src/components/Dialogs/index.tsx @@ -46,6 +46,7 @@ export * from './PayoutDialog' export * from './ResetPaymentPasswordDialog' export * from './SubscribeCircleDialog' export * from './UnsubscribeCircleDialog' +export * from './WithdrawLockedTokensDialog' // Misc export * from './BillboardDialog' diff --git a/src/views/Me/Wallet/Balance/USDT.tsx b/src/views/Me/Wallet/Balance/USDT.tsx index e7e42ef235..40c365d215 100644 --- a/src/views/Me/Wallet/Balance/USDT.tsx +++ b/src/views/Me/Wallet/Balance/USDT.tsx @@ -3,6 +3,7 @@ import { useContext } from 'react' import { FormattedMessage } from 'react-intl' import { formatUnits } from 'viem' +import { ReactComponent as IconRight } from '@/public/static/icons/24px/right.svg' import { ReactComponent as IconTether } from '@/public/static/icons/24px/tether.svg' import { contract, PATHS } from '~/common/enums' import { formatAmount } from '~/common/utils' @@ -15,6 +16,7 @@ import { useBalanceUSDT, useVaultBalanceUSDT, ViewerContext, + WithdrawLockedTokensDialog, } from '~/components' import { QuoteCurrency } from '~/gql/graphql' @@ -38,10 +40,12 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { ) ) const balance = address ? balanceUSDT : vaultBalanceUSDT + const canWithdrawVaultBalance = !address && vaultBalanceUSDT > 0 const classes = classNames({ [styles.assetsItem]: true, assetsItem: true, // global selector for overriding + [styles.clickable]: canWithdrawVaultBalance, }) if (!address && !vaultBalanceUSDT) { @@ -74,27 +78,48 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { } return ( -
- } - size={16} - spacing={8} - > - - + + {({ openDialog }) => ( +
+ } + size={16} + spacing={8} + > + + - - ) - } - weight="normal" - /> -
+ } + spacing={8} + placement="left" + > + + ) + } + weight="normal" + /> + +
+ )} + ) } From 9987bfa14b89834e57a22d0cb71aecffef14c2fd Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:58:55 +0700 Subject: [PATCH 10/19] feat(vault): add dialog to claim locked USDT --- lang/default.json | 9 +++ lang/en.json | 9 +++ lang/zh-Hans.json | 9 +++ lang/zh-Hant.json | 9 +++ src/common/enums/contract.ts | 8 +-- .../CurrencyFormatter/styles.module.css | 4 +- .../Dialogs/AddWalletLoginDialog/Content.tsx | 8 ++- .../WithdrawLockedTokensDialog/index.tsx | 47 -------------- .../WithdrawLockedTokensDialog/types.d.ts | 1 - .../WithdrawVaultUSDTDialog/Content.tsx | 54 ++++++++++++++++ .../Dialogs/WithdrawVaultUSDTDialog/Intro.tsx | 64 +++++++++++++++++++ .../Dialogs/WithdrawVaultUSDTDialog/index.tsx | 53 +++++++++++++++ .../WithdrawVaultUSDTDialog/types.d.ts | 1 + src/components/Dialogs/index.tsx | 2 +- .../Forms/WalletAuthForm/Connect.tsx | 8 ++- src/views/Me/Wallet/Balance/USDT.tsx | 6 +- 16 files changed, 232 insertions(+), 60 deletions(-) delete mode 100644 src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx delete mode 100644 src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts create mode 100644 src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx create mode 100644 src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx create mode 100644 src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx create mode 100644 src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts diff --git a/lang/default.json b/lang/default.json index f9e9b6c110..0f7b8015ea 100644 --- a/lang/default.json +++ b/lang/default.json @@ -180,6 +180,9 @@ "0tRUjd": { "defaultMessage": "This comment has been hidden due to violation of community terms of services" }, + "0zPaEM": { + "defaultMessage": "Matters will send {amount} USDT to your connected wallet via a contract transaction (Matters will temporarily cover the transaction fee)." + }, "0zZd0T": { "defaultMessage": "Article successfully published. Share it on different platforms to receive more likes and donations!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -844,6 +847,9 @@ "defaultMessage": "Provide support funds to", "description": "src/components/Forms/PaymentForm/PaymentInfo/index.tsx" }, + "C/4nS6": { + "defaultMessage": "Connect and claim" + }, "C3NKBg": { "defaultMessage": "Connected to {type}", "description": "src/views/Me/Settings/Settings/Socials/index.tsx" @@ -2771,6 +2777,9 @@ "mJEqC/": { "defaultMessage": "Go to {href}" }, + "mN1KwW": { + "defaultMessage": "Connect wallet and claim support" + }, "mObpsB": { "defaultMessage": "Insert Blockquote" }, diff --git a/lang/en.json b/lang/en.json index d04982a65e..64d0d21a32 100644 --- a/lang/en.json +++ b/lang/en.json @@ -180,6 +180,9 @@ "0tRUjd": { "defaultMessage": "This comment has been hidden due to violation of community terms of services" }, + "0zPaEM": { + "defaultMessage": "Matters will send {amount} USDT to your connected wallet via a contract transaction (Matters will temporarily cover the transaction fee)." + }, "0zZd0T": { "defaultMessage": "Article successfully published. Share it on different platforms to receive more likes and donations!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -844,6 +847,9 @@ "defaultMessage": "Provide support funds to", "description": "src/components/Forms/PaymentForm/PaymentInfo/index.tsx" }, + "C/4nS6": { + "defaultMessage": "Connect and claim" + }, "C3NKBg": { "defaultMessage": "Connected to {type}", "description": "src/views/Me/Settings/Settings/Socials/index.tsx" @@ -2771,6 +2777,9 @@ "mJEqC/": { "defaultMessage": "Go to {href}" }, + "mN1KwW": { + "defaultMessage": "Connect wallet and claim support" + }, "mObpsB": { "defaultMessage": "Insert Blockquote" }, diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 6cfe8d89c0..e292bbf719 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -180,6 +180,9 @@ "0tRUjd": { "defaultMessage": "因违反社区规定,评论已被隐藏" }, + "0zPaEM": { + "defaultMessage": "Matters 会通过合约交易将 {amount} USDT 发送到你绑定的钱包(Matters 将暂时承担交易手续费)。" + }, "0zZd0T": { "defaultMessage": "作品发布成功,快把作品分享到不同渠道,吸引更多人为你拍手!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -844,6 +847,9 @@ "defaultMessage": "递出支持资金给", "description": "src/components/Forms/PaymentForm/PaymentInfo/index.tsx" }, + "C/4nS6": { + "defaultMessage": "绑定并提领" + }, "C3NKBg": { "defaultMessage": "{type} 已绑定", "description": "src/views/Me/Settings/Settings/Socials/index.tsx" @@ -2771,6 +2777,9 @@ "mJEqC/": { "defaultMessage": "跳转至 {href}" }, + "mN1KwW": { + "defaultMessage": "绑定钱包并提领支持" + }, "mObpsB": { "defaultMessage": "插入引用" }, diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 6d2a126f42..df123d0ae8 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -180,6 +180,9 @@ "0tRUjd": { "defaultMessage": "因違反社區約章,評論已被隱藏" }, + "0zPaEM": { + "defaultMessage": "Matters 會通過合約交易將 {amount} USDT 發送至你綁定的錢包(Matters 將暫時承擔交易手續費)。" + }, "0zZd0T": { "defaultMessage": "作品發布成功,快把作品分享到不同渠道,吸引更多人為你拍手!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -844,6 +847,9 @@ "defaultMessage": "遞出支持資金給", "description": "src/components/Forms/PaymentForm/PaymentInfo/index.tsx" }, + "C/4nS6": { + "defaultMessage": "綁定並提領" + }, "C3NKBg": { "defaultMessage": "{type} 已綁定", "description": "src/views/Me/Settings/Settings/Socials/index.tsx" @@ -2771,6 +2777,9 @@ "mJEqC/": { "defaultMessage": "跳轉至 {href}" }, + "mN1KwW": { + "defaultMessage": "綁定錢包並提領支持" + }, "mObpsB": { "defaultMessage": "插入引用" }, diff --git a/src/common/enums/contract.ts b/src/common/enums/contract.ts index 1dbec7183e..084fec14a6 100644 --- a/src/common/enums/contract.ts +++ b/src/common/enums/contract.ts @@ -40,8 +40,8 @@ export const contract = { '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58'.toLowerCase() as `0x${string}`, tokenDecimals: 6, curationVaultAddress: - '0x7CC566aa9488a9990977Cb31D856C47e67b35465'.toLowerCase() as `0x${string}`, - curationVaultBlockNum: '128886733', + '0x79691206F498CdfAEDD059A48f61835408d81a2F'.toLowerCase() as `0x${string}`, + curationVaultBlockNum: '129071092', } : { curationAddress: @@ -51,7 +51,7 @@ export const contract = { '0x5fd84259d66Cd46123540766Be93DFE6D43130D7'.toLowerCase() as `0x${string}`, tokenDecimals: 6, curationVaultAddress: - '0x891060263b8397cB3c69F01E3383e7f8838Fd8a8'.toLowerCase() as `0x${string}`, - curationVaultBlockNum: '20457192', + '0xd41be66Bf309Ce5c3949BDe5C8091edc4870c27F'.toLowerCase() as `0x${string}`, + curationVaultBlockNum: '20969176', }, } diff --git a/src/components/CurrencyFormatter/styles.module.css b/src/components/CurrencyFormatter/styles.module.css index f81932872a..a95638b301 100644 --- a/src/components/CurrencyFormatter/styles.module.css +++ b/src/components/CurrencyFormatter/styles.module.css @@ -18,13 +18,13 @@ } & .subCurrency { - padding-top: var(--sp8); + padding-top: var(--sp4); font-size: var(--text12); color: var(--color-grey); } & .subtitle { - padding-top: var(--sp8); + padding-top: var(--sp4); font-size: var(--text12); } } diff --git a/src/components/Dialogs/AddWalletLoginDialog/Content.tsx b/src/components/Dialogs/AddWalletLoginDialog/Content.tsx index d69441bd65..30d4a3bbc9 100644 --- a/src/components/Dialogs/AddWalletLoginDialog/Content.tsx +++ b/src/components/Dialogs/AddWalletLoginDialog/Content.tsx @@ -6,11 +6,15 @@ import { AuthWalletFeed, Dialog, WalletAuthForm } from '~/components' interface Props { closeDialog: () => void + submitCallback?: () => void } type Step = 'select' | 'connect' -const AddWalletLoginDialogContent: React.FC = ({ closeDialog }) => { +const AddWalletLoginDialogContent: React.FC = ({ + closeDialog, + submitCallback, +}) => { const [step, setStep] = useState('select') const [walletType, setWalletType] = useState('MetaMask') const [hasWalletExist, setHasWalletExist] = useState(false) @@ -63,6 +67,7 @@ const AddWalletLoginDialogContent: React.FC = ({ closeDialog }) => { /> )} + {isConnect && ( = ({ closeDialog }) => { setHasUnavailable(true) setStep('select') }} + submitCallback={submitCallback} /> )} diff --git a/src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx b/src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx deleted file mode 100644 index 541305b3a0..0000000000 --- a/src/components/Dialogs/WithdrawLockedTokensDialog/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -// import dynamic from 'next/dynamic' - -import { - Dialog, - // SpinnerBlock, - useDialogSwitch, - // useStep -} from '~/components' - -// import { Step } from './types' - -interface WithdrawLockedTokensDialogProps { - children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode -} - -const BaseWithdrawLockedTokensDialog = ({ - children, -}: WithdrawLockedTokensDialogProps) => { - const { - show, - openDialog: baseOpenDialog, - closeDialog, - } = useDialogSwitch(true) - // const { currStep, prevStep, forward, back } = useStep('confirm') - - const openDialog = () => { - baseOpenDialog() - } - - return ( - <> - {children({ openDialog })} - - - TODO - - - ) -} - -export const WithdrawLockedTokensDialog = ( - props: WithdrawLockedTokensDialogProps -) => ( - }> - {({ openDialog }) => <>{props.children({ openDialog })}} - -) diff --git a/src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts b/src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts deleted file mode 100644 index 92dee5063c..0000000000 --- a/src/components/Dialogs/WithdrawLockedTokensDialog/types.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type Step = 'connectWallet' | 'confirm' diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx new file mode 100644 index 0000000000..38f81a7954 --- /dev/null +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx @@ -0,0 +1,54 @@ +import dynamic from 'next/dynamic' + +import { SpinnerBlock } from '~/components' + +import { Step } from './types' + +type WithdrawVaultUSDTDialogContentProps = { + amount: number + closeDialog: () => void + forward: (step: Step) => void + currStep: Step +} + +const DynamicIntro = dynamic(() => import('./Intro'), { + ssr: false, + loading: () => , +}) + +const DynamicAddWalletLogin = dynamic( + () => import('~/components/Dialogs/AddWalletLoginDialog/Content'), + { ssr: false, loading: () => } +) + +const WithdrawVaultUSDTDialogContent: React.FC< + WithdrawVaultUSDTDialogContentProps +> = ({ amount, closeDialog, forward, currStep }) => { + const isIntro = currStep === 'intro' + const isConnectWallet = currStep === 'connectWallet' + + return ( + <> + {isIntro && ( + { + forward('connectWallet') + }} + closeDialog={closeDialog} + /> + )} + + {isConnectWallet && ( + { + alert('asada') + }} + /> + )} + + ) +} + +export default WithdrawVaultUSDTDialogContent diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx new file mode 100644 index 0000000000..53f21cdeaa --- /dev/null +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx @@ -0,0 +1,64 @@ +import { FormattedMessage } from 'react-intl' + +import { formatAmount } from '~/common/utils' +import { Dialog } from '~/components' + +type IntroProps = { + amount: number + switchToConnectWallet: () => void + closeDialog: () => void +} + +const Intro: React.FC = ({ + amount, + switchToConnectWallet, + closeDialog, +}) => { + return ( + <> + + } + /> + + + +

+ +

+
+
+ + } + onClick={closeDialog} + /> + } + smUpBtns={ + + } + onClick={switchToConnectWallet} + /> + } + /> + + ) +} + +export default Intro diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx new file mode 100644 index 0000000000..b007bb2c12 --- /dev/null +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx @@ -0,0 +1,53 @@ +import dynamic from 'next/dynamic' + +import { Dialog, SpinnerBlock, useDialogSwitch, useStep } from '~/components' + +import { Step } from './types' + +interface WithdrawVaultUSDTDialogProps { + amount: number + children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode +} + +const DynamicContent = dynamic(() => import('./Content'), { + loading: () => , +}) + +const BaseWithdrawVaultUSDTDialog = ({ + amount, + children, +}: WithdrawVaultUSDTDialogProps) => { + const { + show, + openDialog: baseOpenDialog, + closeDialog, + } = useDialogSwitch(true) + const { currStep, forward } = useStep('intro') + + const openDialog = () => { + baseOpenDialog() + } + + return ( + <> + {children({ openDialog })} + + + + + + ) +} + +export const WithdrawVaultUSDTDialog = ( + props: WithdrawVaultUSDTDialogProps +) => ( + }> + {({ openDialog }) => <>{props.children({ openDialog })}} + +) diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts b/src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts new file mode 100644 index 0000000000..cc8be6364c --- /dev/null +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts @@ -0,0 +1 @@ +export type Step = 'intro' | 'connectWallet' diff --git a/src/components/Dialogs/index.tsx b/src/components/Dialogs/index.tsx index 31cb83190b..a59e524f24 100644 --- a/src/components/Dialogs/index.tsx +++ b/src/components/Dialogs/index.tsx @@ -46,7 +46,7 @@ export * from './PayoutDialog' export * from './ResetPaymentPasswordDialog' export * from './SubscribeCircleDialog' export * from './UnsubscribeCircleDialog' -export * from './WithdrawLockedTokensDialog' +export * from './WithdrawVaultUSDTDialog' // Misc export * from './BillboardDialog' diff --git a/src/components/Forms/WalletAuthForm/Connect.tsx b/src/components/Forms/WalletAuthForm/Connect.tsx index 72198988e9..ac5dc890a5 100644 --- a/src/components/Forms/WalletAuthForm/Connect.tsx +++ b/src/components/Forms/WalletAuthForm/Connect.tsx @@ -253,7 +253,13 @@ const Connect: React.FC = ({ ), }) - !!closeDialog && closeDialog() + if (submitCallback) { + submitCallback() + } + + if (closeDialog) { + closeDialog() + } } } catch (error) { const [messages, codes] = parseFormSubmitErrors(error as any) diff --git a/src/views/Me/Wallet/Balance/USDT.tsx b/src/views/Me/Wallet/Balance/USDT.tsx index 40c365d215..1b012ec242 100644 --- a/src/views/Me/Wallet/Balance/USDT.tsx +++ b/src/views/Me/Wallet/Balance/USDT.tsx @@ -16,7 +16,7 @@ import { useBalanceUSDT, useVaultBalanceUSDT, ViewerContext, - WithdrawLockedTokensDialog, + WithdrawVaultUSDTDialog, } from '~/components' import { QuoteCurrency } from '~/gql/graphql' @@ -78,7 +78,7 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { } return ( - + {({ openDialog }) => (
{
)} -
+ ) } From 78586b98b22c23c65b457609c76b1e3995a3e375 Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:48:07 +0700 Subject: [PATCH 11/19] feat(transaction): support vault withdrawal transaction --- lang/default.json | 10 +++++-- lang/en.json | 10 +++++-- lang/zh-Hans.json | 10 +++++-- lang/zh-Hant.json | 10 +++++-- .../Dialogs/WithdrawVaultUSDTDialog/Intro.tsx | 4 +-- src/components/TextIcon/index.tsx | 2 +- src/components/Transaction/Amount/index.tsx | 29 ++++++++++++------- .../Transaction/PurposeTitle/index.tsx | 13 ++++++++- 8 files changed, 62 insertions(+), 26 deletions(-) diff --git a/lang/default.json b/lang/default.json index 0f7b8015ea..b9ebf1bf1e 100644 --- a/lang/default.json +++ b/lang/default.json @@ -49,6 +49,10 @@ "+ixiPI": { "defaultMessage": "Delete moment" }, + "+jt4rV": { + "defaultMessage": "Claim USDT support", + "description": "src/components/Transaction/index.tsx" + }, "+o9W2T": { "defaultMessage": "File upload failed, please verify the file link is valid, or manually download and upload again.", "description": "UNABLE_TO_UPLOAD_FROM_URL" @@ -2777,9 +2781,6 @@ "mJEqC/": { "defaultMessage": "Go to {href}" }, - "mN1KwW": { - "defaultMessage": "Connect wallet and claim support" - }, "mObpsB": { "defaultMessage": "Insert Blockquote" }, @@ -2807,6 +2808,9 @@ "ml3SZN": { "defaultMessage": "Minimum 8 characters. Uppercase/lowercase letters, numbers and symbols are allowed" }, + "mm2UAM": { + "defaultMessage": "Connect wallet and claim USDT" + }, "mp9SBo": { "defaultMessage": "Circle notifications", "description": "src/views/Me/Settings/Notifications/index.tsx" diff --git a/lang/en.json b/lang/en.json index 64d0d21a32..a691d91d85 100644 --- a/lang/en.json +++ b/lang/en.json @@ -49,6 +49,10 @@ "+ixiPI": { "defaultMessage": "Delete moment" }, + "+jt4rV": { + "defaultMessage": "Claim USDT support", + "description": "src/components/Transaction/index.tsx" + }, "+o9W2T": { "defaultMessage": "File upload failed, please verify the file link is valid, or manually download and upload again.", "description": "UNABLE_TO_UPLOAD_FROM_URL" @@ -2777,9 +2781,6 @@ "mJEqC/": { "defaultMessage": "Go to {href}" }, - "mN1KwW": { - "defaultMessage": "Connect wallet and claim support" - }, "mObpsB": { "defaultMessage": "Insert Blockquote" }, @@ -2807,6 +2808,9 @@ "ml3SZN": { "defaultMessage": "Minimum 8 characters. Uppercase/lowercase letters, numbers and symbols are allowed" }, + "mm2UAM": { + "defaultMessage": "Connect wallet and claim USDT" + }, "mp9SBo": { "defaultMessage": "Circle notifications", "description": "src/views/Me/Settings/Notifications/index.tsx" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index e292bbf719..f5611c8c92 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -49,6 +49,10 @@ "+ixiPI": { "defaultMessage": "删除动态" }, + "+jt4rV": { + "defaultMessage": "提領支持", + "description": "src/components/Transaction/index.tsx" + }, "+o9W2T": { "defaultMessage": "文件上传失败,请确认文件链接是否有效,或手动下载后再上传", "description": "UNABLE_TO_UPLOAD_FROM_URL" @@ -2777,9 +2781,6 @@ "mJEqC/": { "defaultMessage": "跳转至 {href}" }, - "mN1KwW": { - "defaultMessage": "绑定钱包并提领支持" - }, "mObpsB": { "defaultMessage": "插入引用" }, @@ -2807,6 +2808,9 @@ "ml3SZN": { "defaultMessage": "至少 8 个字符,支持英文大小写字母、数字和特殊符号" }, + "mm2UAM": { + "defaultMessage": "綁定錢包並提領支持" + }, "mp9SBo": { "defaultMessage": "围炉通知", "description": "src/views/Me/Settings/Notifications/index.tsx" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index df123d0ae8..8208ebbb13 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -49,6 +49,10 @@ "+ixiPI": { "defaultMessage": "刪除動態" }, + "+jt4rV": { + "defaultMessage": "提領支持", + "description": "src/components/Transaction/index.tsx" + }, "+o9W2T": { "defaultMessage": "檔案上傳失敗,請確認檔案連結是否有效,或手動下載後再上傳", "description": "UNABLE_TO_UPLOAD_FROM_URL" @@ -2777,9 +2781,6 @@ "mJEqC/": { "defaultMessage": "跳轉至 {href}" }, - "mN1KwW": { - "defaultMessage": "綁定錢包並提領支持" - }, "mObpsB": { "defaultMessage": "插入引用" }, @@ -2807,6 +2808,9 @@ "ml3SZN": { "defaultMessage": "至少 8 個字元,支持英文大小寫字母、數字和特殊符號" }, + "mm2UAM": { + "defaultMessage": "綁定錢包並提領支持" + }, "mp9SBo": { "defaultMessage": "圍爐通知", "description": "src/views/Me/Settings/Notifications/index.tsx" diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx index 53f21cdeaa..1a6f7db705 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx @@ -20,8 +20,8 @@ const Intro: React.FC = ({ closeDialog={closeDialog} title={ } /> diff --git a/src/components/TextIcon/index.tsx b/src/components/TextIcon/index.tsx index baa79a1f4b..a451785e49 100644 --- a/src/components/TextIcon/index.tsx +++ b/src/components/TextIcon/index.tsx @@ -4,7 +4,7 @@ import { capitalizeFirstLetter } from '~/common/utils' import styles from './styles.module.css' -type TextIconColor = +export type TextIconColor = | 'black' | 'green' | 'gold' diff --git a/src/components/Transaction/Amount/index.tsx b/src/components/Transaction/Amount/index.tsx index 57c6c3f7db..0d84078411 100644 --- a/src/components/Transaction/Amount/index.tsx +++ b/src/components/Transaction/Amount/index.tsx @@ -1,6 +1,6 @@ import { TEST_ID } from '~/common/enums' import { formatAmount } from '~/common/utils' -import { TextIcon } from '~/components' +import { TextIcon, TextIconColor } from '~/components' import { DigestTransactionFragment, TransactionPurpose, @@ -33,14 +33,23 @@ const Amount = ({ tx: { amount, purpose, currency, state }, testId, }: AmountProps) => { - const color = - purpose === TransactionPurpose.Dispute && state === TransactionState.Pending - ? 'black' - : state !== TransactionState.Succeeded - ? 'grey' - : amount > 0 - ? 'gold' - : 'black' + const isVaultWithdrawal = + purpose === TransactionPurpose.CurationVaultWithdrawal + const showSymbol = !isVaultWithdrawal + + let color: TextIconColor = 'black' + if (state === TransactionState.Failed) { + color = 'red' + } else if ( + (purpose === TransactionPurpose.Dispute && + state === TransactionState.Pending) || + isVaultWithdrawal + ) { + color = 'black' + } else if (state !== TransactionState.Succeeded) color = 'grey' + else if (amount > 0) { + color = 'gold' + } return ( @@ -48,7 +57,7 @@ const Amount = ({ className={styles.amount} {...(testId ? { ['data-test-id']: testId } : {})} > - {amount > 0 ? '+' : '-'} + {showSymbol && (amount > 0 ? '+' : '-')}   {currency}   diff --git a/src/components/Transaction/PurposeTitle/index.tsx b/src/components/Transaction/PurposeTitle/index.tsx index bb5da6642f..ce8dd67a5c 100644 --- a/src/components/Transaction/PurposeTitle/index.tsx +++ b/src/components/Transaction/PurposeTitle/index.tsx @@ -5,6 +5,7 @@ import { ReactComponent as IconFiatCurrency } from '@/public/static/icons/24px/f import { ReactComponent as IconHelp } from '@/public/static/icons/24px/help.svg' import { ReactComponent as IconLikeCoin } from '@/public/static/icons/24px/likecoin.svg' import { ReactComponent as IconTether } from '@/public/static/icons/24px/tether.svg' +import { ReactComponent as IconLogoGraph } from '@/public/static/icons/logo-graph.svg' import { Icon, Tooltip, ViewerContext } from '~/components' import { DigestTransactionFragment, @@ -19,10 +20,13 @@ const PurposeTitle = ({ tx }: { tx: DigestTransactionFragment }) => { const { purpose, currency, sender, recipient } = tx const isViewerSender = sender && viewer.id === sender.id const isViewerRecipient = recipient && viewer.id === recipient.id + const isVaultWithdrawal = + purpose === TransactionPurpose.CurationVaultWithdrawal return (
- {currency === TransactionCurrency.Usdt && ( + {isVaultWithdrawal && } + {currency === TransactionCurrency.Usdt && !isVaultWithdrawal && ( )} {currency === TransactionCurrency.Hkd && ( @@ -33,6 +37,13 @@ const PurposeTitle = ({ tx }: { tx: DigestTransactionFragment }) => { )}
+ {isVaultWithdrawal && ( + + )} {purpose === TransactionPurpose.SubscriptionSplit && isViewerRecipient && ( Date: Wed, 11 Dec 2024 18:22:35 +0700 Subject: [PATCH 12/19] feat(vault): revise claim button and dialog --- lang/default.json | 9 ++++ lang/en.json | 9 ++++ lang/zh-Hans.json | 9 ++++ lang/zh-Hant.json | 9 ++++ .../WithdrawVaultUSDTDialog/Content.tsx | 4 +- .../Dialogs/WithdrawVaultUSDTDialog/Intro.tsx | 54 ++++++++++++++----- .../Dialogs/WithdrawVaultUSDTDialog/index.tsx | 3 ++ src/views/Me/Wallet/Balance/USDT.tsx | 39 +++++++++----- 8 files changed, 107 insertions(+), 29 deletions(-) diff --git a/lang/default.json b/lang/default.json index b9ebf1bf1e..fc45e48f7f 100644 --- a/lang/default.json +++ b/lang/default.json @@ -2248,6 +2248,9 @@ "defaultMessage": "Incorrect email or password", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, + "c8n+rF": { + "defaultMessage": "Matters will send {amount} USDT to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" + }, "cAP9g5": { "defaultMessage": "pinned your comment in {commentArticle}", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2340,6 +2343,9 @@ "dTOtPO": { "defaultMessage": "Top Up" }, + "dUkC8R": { + "defaultMessage": "Claim USDT" + }, "dVbKzB": { "defaultMessage": "Comments and replies", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -2443,6 +2449,9 @@ "defaultMessage": "Pending", "description": "src/views/Circle/Settings/ManageInvitation/Invites/index.tsx" }, + "fidQDr": { + "defaultMessage": "{amount} USDT pending claim" + }, "fnv5rD": { "defaultMessage": "like article (current {total} likes)" }, diff --git a/lang/en.json b/lang/en.json index a691d91d85..b1e299760d 100644 --- a/lang/en.json +++ b/lang/en.json @@ -2248,6 +2248,9 @@ "defaultMessage": "Incorrect email or password", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, + "c8n+rF": { + "defaultMessage": "Matters will send {amount} USDT to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" + }, "cAP9g5": { "defaultMessage": "pinned your comment in {commentArticle}", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2340,6 +2343,9 @@ "dTOtPO": { "defaultMessage": "Top Up" }, + "dUkC8R": { + "defaultMessage": "Claim USDT" + }, "dVbKzB": { "defaultMessage": "Comments and replies", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -2443,6 +2449,9 @@ "defaultMessage": "Pending", "description": "src/views/Circle/Settings/ManageInvitation/Invites/index.tsx" }, + "fidQDr": { + "defaultMessage": "{amount} USDT pending claim" + }, "fnv5rD": { "defaultMessage": "like article (current {total} likes)" }, diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index f5611c8c92..026b8d42bb 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -2248,6 +2248,9 @@ "defaultMessage": "邮箱或密码错误", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, + "c8n+rF": { + "defaultMessage": "Matters 会通过合约交易将 {amount} USDT 发送至你绑定的钱包 {address}(Matters 将暂时承担交易手续费)。如需帮助请联系 ask@matters.town" + }, "cAP9g5": { "defaultMessage": "将你的评论在 {commentArticle} 中置顶", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2340,6 +2343,9 @@ "dTOtPO": { "defaultMessage": "储值" }, + "dUkC8R": { + "defaultMessage": "提领支持" + }, "dVbKzB": { "defaultMessage": "评论和回复", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -2443,6 +2449,9 @@ "defaultMessage": "邀请中", "description": "src/views/Circle/Settings/ManageInvitation/Invites/index.tsx" }, + "fidQDr": { + "defaultMessage": "{amount} USDT 待提领" + }, "fnv5rD": { "defaultMessage": "赞赏作品(当前 {total} 次赞赏)" }, diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 8208ebbb13..506df98997 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -2248,6 +2248,9 @@ "defaultMessage": "郵件地址或密碼錯誤", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, + "c8n+rF": { + "defaultMessage": "Matters 會通過合約交易將 {amount} USDT 發送至你綁定的錢包 {address}(Matters 將暫時承擔交易手續費)。如需幫助請聯繫 ask@matters.town" + }, "cAP9g5": { "defaultMessage": "將你的評論在 {commentArticle} 中置頂", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2340,6 +2343,9 @@ "dTOtPO": { "defaultMessage": "儲值" }, + "dUkC8R": { + "defaultMessage": "提領支持" + }, "dVbKzB": { "defaultMessage": "評論和回覆", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -2443,6 +2449,9 @@ "defaultMessage": "邀請中", "description": "src/views/Circle/Settings/ManageInvitation/Invites/index.tsx" }, + "fidQDr": { + "defaultMessage": "{amount} USDT 待提領" + }, "fnv5rD": { "defaultMessage": "讚賞作品(當前 {total} 次讚賞)" }, diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx index 38f81a7954..0fe4588f8a 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx @@ -6,6 +6,7 @@ import { Step } from './types' type WithdrawVaultUSDTDialogContentProps = { amount: number + type?: 'connectAndClaim' | 'claim' closeDialog: () => void forward: (step: Step) => void currStep: Step @@ -23,7 +24,7 @@ const DynamicAddWalletLogin = dynamic( const WithdrawVaultUSDTDialogContent: React.FC< WithdrawVaultUSDTDialogContentProps -> = ({ amount, closeDialog, forward, currStep }) => { +> = ({ amount, type, closeDialog, forward, currStep }) => { const isIntro = currStep === 'intro' const isConnectWallet = currStep === 'connectWallet' @@ -32,6 +33,7 @@ const WithdrawVaultUSDTDialogContent: React.FC< {isIntro && ( { forward('connectWallet') }} diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx index 1a6f7db705..4b547404a8 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx @@ -1,39 +1,61 @@ +import { useContext } from 'react' import { FormattedMessage } from 'react-intl' import { formatAmount } from '~/common/utils' -import { Dialog } from '~/components' +import { Dialog, ViewerContext } from '~/components' type IntroProps = { + type?: 'connectAndClaim' | 'claim' amount: number switchToConnectWallet: () => void closeDialog: () => void } const Intro: React.FC = ({ + type = 'connectAndClaim', amount, switchToConnectWallet, closeDialog, }) => { + const viewer = useContext(ViewerContext) + const address = viewer.info.ethAddress + const isClaimOnly = type === 'claim' + return ( <> + isClaimOnly ? ( + + ) : ( + + ) } />

- + {address ? ( + + ) : ( + + )}

@@ -48,10 +70,14 @@ const Intro: React.FC = ({ smUpBtns={ + isClaimOnly ? ( + + ) : ( + + ) } onClick={switchToConnectWallet} /> diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx index b007bb2c12..bc25620d14 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx @@ -6,6 +6,7 @@ import { Step } from './types' interface WithdrawVaultUSDTDialogProps { amount: number + type?: 'connectAndClaim' | 'claim' children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode } @@ -15,6 +16,7 @@ const DynamicContent = dynamic(() => import('./Content'), { const BaseWithdrawVaultUSDTDialog = ({ amount, + type, children, }: WithdrawVaultUSDTDialogProps) => { const { @@ -35,6 +37,7 @@ const BaseWithdrawVaultUSDTDialog = ({ { ) ) const balance = address ? balanceUSDT : vaultBalanceUSDT - const canWithdrawVaultBalance = !address && vaultBalanceUSDT > 0 + const hasVaultBalance = vaultBalanceUSDT > 0 const classes = classNames({ [styles.assetsItem]: true, assetsItem: true, // global selector for overriding - [styles.clickable]: canWithdrawVaultBalance, + [styles.clickable]: hasVaultBalance, }) if (!address && !vaultBalanceUSDT) { @@ -78,12 +78,15 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { } return ( - + {({ openDialog }) => (
} @@ -94,26 +97,34 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { } + icon={hasVaultBalance && } spacing={8} placement="left" > - ) + hasVaultBalance ? ( + !address ? ( + + ) : ( + + ) + ) : undefined } weight="normal" /> From 141b8fa9fcf3849071e34df6252012eefdc99edd Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Wed, 11 Dec 2024 22:46:00 +0700 Subject: [PATCH 13/19] feat(vault): impl withdraw vault USDT --- lang/default.json | 19 +++-- lang/en.json | 19 +++-- lang/zh-Hans.json | 19 +++-- lang/zh-Hant.json | 19 +++-- .../WithdrawVaultUSDTDialog/Content.tsx | 46 ++++++++++- .../Dialogs/WithdrawVaultUSDTDialog/Intro.tsx | 36 ++++++--- .../WithdrawVaultUSDTDialog/styles.module.css | 3 + src/views/Me/Wallet/Balance/USDT.tsx | 78 ++++++++++--------- 8 files changed, 169 insertions(+), 70 deletions(-) create mode 100644 src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css diff --git a/lang/default.json b/lang/default.json index fc45e48f7f..55c3ce5e1e 100644 --- a/lang/default.json +++ b/lang/default.json @@ -184,9 +184,6 @@ "0tRUjd": { "defaultMessage": "This comment has been hidden due to violation of community terms of services" }, - "0zPaEM": { - "defaultMessage": "Matters will send {amount} USDT to your connected wallet via a contract transaction (Matters will temporarily cover the transaction fee)." - }, "0zZd0T": { "defaultMessage": "Article successfully published. Share it on different platforms to receive more likes and donations!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -401,6 +398,9 @@ "defaultMessage": "No discussion yet", "description": "src/views/Circle/Discussion/Discussion.tsx" }, + "55jJzY": { + "defaultMessage": "Claiming USDT" + }, "5CcjZy": { "defaultMessage": "Do you want to disconnect from {type}?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -1994,6 +1994,10 @@ "XOEFDf": { "defaultMessage": "{total} articles" }, + "XQ9bi3": { + "defaultMessage": "More", + "description": "src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx" + }, "XQTBu6": { "defaultMessage": "mentioned you in your circle broadcast comment", "description": "src/components/Notice/CircleNotice/CircleNewBroadcastComments.tsx" @@ -2248,9 +2252,6 @@ "defaultMessage": "Incorrect email or password", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, - "c8n+rF": { - "defaultMessage": "Matters will send {amount} USDT to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" - }, "cAP9g5": { "defaultMessage": "pinned your comment in {commentArticle}", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2529,6 +2530,9 @@ "hBLCwn": { "defaultMessage": "other amount" }, + "hDDFgp": { + "defaultMessage": "Matters will send {amount} to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" + }, "hG2cBH": { "defaultMessage": "Subscribe Circle" }, @@ -3016,6 +3020,9 @@ "defaultMessage": "Unavailable", "description": "FORBIDDEN_BY_STATE" }, + "rAFb3E": { + "defaultMessage": "Matters will send {amount} to your connected wallet via a contract transaction (Matters will temporarily cover the transaction fee)." + }, "rDX3h6": { "defaultMessage": "Version Description" }, diff --git a/lang/en.json b/lang/en.json index b1e299760d..bb1406e357 100644 --- a/lang/en.json +++ b/lang/en.json @@ -184,9 +184,6 @@ "0tRUjd": { "defaultMessage": "This comment has been hidden due to violation of community terms of services" }, - "0zPaEM": { - "defaultMessage": "Matters will send {amount} USDT to your connected wallet via a contract transaction (Matters will temporarily cover the transaction fee)." - }, "0zZd0T": { "defaultMessage": "Article successfully published. Share it on different platforms to receive more likes and donations!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -401,6 +398,9 @@ "defaultMessage": "No discussion yet", "description": "src/views/Circle/Discussion/Discussion.tsx" }, + "55jJzY": { + "defaultMessage": "Claiming USDT" + }, "5CcjZy": { "defaultMessage": "Do you want to disconnect from {type}?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -1994,6 +1994,10 @@ "XOEFDf": { "defaultMessage": "{total} articles" }, + "XQ9bi3": { + "defaultMessage": "More", + "description": "src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx" + }, "XQTBu6": { "defaultMessage": "mentioned you in your circle broadcast comment", "description": "src/components/Notice/CircleNotice/CircleNewBroadcastComments.tsx" @@ -2248,9 +2252,6 @@ "defaultMessage": "Incorrect email or password", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, - "c8n+rF": { - "defaultMessage": "Matters will send {amount} USDT to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" - }, "cAP9g5": { "defaultMessage": "pinned your comment in {commentArticle}", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2529,6 +2530,9 @@ "hBLCwn": { "defaultMessage": "other amount" }, + "hDDFgp": { + "defaultMessage": "Matters will send {amount} to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" + }, "hG2cBH": { "defaultMessage": "Subscribe Circle" }, @@ -3016,6 +3020,9 @@ "defaultMessage": "Unavailable", "description": "FORBIDDEN_BY_STATE" }, + "rAFb3E": { + "defaultMessage": "Matters will send {amount} to your connected wallet via a contract transaction (Matters will temporarily cover the transaction fee)." + }, "rDX3h6": { "defaultMessage": "Version Description" }, diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index 026b8d42bb..d8787e78a2 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -184,9 +184,6 @@ "0tRUjd": { "defaultMessage": "因违反社区规定,评论已被隐藏" }, - "0zPaEM": { - "defaultMessage": "Matters 会通过合约交易将 {amount} USDT 发送到你绑定的钱包(Matters 将暂时承担交易手续费)。" - }, "0zZd0T": { "defaultMessage": "作品发布成功,快把作品分享到不同渠道,吸引更多人为你拍手!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -401,6 +398,9 @@ "defaultMessage": "还没有众聊", "description": "src/views/Circle/Discussion/Discussion.tsx" }, + "55jJzY": { + "defaultMessage": "正在提领支持金额" + }, "5CcjZy": { "defaultMessage": "确认要解绑 {type} 吗?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -1994,6 +1994,10 @@ "XOEFDf": { "defaultMessage": "{total} 篇作品" }, + "XQ9bi3": { + "defaultMessage": "详情", + "description": "src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx" + }, "XQTBu6": { "defaultMessage": "在你的围炉广播中留言提及你", "description": "src/components/Notice/CircleNotice/CircleNewBroadcastComments.tsx" @@ -2248,9 +2252,6 @@ "defaultMessage": "邮箱或密码错误", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, - "c8n+rF": { - "defaultMessage": "Matters 会通过合约交易将 {amount} USDT 发送至你绑定的钱包 {address}(Matters 将暂时承担交易手续费)。如需帮助请联系 ask@matters.town" - }, "cAP9g5": { "defaultMessage": "将你的评论在 {commentArticle} 中置顶", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2529,6 +2530,9 @@ "hBLCwn": { "defaultMessage": "其他金额" }, + "hDDFgp": { + "defaultMessage": "Matters 会通过合约交易将 {amount} 发送至你绑定的钱包 {address}(Matters 将暂时承担交易手续费)。如需帮助请联系 ask@matters.town" + }, "hG2cBH": { "defaultMessage": "订阅围炉" }, @@ -3016,6 +3020,9 @@ "defaultMessage": "不可用", "description": "FORBIDDEN_BY_STATE" }, + "rAFb3E": { + "defaultMessage": "Matters 会通过合约交易将 {amount} 发送到你绑定的钱包(Matters 将暂时承担交易手续费)。" + }, "rDX3h6": { "defaultMessage": "版本简述" }, diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 506df98997..83d825808a 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -184,9 +184,6 @@ "0tRUjd": { "defaultMessage": "因違反社區約章,評論已被隱藏" }, - "0zPaEM": { - "defaultMessage": "Matters 會通過合約交易將 {amount} USDT 發送至你綁定的錢包(Matters 將暫時承擔交易手續費)。" - }, "0zZd0T": { "defaultMessage": "作品發布成功,快把作品分享到不同渠道,吸引更多人為你拍手!", "description": "src/views/Me/DraftDetail/PublishState/PublishedState.tsx" @@ -401,6 +398,9 @@ "defaultMessage": "還沒有眾聊", "description": "src/views/Circle/Discussion/Discussion.tsx" }, + "55jJzY": { + "defaultMessage": "正在提領支持金額" + }, "5CcjZy": { "defaultMessage": "確認要解綁 {type} 嗎?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -1994,6 +1994,10 @@ "XOEFDf": { "defaultMessage": "{total} 篇作品" }, + "XQ9bi3": { + "defaultMessage": "詳情", + "description": "src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx" + }, "XQTBu6": { "defaultMessage": "在你的圍爐廣播中留言提及你", "description": "src/components/Notice/CircleNotice/CircleNewBroadcastComments.tsx" @@ -2248,9 +2252,6 @@ "defaultMessage": "郵件地址或密碼錯誤", "description": "src/components/Forms/EmailLoginForm/index.tsx" }, - "c8n+rF": { - "defaultMessage": "Matters 會通過合約交易將 {amount} USDT 發送至你綁定的錢包 {address}(Matters 將暫時承擔交易手續費)。如需幫助請聯繫 ask@matters.town" - }, "cAP9g5": { "defaultMessage": "將你的評論在 {commentArticle} 中置頂", "description": "src/components/Notice/CommentNotice/CommentPinnedNotice.tsx" @@ -2529,6 +2530,9 @@ "hBLCwn": { "defaultMessage": "其他金額" }, + "hDDFgp": { + "defaultMessage": "Matters 會通過合約交易將 {amount} 發送至你綁定的錢包 {address}(Matters 將暫時承擔交易手續費)。如需幫助請聯繫 ask@matters.town" + }, "hG2cBH": { "defaultMessage": "訂閱圍爐" }, @@ -3016,6 +3020,9 @@ "defaultMessage": "不可用", "description": "FORBIDDEN_BY_STATE" }, + "rAFb3E": { + "defaultMessage": "Matters 會通過合約交易將 {amount} 發送至你綁定的錢包(Matters 將暫時承擔交易手續費)。" + }, "rDX3h6": { "defaultMessage": "版本簡述" }, diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx index 0fe4588f8a..ecb015e9eb 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx @@ -1,6 +1,11 @@ +import { useMutation } from '@apollo/react-hooks' +import { gql } from 'graphql-tag' import dynamic from 'next/dynamic' +import { FormattedMessage } from 'react-intl' -import { SpinnerBlock } from '~/components' +import { PATHS } from '~/common/enums' +import { SpinnerBlock, toast, useRoute } from '~/components' +import { WithdrawVaultUsdtMutation } from '~/gql/graphql' import { Step } from './types' @@ -22,11 +27,47 @@ const DynamicAddWalletLogin = dynamic( { ssr: false, loading: () => } ) +const WITHDRAW_VAULT_USDT = gql` + mutation WithdrawVaultUSDT { + withdrawLockedTokens { + transaction { + id + } + } + } +` + const WithdrawVaultUSDTDialogContent: React.FC< WithdrawVaultUSDTDialogContentProps > = ({ amount, type, closeDialog, forward, currStep }) => { + const { router } = useRoute() const isIntro = currStep === 'intro' const isConnectWallet = currStep === 'connectWallet' + const [withdraw] = useMutation(WITHDRAW_VAULT_USDT) + + const onWithdraw = async () => { + withdraw() + + closeDialog() + + toast.success({ + message: , + actions: [ + { + content: ( + + ), + onClick: () => { + router.push(PATHS.ME_WALLET_TRANSACTIONS) + }, + }, + ], + }) + } return ( <> @@ -37,6 +78,7 @@ const WithdrawVaultUSDTDialogContent: React.FC< switchToConnectWallet={() => { forward('connectWallet') }} + onWithdraw={onWithdraw} closeDialog={closeDialog} /> )} @@ -45,7 +87,7 @@ const WithdrawVaultUSDTDialogContent: React.FC< { - alert('asada') + onWithdraw() }} /> )} diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx index 4b547404a8..87b8366400 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx @@ -1,14 +1,17 @@ import { useContext } from 'react' import { FormattedMessage } from 'react-intl' -import { formatAmount } from '~/common/utils' +import { formatAmount, truncate } from '~/common/utils' import { Dialog, ViewerContext } from '~/components' +import styles from './styles.module.css' + type IntroProps = { type?: 'connectAndClaim' | 'claim' amount: number switchToConnectWallet: () => void closeDialog: () => void + onWithdraw: () => void } const Intro: React.FC = ({ @@ -16,6 +19,7 @@ const Intro: React.FC = ({ amount, switchToConnectWallet, closeDialog, + onWithdraw, }) => { const viewer = useContext(ViewerContext) const address = viewer.info.ethAddress @@ -42,18 +46,32 @@ const Intro: React.FC = ({

{address ? ( + {formatAmount(amount)} USDT + + ), + address: ( + + {truncate(address)} + + ), }} /> ) : ( + {formatAmount(amount)} USDT + + ), + }} /> )}

@@ -79,7 +97,7 @@ const Intro: React.FC = ({ /> ) } - onClick={switchToConnectWallet} + onClick={isClaimOnly ? onWithdraw : switchToConnectWallet} /> } /> diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css b/src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css new file mode 100644 index 0000000000..814e82fedc --- /dev/null +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css @@ -0,0 +1,3 @@ +.highlight { + color: var(--color-matters-green); +} diff --git a/src/views/Me/Wallet/Balance/USDT.tsx b/src/views/Me/Wallet/Balance/USDT.tsx index 667cac7d99..bd2c4e2f55 100644 --- a/src/views/Me/Wallet/Balance/USDT.tsx +++ b/src/views/Me/Wallet/Balance/USDT.tsx @@ -11,6 +11,7 @@ import { Button, CurrencyFormatter, Icon, + Spinner, TextIcon, Translate, useBalanceUSDT, @@ -30,8 +31,10 @@ interface USDTBalanceProps { export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { const viewer = useContext(ViewerContext) const address = viewer.info.ethAddress - const { data: balanceUSDTData } = useBalanceUSDT({}) - const { data: vaultBalanceUSDTData } = useVaultBalanceUSDT() + const { data: balanceUSDTData, isLoading: balanceUSDTLoading } = + useBalanceUSDT({}) + const { data: vaultBalanceUSDTData, isLoading: vaultBalanceUSDTLoading } = + useVaultBalanceUSDT() const balanceUSDT = parseFloat(balanceUSDTData?.formatted || '0') const vaultBalanceUSDT = parseFloat( formatUnits( @@ -40,6 +43,7 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { ) ) const balance = address ? balanceUSDT : vaultBalanceUSDT + const loading = balanceUSDTLoading || vaultBalanceUSDTLoading const hasVaultBalance = vaultBalanceUSDT > 0 const classes = classNames({ @@ -96,39 +100,43 @@ export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => {
- } - spacing={8} - placement="left" - > - - ) : ( - - ) - ) : undefined - } - weight="normal" - /> - + {loading ? ( + + ) : ( + } + spacing={8} + placement="left" + > + + ) : ( + + ) + ) : undefined + } + weight="normal" + /> + + )}
)}
From f9b7a7418ff35456636ad2dbbccc029bbb788457 Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:49:08 +0700 Subject: [PATCH 14/19] feat(vault): revise withdraw steps; revise notices --- lang/default.json | 21 ++- lang/en.json | 21 ++- lang/zh-Hans.json | 21 ++- lang/zh-Hant.json | 21 ++- src/common/enums/events.ts | 1 + src/components/Dialog/Buttons.tsx | 8 +- .../WithdrawVaultUSDTDialog/Confirming.tsx | 139 ++++++++++++++++++ .../WithdrawVaultUSDTDialog/Content.tsx | 80 ++++------ .../Dialogs/WithdrawVaultUSDTDialog/Intro.tsx | 10 +- .../Dialogs/WithdrawVaultUSDTDialog/index.tsx | 68 ++++----- .../WithdrawVaultUSDTDialog/types.d.ts | 2 +- .../ArticleNewCollectedNotice.tsx | 4 - .../Notice/ArticleNotice/CircleNewArticle.tsx | 3 +- .../CircleNotice/CircleInvitationNotice.tsx | 8 +- .../CircleNewDiscussionComments.tsx | 4 - .../CircleNotice/CircleNewUserNotice.tsx | 4 - .../CommentNotice/ArticleNewCommentNotice.tsx | 4 - .../CommentNotice/CommentLikedNotice.tsx | 4 - .../CommentMentionedYouNotice.tsx | 4 - .../CommentNotice/MomentNewCommentNotice.tsx | 4 - src/components/Notice/NoticeActorAvatar.tsx | 9 +- src/components/Notice/NoticeDigest/index.tsx | 105 +++---------- src/components/Notice/NoticeMultiActors.tsx | 12 +- .../PaymentReceivedDonationNotice.tsx | 4 - .../WithdrewLockedTokensNotice.tsx | 2 +- src/components/Notice/styles.module.css | 1 + src/views/Me/Wallet/Balance/USDT.tsx | 114 +++++++------- src/views/Me/Wallet/index.tsx | 5 + 28 files changed, 383 insertions(+), 300 deletions(-) create mode 100644 src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx diff --git a/lang/default.json b/lang/default.json index 55c3ce5e1e..8c34d96451 100644 --- a/lang/default.json +++ b/lang/default.json @@ -398,9 +398,6 @@ "defaultMessage": "No discussion yet", "description": "src/views/Circle/Discussion/Discussion.tsx" }, - "55jJzY": { - "defaultMessage": "Claiming USDT" - }, "5CcjZy": { "defaultMessage": "Do you want to disconnect from {type}?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -883,6 +880,9 @@ "defaultMessage": "Copy comment", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CcVXhc": { + "defaultMessage": "Matters is sending {amount} to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" + }, "CgPGAu": { "defaultMessage": ", connect your wallet to claim" }, @@ -1147,6 +1147,9 @@ "HAlOn1": { "defaultMessage": "Name" }, + "HBdVkS": { + "defaultMessage": "Claiming in progress" + }, "HBxXD/": { "defaultMessage": "License" }, @@ -1157,6 +1160,9 @@ "HJ0iZJ": { "defaultMessage": "Confirm Archiving" }, + "HJsl78": { + "defaultMessage": "An issue occurred while claiming USDT. Please retry or contact ask@matters.town" + }, "HPVOw/": { "defaultMessage": "Wallet", "description": "src/views/Me/Settings/Settings/index.tsx" @@ -1529,6 +1535,9 @@ "O7ozeo": { "defaultMessage": "Update profile" }, + "ODncRd": { + "defaultMessage": "Claiming..." + }, "OIj8pQ": { "defaultMessage": "Invitation Sent", "description": "src/views/Circle/Settings/ManageInvitation/AddInvitationDialog/Sent.tsx" @@ -2453,6 +2462,9 @@ "fidQDr": { "defaultMessage": "{amount} USDT pending claim" }, + "fko+MR": { + "defaultMessage": "Retry claiming" + }, "fnv5rD": { "defaultMessage": "like article (current {total} likes)" }, @@ -3029,6 +3041,9 @@ "rE7sE3": { "defaultMessage": "CC0 License" }, + "rG2xmp": { + "defaultMessage": "Claim successful" + }, "rHi+cL": { "defaultMessage": "Most readers", "description": "src/views/Me/Works/Published/SortTabs.tsx" diff --git a/lang/en.json b/lang/en.json index bb1406e357..a22db03108 100644 --- a/lang/en.json +++ b/lang/en.json @@ -398,9 +398,6 @@ "defaultMessage": "No discussion yet", "description": "src/views/Circle/Discussion/Discussion.tsx" }, - "55jJzY": { - "defaultMessage": "Claiming USDT" - }, "5CcjZy": { "defaultMessage": "Do you want to disconnect from {type}?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -883,6 +880,9 @@ "defaultMessage": "Copy comment", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CcVXhc": { + "defaultMessage": "Matters is sending {amount} to your connected wallet {address} via a contract transaction (Matters will temporarily cover the transaction fee). For assistance, please contact ask@matters.town" + }, "CgPGAu": { "defaultMessage": ", connect your wallet to claim" }, @@ -1147,6 +1147,9 @@ "HAlOn1": { "defaultMessage": "Name" }, + "HBdVkS": { + "defaultMessage": "Claiming in progress" + }, "HBxXD/": { "defaultMessage": "License" }, @@ -1157,6 +1160,9 @@ "HJ0iZJ": { "defaultMessage": "Confirm Archiving" }, + "HJsl78": { + "defaultMessage": "An issue occurred while claiming USDT. Please retry or contact ask@matters.town" + }, "HPVOw/": { "defaultMessage": "Wallet", "description": "src/views/Me/Settings/Settings/index.tsx" @@ -1529,6 +1535,9 @@ "O7ozeo": { "defaultMessage": "Update profile" }, + "ODncRd": { + "defaultMessage": "Claiming..." + }, "OIj8pQ": { "defaultMessage": "Invitation Sent", "description": "src/views/Circle/Settings/ManageInvitation/AddInvitationDialog/Sent.tsx" @@ -2453,6 +2462,9 @@ "fidQDr": { "defaultMessage": "{amount} USDT pending claim" }, + "fko+MR": { + "defaultMessage": "Retry claiming" + }, "fnv5rD": { "defaultMessage": "like article (current {total} likes)" }, @@ -3029,6 +3041,9 @@ "rE7sE3": { "defaultMessage": "CC0 License" }, + "rG2xmp": { + "defaultMessage": "Claim successful" + }, "rHi+cL": { "defaultMessage": "Most readers", "description": "src/views/Me/Works/Published/SortTabs.tsx" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index d8787e78a2..8785d72f4a 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -398,9 +398,6 @@ "defaultMessage": "还没有众聊", "description": "src/views/Circle/Discussion/Discussion.tsx" }, - "55jJzY": { - "defaultMessage": "正在提领支持金额" - }, "5CcjZy": { "defaultMessage": "确认要解绑 {type} 吗?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -883,6 +880,9 @@ "defaultMessage": "复制留言", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CcVXhc": { + "defaultMessage": "Matters 正在通过合约交易将 {amount} 发送至你绑定的钱包 {address}(Matters 将暂时承担交易手续费)。如需帮助请联系 ask@matters.town" + }, "CgPGAu": { "defaultMessage": ",绑定钱包后可领取" }, @@ -1147,6 +1147,9 @@ "HAlOn1": { "defaultMessage": "用户名" }, + "HBdVkS": { + "defaultMessage": "正在提领支持" + }, "HBxXD/": { "defaultMessage": "版权声明" }, @@ -1157,6 +1160,9 @@ "HJ0iZJ": { "defaultMessage": "确认归档" }, + "HJsl78": { + "defaultMessage": "提领支持金额时遇到问题,请重试或联系 ask@matters.town" + }, "HPVOw/": { "defaultMessage": "数字钱包", "description": "src/views/Me/Settings/Settings/index.tsx" @@ -1529,6 +1535,9 @@ "O7ozeo": { "defaultMessage": "修改个人资料" }, + "ODncRd": { + "defaultMessage": "提领中..." + }, "OIj8pQ": { "defaultMessage": "成功发送邀请", "description": "src/views/Circle/Settings/ManageInvitation/AddInvitationDialog/Sent.tsx" @@ -2453,6 +2462,9 @@ "fidQDr": { "defaultMessage": "{amount} USDT 待提领" }, + "fko+MR": { + "defaultMessage": "重试提领" + }, "fnv5rD": { "defaultMessage": "赞赏作品(当前 {total} 次赞赏)" }, @@ -3029,6 +3041,9 @@ "rE7sE3": { "defaultMessage": "CC0 公众领域贡献宣告" }, + "rG2xmp": { + "defaultMessage": "提领成功" + }, "rHi+cL": { "defaultMessage": "最多读者", "description": "src/views/Me/Works/Published/SortTabs.tsx" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 83d825808a..ea823b28a0 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -398,9 +398,6 @@ "defaultMessage": "還沒有眾聊", "description": "src/views/Circle/Discussion/Discussion.tsx" }, - "55jJzY": { - "defaultMessage": "正在提領支持金額" - }, "5CcjZy": { "defaultMessage": "確認要解綁 {type} 嗎?", "description": "src/components/Dialogs/RemoveSocialLoginDialog/Content.tsx" @@ -883,6 +880,9 @@ "defaultMessage": "複製留言", "description": "src/components/Comment/DropdownActions/index.tsx" }, + "CcVXhc": { + "defaultMessage": "Matters 正在通過合約交易將 {amount} 發送至你綁定的錢包 {address}(Matters 將暫時承擔交易手續費)。如需幫助請聯繫 ask@matters.town" + }, "CgPGAu": { "defaultMessage": ",連接錢包領取" }, @@ -1147,6 +1147,9 @@ "HAlOn1": { "defaultMessage": "用戶名" }, + "HBdVkS": { + "defaultMessage": "正在提領支持" + }, "HBxXD/": { "defaultMessage": "版權聲明" }, @@ -1157,6 +1160,9 @@ "HJ0iZJ": { "defaultMessage": "確認封存" }, + "HJsl78": { + "defaultMessage": "提領支持金額時遇到問題,請重試或聯繫 ask@matters.town" + }, "HPVOw/": { "defaultMessage": "數字錢包", "description": "src/views/Me/Settings/Settings/index.tsx" @@ -1529,6 +1535,9 @@ "O7ozeo": { "defaultMessage": "修改個人資料" }, + "ODncRd": { + "defaultMessage": "提領中..." + }, "OIj8pQ": { "defaultMessage": "成功發送邀請", "description": "src/views/Circle/Settings/ManageInvitation/AddInvitationDialog/Sent.tsx" @@ -2453,6 +2462,9 @@ "fidQDr": { "defaultMessage": "{amount} USDT 待提領" }, + "fko+MR": { + "defaultMessage": "重試提領" + }, "fnv5rD": { "defaultMessage": "讚賞作品(當前 {total} 次讚賞)" }, @@ -3029,6 +3041,9 @@ "rE7sE3": { "defaultMessage": "CC0 公眾領域貢獻宣告" }, + "rG2xmp": { + "defaultMessage": "提領成功" + }, "rHi+cL": { "defaultMessage": "最多讀者", "description": "src/views/Me/Works/Published/SortTabs.tsx" diff --git a/src/common/enums/events.ts b/src/common/enums/events.ts index f40039c0a2..646341e190 100644 --- a/src/common/enums/events.ts +++ b/src/common/enums/events.ts @@ -42,6 +42,7 @@ export const BYPASS_SCROLL_LOCK = 'bypassScrollLock' export const ENBABLE_SCROLL_LOCK = 'enableScrollLock' export const BYPASS_FOCUS_LOCK = 'bypassFocusLock' export const ENBABLE_FOCUS_LOCK = 'enableFocusLock' +export const OPEN_WITHDRAW_VAULT_USDT_DIALOG = 'openWithdrawVaultUsdtDialog' // Toast export const TOAST_SEND_EMAIL_VERIFICATION = 'toastSendEmailVerification' diff --git a/src/components/Dialog/Buttons.tsx b/src/components/Dialog/Buttons.tsx index 21119a7130..6044f41081 100644 --- a/src/components/Dialog/Buttons.tsx +++ b/src/components/Dialog/Buttons.tsx @@ -6,12 +6,14 @@ export type DialogTextButtonProps = { text: React.ReactNode color?: 'greyDarker' | 'green' | 'red' | 'black' loading?: boolean + icon?: React.ReactNode } & ButtonProps export const TextButton: React.FC = ({ text, color = 'green', loading, + icon, ...restProps }) => { let buttonProps: ButtonProps = restProps @@ -49,7 +51,11 @@ export const TextButton: React.FC = ({ return ( diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx new file mode 100644 index 0000000000..e0580e11c4 --- /dev/null +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx @@ -0,0 +1,139 @@ +import { useMutation } from '@apollo/react-hooks' +import gql from 'graphql-tag' +import { useContext, useEffect } from 'react' +import { FormattedMessage } from 'react-intl' + +import { OPEN_WITHDRAW_VAULT_USDT_DIALOG, PATHS } from '~/common/enums' +import { formatAmount, truncate } from '~/common/utils' +import { Dialog, Spinner, toast, useRoute, ViewerContext } from '~/components' +import { WithdrawVaultUsdtMutation } from '~/gql/graphql' + +import styles from './styles.module.css' + +type ConfirmingProps = { + amount: number + closeDialog: () => void +} + +const WITHDRAW_VAULT_USDT = gql` + mutation WithdrawVaultUSDT { + withdrawLockedTokens { + transaction { + id + } + } + } +` + +const Confirming: React.FC = ({ amount, closeDialog }) => { + const viewer = useContext(ViewerContext) + const address = viewer.info.ethAddress! + const { router } = useRoute() + + const [withdraw] = useMutation(WITHDRAW_VAULT_USDT) + + const onWithdraw = async () => { + try { + await withdraw() + + toast.success({ + message: ( + + ), + actions: [ + { + content: ( + + ), + onClick: () => { + router.push(PATHS.ME_WALLET_TRANSACTIONS) + }, + }, + ], + }) + } catch (error) { + toast.error({ + message: ( + + ), + actions: [ + { + content: ( + + ), + onClick: () => { + window.dispatchEvent( + new CustomEvent(OPEN_WITHDRAW_VAULT_USDT_DIALOG, {}) + ) + }, + }, + ], + }) + } + + closeDialog() + } + + useEffect(() => { + onWithdraw() + }, []) + + return ( + <> + + } + rightBtn={ + } + color="greyDarker" + disabled + /> + } + /> + + + +

+ + {formatAmount(amount)} USDT + + ), + address: ( + {truncate(address)} + ), + }} + /> +

+
+
+ + } + icon={} + /> + } + /> + + ) +} + +export default Confirming diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx index ecb015e9eb..266a6b7a9a 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Content.tsx @@ -1,17 +1,12 @@ -import { useMutation } from '@apollo/react-hooks' -import { gql } from 'graphql-tag' import dynamic from 'next/dynamic' -import { FormattedMessage } from 'react-intl' +import { formatUnits } from 'viem' -import { PATHS } from '~/common/enums' -import { SpinnerBlock, toast, useRoute } from '~/components' -import { WithdrawVaultUsdtMutation } from '~/gql/graphql' +import { contract } from '~/common/enums' +import { SpinnerBlock, useVaultBalanceUSDT } from '~/components' import { Step } from './types' type WithdrawVaultUSDTDialogContentProps = { - amount: number - type?: 'connectAndClaim' | 'claim' closeDialog: () => void forward: (step: Step) => void currStep: Step @@ -27,58 +22,40 @@ const DynamicAddWalletLogin = dynamic( { ssr: false, loading: () => } ) -const WITHDRAW_VAULT_USDT = gql` - mutation WithdrawVaultUSDT { - withdrawLockedTokens { - transaction { - id - } - } - } -` +const DynamicConfirming = dynamic(() => import('./Confirming'), { + ssr: false, + loading: () => , +}) const WithdrawVaultUSDTDialogContent: React.FC< WithdrawVaultUSDTDialogContentProps -> = ({ amount, type, closeDialog, forward, currStep }) => { - const { router } = useRoute() +> = ({ closeDialog, forward, currStep }) => { + const { data: vaultBalanceUSDTData, isLoading: vaultBalanceUSDTLoading } = + useVaultBalanceUSDT() + const vaultBalanceUSDT = parseFloat( + formatUnits( + BigInt(vaultBalanceUSDTData || '0'), + contract.Optimism.tokenDecimals + ) + ) + const isIntro = currStep === 'intro' const isConnectWallet = currStep === 'connectWallet' - const [withdraw] = useMutation(WITHDRAW_VAULT_USDT) - - const onWithdraw = async () => { - withdraw() - - closeDialog() - - toast.success({ - message: , - actions: [ - { - content: ( - - ), - onClick: () => { - router.push(PATHS.ME_WALLET_TRANSACTIONS) - }, - }, - ], - }) - } + const isConfirming = currStep === 'confirming' return ( <> + {vaultBalanceUSDTLoading && } + {isIntro && ( { forward('connectWallet') }} - onWithdraw={onWithdraw} + switchToConfirming={() => { + forward('confirming') + }} closeDialog={closeDialog} /> )} @@ -87,10 +64,17 @@ const WithdrawVaultUSDTDialogContent: React.FC< { - onWithdraw() + forward('confirming') }} /> )} + + {isConfirming && ( + + )} ) } diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx index 87b8366400..dc41d4c4c5 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx @@ -7,23 +7,21 @@ import { Dialog, ViewerContext } from '~/components' import styles from './styles.module.css' type IntroProps = { - type?: 'connectAndClaim' | 'claim' amount: number switchToConnectWallet: () => void + switchToConfirming: () => void closeDialog: () => void - onWithdraw: () => void } const Intro: React.FC = ({ - type = 'connectAndClaim', amount, switchToConnectWallet, + switchToConfirming, closeDialog, - onWithdraw, }) => { const viewer = useContext(ViewerContext) const address = viewer.info.ethAddress - const isClaimOnly = type === 'claim' + const isClaimOnly = !!address return ( <> @@ -97,7 +95,7 @@ const Intro: React.FC = ({ /> ) } - onClick={isClaimOnly ? onWithdraw : switchToConnectWallet} + onClick={isClaimOnly ? switchToConfirming : switchToConnectWallet} /> } /> diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx index bc25620d14..274b150a14 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx @@ -1,56 +1,44 @@ import dynamic from 'next/dynamic' -import { Dialog, SpinnerBlock, useDialogSwitch, useStep } from '~/components' +import { OPEN_WITHDRAW_VAULT_USDT_DIALOG } from '~/common/enums' +import { + Dialog, + SpinnerBlock, + useDialogSwitch, + useEventListener, + useStep, +} from '~/components' import { Step } from './types' -interface WithdrawVaultUSDTDialogProps { - amount: number - type?: 'connectAndClaim' | 'claim' - children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode -} - const DynamicContent = dynamic(() => import('./Content'), { loading: () => , }) -const BaseWithdrawVaultUSDTDialog = ({ - amount, - type, - children, -}: WithdrawVaultUSDTDialogProps) => { - const { - show, - openDialog: baseOpenDialog, - closeDialog, - } = useDialogSwitch(true) +const BaseWithdrawVaultUSDTDialog = () => { + const { show, closeDialog } = useDialogSwitch(true) const { currStep, forward } = useStep('intro') - const openDialog = () => { - baseOpenDialog() + return ( + + + + ) +} + +export const WithdrawVaultUSDTDialog = () => { + const Children = ({ openDialog }: { openDialog: () => void }) => { + useEventListener(OPEN_WITHDRAW_VAULT_USDT_DIALOG, openDialog) + return <> } return ( - <> - {children({ openDialog })} - - - - - + }> + {({ openDialog }) => } + ) } - -export const WithdrawVaultUSDTDialog = ( - props: WithdrawVaultUSDTDialogProps -) => ( - }> - {({ openDialog }) => <>{props.children({ openDialog })}} - -) diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts b/src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts index cc8be6364c..25a92599d1 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/types.d.ts @@ -1 +1 @@ -export type Step = 'intro' | 'connectWallet' +export type Step = 'intro' | 'connectWallet' | 'confirming' diff --git a/src/components/Notice/ArticleArticleNotice/ArticleNewCollectedNotice.tsx b/src/components/Notice/ArticleArticleNotice/ArticleNewCollectedNotice.tsx index 9b862bb2f5..341b5acc6d 100644 --- a/src/components/Notice/ArticleArticleNotice/ArticleNewCollectedNotice.tsx +++ b/src/components/Notice/ArticleArticleNotice/ArticleNewCollectedNotice.tsx @@ -16,10 +16,6 @@ const ArticleNewCollectedNotice = ({ }: { notice: ArticleNewCollectedNoticeFragment }) => { - if (!notice.actors) { - return null - } - return ( { - if (!notice.actors || !notice.circle) { + if (!notice.circle) { return null } @@ -46,7 +46,7 @@ CircleInvitationNotice.fragments = { id ...NoticeDate actors { - ...NoticeActorNameUser + ...NoticeActorAvatarUser } circle: target { id @@ -57,7 +57,7 @@ CircleInvitationNotice.fragments = { ...NoticeCircleCard } } - ${NoticeActorName.fragments.user} + ${NoticeActorAvatar.fragments.user} ${NoticeCircleCard.fragments.circle} ${NoticeDate.fragments.notice} `, diff --git a/src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx b/src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx index 63649595a3..a8f3c0821d 100644 --- a/src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx +++ b/src/components/Notice/CircleNotice/CircleNewDiscussionComments.tsx @@ -24,10 +24,6 @@ const CircleNewDiscussionComments = ({ const viewer = useContext(ViewerContext) const { comments, replies, mentions } = notice - if (!notice.actors) { - return null - } - const isCircleOwner = notice.circle.owner.id === viewer.id const newDiscussionCount = comments?.length const replyCount = replies?.length diff --git a/src/components/Notice/CircleNotice/CircleNewUserNotice.tsx b/src/components/Notice/CircleNotice/CircleNewUserNotice.tsx index c8e4bc7272..b710796393 100644 --- a/src/components/Notice/CircleNotice/CircleNewUserNotice.tsx +++ b/src/components/Notice/CircleNotice/CircleNewUserNotice.tsx @@ -16,10 +16,6 @@ type CircleNewUserNotice = { } const CircleNewUserNotice = ({ notice, userType }: CircleNewUserNotice) => { - if (!notice.actors) { - return null - } - const isNewFollower = userType === 'follower' const isNewSubscriber = userType === 'subscriber' diff --git a/src/components/Notice/CommentNotice/ArticleNewCommentNotice.tsx b/src/components/Notice/CommentNotice/ArticleNewCommentNotice.tsx index 8326efb55f..6c3f0fb783 100644 --- a/src/components/Notice/CommentNotice/ArticleNewCommentNotice.tsx +++ b/src/components/Notice/CommentNotice/ArticleNewCommentNotice.tsx @@ -16,10 +16,6 @@ const ArticleNewCommentNotice = ({ }: { notice: ArticleNewCommentNoticeFragment }) => { - if (!notice.actors) { - return null - } - const commentArticle = notice.comment?.node.__typename === 'Article' ? notice.comment.node diff --git a/src/components/Notice/CommentNotice/CommentLikedNotice.tsx b/src/components/Notice/CommentNotice/CommentLikedNotice.tsx index cf5fc69fc1..3f685c4a71 100644 --- a/src/components/Notice/CommentNotice/CommentLikedNotice.tsx +++ b/src/components/Notice/CommentNotice/CommentLikedNotice.tsx @@ -13,10 +13,6 @@ import NoticeHeadActors from '../NoticeHeadActors' import NoticeMomentTitle from '../NoticeMomentTitle' const CommentLikedNotice = ({ notice }: { notice: CommentNoticeFragment }) => { - if (!notice.actors) { - return null - } - const isMoment = notice.comment.node.__typename === 'Moment' const commentMoment = notice.comment.node.__typename === 'Moment' diff --git a/src/components/Notice/CommentNotice/CommentMentionedYouNotice.tsx b/src/components/Notice/CommentNotice/CommentMentionedYouNotice.tsx index 8a2fb29812..b8cca5394f 100644 --- a/src/components/Notice/CommentNotice/CommentMentionedYouNotice.tsx +++ b/src/components/Notice/CommentNotice/CommentMentionedYouNotice.tsx @@ -19,10 +19,6 @@ const CommentMentionedYouNotice = ({ }: { notice: CommentMentionedYouNoticeFragment }) => { - if (!notice.actors) { - return null - } - const commentArticle = notice.comment?.node.__typename === 'Article' ? notice.comment.node : null const commentCircle = diff --git a/src/components/Notice/CommentNotice/MomentNewCommentNotice.tsx b/src/components/Notice/CommentNotice/MomentNewCommentNotice.tsx index d6232bf265..1e5360658a 100644 --- a/src/components/Notice/CommentNotice/MomentNewCommentNotice.tsx +++ b/src/components/Notice/CommentNotice/MomentNewCommentNotice.tsx @@ -16,10 +16,6 @@ const MomentNewCommentNotice = ({ }: { notice: MomentNewCommentNoticeFragment }) => { - if (!notice.actors) { - return null - } - const commentMoment = notice.comment?.node.__typename === 'Moment' ? notice.comment.node diff --git a/src/components/Notice/NoticeActorAvatar.tsx b/src/components/Notice/NoticeActorAvatar.tsx index 4436090f1c..2db992b15e 100644 --- a/src/components/Notice/NoticeActorAvatar.tsx +++ b/src/components/Notice/NoticeActorAvatar.tsx @@ -1,20 +1,13 @@ import gql from 'graphql-tag' -import { AvatarSize } from '~/components/Avatar' import { UserDigest } from '~/components/UserDigest' import { NoticeActorAvatarUserFragment } from '~/gql/graphql' export const NoticeActorAvatar = ({ user, - size = 32, }: { - user: NoticeActorAvatarUserFragment | null - size?: AvatarSize + user?: NoticeActorAvatarUserFragment }) => { - if (!user) { - return null - } - return } diff --git a/src/components/Notice/NoticeDigest/index.tsx b/src/components/Notice/NoticeDigest/index.tsx index c3c6b4e885..1085e724af 100644 --- a/src/components/Notice/NoticeDigest/index.tsx +++ b/src/components/Notice/NoticeDigest/index.tsx @@ -1,57 +1,21 @@ -import gql from 'graphql-tag' import { ReactElement } from 'react' +import { FormattedMessage } from 'react-intl' import { TEST_ID } from '~/common/enums' -import { - ArticleNewAppreciationNoticeFragment, - ArticleNewCollectedNoticeFragment, - ArticleNewCommentNoticeFragment, - ArticleNewSubscriberNoticeFragment, - CampaignArticleFeaturedNoticeFragment, - CircleInvitationNoticeFragment, - CircleNewBroadcastNoticeFragment, - CircleNewDiscussionCommentsFragment, - CircleNewUserNoticeFragment, - CollectionNewLikeNoticeFragment, - CommentMentionedYouNoticeFragment, - CommentNewReplyNoticeFragment, - MomentLikedNoticeFragment, - MomentMentionedYouNoticeFragment, - MomentNewCommentNoticeFragment, - NoticeActorAvatarUserFragment, - NoticeHeadActorsUserFragment, - PaymentReceivedDonationNoticeFragment, - UserNewFollowerNoticeFragment, -} from '~/gql/graphql' +import { NoticeActorAvatarUserFragment } from '~/gql/graphql' import NoticeActorAvatar from '../NoticeActorAvatar' import NoticeActorsNameAndTitle from '../NoticeActorsNameAndTitle' -import NoticeArticleCard from '../NoticeArticleCard' import NoticeDate from '../NoticeDate' -import NoticeHeadActors from '../NoticeHeadActors' import NoticeMultiActors from '../NoticeMultiActors' import styles from '../styles.module.css' type NoticeDigestProps = { - notice: - | ArticleNewSubscriberNoticeFragment - | ArticleNewAppreciationNoticeFragment - | ArticleNewCollectedNoticeFragment - | ArticleNewCommentNoticeFragment - | CircleInvitationNoticeFragment - | CircleNewBroadcastNoticeFragment - | CircleNewDiscussionCommentsFragment - | CircleNewUserNoticeFragment - | CommentMentionedYouNoticeFragment - | CommentNewReplyNoticeFragment - | PaymentReceivedDonationNoticeFragment - | UserNewFollowerNoticeFragment - | MomentNewCommentNoticeFragment - | MomentLikedNoticeFragment - | MomentMentionedYouNoticeFragment - | CollectionNewLikeNoticeFragment - | CampaignArticleFeaturedNoticeFragment - actors?: (NoticeActorAvatarUserFragment & NoticeHeadActorsUserFragment)[] + notice: { + id: string + actors?: NoticeActorAvatarUserFragment[] | null + createdAt: string + } action: string | ReactElement secondAction?: string | ReactElement title?: string | ReactElement @@ -61,20 +25,16 @@ type NoticeDigestProps = { const NoticeDigest = ({ notice, - actors: extendActors, action, secondAction, title, content, testId, }: NoticeDigestProps) => { - if (!notice.actors) { - return null - } - - let actors = extendActors || notice.actors + const actors = notice.actors || [] const actorsCount = actors.length + const isAnonymous = actorsCount <= 0 const isMultiActors = actorsCount > 1 return ( @@ -83,7 +43,20 @@ const NoticeDigest = ({ {...(testId ? { ['data-test-id']: testId } : {})} >
- + + + {isAnonymous && ( + <> + + +
+ + + +
+ + )} + {!isMultiActors && (
{ +const NoticeMultiActors = ({ actors }: NoticeMultiActorsProps) => { const actorsCount = actors.length const showAll = actorsCount <= 8 @@ -17,7 +17,7 @@ const NoticeMultiActors = ({ actors, size }: NoticeMultiActorsProps) => { return ( <> {actors.map((actor, index) => ( - + ))} ) @@ -26,7 +26,7 @@ const NoticeMultiActors = ({ actors, size }: NoticeMultiActorsProps) => { return ( <> {actors.slice(0, 7).map((actor, index) => ( - + ))} + } + /> - - - + title={ + + } + /> - - - - + title={ + + } + /> + ) } diff --git a/src/views/Circle/Discussion/styles.module.css b/src/views/Circle/Discussion/styles.module.css index bcfcc549be..23923e5691 100644 --- a/src/views/Circle/Discussion/styles.module.css +++ b/src/views/Circle/Discussion/styles.module.css @@ -6,6 +6,10 @@ padding: 0 var(--sp16); margin-top: var(--sp8); + @media (--sm-up) { + padding: 0; + } + & .header { margin-bottom: var(--sp24); } diff --git a/src/views/Circle/Settings/ManageInvitation/Invites/index.tsx b/src/views/Circle/Settings/ManageInvitation/Invites/index.tsx index 17ccf5ee65..c5907ec40e 100644 --- a/src/views/Circle/Settings/ManageInvitation/Invites/index.tsx +++ b/src/views/Circle/Settings/ManageInvitation/Invites/index.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' -import { FormattedMessage } from 'react-intl' +import { useIntl } from 'react-intl' -import { SegmentedTabs } from '~/components' +import { SquareTabs } from '~/components' import AcceptedInvites from './Accepted' import PendingInvites from './Pending' @@ -9,6 +9,7 @@ import PendingInvites from './Pending' type InvitesType = 'accepted' | 'pending' const InvitesFeed: React.FC = () => { + const intl = useIntl() const [type, setType] = useState('pending') const isPending = type === 'pending' @@ -16,29 +17,29 @@ const InvitesFeed: React.FC = () => { return ( <> - - + setType('pending')} selected={isPending} - > - - - - + + setType('accepted')} selected={isAccepted} - > - - - + title={intl.formatMessage({ + defaultMessage: 'Accepted', + id: 'JpS59y', + description: + 'src/views/Circle/Settings/ManageInvitation/Invites/index.tsx', + })} + /> + {isPending && } {isAccepted && } diff --git a/src/views/Me/History/LikesTabs.tsx b/src/views/Me/History/LikesTabs.tsx index 65ffc48529..5b86d81263 100644 --- a/src/views/Me/History/LikesTabs.tsx +++ b/src/views/Me/History/LikesTabs.tsx @@ -1,7 +1,7 @@ import { FormattedMessage } from 'react-intl' import { PATHS } from '~/common/enums' -import { HorizontalRule, SegmentedTabs, useRoute } from '~/components' +import { Button, HorizontalRule, SquareTabs, useRoute } from '~/components' import styles from './styles.module.css' @@ -11,21 +11,25 @@ const LikesTabs: React.FC = () => { return ( <>
- - + - - + title={ + + } + /> - - - - + title={ + + } + /> +
diff --git a/src/views/Me/Transactions/index.tsx b/src/views/Me/Transactions/index.tsx index ac9ea922d7..e318456004 100644 --- a/src/views/Me/Transactions/index.tsx +++ b/src/views/Me/Transactions/index.tsx @@ -1,7 +1,7 @@ import { useQuery } from '@apollo/react-hooks' import gql from 'graphql-tag' import { useState } from 'react' -import { FormattedMessage, useIntl } from 'react-intl' +import { useIntl } from 'react-intl' import { analytics, mergeConnections } from '~/common/utils' import { @@ -13,8 +13,8 @@ import { InfiniteScroll, Layout, List, - SegmentedTabs, SpinnerBlock, + SquareTabs, Transaction, } from '~/components' import { MeTransactionsQuery } from '~/gql/graphql' @@ -163,8 +163,9 @@ const Transactions = () => { - {
} > - setPurpose(Purpose.ALL)} - > - - - - + + setPurpose(Purpose.DONATION)} - > - - - - + + setPurpose(Purpose.SUBSCRIPTION)} - > - - - + title={intl.formatMessage({ + defaultMessage: 'Subscriptions', + id: 'T73SwS', + description: 'src/views/Me/Transactions/index.tsx', + })} + /> + diff --git a/src/views/Search/AggregateResults/Tabs.tsx b/src/views/Search/AggregateResults/Tabs.tsx index 8fdd8a44f8..98711a690a 100644 --- a/src/views/Search/AggregateResults/Tabs.tsx +++ b/src/views/Search/AggregateResults/Tabs.tsx @@ -2,8 +2,6 @@ import { useIntl } from 'react-intl' import { SquareTabs } from '~/components' -import styles from './styles.module.css' - export type TABS = 'article' | 'user' | 'tag' type TabsProps = { @@ -15,33 +13,31 @@ export const Tabs = ({ tab, setTab }: TabsProps) => { const intl = useIntl() return ( -
- - setTab('article')} - title={intl.formatMessage({ - defaultMessage: 'Articles', - id: '3KNMbJ', - })} - /> - setTab('user')} - title={intl.formatMessage({ - defaultMessage: 'Users', - id: 'YDMrKK', - })} - /> - setTab('tag')} - title={intl.formatMessage({ - defaultMessage: 'Tags', - id: '1EYCdR', - })} - /> - -
+ + setTab('article')} + title={intl.formatMessage({ + defaultMessage: 'Articles', + id: '3KNMbJ', + })} + /> + setTab('user')} + title={intl.formatMessage({ + defaultMessage: 'Users', + id: 'YDMrKK', + })} + /> + setTab('tag')} + title={intl.formatMessage({ + defaultMessage: 'Tags', + id: '1EYCdR', + })} + /> + ) } diff --git a/src/views/Search/AggregateResults/styles.module.css b/src/views/Search/AggregateResults/styles.module.css index b664c825a3..2148547f0c 100644 --- a/src/views/Search/AggregateResults/styles.module.css +++ b/src/views/Search/AggregateResults/styles.module.css @@ -31,12 +31,3 @@ .result-item { padding: var(--sp16); } - -.tabs { - padding: 0 var(--sp16); - margin: var(--sp32) 0 var(--sp16); - - @media (--sm-up) { - padding: 0; - } -} diff --git a/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/index.tsx b/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/index.tsx index 4f992a359a..d508c20fa6 100644 --- a/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/index.tsx +++ b/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/index.tsx @@ -1,4 +1,6 @@ -import { HorizontalRule, SegmentedTabs, Translate } from '~/components' +import { useIntl } from 'react-intl' + +import { HorizontalRule, SquareTabs } from '~/components' import styles from './styles.module.css' @@ -10,30 +12,37 @@ interface CirclesFeedTypeProps { } const CirclesTabs = ({ type, setFeedType }: CirclesFeedTypeProps) => { + const intl = useIntl() const isFollowing = type === 'following' const isSubscribed = type === 'subscribed' return ( - <> -
- - setFeedType('following')} - selected={isFollowing} - > - - - - setFeedType('subscribed')} - selected={isSubscribed} - > - - - - -
- +
+ + setFeedType('following')} + selected={isFollowing} + title={intl.formatMessage({ + defaultMessage: 'Followed', + id: 'nVoVnb', + description: + 'src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/index.tsx', + })} + /> + + setFeedType('subscribed')} + selected={isSubscribed} + title={intl.formatMessage({ + defaultMessage: 'Subscribed', + id: 'mBmmr+', + description: + 'src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/index.tsx', + })} + /> + + +
) } diff --git a/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/styles.module.css b/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/styles.module.css index 3a7cf7d27b..3fb1b1d9eb 100644 --- a/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/styles.module.css +++ b/src/views/User/UserProfile/FollowingDialog/CirclesFeed/CirclesTabs/styles.module.css @@ -1,8 +1,5 @@ .tabs { - padding: var(--sp8) 0; - @media (--sm-up) { - padding: 0; margin: 0 var(--sp20); } } From c032103238ca2cde9087f5381337776b8853f1e7 Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:37:47 +0700 Subject: [PATCH 18/19] feat(vault): open withdraw dialog from notice --- lang/default.json | 9 ++-- lang/en.json | 9 ++-- lang/zh-Hans.json | 9 ++-- lang/zh-Hant.json | 9 ++-- src/common/enums/url.ts | 7 +++ .../WithdrawVaultUSDTDialog/Confirming.tsx | 6 +-- .../Dialogs/WithdrawVaultUSDTDialog/Intro.tsx | 10 ++--- .../Dialogs/WithdrawVaultUSDTDialog/index.tsx | 16 ++++++- .../WithdrawVaultUSDTDialog/styles.module.css | 3 -- .../WithdrewLockedTokensNotice.tsx | 44 ++++++++++++++----- 10 files changed, 84 insertions(+), 38 deletions(-) delete mode 100644 src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css diff --git a/lang/default.json b/lang/default.json index 269d0fa8c1..e16faadfdb 100644 --- a/lang/default.json +++ b/lang/default.json @@ -480,6 +480,9 @@ "6BbPcY": { "defaultMessage": "The comment has been forcibly hidden" }, + "6Bxl4S": { + "defaultMessage": "Claim {amount} USDT failed. Click here to retry or contact ask@matters.town" + }, "6CQaLH": { "defaultMessage": "Please select or enter amount" }, @@ -1291,9 +1294,6 @@ "defaultMessage": "New followers", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, - "JlpeDH": { - "defaultMessage": "The vault contract has sent {amount} USDT to the linked wallet. Click here for details." - }, "Jmg5do": { "defaultMessage": "Archived Work" }, @@ -2867,6 +2867,9 @@ "defaultMessage": "My profile", "description": "src/views/Me/Settings/Settings/MyProfile/index.tsx" }, + "n3SsO1": { + "defaultMessage": "The contract has sent {amount} to the linked wallet. Click here for details." + }, "n3shsQ": { "defaultMessage": "Invalid name", "description": "NAME_INVALID" diff --git a/lang/en.json b/lang/en.json index 68cb8c4ebd..244068e004 100644 --- a/lang/en.json +++ b/lang/en.json @@ -480,6 +480,9 @@ "6BbPcY": { "defaultMessage": "The comment has been forcibly hidden" }, + "6Bxl4S": { + "defaultMessage": "Claim {amount} USDT failed. Click here to retry or contact ask@matters.town" + }, "6CQaLH": { "defaultMessage": "Please select or enter amount" }, @@ -1291,9 +1294,6 @@ "defaultMessage": "New followers", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, - "JlpeDH": { - "defaultMessage": "The vault contract has sent {amount} USDT to the linked wallet. Click here for details." - }, "Jmg5do": { "defaultMessage": "Archived Work" }, @@ -2867,6 +2867,9 @@ "defaultMessage": "My profile", "description": "src/views/Me/Settings/Settings/MyProfile/index.tsx" }, + "n3SsO1": { + "defaultMessage": "The contract has sent {amount} to the linked wallet. Click here for details." + }, "n3shsQ": { "defaultMessage": "Invalid name", "description": "NAME_INVALID" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index fc8519a94d..deef60347a 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -480,6 +480,9 @@ "6BbPcY": { "defaultMessage": "评论已被强制隐藏" }, + "6Bxl4S": { + "defaultMessage": "提领支持金额({amount} USDT)时遇到问题,点此重试或联系 ask@matters.town" + }, "6CQaLH": { "defaultMessage": "请选择或输入金额" }, @@ -1291,9 +1294,6 @@ "defaultMessage": "被关注", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, - "JlpeDH": { - "defaultMessage": "交易合约已将金额 {amount} USDT 发送至绑定钱包,点此查看详情" - }, "Jmg5do": { "defaultMessage": "作品已归档" }, @@ -2867,6 +2867,9 @@ "defaultMessage": "个人信息", "description": "src/views/Me/Settings/Settings/MyProfile/index.tsx" }, + "n3SsO1": { + "defaultMessage": "交易合约已将金额 {amount} 发送至绑定钱包,点此查看详情" + }, "n3shsQ": { "defaultMessage": "名称不正确", "description": "NAME_INVALID" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 3be16ca816..9b496aa89f 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -480,6 +480,9 @@ "6BbPcY": { "defaultMessage": "因違反社區約章,評論已被隱藏" }, + "6Bxl4S": { + "defaultMessage": "提領支持金額({amount} USDT)時遇到問題,點此重試或聯繫 ask@matters.town" + }, "6CQaLH": { "defaultMessage": "請選擇或輸入金額" }, @@ -1291,9 +1294,6 @@ "defaultMessage": "被追蹤", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, - "JlpeDH": { - "defaultMessage": "交易合約已將金額 {amount} USDT 發送至綁定錢包,點此查看詳情" - }, "Jmg5do": { "defaultMessage": "作品已封存" }, @@ -2867,6 +2867,9 @@ "defaultMessage": "個人資料", "description": "src/views/Me/Settings/Settings/MyProfile/index.tsx" }, + "n3SsO1": { + "defaultMessage": "交易合約已將金額 {amount} 發送至綁定錢包,點此查看詳情" + }, "n3shsQ": { "defaultMessage": "名稱不正確", "description": "NAME_INVALID" diff --git a/src/common/enums/url.ts b/src/common/enums/url.ts index b5be7bb1bd..23b072b9c3 100644 --- a/src/common/enums/url.ts +++ b/src/common/enums/url.ts @@ -16,6 +16,13 @@ export const URL_ME_SETTINGS = { OPEN_SET_EMAIL_DIALOG: { key: 'dialog', value: 'set-email' }, } +export const URL_ME_WALLET = { + OPEN_WITHDRAW_VAULT_USDT_DIALOG: { + key: 'dialog', + value: 'withdraw-vault-usdt', + }, +} + export const URL_COLLECTION_DETAIL = { // ?sort=seq:asc,date:dsc SORTER_KEY: 'sort', diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx index 085c795e69..28daf94486 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Confirming.tsx @@ -12,8 +12,6 @@ import { WithdrawVaultUsdtPollingQuery, } from '~/gql/graphql' -import styles from './styles.module.css' - type ConfirmingProps = { amount: number closeDialog: () => void @@ -173,12 +171,12 @@ const Confirming: React.FC = ({ amount, closeDialog }) => { id="CcVXhc" values={{ amount: ( - + {formatAmount(amount)} USDT ), address: ( - {truncate(address)} + {truncate(address)} ), }} /> diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx index 51e983f8af..7a2fab61c9 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/Intro.tsx @@ -4,8 +4,6 @@ import { FormattedMessage } from 'react-intl' import { formatAmount, truncate } from '~/common/utils' import { Dialog, ViewerContext } from '~/components' -import styles from './styles.module.css' - type IntroProps = { amount: number switchToConnectWallet: () => void @@ -48,14 +46,12 @@ const Intro: React.FC = ({ id="hDDFgp" values={{ amount: ( - + {formatAmount(amount)} USDT ), address: ( - - {truncate(address)} - + {truncate(address)} ), }} /> @@ -65,7 +61,7 @@ const Intro: React.FC = ({ id="rAFb3E" values={{ amount: ( - + {formatAmount(amount)} USDT ), diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx index e3dbd9cf8f..d65d5179ec 100644 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx +++ b/src/components/Dialogs/WithdrawVaultUSDTDialog/index.tsx @@ -1,11 +1,13 @@ import dynamic from 'next/dynamic' +import { useEffect } from 'react' -import { OPEN_WITHDRAW_VAULT_USDT_DIALOG } from '~/common/enums' +import { OPEN_WITHDRAW_VAULT_USDT_DIALOG, URL_ME_WALLET } from '~/common/enums' import { Dialog, SpinnerBlock, useDialogSwitch, useEventListener, + useRoute, useStep, } from '~/components' @@ -33,11 +35,23 @@ const BaseWithdrawVaultUSDTDialog = () => { } export const WithdrawVaultUSDTDialog = () => { + const { getQuery } = useRoute() + const Children = ({ openDialog }: { openDialog: () => void }) => { useEventListener(OPEN_WITHDRAW_VAULT_USDT_DIALOG, openDialog) return <> } + const shouldOpenDialog = + getQuery(URL_ME_WALLET.OPEN_WITHDRAW_VAULT_USDT_DIALOG.key) === + URL_ME_WALLET.OPEN_WITHDRAW_VAULT_USDT_DIALOG.value + + useEffect(() => { + if (shouldOpenDialog) { + window.dispatchEvent(new CustomEvent(OPEN_WITHDRAW_VAULT_USDT_DIALOG)) + } + }, [shouldOpenDialog]) + return ( }> {({ openDialog }) => } diff --git a/src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css b/src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css deleted file mode 100644 index 814e82fedc..0000000000 --- a/src/components/Dialogs/WithdrawVaultUSDTDialog/styles.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.highlight { - color: var(--color-matters-green); -} diff --git a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx index 98e9fe62af..da9722d63b 100644 --- a/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx +++ b/src/components/Notice/TransactionNotice/WithdrewLockedTokensNotice.tsx @@ -1,9 +1,12 @@ import gql from 'graphql-tag' import { FormattedMessage } from 'react-intl' -import { TEST_ID } from '~/common/enums' +import { PATHS, TEST_ID, URL_ME_WALLET } from '~/common/enums' import { explorers } from '~/common/utils/wallet' -import { WithdrewLockedTokensNoticeFragment } from '~/gql/graphql' +import { + TransactionState, + WithdrewLockedTokensNoticeFragment, +} from '~/gql/graphql' import NoticeActorAvatar from '../NoticeActorAvatar' import NoticeActorName from '../NoticeActorName' @@ -17,25 +20,43 @@ const WithdrewLockedTokensNotice = ({ }) => { const tx = notice.tx const blockchainTx = tx.blockchainTx + const isFailed = + tx.state === TransactionState.Failed || + tx.state === TransactionState.Canceled + const link = isFailed + ? `${PATHS.ME_WALLET}?${URL_ME_WALLET.OPEN_WITHDRAW_VAULT_USDT_DIALOG.key}=${URL_ME_WALLET.OPEN_WITHDRAW_VAULT_USDT_DIALOG.value}` + : blockchainTx + ? `${explorers[blockchainTx.chain].url}/tx/${blockchainTx.txHash}` + : '' - if (!blockchainTx) { + if (!isFailed && !blockchainTx) { return null } - const link = `${explorers[blockchainTx.chain].url}/tx/${blockchainTx.txHash}` - return (
- - + + {isFailed ? ( + + ) : ( + {tx.amount} USDT, + }} + /> + )}
@@ -58,6 +79,7 @@ WithdrewLockedTokensNotice.fragments = { id amount currency + state blockchainTx { chain txHash From 6fbe6337d101997a8cb9f5dd89188b4bec38fa36 Mon Sep 17 00:00:00 2001 From: gitwoz <177856586+gitwoz@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:28:21 +0700 Subject: [PATCH 19/19] feat(vault): no need to close dialog if "submitCallback" is provided --- src/components/Forms/WalletAuthForm/Connect.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Forms/WalletAuthForm/Connect.tsx b/src/components/Forms/WalletAuthForm/Connect.tsx index ac5dc890a5..41f7297c4e 100644 --- a/src/components/Forms/WalletAuthForm/Connect.tsx +++ b/src/components/Forms/WalletAuthForm/Connect.tsx @@ -255,9 +255,7 @@ const Connect: React.FC = ({ if (submitCallback) { submitCallback() - } - - if (closeDialog) { + } else if (closeDialog) { closeDialog() } }