From 468968c3d36f4cdb1e040960d58a569429f5a9cf Mon Sep 17 00:00:00 2001 From: Aka jazzy Date: Fri, 18 Nov 2022 11:04:36 +0800 Subject: [PATCH 01/25] fix(me-setting): add setting into me-setting --- src/pages/me/settings/index.tsx | 8 ++------ src/pages/settings.tsx | 6 ++++-- src/views/Me/Settings/Settings/index.tsx | 19 ++++++++++++++++++- .../SwitchLanguage/index.tsx | 0 .../DisplayPreferences/index.tsx | 0 .../ViewerSettings}/Enhance/index.tsx | 0 .../Settings/ViewerSettings}/Learn/index.tsx | 0 .../Settings/ViewerSettings}/index.tsx | 0 .../Settings/ViewerSettings}/styles.css | 0 9 files changed, 24 insertions(+), 9 deletions(-) rename src/views/{Settings => Me/Settings/ViewerSettings}/DisplayPreferences/SwitchLanguage/index.tsx (100%) rename src/views/{Settings => Me/Settings/ViewerSettings}/DisplayPreferences/index.tsx (100%) rename src/views/{Settings => Me/Settings/ViewerSettings}/Enhance/index.tsx (100%) rename src/views/{Settings => Me/Settings/ViewerSettings}/Learn/index.tsx (100%) rename src/views/{Settings => Me/Settings/ViewerSettings}/index.tsx (100%) rename src/views/{Settings => Me/Settings/ViewerSettings}/styles.css (100%) diff --git a/src/pages/me/settings/index.tsx b/src/pages/me/settings/index.tsx index 4c6e3d7ac5..82550e9432 100644 --- a/src/pages/me/settings/index.tsx +++ b/src/pages/me/settings/index.tsx @@ -1,11 +1,7 @@ import MeSettings from '~/views/Me/Settings/Settings' -import { Protected } from '~/components' +// import { Protected } from '~/components' -const ProtectedMeSettings = () => ( - - - -) +const ProtectedMeSettings = () => export default ProtectedMeSettings diff --git a/src/pages/settings.tsx b/src/pages/settings.tsx index ca991702c5..fdb69489ac 100644 --- a/src/pages/settings.tsx +++ b/src/pages/settings.tsx @@ -1,3 +1,5 @@ -import Settings from '~/views/Settings' +// import Settings from '~/views/Me/Settings/ViewerSettings' -export default Settings +import MeSettings from '~/views/Me/Settings/Settings' + +export default MeSettings diff --git a/src/views/Me/Settings/Settings/index.tsx b/src/views/Me/Settings/Settings/index.tsx index 7e9d8b1e8f..721997415e 100644 --- a/src/views/Me/Settings/Settings/index.tsx +++ b/src/views/Me/Settings/Settings/index.tsx @@ -1,10 +1,27 @@ -import { Head, Layout, PullToRefresh, Spacer } from '~/components' +import React, { useContext } from 'react' +import { + Head, + Layout, + PullToRefresh, + Spacer, + ViewerContext, +} from '~/components' + +// import { redirectToLogin } from '~/common/utils' + +import ViewerSetting from '../ViewerSettings' import AccountSettings from './Account' import UISettings from './UI' import WalletSettings from './Wallet' const Settings = () => { + const viewer = useContext(ViewerContext) + + if (viewer.privateFetched && !viewer.isAuthed) { + return + } + return ( Date: Mon, 14 Nov 2022 15:24:28 +0800 Subject: [PATCH 02/25] feat(Setting): add currency converter preference --- src/common/enums/payment.ts | 6 + src/components/Context/Viewer/index.tsx | 3 + .../Settings/UI/CurrencyConvertor/index.tsx | 139 ++++++++++++++++++ src/views/Me/Settings/Settings/UI/index.tsx | 2 + 4 files changed, 150 insertions(+) create mode 100644 src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx diff --git a/src/common/enums/payment.ts b/src/common/enums/payment.ts index 5bf34b4376..ee3fef1a40 100644 --- a/src/common/enums/payment.ts +++ b/src/common/enums/payment.ts @@ -32,6 +32,12 @@ export enum PAYMENT_CURRENCY { USDT = 'USDT', } +export enum QUOTE_CURRENCY { + TWD = 'TWD', + HKD = 'HKD', + USD = 'USD', +} + export enum CHAIN { POLYGON = 'Polygon', } diff --git a/src/components/Context/Viewer/index.tsx b/src/components/Context/Viewer/index.tsx index b1cf1a9d80..9abab33c20 100644 --- a/src/components/Context/Viewer/index.tsx +++ b/src/components/Context/Viewer/index.tsx @@ -69,6 +69,9 @@ const ViewerFragments = { articles(input: { first: 0 }) { totalCount } + settings { + currency + } } `, }, diff --git a/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx b/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx new file mode 100644 index 0000000000..ed8d58c11d --- /dev/null +++ b/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx @@ -0,0 +1,139 @@ +import gql from 'graphql-tag' +import { useContext } from 'react' + +import { + DropdownDialog, + Form, + Menu, + TextIcon, + Translate, + useMutation, + ViewerContext, +} from '~/components' + +import { ADD_TOAST } from '~/common/enums' + +import { QuoteCurrency } from '@/__generated__/globalTypes' +import { SetCurrency } from './__generated__/SetCurrency' + +const SET_CURRENCY = gql` + mutation SetCurrency($input: SetCurrencyInput!) { + setCurrency(input: $input) { + id + settings { + currency + } + } + } +` + +const CurrencyConvertor = () => { + const viewer = useContext(ViewerContext) + const currency = viewer.settings.currency + const [setCurrency] = useMutation(SET_CURRENCY) + + const updateCurrency = async (c: QuoteCurrency) => { + if (!viewer.isAuthed) { + return + } + + try { + await setCurrency({ + variables: { input: { currency: c } }, + optimisticResponse: { + setCurrency: { + id: viewer.id, + settings: { + currency, + __typename: 'UserSettings', + }, + __typename: 'User', + }, + }, + }) + } catch (e) { + window.dispatchEvent( + new CustomEvent(ADD_TOAST, { + detail: { + color: 'red', + content: , + }, + }) + ) + } + } + + const isUSDActive = currency === QuoteCurrency.USD + const isHKDActive = currency === QuoteCurrency.HKD + const isTWDActive = currency === QuoteCurrency.TWD + + const Content = ({ isInDropdown }: { isInDropdown?: boolean }) => ( + + updateCurrency(QuoteCurrency.USD)}> + + {QuoteCurrency.USD} + + + updateCurrency(QuoteCurrency.HKD)}> + + {QuoteCurrency.HKD} + + + updateCurrency(QuoteCurrency.TWD)}> + + {QuoteCurrency.TWD} + + + + ) + + return ( + , + placement: 'bottom-end', + }} + dialog={{ + content: , + // TODO: comfirm title with PM + title: ( + + ), + }} + > + {({ openDialog, ref }) => ( + + } + onClick={openDialog} + rightText={currency} + ref={ref} + /> + )} + + ) +} + +export default CurrencyConvertor diff --git a/src/views/Me/Settings/Settings/UI/index.tsx b/src/views/Me/Settings/Settings/UI/index.tsx index 2ef4bf9bcc..2535df36d6 100644 --- a/src/views/Me/Settings/Settings/UI/index.tsx +++ b/src/views/Me/Settings/Settings/UI/index.tsx @@ -1,11 +1,13 @@ import { Form, Translate } from '~/components' +import CurrencyConvertor from './CurrencyConvertor' import SwitchLanguage from './SwitchLanguage' const UISettings = () => { return ( }> + ) } From 64c841795025faa41362412192d9f2eb9eddc87d Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 14 Nov 2022 15:44:47 +0800 Subject: [PATCH 03/25] feat(Setting): update copy --- .../Settings/UI/CurrencyConvertor/index.tsx | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx b/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx index ed8d58c11d..dac9e7cd5d 100644 --- a/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx +++ b/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx @@ -107,25 +107,15 @@ const CurrencyConvertor = () => { }} dialog={{ content: , - // TODO: comfirm title with PM title: ( - + ), }} > {({ openDialog, ref }) => ( + } onClick={openDialog} rightText={currency} From 4956a441ffa22f5380096a3c5f2bb53b23204634 Mon Sep 17 00:00:00 2001 From: Aka jazzy Date: Fri, 18 Nov 2022 11:54:52 +0800 Subject: [PATCH 04/25] fix(me-setting): add setting route into me/setting --- src/common/enums/route.ts | 2 +- src/pages/me/settings/index.tsx | 3 --- src/pages/settings.tsx | 5 ----- 3 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 src/pages/settings.tsx diff --git a/src/common/enums/route.ts b/src/common/enums/route.ts index e76ac89482..95ba1197c1 100644 --- a/src/common/enums/route.ts +++ b/src/common/enums/route.ts @@ -83,7 +83,7 @@ export const ROUTES: { { key: 'FOLLOW', pathname: '/follow' }, { key: 'AUTHORS', pathname: '/authors' }, { key: 'SEARCH', pathname: '/search' }, - { key: 'SETTINGS', pathname: '/settings' }, + { key: 'SETTINGS', pathname: '/me/settings' }, // experient page for recommendation engine testing { key: 'RECOMMENDATION', pathname: '/recommendation' }, diff --git a/src/pages/me/settings/index.tsx b/src/pages/me/settings/index.tsx index 82550e9432..b3e0d9e168 100644 --- a/src/pages/me/settings/index.tsx +++ b/src/pages/me/settings/index.tsx @@ -1,7 +1,4 @@ import MeSettings from '~/views/Me/Settings/Settings' - -// import { Protected } from '~/components' - const ProtectedMeSettings = () => export default ProtectedMeSettings diff --git a/src/pages/settings.tsx b/src/pages/settings.tsx deleted file mode 100644 index fdb69489ac..0000000000 --- a/src/pages/settings.tsx +++ /dev/null @@ -1,5 +0,0 @@ -// import Settings from '~/views/Me/Settings/ViewerSettings' - -import MeSettings from '~/views/Me/Settings/Settings' - -export default MeSettings From d6639569b779acd97470326a87c9ff8ea9a53e9f Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 18 Nov 2022 13:07:07 +0800 Subject: [PATCH 05/25] fix(Settings): use same title copy --- .../Settings/Settings/UI/CurrencyConvertor/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx b/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx index dac9e7cd5d..1055407fef 100644 --- a/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx +++ b/src/views/Me/Settings/Settings/UI/CurrencyConvertor/index.tsx @@ -99,6 +99,10 @@ const CurrencyConvertor = () => { ) + const Title = () => { + return + } + return ( { }} dialog={{ content: , - title: ( - - ), + title: , }} > {({ openDialog, ref }) => ( <Form.List.Item - title={ - <Translate zh_hant="匯率幣別" zh_hans="汇率币别" en="Currency" /> - } + title={<Title />} onClick={openDialog} rightText={currency} ref={ref} From 6258b468836ed7f5c2ad118b453305b67c8cfa3e Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Tue, 15 Nov 2022 15:59:08 +0800 Subject: [PATCH 06/25] feat(exchangeRate): add ExchangeRates GQL query --- src/components/GQL/queries/exchangeRates.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/components/GQL/queries/exchangeRates.ts diff --git a/src/components/GQL/queries/exchangeRates.ts b/src/components/GQL/queries/exchangeRates.ts new file mode 100644 index 0000000000..c3d8abdbc1 --- /dev/null +++ b/src/components/GQL/queries/exchangeRates.ts @@ -0,0 +1,12 @@ +import gql from 'graphql-tag' + +export default gql` + query ExchangeRates($from: TransactionCurrency, $to: QuoteCurrency) { + exchangeRates(input: { from: $from, to: $to }) { + from + to + rate + updatedAt + } + } +` From 37ef4533ee4f6e4e97b9f54993157527422504d1 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:32:16 +0800 Subject: [PATCH 07/25] feat(CurrencyFormatter): add currency symbol --- src/components/CurrencyFormatter/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/CurrencyFormatter/index.tsx b/src/components/CurrencyFormatter/index.tsx index 3a482dc1f3..540fb7fc0c 100644 --- a/src/components/CurrencyFormatter/index.tsx +++ b/src/components/CurrencyFormatter/index.tsx @@ -20,7 +20,7 @@ export const CurrencyFormatter: React.FC<Props> = ({ </span> {subCurrency && ( <span className="subCurrency"> - ≈ {subCurrency} {subValue} + ≈ {subCurrency} $ {subValue} </span> )} <style jsx>{styles}</style> From 6c7e38d095f6e1205569a4936b1dbb27a0da53f6 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:36:48 +0800 Subject: [PATCH 08/25] feat(Donation): add currency conversion in <CurrencyChoice> --- .../PayTo/CurrencyChoice/LikeCoinChoice.tsx | 12 ++++- .../PayTo/CurrencyChoice/USDTChoice.tsx | 9 +++- .../PayTo/CurrencyChoice/index.tsx | 47 +++++++++++++++++-- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx index ade159c4fe..ae88d32c24 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx @@ -14,11 +14,14 @@ import { formatAmount } from '~/common/utils' import styles from './styles.css' +import { QuoteCurrency } from '@/__generated__/globalTypes' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' type LikeCoinChoiceProps = { balance: number recipient: UserDonationRecipient + currency: QuoteCurrency + exchangeRate: number switchToSetAmount: () => void } @@ -36,6 +39,8 @@ const IconLikeDisabled = () => ( const LikeCoinChoice: React.FC<LikeCoinChoiceProps> = ({ balance, recipient, + currency, + exchangeRate, switchToSetAmount, }) => { const viewer = useContext(ViewerContext) @@ -100,7 +105,12 @@ const LikeCoinChoice: React.FC<LikeCoinChoiceProps> = ({ LikeCoin </TextIcon> - <CurrencyFormatter value={formatAmount(balance, 0)} currency="LIKE" /> + <CurrencyFormatter + value={formatAmount(balance, 0)} + currency="LIKE" + subValue={formatAmount(balance * exchangeRate, 4)} + subCurrency={currency} + /> <style jsx>{styles}</style> </section> diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx index 89ccc4b515..c5e960a2d9 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx @@ -18,12 +18,15 @@ import { formatAmount } from '~/common/utils' import styles from './styles.css' +import { QuoteCurrency } from '@/__generated__/globalTypes' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface FormProps { article: ArticleDetailPublic_article recipient: UserDonationRecipient + currency: QuoteCurrency + exchangeRate: number switchToSetAmount: () => void switchToWalletSelect: () => void } @@ -31,6 +34,8 @@ interface FormProps { const USDTChoice: React.FC<FormProps> = ({ article, recipient, + currency, + exchangeRate, switchToSetAmount, switchToWalletSelect, }) => { @@ -111,8 +116,10 @@ const USDTChoice: React.FC<FormProps> = ({ <IconSpinner16 color="grey" size="sm" /> ) : ( <CurrencyFormatter - value={formatAmount(balanceUSDT)} currency={CURRENCY.USDT} + value={formatAmount(balanceUSDT)} + subCurrency={currency} + subValue={formatAmount(balanceUSDT * exchangeRate, 4)} /> )} diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx index 0457fbaa6f..60e970ddb3 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx @@ -1,5 +1,7 @@ import { useQuery } from '@apollo/react-hooks' -import _pickBy from 'lodash/pickBy' +import _find from 'lodash/find' +import _matchesProperty from 'lodash/matchesProperty' +import { useContext } from 'react' import { CurrencyFormatter, @@ -9,7 +11,9 @@ import { TextIcon, Translate, UserDigest, + ViewerContext, } from '~/components' +import EXCHANGE_RATES from '~/components/GQL/queries/exchangeRates' import WALLET_BALANCE from '~/components/GQL/queries/walletBalance' import { PAYMENT_CURRENCY as CURRENCY } from '~/common/enums' @@ -21,6 +25,7 @@ import Tips from './Tips' import USDTChoice from './USDTChoice' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' +import { ExchangeRates } from '~/components/GQL/queries/__generated__/ExchangeRates' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' @@ -37,11 +42,36 @@ const CurrencyChoice: React.FC<FormProps> = ({ switchToSetAmount, switchToWalletSelect, }) => { - // HKD balance + const viewer = useContext(ViewerContext) + const currency = viewer.settings.currency + + const { data: exchangeRateDate, loading: exchangeRateLoading } = + useQuery<ExchangeRates>(EXCHANGE_RATES, { + variables: { + to: currency, + }, + }) + + // HKD、Like balance const { data, loading } = useQuery<WalletBalance>(WALLET_BALANCE, { fetchPolicy: 'network-only', }) + const exchangeRateUSDT = _find( + exchangeRateDate?.exchangeRates, + _matchesProperty('from', CURRENCY.USDT) + ) + + const exchangeRateHKD = _find( + exchangeRateDate?.exchangeRates, + _matchesProperty('from', CURRENCY.HKD) + ) + + const exchangeRateLIKE = _find( + exchangeRateDate?.exchangeRates, + _matchesProperty('from', CURRENCY.LIKE) + ) + const balanceHKD = data?.viewer?.wallet.balance.HKD || 0 const balanceLike = data?.viewer?.liker.total || 0 @@ -72,6 +102,8 @@ const CurrencyChoice: React.FC<FormProps> = ({ <USDTChoice article={article} recipient={recipient} + currency={currency} + exchangeRate={exchangeRateUSDT?.rate || 0} switchToSetAmount={() => switchToSetAmount(CURRENCY.USDT)} switchToWalletSelect={switchToWalletSelect} /> @@ -91,13 +123,20 @@ const CurrencyChoice: React.FC<FormProps> = ({ > <Translate zh_hant="法幣" zh_hans="法币" en="Fiat Currency" /> </TextIcon> - <CurrencyFormatter value={formatAmount(balanceHKD)} currency="HKD" /> + <CurrencyFormatter + value={formatAmount(balanceHKD)} + currency={CURRENCY.HKD} + subCurrency={currency} + subValue={formatAmount(balanceHKD * (exchangeRateHKD?.rate || 0), 4)} + /> </section> {/* LikeCoin */} <LikeCoinChoice balance={balanceLike} recipient={recipient} + currency={currency} + exchangeRate={exchangeRateLIKE?.rate || 0} switchToSetAmount={() => switchToSetAmount(CURRENCY.LIKE)} /> @@ -107,7 +146,7 @@ const CurrencyChoice: React.FC<FormProps> = ({ </section> ) - if (loading) { + if (exchangeRateLoading || loading) { return <Spinner /> } From f05f473dccddd970ee11b460265e5bcf10bcb2e3 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 16 Nov 2022 17:01:22 +0800 Subject: [PATCH 09/25] feat(CurrencyChoice): revise converted value --- .../Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx | 2 +- .../Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx | 2 +- src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx index ae88d32c24..8c89f5824c 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/LikeCoinChoice.tsx @@ -108,7 +108,7 @@ const LikeCoinChoice: React.FC<LikeCoinChoiceProps> = ({ <CurrencyFormatter value={formatAmount(balance, 0)} currency="LIKE" - subValue={formatAmount(balance * exchangeRate, 4)} + subValue={formatAmount(balance * exchangeRate, 2)} subCurrency={currency} /> diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx index c5e960a2d9..dcadd001a6 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx @@ -119,7 +119,7 @@ const USDTChoice: React.FC<FormProps> = ({ currency={CURRENCY.USDT} value={formatAmount(balanceUSDT)} subCurrency={currency} - subValue={formatAmount(balanceUSDT * exchangeRate, 4)} + subValue={formatAmount(balanceUSDT * exchangeRate, 2)} /> )} diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx index 60e970ddb3..e39be71906 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx @@ -127,7 +127,7 @@ const CurrencyChoice: React.FC<FormProps> = ({ value={formatAmount(balanceHKD)} currency={CURRENCY.HKD} subCurrency={currency} - subValue={formatAmount(balanceHKD * (exchangeRateHKD?.rate || 0), 4)} + subValue={formatAmount(balanceHKD * (exchangeRateHKD?.rate || 0), 2)} /> </section> From 4461ad4736ac64909bce999bea11b97b52c30e37 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 16 Nov 2022 17:10:54 +0800 Subject: [PATCH 10/25] feat(Donation): add currency conversion in <SetAmount> --- .../PaymentForm/PayTo/SetAmount/index.tsx | 55 ++++++++++++++++--- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index 46c2527c86..00819fc2fa 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -1,6 +1,7 @@ import { useQuery } from '@apollo/react-hooks' import { BigNumber } from 'ethers' import { useFormik } from 'formik' +import _get from 'lodash/get' import _pickBy from 'lodash/pickBy' import { useContext, useEffect, useRef, useState } from 'react' import { useAccount, useNetwork, useSwitchNetwork } from 'wagmi' @@ -9,6 +10,7 @@ import { Dialog, Form, LanguageContext, + Spacer, Spinner, Translate, useAllowanceUSDT, @@ -18,6 +20,7 @@ import { ViewerContext, } from '~/components' import PAY_TO from '~/components/GQL/mutations/payTo' +import EXCHANGE_RATES from '~/components/GQL/queries/exchangeRates' import WALLET_BALANCE from '~/components/GQL/queries/walletBalance' import updateDonation from '~/components/GQL/updates/donation' @@ -26,6 +29,7 @@ import { PAYMENT_MAXIMUM_PAYTO_AMOUNT, } from '~/common/enums' import { + formatAmount, numRound, validateCurrency, validateDonationAmount, @@ -37,6 +41,7 @@ import ReconnectButton from './ReconnectButton' import SetAmountBalance from './SetAmountBalance' import SetAmountHeader from './SetAmountHeader' +import { ExchangeRates } from '@/src/components/GQL/queries/__generated__/ExchangeRates' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' import { PayTo as PayToMutate, @@ -98,6 +103,7 @@ const SetAmount: React.FC<FormProps> = ({ // contexts const viewer = useContext(ViewerContext) + const quoteCurrency = viewer.settings.currency const { lang } = useContext(LanguageContext) const { address } = useAccount() const { chain } = useNetwork() @@ -117,6 +123,14 @@ const SetAmount: React.FC<FormProps> = ({ // states const [payTo] = useMutation<PayToMutate>(PAY_TO) + const { data: exchangeRateDate, loading: exchangeRateLoading } = + useQuery<ExchangeRates>(EXCHANGE_RATES, { + variables: { + from: currency, + to: quoteCurrency, + }, + }) + // HKD balance const { data, loading, error } = useQuery<WalletBalance>(WALLET_BALANCE, { fetchPolicy: 'network-only', @@ -207,6 +221,37 @@ const SetAmount: React.FC<FormProps> = ({ const isBalanceInsufficient = balance < (values.customAmount || values.amount) + const ComposedAmountInputHint = () => { + const hkdHint = isHKD ? ( + <section> + <Spacer /> + <Translate + zh_hant="付款將由 Stripe 處理,讓你的支持不受地域限制" + zh_hans="付款将由 Stripe 处理,让你的支持不受地域限制" + en="Stripe will process your payment, so you can support the author wherever you are." + /> + </section> + ) : null + + const value = values.customAmount || values.amount + + if (value === 0) { + return hkdHint + } + + const rate = _get(exchangeRateDate, 'exchangeRates.0.rate', 0) + const convertedTotal = formatAmount(value * rate, 2) + + return ( + <section> + <p> + ≈ {quoteCurrency} $ {convertedTotal} + </p> + {hkdHint} + </section> + ) + } + /** * useEffect Hooks */ @@ -304,20 +349,14 @@ const SetAmount: React.FC<FormProps> = ({ } }, error: errors.amount, - hint: isHKD ? ( - <Translate - zh_hant="付款將由 Stripe 處理,讓你的支持不受地域限制" - zh_hans="付款将由 Stripe 处理,让你的支持不受地域限制" - en="Stripe will process your payment, so you can support the author wherever you are." - /> - ) : null, + hint: <ComposedAmountInputHint />, ref: customInputRef, }} /> </Form> ) - if (loading) { + if (exchangeRateLoading || loading) { return <Spinner /> } From f7cd399bc7737a48275fc7a6e6d47bd6ee8fe930 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 17 Nov 2022 16:49:00 +0800 Subject: [PATCH 11/25] feat(Donation): use ~ replace @ in <SetAmount> --- .../PaymentForm/PayTo/SetAmount/index.tsx | 2 +- src/views/Me/Wallet/Balance/FiatCurrency.tsx | 8 ++++++++ src/views/Me/Wallet/Balance/LikeCoin.tsx | 18 ++++++++++++++++-- src/views/Me/Wallet/Balance/USDT.tsx | 16 ++++++++++++++-- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index 00819fc2fa..3af5301095 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -41,12 +41,12 @@ import ReconnectButton from './ReconnectButton' import SetAmountBalance from './SetAmountBalance' import SetAmountHeader from './SetAmountHeader' -import { ExchangeRates } from '@/src/components/GQL/queries/__generated__/ExchangeRates' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' import { PayTo as PayToMutate, PayTo_payTo_transaction as PayToTx, } from '~/components/GQL/mutations/__generated__/PayTo' +import { ExchangeRates } from '~/components/GQL/queries/__generated__/ExchangeRates' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' diff --git a/src/views/Me/Wallet/Balance/FiatCurrency.tsx b/src/views/Me/Wallet/Balance/FiatCurrency.tsx index 7716478228..d075a4b0eb 100644 --- a/src/views/Me/Wallet/Balance/FiatCurrency.tsx +++ b/src/views/Me/Wallet/Balance/FiatCurrency.tsx @@ -16,10 +16,14 @@ import { analytics, formatAmount } from '~/common/utils' import styles from './styles.css' +import { QuoteCurrency } from '@/__generated__/globalTypes' + interface FiatCurrencyProps { balanceHKD: number canPayout: boolean hasStripeAccount: boolean + currency: QuoteCurrency + exchangeRate: number } interface ItemProps { @@ -85,6 +89,8 @@ export const FiatCurrencyBalance: React.FC<FiatCurrencyProps> = ({ balanceHKD, canPayout, hasStripeAccount, + currency, + exchangeRate, }) => { const Content = ({ isInDropdown, @@ -152,6 +158,8 @@ export const FiatCurrencyBalance: React.FC<FiatCurrencyProps> = ({ <CurrencyFormatter value={formatAmount(balanceHKD)} currency="HKD" + subCurrency={currency} + subValue={formatAmount(balanceHKD * exchangeRate, 2)} /> </TextIcon> <style jsx>{styles}</style> diff --git a/src/views/Me/Wallet/Balance/LikeCoin.tsx b/src/views/Me/Wallet/Balance/LikeCoin.tsx index 21e2ad7239..3fe5e24659 100644 --- a/src/views/Me/Wallet/Balance/LikeCoin.tsx +++ b/src/views/Me/Wallet/Balance/LikeCoin.tsx @@ -18,8 +18,14 @@ import { formatAmount } from '~/common/utils' import styles from './styles.css' +import { QuoteCurrency } from '@/__generated__/globalTypes' import { ViewerLikeBalance } from './__generated__/ViewerLikeBalance' +interface LikeCoinBalanceProps { + currency: QuoteCurrency + exchangeRate: number +} + const VIEWER_LIKE_BALANCE = gql` query ViewerLikeBalance { viewer { @@ -44,7 +50,10 @@ const Wrapper: React.FC = ({ children }) => ( </section> ) -export const LikeCoinBalance = () => { +export const LikeCoinBalance = ({ + currency, + exchangeRate, +}: LikeCoinBalanceProps) => { const viewer = useContext(ViewerContext) const likerId = viewer.liker.likerId @@ -94,7 +103,12 @@ export const LikeCoinBalance = () => { if (likerId) { return ( <Wrapper> - <CurrencyFormatter value={formatAmount(total, 0)} currency="LIKE" /> + <CurrencyFormatter + value={formatAmount(total, 0)} + currency="LIKE" + subValue={formatAmount(total * exchangeRate, 2)} + subCurrency={currency} + /> </Wrapper> ) } diff --git a/src/views/Me/Wallet/Balance/USDT.tsx b/src/views/Me/Wallet/Balance/USDT.tsx index ea97282dbd..69e0ad791c 100644 --- a/src/views/Me/Wallet/Balance/USDT.tsx +++ b/src/views/Me/Wallet/Balance/USDT.tsx @@ -15,7 +15,14 @@ import { formatAmount } from '~/common/utils' import styles from './styles.css' -export const USDTBalance = () => { +import { QuoteCurrency } from '@/__generated__/globalTypes' + +interface USDTBalanceProps { + currency: QuoteCurrency + exchangeRate: number +} + +export const USDTBalance = ({ currency, exchangeRate }: USDTBalanceProps) => { const viewer = useContext(ViewerContext) const address = viewer.info.ethAddress const { data: balanceUSDTData } = useBalanceUSDT({}) @@ -58,7 +65,12 @@ export const USDTBalance = () => { <Translate zh_hant="USDT" zh_hans="USDT" en="USDT" /> </TextIcon> - <CurrencyFormatter value={formatAmount(balanceUSDT)} currency="USDT" /> + <CurrencyFormatter + value={formatAmount(balanceUSDT)} + currency="USDT" + subCurrency={currency} + subValue={formatAmount(balanceUSDT * exchangeRate, 2)} + /> <style jsx>{styles}</style> </section> From 19e4f5cf11c8f3467f1f4e8023a09989e55b22f1 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 17 Nov 2022 21:08:21 +0800 Subject: [PATCH 12/25] feat(Wallet): add currency conversion --- src/views/Me/Wallet/index.tsx | 47 ++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/views/Me/Wallet/index.tsx b/src/views/Me/Wallet/index.tsx index 9efd597c54..14d7fe3703 100644 --- a/src/views/Me/Wallet/index.tsx +++ b/src/views/Me/Wallet/index.tsx @@ -1,4 +1,6 @@ import { useQuery } from '@apollo/react-hooks' +import _find from 'lodash/find' +import _matchesProperty from 'lodash/matchesProperty' import { useContext } from 'react' import { @@ -9,9 +11,13 @@ import { Spinner, ViewerContext, } from '~/components' +import EXCHANGE_RATES from '~/components/GQL/queries/exchangeRates' import WALLET_BALANCE from '~/components/GQL/queries/walletBalance' -import { PAYMENT_MINIMAL_PAYOUT_AMOUNT } from '~/common/enums' +import { + PAYMENT_CURRENCY as CURRENCY, + PAYMENT_MINIMAL_PAYOUT_AMOUNT, +} from '~/common/enums' import { FiatCurrencyBalance, LikeCoinBalance, USDTBalance } from './Balance' import PaymentPassword from './PaymentPassword' @@ -21,11 +27,36 @@ import TotalAssets from './TotalAssets' import ViewStripeAccount from './ViewStripeAccount' import ViewStripeCustomerPortal from './ViewStripeCustomerPortal' +import { ExchangeRates } from '~/components/GQL/queries/__generated__/ExchangeRates' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' const Wallet = () => { const viewer = useContext(ViewerContext) + const currency = viewer.settings.currency + + const { data: exchangeRateDate, loading: exchangeRateLoading } = + useQuery<ExchangeRates>(EXCHANGE_RATES, { + variables: { + to: currency, + }, + }) + + const exchangeRateUSDT = _find( + exchangeRateDate?.exchangeRates, + _matchesProperty('from', CURRENCY.USDT) + ) + + const exchangeRateHKD = _find( + exchangeRateDate?.exchangeRates, + _matchesProperty('from', CURRENCY.HKD) + ) + + const exchangeRateLIKE = _find( + exchangeRateDate?.exchangeRates, + _matchesProperty('from', CURRENCY.LIKE) + ) + const { data, loading, refetch } = useQuery<WalletBalance>(WALLET_BALANCE, { fetchPolicy: 'network-only', errorPolicy: 'none', @@ -36,7 +67,7 @@ const Wallet = () => { const hasStripeAccount = !!data?.viewer?.wallet.stripeAccount?.id const hasPaymentPassword = viewer.status?.hasPaymentPassword - if (loading) { + if (exchangeRateLoading || loading) { return ( <Layout.Main> <Layout.Header @@ -65,9 +96,17 @@ const Wallet = () => { balanceHKD={balanceHKD} canPayout={canPayout} hasStripeAccount={hasStripeAccount} + currency={currency} + exchangeRate={exchangeRateHKD?.rate || 0} + /> + <LikeCoinBalance + currency={currency} + exchangeRate={exchangeRateLIKE?.rate || 0} + /> + <USDTBalance + currency={currency} + exchangeRate={exchangeRateUSDT?.rate || 0} /> - <LikeCoinBalance /> - <USDTBalance /> </section> <Form.List> From 946ba0ff63cd1b15b1c961a78bea89f0ece41bb2 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 18 Nov 2022 16:42:52 +0800 Subject: [PATCH 13/25] feat(Settings): add exchange rate hint --- src/views/Me/Settings/Settings/UI/index.tsx | 13 ++++++++++++- src/views/Me/Settings/Settings/UI/styles.css | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/views/Me/Settings/Settings/UI/styles.css diff --git a/src/views/Me/Settings/Settings/UI/index.tsx b/src/views/Me/Settings/Settings/UI/index.tsx index 2535df36d6..12aaef0992 100644 --- a/src/views/Me/Settings/Settings/UI/index.tsx +++ b/src/views/Me/Settings/Settings/UI/index.tsx @@ -1,6 +1,7 @@ -import { Form, Translate } from '~/components' +import { Form, IconInfo16, TextIcon, Translate } from '~/components' import CurrencyConvertor from './CurrencyConvertor' +import styles from './styles.css' import SwitchLanguage from './SwitchLanguage' const UISettings = () => { @@ -8,6 +9,16 @@ const UISettings = () => { <Form.List groupName={<Translate id="settingsUI" />}> <SwitchLanguage /> <CurrencyConvertor /> + <section className="rate-hint"> + <TextIcon icon={<IconInfo16 size="xs" />} color="grey" size="xs"> + <Translate + zh_hans="加密货币汇率由 CoinGecko 提供" + zh_hant="加密貨幣匯率由 CoinGecko 提供" + en="Crypto rates provided by CoinGecko" + /> + </TextIcon> + </section> + <style jsx>{styles}</style> </Form.List> ) } diff --git a/src/views/Me/Settings/Settings/UI/styles.css b/src/views/Me/Settings/Settings/UI/styles.css new file mode 100644 index 0000000000..a11011e28c --- /dev/null +++ b/src/views/Me/Settings/Settings/UI/styles.css @@ -0,0 +1,5 @@ +.rate-hint { + @mixin flex-center-end; + + padding: var(--spacing-x-tight) var(--spacing-x-tight) 0; +} From 278caf85e293919fc05d9b3934caa83445a57cdc Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 18 Nov 2022 18:50:35 +0800 Subject: [PATCH 14/25] feat(CurrencyConversion): remove currency symbol --- src/components/CurrencyFormatter/index.tsx | 2 +- src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/CurrencyFormatter/index.tsx b/src/components/CurrencyFormatter/index.tsx index 540fb7fc0c..3a482dc1f3 100644 --- a/src/components/CurrencyFormatter/index.tsx +++ b/src/components/CurrencyFormatter/index.tsx @@ -20,7 +20,7 @@ export const CurrencyFormatter: React.FC<Props> = ({ </span> {subCurrency && ( <span className="subCurrency"> - ≈ {subCurrency} $ {subValue} + ≈ {subCurrency} {subValue} </span> )} <style jsx>{styles}</style> diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index 3af5301095..754cac47eb 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -245,7 +245,7 @@ const SetAmount: React.FC<FormProps> = ({ return ( <section> <p> - ≈ {quoteCurrency} $ {convertedTotal} + ≈ {quoteCurrency} {convertedTotal} </p> {hkdHint} </section> From c44b35930173764a67fdbec9d786dd5da076d734 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 18 Nov 2022 18:52:11 +0800 Subject: [PATCH 15/25] feat(CurrencyFormatter): revise space style --- src/components/CurrencyFormatter/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/CurrencyFormatter/styles.css b/src/components/CurrencyFormatter/styles.css index beeab5457b..1a8bced246 100644 --- a/src/components/CurrencyFormatter/styles.css +++ b/src/components/CurrencyFormatter/styles.css @@ -10,6 +10,7 @@ } & .subCurrency { + padding-top: var(--spacing-x-tight); font-size: var(--font-size-xs); color: var(--color-grey); } From c6053a78e7339592ba4f95b29f2fea4385c28159 Mon Sep 17 00:00:00 2001 From: Aka jazzy <mingchenliang954@gmail.com> Date: Mon, 21 Nov 2022 20:24:53 +0800 Subject: [PATCH 16/25] fix(me-setting): remove /setting route --- src/common/enums/route.ts | 2 -- src/components/Layout/NavBar/index.tsx | 2 +- src/components/Layout/SideNav/index.tsx | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/common/enums/route.ts b/src/common/enums/route.ts index 95ba1197c1..faabbef613 100644 --- a/src/common/enums/route.ts +++ b/src/common/enums/route.ts @@ -83,8 +83,6 @@ export const ROUTES: { { key: 'FOLLOW', pathname: '/follow' }, { key: 'AUTHORS', pathname: '/authors' }, { key: 'SEARCH', pathname: '/search' }, - { key: 'SETTINGS', pathname: '/me/settings' }, - // experient page for recommendation engine testing { key: 'RECOMMENDATION', pathname: '/recommendation' }, diff --git a/src/components/Layout/NavBar/index.tsx b/src/components/Layout/NavBar/index.tsx index c6276400ea..1262797bac 100644 --- a/src/components/Layout/NavBar/index.tsx +++ b/src/components/Layout/NavBar/index.tsx @@ -79,7 +79,7 @@ const NavBar = () => { icon={<IconNavSettings24 size="md" />} activeIcon={<IconNavSettings24 size="md" color="green" />} active={isInSettings} - href={PATHS.SETTINGS} + href={PATHS.ME_SETTINGS} /> )} </ul> diff --git a/src/components/Layout/SideNav/index.tsx b/src/components/Layout/SideNav/index.tsx index 0ce5836574..5a3dff22a3 100644 --- a/src/components/Layout/SideNav/index.tsx +++ b/src/components/Layout/SideNav/index.tsx @@ -110,7 +110,7 @@ const SideNav = () => { activeIcon={<IconNavSettings24 size="md" color="green" />} active={isInSettings} isMediumUp={isMediumUp} - href={PATHS.SETTINGS} + href={PATHS.ME_SETTINGS} /> )} From 26af5426e65eac05854bf96e548b50dce9502bf7 Mon Sep 17 00:00:00 2001 From: Aka jazzy <mingchenliang954@gmail.com> Date: Mon, 21 Nov 2022 20:28:48 +0800 Subject: [PATCH 17/25] fix(me-setting): rename VistorSettings to AnonymousSettings --- .husky/pre-commit | 2 +- .../DisplayPreferences/SwitchLanguage/index.tsx | 0 .../DisplayPreferences/index.tsx | 0 .../{ViewerSettings => AnonymousSettings}/Enhance/index.tsx | 0 .../{ViewerSettings => AnonymousSettings}/Learn/index.tsx | 0 .../Settings/{ViewerSettings => AnonymousSettings}/index.tsx | 0 .../Settings/{ViewerSettings => AnonymousSettings}/styles.css | 0 src/views/Me/Settings/Settings/index.tsx | 4 ++-- 8 files changed, 3 insertions(+), 3 deletions(-) rename src/views/Me/Settings/{ViewerSettings => AnonymousSettings}/DisplayPreferences/SwitchLanguage/index.tsx (100%) rename src/views/Me/Settings/{ViewerSettings => AnonymousSettings}/DisplayPreferences/index.tsx (100%) rename src/views/Me/Settings/{ViewerSettings => AnonymousSettings}/Enhance/index.tsx (100%) rename src/views/Me/Settings/{ViewerSettings => AnonymousSettings}/Learn/index.tsx (100%) rename src/views/Me/Settings/{ViewerSettings => AnonymousSettings}/index.tsx (100%) rename src/views/Me/Settings/{ViewerSettings => AnonymousSettings}/styles.css (100%) diff --git a/.husky/pre-commit b/.husky/pre-commit index cb9be4a68d..088f68408c 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -2,4 +2,4 @@ . "$(dirname "$0")/_/husky.sh" npm run format -- --list-different && \ -npm run lint +npm run lint \ No newline at end of file diff --git a/src/views/Me/Settings/ViewerSettings/DisplayPreferences/SwitchLanguage/index.tsx b/src/views/Me/Settings/AnonymousSettings/DisplayPreferences/SwitchLanguage/index.tsx similarity index 100% rename from src/views/Me/Settings/ViewerSettings/DisplayPreferences/SwitchLanguage/index.tsx rename to src/views/Me/Settings/AnonymousSettings/DisplayPreferences/SwitchLanguage/index.tsx diff --git a/src/views/Me/Settings/ViewerSettings/DisplayPreferences/index.tsx b/src/views/Me/Settings/AnonymousSettings/DisplayPreferences/index.tsx similarity index 100% rename from src/views/Me/Settings/ViewerSettings/DisplayPreferences/index.tsx rename to src/views/Me/Settings/AnonymousSettings/DisplayPreferences/index.tsx diff --git a/src/views/Me/Settings/ViewerSettings/Enhance/index.tsx b/src/views/Me/Settings/AnonymousSettings/Enhance/index.tsx similarity index 100% rename from src/views/Me/Settings/ViewerSettings/Enhance/index.tsx rename to src/views/Me/Settings/AnonymousSettings/Enhance/index.tsx diff --git a/src/views/Me/Settings/ViewerSettings/Learn/index.tsx b/src/views/Me/Settings/AnonymousSettings/Learn/index.tsx similarity index 100% rename from src/views/Me/Settings/ViewerSettings/Learn/index.tsx rename to src/views/Me/Settings/AnonymousSettings/Learn/index.tsx diff --git a/src/views/Me/Settings/ViewerSettings/index.tsx b/src/views/Me/Settings/AnonymousSettings/index.tsx similarity index 100% rename from src/views/Me/Settings/ViewerSettings/index.tsx rename to src/views/Me/Settings/AnonymousSettings/index.tsx diff --git a/src/views/Me/Settings/ViewerSettings/styles.css b/src/views/Me/Settings/AnonymousSettings/styles.css similarity index 100% rename from src/views/Me/Settings/ViewerSettings/styles.css rename to src/views/Me/Settings/AnonymousSettings/styles.css diff --git a/src/views/Me/Settings/Settings/index.tsx b/src/views/Me/Settings/Settings/index.tsx index 721997415e..b773e97831 100644 --- a/src/views/Me/Settings/Settings/index.tsx +++ b/src/views/Me/Settings/Settings/index.tsx @@ -10,7 +10,7 @@ import { // import { redirectToLogin } from '~/common/utils' -import ViewerSetting from '../ViewerSettings' +import AnonymousSettings from '../AnonymousSettings' import AccountSettings from './Account' import UISettings from './UI' import WalletSettings from './Wallet' @@ -19,7 +19,7 @@ const Settings = () => { const viewer = useContext(ViewerContext) if (viewer.privateFetched && !viewer.isAuthed) { - return <ViewerSetting /> + return <AnonymousSettings /> } return ( From 74e83a8cd005d93c2f52d17b0b94eadb12e1930b Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Mon, 21 Nov 2022 19:57:55 +0800 Subject: [PATCH 18/25] feat(verification-code): add hints to code inputs; handle CODE_INACTIVE error; --- src/common/enums/errorCode.ts | 1 + src/common/enums/text.ts | 20 +++++++++++++------ .../Forms/ChangeEmailForm/Confirm.tsx | 1 + .../Forms/ChangeEmailForm/Request.tsx | 1 + .../PaymentForm/ResetPassword/Request.tsx | 1 + .../Forms/Verification/LinkSent.tsx | 6 +++--- .../Forms/WalletAuthForm/Connect.tsx | 1 + 7 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/common/enums/errorCode.ts b/src/common/enums/errorCode.ts index b8ede49fcf..cbf2cf9ce8 100644 --- a/src/common/enums/errorCode.ts +++ b/src/common/enums/errorCode.ts @@ -62,6 +62,7 @@ export const ERROR_CODES = { // Verification Code CODE_INVALID: 'CODE_INVALID', + CODE_INACTIVE: 'CODE_INACTIVE', CODE_EXPIRED: 'CODE_EXPIRED', // GQL diff --git a/src/common/enums/text.ts b/src/common/enums/text.ts index db21e9dcd3..e9ef187149 100644 --- a/src/common/enums/text.ts +++ b/src/common/enums/text.ts @@ -60,8 +60,9 @@ export const TEXT = { circleEdited: '圍爐已更新', clear: '清空', close: '關閉', - CODE_EXPIRED: '驗證碼已過期', - CODE_INVALID: '驗證碼不正確', + CODE_EXPIRED: '驗證碼已過期,請重新發送', + CODE_INACTIVE: '驗證碼已失效,請使用最新驗證碼或重新發送', + CODE_INVALID: '驗證碼不正確,請檢查輸入內容或重新發送', collectedOnly: '只看衍生作品', COMMENT_NOT_FOUND: '評論不存在', comment: '評論', @@ -165,6 +166,7 @@ export const TEXT = { hintPaymentPointer: '錢包地址以“$”開頭', hintTerm: '我們的用戶協議和隱私政策發生了更改,請閱讀並同意後繼續使用。', hintUserName: '4-15 個字元,僅支持英文、數字或下劃線', + hintVerificationCode: '驗證碼有效期 20 分鐘', history: '足跡', hkd: '港幣', hottest: '熱門', @@ -450,8 +452,9 @@ export const TEXT = { circleEdited: '围炉已更新', clear: '清空', close: '关闭', - CODE_EXPIRED: '验证码已过期', - CODE_INVALID: '验证码不正确', + CODE_EXPIRED: '验证码已过期,请重新发送', + CODE_INACTIVE: '验证码已失效,请使用最新验证码或重新发送', + CODE_INVALID: '验证码不正确,请检查输入内容或重新发送', collectedOnly: '只看衍生作品', COMMENT_NOT_FOUND: '评论不存在', comment: '评论', @@ -555,6 +558,7 @@ export const TEXT = { hintPaymentPointer: '钱包地址以“$”开头', hintTerm: '我们的用户协议和隐私政策发生了更改,请阅读并同意后继续使用。', hintUserName: '4-15 个字符,仅支持英文、数字或下划线', + hintVerificationCode: '验证码有效期 20 分钟', history: '足迹', hkd: '港币', hottest: '热门', @@ -840,8 +844,11 @@ export const TEXT = { circleEdited: 'Circle Edited', clear: 'Clear', close: 'Cancel', - CODE_EXPIRED: 'Verification code expired', - CODE_INVALID: 'Invalid verification code', + CODE_EXPIRED: 'Verification code expired, try resend', + CODE_INACTIVE: + 'Verification code is no longer valid. Please use the latest code we sent, or try resend', + CODE_INVALID: + 'Incorrect verification code. Please check your input, or try resend', collapseComment: 'Collapse response', collectedOnly: 'Articles Only', COMMENT_NOT_FOUND: 'Response not found', @@ -961,6 +968,7 @@ export const TEXT = { hintUserDescription: 'Recommended within 50 words and 200 words maximum.', hintUserName: 'Must be between 4-15 characters long. Only English alphabets, numbers and underline are accepted.', + hintVerificationCode: 'Code will expire after 20 minutes', history: 'History', hkd: 'HKD', hottest: 'Trending', diff --git a/src/components/Forms/ChangeEmailForm/Confirm.tsx b/src/components/Forms/ChangeEmailForm/Confirm.tsx index 6a3691abbe..5488136ae6 100644 --- a/src/components/Forms/ChangeEmailForm/Confirm.tsx +++ b/src/components/Forms/ChangeEmailForm/Confirm.tsx @@ -134,6 +134,7 @@ const Confirm: React.FC<FormProps> = ({ name="code" required placeholder={translate({ id: 'enterVerificationCode', lang })} + hint={translate({ id: 'hintVerificationCode', lang })} value={values.code} error={touched.code && errors.code} onBlur={handleBlur} diff --git a/src/components/Forms/ChangeEmailForm/Request.tsx b/src/components/Forms/ChangeEmailForm/Request.tsx index 5e4551d10a..4e9f6253c2 100644 --- a/src/components/Forms/ChangeEmailForm/Request.tsx +++ b/src/components/Forms/ChangeEmailForm/Request.tsx @@ -111,6 +111,7 @@ const Request: React.FC<FormProps> = ({ name="code" required placeholder={translate({ id: 'enterVerificationCode', lang })} + hint={translate({ id: 'hintVerificationCode', lang })} value={values.code} error={touched.code && errors.code} onBlur={handleBlur} diff --git a/src/components/Forms/PaymentForm/ResetPassword/Request.tsx b/src/components/Forms/PaymentForm/ResetPassword/Request.tsx index 17692e3a2f..cdaf723d1c 100644 --- a/src/components/Forms/PaymentForm/ResetPassword/Request.tsx +++ b/src/components/Forms/PaymentForm/ResetPassword/Request.tsx @@ -114,6 +114,7 @@ const Request: React.FC<FormProps> = ({ name="code" required placeholder={translate({ id: 'enterVerificationCode', lang })} + hint={translate({ id: 'hintVerificationCode', lang })} value={values.code} error={touched.code && errors.code} onBlur={handleBlur} diff --git a/src/components/Forms/Verification/LinkSent.tsx b/src/components/Forms/Verification/LinkSent.tsx index 6d3c760b97..ef0e00a003 100644 --- a/src/components/Forms/Verification/LinkSent.tsx +++ b/src/components/Forms/Verification/LinkSent.tsx @@ -41,9 +41,9 @@ export const VerificationLinkSent = ({ /> <br /> <Translate - zh_hant="快去你的電子信箱看看吧!" - zh_hans="快去你的邮箱看看吧!" - en="Let's check your inbox!" + zh_hant="連結有效期 20 分鐘,快去你的電子信箱看看吧!" + zh_hans="连结有效期 20 分钟,快去你的邮箱看看吧!" + en="Link is valid for 20 minutes. Let's check your inbox!" /> </p> </Dialog.Message> diff --git a/src/components/Forms/WalletAuthForm/Connect.tsx b/src/components/Forms/WalletAuthForm/Connect.tsx index e3105647bf..75a2148c7c 100644 --- a/src/components/Forms/WalletAuthForm/Connect.tsx +++ b/src/components/Forms/WalletAuthForm/Connect.tsx @@ -347,6 +347,7 @@ const Connect: React.FC<FormProps> = ({ name="code" required placeholder={translate({ id: 'enterVerificationCode', lang })} + hint={translate({ id: 'hintVerificationCode', lang })} value={values.code} error={touched.code && errors.code} onBlur={handleBlur} From 62eda3c2acc0b96ee4b80c258948883a89fe07bd Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Tue, 22 Nov 2022 21:59:44 +0800 Subject: [PATCH 19/25] fix(tag-detail): fix missing add/remove article to tag buttons --- .../DropdownActions/RemoveTagButton.tsx | 16 ++--- .../DropdownActions/SetTagSelectedButton.tsx | 13 +---- .../SetTagUnselectedButton.tsx | 11 ++-- .../ArticleDigest/DropdownActions/index.tsx | 58 +++++++++---------- src/components/ArticleDigest/Feed/index.tsx | 7 ++- .../Dialogs/TagAdoptionDialog/index.tsx | 10 +--- .../Dialogs/TagEditorDialog/index.tsx | 3 - .../Dialogs/TagLeaveDialog/index.tsx | 10 +--- src/views/TagDetail/Articles/index.tsx | 32 ++++++---- src/views/TagDetail/index.tsx | 2 +- 10 files changed, 75 insertions(+), 87 deletions(-) diff --git a/src/components/ArticleDigest/DropdownActions/RemoveTagButton.tsx b/src/components/ArticleDigest/DropdownActions/RemoveTagButton.tsx index 567d7fd15a..55749fb765 100644 --- a/src/components/ArticleDigest/DropdownActions/RemoveTagButton.tsx +++ b/src/components/ArticleDigest/DropdownActions/RemoveTagButton.tsx @@ -7,7 +7,6 @@ import { TextIcon, Translate, useMutation, - useRoute, } from '~/components' import updateTagArticlesCount from '~/components/GQL/updates/tagArticlesCount' @@ -44,16 +43,19 @@ const fragments = { `, } -const RemoveTagButton = ({ article }: { article: RemoveTagButtonArticle }) => { - const { getQuery } = useRoute() - const id = getQuery('tagId') - +const RemoveTagButton = ({ + article, + tagId, +}: { + article: RemoveTagButtonArticle + tagId: string +}) => { const [deleteArticlesTags] = useMutation<DeleteArticlesTags>( DELETE_ARTICLES_TAGS, { - variables: { id, articles: [article.id] }, + variables: { id: tagId, articles: [article.id] }, update: (cache) => { - updateTagArticlesCount({ cache, type: 'decrement', id }) + updateTagArticlesCount({ cache, type: 'decrement', id: tagId }) }, } ) diff --git a/src/components/ArticleDigest/DropdownActions/SetTagSelectedButton.tsx b/src/components/ArticleDigest/DropdownActions/SetTagSelectedButton.tsx index 4a60aded89..a1a04b519f 100644 --- a/src/components/ArticleDigest/DropdownActions/SetTagSelectedButton.tsx +++ b/src/components/ArticleDigest/DropdownActions/SetTagSelectedButton.tsx @@ -1,13 +1,6 @@ import gql from 'graphql-tag' -import { - IconAdd24, - Menu, - TextIcon, - Translate, - useMutation, - useRoute, -} from '~/components' +import { IconAdd24, Menu, TextIcon, Translate, useMutation } from '~/components' import { ADD_TOAST } from '~/common/enums' @@ -46,11 +39,11 @@ const fragments = { const SetTagSelectedButton = ({ article, + tagId, }: { article: SetTagSelectedButtonArticle + tagId: string }) => { - const { getQuery } = useRoute() - const tagId = getQuery('tagId') const [update] = useMutation<SetTagSelected>(SET_TAG_SELECTED, { variables: { id: tagId, articles: [article.id] }, }) diff --git a/src/components/ArticleDigest/DropdownActions/SetTagUnselectedButton.tsx b/src/components/ArticleDigest/DropdownActions/SetTagUnselectedButton.tsx index 0275070224..c1f0a39fde 100644 --- a/src/components/ArticleDigest/DropdownActions/SetTagUnselectedButton.tsx +++ b/src/components/ArticleDigest/DropdownActions/SetTagUnselectedButton.tsx @@ -8,7 +8,6 @@ import { TextIcon, Translate, useMutation, - useRoute, } from '~/components' import { ADD_TOAST } from '~/common/enums' @@ -52,11 +51,11 @@ const fragments = { const SetTagUnselectedButton = ({ article, + tagId, }: { article: SetTagUnselectedButtonArticle + tagId: string }) => { - const { getQuery } = useRoute() - const tagId = getQuery('tagId') const [update] = useMutation<SetTagUnselected>(SET_TAG_UNSELECTED, { variables: { id: tagId, articles: [article.id] }, update: (cache) => { @@ -65,7 +64,11 @@ const SetTagUnselectedButton = ({ const { TAG_ARTICLES_PUBLIC: query, } = require('~/components/GQL/queries/tagArticles') - const variables = { id: tagId, selected: true } + const variables = { + id: tagId, + selected: true, + sortBy: 'byCreatedAtDesc', + } const data = cache.readQuery<TagArticlesPublic>({ query, variables }) const node = _get(data, 'node', {}) as TagArticlesPublic_node_Tag if ( diff --git a/src/components/ArticleDigest/DropdownActions/index.tsx b/src/components/ArticleDigest/DropdownActions/index.tsx index a0ddc2197c..21bd19c44e 100644 --- a/src/components/ArticleDigest/DropdownActions/index.tsx +++ b/src/components/ArticleDigest/DropdownActions/index.tsx @@ -1,7 +1,5 @@ -import _find from 'lodash/find' import _isEmpty from 'lodash/isEmpty' import _pickBy from 'lodash/pickBy' -import _some from 'lodash/some' import { useContext } from 'react' import { @@ -16,7 +14,6 @@ import { Menu, ShareDialog, Translate, - useRoute, ViewerContext, } from '~/components' @@ -54,8 +51,12 @@ export interface DropdownActionsControls { // based on type inCard?: boolean inUserArticles?: boolean - inTagDetailLatest?: boolean - inTagDetailSelected?: boolean + + // tag + tagDetailId?: string + hasSetTagSelected?: boolean + hasSetTagUnselected?: boolean + hasRemoveTag?: boolean morePublicActions?: React.ReactNode } @@ -73,7 +74,7 @@ interface Controls { hasSticky: boolean hasArchive: boolean hasSetTagSelected: boolean - hasSetTagUnSelected: boolean + hasSetTagUnselected: boolean hasRemoveTag: boolean hasEdit: boolean } @@ -90,6 +91,7 @@ type BaseDropdownActionsProps = DropdownActionsProps & Controls & DialogProps const BaseDropdownActions = ({ article, + tagDetailId, icon, size, @@ -105,7 +107,7 @@ const BaseDropdownActions = ({ hasSticky, hasArchive, hasSetTagSelected, - hasSetTagUnSelected, + hasSetTagUnselected, hasRemoveTag, hasEdit, @@ -128,7 +130,7 @@ const BaseDropdownActions = ({ hasSticky || hasArchive || hasSetTagSelected || - hasSetTagUnSelected || + hasSetTagUnselected || hasRemoveTag const Content = ({ isInDropdown }: { isInDropdown?: boolean }) => ( @@ -150,9 +152,15 @@ const BaseDropdownActions = ({ {hasSticky && <StickyButton article={article} />} {hasArchive && <ArchiveArticle.Button openDialog={openArchiveDialog} />} - {hasSetTagSelected && <SetTagSelectedButton article={article} />} - {hasSetTagUnSelected && <SetTagUnselectedButton article={article} />} - {hasRemoveTag && <RemoveTagButton article={article} />} + {hasSetTagSelected && tagDetailId && ( + <SetTagSelectedButton article={article} tagId={tagDetailId} /> + )} + {hasSetTagUnselected && tagDetailId && ( + <SetTagUnselectedButton article={article} tagId={tagDetailId} /> + )} + {hasRemoveTag && tagDetailId && ( + <RemoveTagButton article={article} tagId={tagDetailId} /> + )} {hasEdit && <EditButton article={article} />} </Menu> ) @@ -195,29 +203,15 @@ const DropdownActions = (props: DropdownActionsProps) => { inCard, inUserArticles, - inTagDetailLatest, - inTagDetailSelected, + + hasSetTagSelected, + hasSetTagUnselected, + hasRemoveTag, } = props - const { getQuery } = useRoute() const viewer = useContext(ViewerContext) const isArticleAuthor = viewer.id === article.author.id const isActive = article.articleState === 'active' - const isInTagDetail = inTagDetailLatest || inTagDetailSelected - - // check permission if in tag detail - let canEditTag = false - if (isInTagDetail) { - const tagId = getQuery('tagId') - const tag = _find(article.tags || [], (item) => item.id === tagId) - const isEditor = _some( - tag?.editors || [], - (editor) => editor.id === viewer.id - ) - const isCreator = tag?.creator?.id === viewer.id - canEditTag = - isEditor || isCreator || viewer.info.email === 'hi@matters.news' - } const forbid = () => { window.dispatchEvent( @@ -247,9 +241,9 @@ const DropdownActions = (props: DropdownActionsProps) => { !viewer.isInactive ), hasArchive: isArticleAuthor && isActive && !viewer.isArchived, - hasSetTagSelected: !!(inTagDetailLatest && canEditTag), - hasSetTagUnSelected: !!(inTagDetailSelected && canEditTag), - hasRemoveTag: !!(isInTagDetail && canEditTag), + hasSetTagSelected: !!hasSetTagSelected, + hasSetTagUnselected: !!hasSetTagUnselected, + hasRemoveTag: !!hasRemoveTag, hasEdit: isActive && isArticleAuthor, } diff --git a/src/components/ArticleDigest/Feed/index.tsx b/src/components/ArticleDigest/Feed/index.tsx index 210fe8859e..4c6e2e9e1a 100644 --- a/src/components/ArticleDigest/Feed/index.tsx +++ b/src/components/ArticleDigest/Feed/index.tsx @@ -115,12 +115,15 @@ type MemoizedArticleDigestFeed = React.MemoExoticComponent< export const ArticleDigestFeed = React.memo( BaseArticleDigestFeed, - ({ article: prevArticle }, { article }) => { + ({ article: prevArticle, ...prevProps }, { article, ...props }) => { return ( prevArticle.subscribed === article.subscribed && prevArticle.articleState === article.articleState && prevArticle.sticky === article.sticky && - prevArticle.author.isFollowee === article.author.isFollowee + prevArticle.author.isFollowee === article.author.isFollowee && + prevProps.hasSetTagSelected === props.hasSetTagSelected && + prevProps.hasSetTagUnselected === props.hasSetTagUnselected && + prevProps.hasRemoveTag === props.hasRemoveTag ) } ) as MemoizedArticleDigestFeed diff --git a/src/components/Dialogs/TagAdoptionDialog/index.tsx b/src/components/Dialogs/TagAdoptionDialog/index.tsx index 1c6fa4b6b6..39c0cd6309 100644 --- a/src/components/Dialogs/TagAdoptionDialog/index.tsx +++ b/src/components/Dialogs/TagAdoptionDialog/index.tsx @@ -1,10 +1,4 @@ -import { - Dialog, - Translate, - useDialogSwitch, - useMutation, - // useRoute, -} from '~/components' +import { Dialog, Translate, useDialogSwitch, useMutation } from '~/components' import UPDATE_TAG_SETTING from '~/components/GQL/mutations/updateTagSetting' import { ADD_TOAST } from '~/common/enums' @@ -34,8 +28,6 @@ const textEn = const BaseDialog = ({ id, children }: Props) => { const { show, openDialog, closeDialog } = useDialogSwitch(true) - // const { getQuery } = useRoute() - // const id = getQuery('tagId') const [update, { loading }] = useMutation<UpdateTagSetting>(UPDATE_TAG_SETTING) diff --git a/src/components/Dialogs/TagEditorDialog/index.tsx b/src/components/Dialogs/TagEditorDialog/index.tsx index 747445e374..4d09e973b0 100644 --- a/src/components/Dialogs/TagEditorDialog/index.tsx +++ b/src/components/Dialogs/TagEditorDialog/index.tsx @@ -49,9 +49,6 @@ const BaseDialog = ({ id, children }: Props) => { baseOpenDialog() } - // const { getQuery } = useRoute() - // const id = getQuery('tagId') - const isAdd = currStep === 'add' const isList = currStep === 'list' const isRemove = currStep === 'remove' diff --git a/src/components/Dialogs/TagLeaveDialog/index.tsx b/src/components/Dialogs/TagLeaveDialog/index.tsx index 3add76c805..e8e65a10cf 100644 --- a/src/components/Dialogs/TagLeaveDialog/index.tsx +++ b/src/components/Dialogs/TagLeaveDialog/index.tsx @@ -1,10 +1,4 @@ -import { - Dialog, - Translate, - useDialogSwitch, - useMutation, - // useRoute, -} from '~/components' +import { Dialog, Translate, useDialogSwitch, useMutation } from '~/components' import UPDATE_TAG_SETTING from '~/components/GQL/mutations/updateTagSetting' import { ADD_TOAST } from '~/common/enums' @@ -20,8 +14,6 @@ interface Props { const BaseDialog = ({ id, isOwner, children }: Props) => { const { show, openDialog, closeDialog } = useDialogSwitch(true) - // const { getQuery } = useRoute() - // const id = getQuery('tagId') const [update, { loading }] = useMutation<UpdateTagSetting>(UPDATE_TAG_SETTING) diff --git a/src/views/TagDetail/Articles/index.tsx b/src/views/TagDetail/Articles/index.tsx index 928c18f3d2..c45178efb0 100644 --- a/src/views/TagDetail/Articles/index.tsx +++ b/src/views/TagDetail/Articles/index.tsx @@ -1,4 +1,6 @@ import { NetworkStatus } from 'apollo-client' +import _find from 'lodash/find' +import _some from 'lodash/some' import React, { useContext, useEffect, useRef } from 'react' import { @@ -25,20 +27,20 @@ import { analytics, mergeConnections } from '~/common/utils' import RelatedTags from '../RelatedTags' import { TagArticlesPublic } from '~/components/GQL/queries/__generated__/TagArticlesPublic' +import { TagFragment } from '../__generated__/TagFragment' interface TagArticlesProps { - tagId: string + tag: TagFragment feedType: string } -const TagDetailArticles = ({ tagId, feedType }: TagArticlesProps) => { +const TagDetailArticles = ({ tag, feedType }: TagArticlesProps) => { const viewer = useContext(ViewerContext) const feed = useRef(feedType) const isLargeUp = useResponsive('lg-up') const isSelected = feedType === 'selected' const isHottest = feedType === 'hottest' - const isLatest = feedType === 'latest' /** * Data Fetching @@ -54,7 +56,7 @@ const TagDetailArticles = ({ tagId, feedType }: TagArticlesProps) => { client, } = usePublicQuery<TagArticlesPublic>(TAG_ARTICLES_PUBLIC, { variables: { - id: tagId, + id: tag.id, selected: feedType === 'selected', sortBy: feedType === 'hottest' ? 'byHottestDesc' : 'byCreatedAtDesc', }, @@ -145,13 +147,13 @@ const TagDetailArticles = ({ tagId, feedType }: TagArticlesProps) => { switch (event) { case 'add': const { data: addData } = await refetchPublic({ - variables: { id: tagId, first: count + differences }, + variables: { id: tag.id, first: count + differences }, }) loadPrivate(addData) break case 'delete': const { data: deleteData } = await refetchPublic({ - variables: { id: tagId, first: Math.max(count - 1, 0) }, + variables: { id: tag.id, first: Math.max(count - 1, 0) }, }) loadPrivate(deleteData) break @@ -176,6 +178,14 @@ const TagDetailArticles = ({ tagId, feedType }: TagArticlesProps) => { return <EmptyTagArticles /> } + const isEditor = _some( + tag?.editors || [], + (editor) => editor.id === viewer.id + ) + const isCreator = tag?.creator?.id === viewer.id + const canEditTag = + isEditor || isCreator || viewer.info.email === 'hi@matters.news' + return ( <InfiniteScroll hasNextPage={pageInfo.hasNextPage} loadMore={loadMore}> <List> @@ -200,19 +210,21 @@ const TagDetailArticles = ({ tagId, feedType }: TagArticlesProps) => { id: node.author.id, }) }} - inTagDetailSelected={isSelected} - inTagDetailLatest={isLatest} + tagDetailId={tag.id} + hasSetTagSelected={canEditTag && !isSelected} + hasSetTagUnselected={canEditTag && isSelected} + hasRemoveTag={canEditTag && !isHottest} /> </List.Item> {!isLargeUp && edges.length >= 4 && i === 3 && ( - <RelatedTags tagId={tagId} /> + <RelatedTags tagId={tag.id} /> )} </React.Fragment> ))} </List> - {!isLargeUp && edges.length < 4 && <RelatedTags tagId={tagId} />} + {!isLargeUp && edges.length < 4 && <RelatedTags tagId={tag.id} />} </InfiniteScroll> ) } diff --git a/src/views/TagDetail/index.tsx b/src/views/TagDetail/index.tsx index 066d48e997..b6e7b876b8 100644 --- a/src/views/TagDetail/index.tsx +++ b/src/views/TagDetail/index.tsx @@ -225,7 +225,7 @@ const TagDetail = ({ tag }: { tag: TagFragment }) => { </Tabs> {(isHottest || isLatest || isSelected) && ( - <TagDetailArticles tagId={tag.id} feedType={feedType} /> + <TagDetailArticles tag={tag} feedType={feedType} /> )} {isCreators && <DynamicCommunity id={tag.id} isOwner={isOwner} />} From c0732716795f4f82cdc91a1e9dd88f08da414ce4 Mon Sep 17 00:00:00 2001 From: Zeck Li <devformatters@gmail.com> Date: Tue, 22 Nov 2022 23:42:31 +0800 Subject: [PATCH 20/25] fix(copy): update copy in paymenet amout setup step --- src/common/enums/text.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/enums/text.ts b/src/common/enums/text.ts index db21e9dcd3..6bdaa41656 100644 --- a/src/common/enums/text.ts +++ b/src/common/enums/text.ts @@ -102,7 +102,7 @@ export const TEXT = { editUserProfile: '編輯資料', email: '電子信箱', emptySearchResults: '不好意思,什麼都沒搜到', - enterCustomAmount: '輸入自訂金額', + enterCustomAmount: '輸入金額', enterDisplayName: '請輸入姓名', enterEmail: '請輸入電子信箱', enterNewEmail: '請輸入新電子信箱', @@ -492,7 +492,7 @@ export const TEXT = { editUserProfile: '编辑资料', email: '邮箱', emptySearchResults: '不好意思,什么都没搜到', - enterCustomAmount: '输入自订金额', + enterCustomAmount: '输入金额', enterDisplayName: '请输入姓名', enterEmail: '请输入邮箱', enterNewEmail: '请输入新邮箱', From 07a06f6dffa5a1db1b948d58023bf61c87b8f362 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:04:15 +0800 Subject: [PATCH 21/25] fix(TagDetail): back behavior is not working correctly after clicking couple times in tag latest feed https://github.com/thematters/matters-web/issues/2921 --- src/views/TagDetail/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/views/TagDetail/index.tsx b/src/views/TagDetail/index.tsx index b6e7b876b8..d42c0382fb 100644 --- a/src/views/TagDetail/index.tsx +++ b/src/views/TagDetail/index.tsx @@ -86,18 +86,17 @@ const TagDetail = ({ tag }: { tag: TagFragment }) => { const isCreators = feedType === 'creators' useEffect(() => { - // if selected feed is empty, switch to latest feed + // if selected feed is empty, switch to hottest feed if (!hasSelectedFeed && isSelected) { - changeFeed('latest') + changeFeed('hottest') } // backward compatible with `/tags/:globalId:` const newPath = toPath({ page: 'tagDetail', tag, - feedType: isLatest ? '' : feedType, + feedType: isHottest ? '' : feedType, }) - if (newPath.href !== window.decodeURI(router.asPath)) { router.replace(newPath.href, undefined, { shallow: true }) } From c07b5ed5c5008ba5b560afc7942024e13029e300 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:15:17 +0800 Subject: [PATCH 22/25] fix(TagDetail): Fix that Tabs and Content are not updated after clicking the <BackButton> --- src/views/TagDetail/index.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/views/TagDetail/index.tsx b/src/views/TagDetail/index.tsx index d42c0382fb..6160027423 100644 --- a/src/views/TagDetail/index.tsx +++ b/src/views/TagDetail/index.tsx @@ -80,6 +80,14 @@ const TagDetail = ({ tag }: { tag: TagFragment }) => { setFeedType(newType) } + useEffect(() => { + setFeedType( + hasSelectedFeed && qsType === 'selected' + ? 'selected' + : qsType || 'hottest' + ) + }, [qsType]) + const isSelected = feedType === 'selected' const isHottest = feedType === 'hottest' const isLatest = feedType === 'latest' From f38eefb63666fc565235ddb5f732bcce2edadca5 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 23 Nov 2022 12:04:42 +0800 Subject: [PATCH 23/25] fix(Card): clickable when selecting the text --- src/components/Interaction/Card/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/Interaction/Card/index.tsx b/src/components/Interaction/Card/index.tsx index 5950f83bc7..73261f6585 100644 --- a/src/components/Interaction/Card/index.tsx +++ b/src/components/Interaction/Card/index.tsx @@ -92,10 +92,6 @@ export const Card: React.FC<React.PropsWithChildren<CardProps>> = forwardRef( newTab: boolean event: React.MouseEvent | React.KeyboardEvent }) => { - if (window.getSelection()?.toString().length) { - return - } - const target = event.target as HTMLElement if (disabled) { From 361989ca411ffdb4c3825accf97f900586f9ef76 Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Wed, 23 Nov 2022 13:32:19 +0800 Subject: [PATCH 24/25] chore(release): v4.11.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c2efe1818..80bee3c9e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matters-web", - "version": "4.10.0", + "version": "4.11.0", "description": "codebase of Matters' website", "sideEffects": false, "author": "Matters <hi@matters.news>", From 2e18af555eddce793b559a11f0cb45bd379211f9 Mon Sep 17 00:00:00 2001 From: Zeck Li <devformatters@gmail.com> Date: Wed, 23 Nov 2022 15:32:27 +0800 Subject: [PATCH 25/25] Update copy in link sent modal --- src/components/Forms/Verification/LinkSent.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Forms/Verification/LinkSent.tsx b/src/components/Forms/Verification/LinkSent.tsx index ef0e00a003..32bd795dc4 100644 --- a/src/components/Forms/Verification/LinkSent.tsx +++ b/src/components/Forms/Verification/LinkSent.tsx @@ -41,8 +41,8 @@ export const VerificationLinkSent = ({ /> <br /> <Translate - zh_hant="連結有效期 20 分鐘,快去你的電子信箱看看吧!" - zh_hans="连结有效期 20 分钟,快去你的邮箱看看吧!" + zh_hant="連結有效期 20 分鐘,快去電子信箱看看吧!" + zh_hans="连结有效期 20 分钟,快去邮箱看看吧!" en="Link is valid for 20 minutes. Let's check your inbox!" /> </p>