From 9fa8192a88a8a1ba2a2258e8a005c7355d60ae66 Mon Sep 17 00:00:00 2001 From: Aka jazzy Date: Mon, 31 Oct 2022 20:29:54 +0800 Subject: [PATCH 01/72] feat(support-setting): add support setting into draft(without backend version) --- src/common/enums/text.ts | 27 ++ src/common/utils/form/validate.ts | 12 + src/components/Button/index.tsx | 4 + src/components/Button/styles.css | 12 + .../SetSupportSetting/Content.tsx | 232 ++++++++++++++++++ .../SetSupportSetting/SupportPreview.tsx | 64 +++++ .../ToggleAccess/SetSupportSetting/Tab.tsx | 27 ++ .../ToggleAccess/SetSupportSetting/index.tsx | 40 +++ .../ToggleAccess/SetSupportSetting/styles.css | 75 ++++++ src/components/Editor/ToggleAccess/index.tsx | 42 +++- src/components/Editor/ToggleAccess/styles.css | 31 +++ src/components/TextIcon/index.tsx | 1 + src/components/TextIcon/styles.css | 4 + 13 files changed, 570 insertions(+), 1 deletion(-) create mode 100644 src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx create mode 100644 src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx create mode 100644 src/components/Editor/ToggleAccess/SetSupportSetting/Tab.tsx create mode 100644 src/components/Editor/ToggleAccess/SetSupportSetting/index.tsx create mode 100644 src/components/Editor/ToggleAccess/SetSupportSetting/styles.css diff --git a/src/common/enums/text.ts b/src/common/enums/text.ts index 4abf9fbfb0..51953d813f 100644 --- a/src/common/enums/text.ts +++ b/src/common/enums/text.ts @@ -85,6 +85,7 @@ export const TEXT = { DISPLAYNAME_INVALID: '名稱不正確', displayName: '姓名', donation: '支持作者', + donateAgain: '再次支持', done: '完成', downloadApp: '下載應用', DRAFT_NOT_FOUND: '草稿不存在', @@ -278,6 +279,7 @@ export const TEXT = { sendVerificationCode: '發送驗證碼', setCover: '設置封面', setCollection: '關聯作品', + setSupportSetting: '支持設置', settings: '設定', settingsAccount: '帳戶設定', settingsBlock: '封鎖用戶', @@ -311,6 +313,13 @@ export const TEXT = { successTopUp: '儲值成功', successUnblock: '已取消封鎖。該用戶現在可以評論你的作品和圍爐。', successUploadImage: '圖片上傳成功', + supportFeedback: '支持後回覆', + supportRequestDescription: + '喜歡我的創作嗎?創作並不容易,別忘了給予支持與讚賞,讓我知道在創作的路上有你陪伴。', + supportResponseDescription: + '感謝 # 的支持 🥳,創作這條路不容易,有你的支持我將能夠蓄積更多能量創作。', + supportResponseTitle: '試試輸入「#」以代稱支持者名稱', + supportSetting: '支持號召', TAG_EDITORS_REACH_LIMIT: '一個標籤最多僅可有 4 名協作者共同管理', TAG_NOT_FOUND: '標籤不存在', TOO_MANY_TAGS_FOR_ARTICLE: '標籤添加最多至 10 個', @@ -455,6 +464,7 @@ export const TEXT = { DISPLAYNAME_INVALID: '名称不正确', displayName: '姓名', donation: '支持作者', + donateAgain: '再次支持', done: '完成', downloadApp: '下载应用', DRAFT_NOT_FOUND: '草稿不存在', @@ -648,6 +658,7 @@ export const TEXT = { sendVerificationCode: '发送验证码', setCover: '设置封面', setCollection: '关联作品', + setSupportSetting: '支持设置', settings: '设定', settingsAccount: '帳戶设定', settingsBlock: '屏蔽用户', @@ -681,6 +692,13 @@ export const TEXT = { successTopUp: '储值成功', successUnblock: '已取消屏蔽。该用户现在可以评论你的作品和围炉。', successUploadImage: '图片上传成功', + supportFeedback: '支持后回复', + supportRequestDescription: + '喜歡我的創作嗎?創作並不容易,別忘了給予支持與讚賞,讓我知道在創作的路上有你陪伴。', + supportResponseDescription: + '感謝 # 的支持 🥳,創作這條路不容易,有你的支持我將能夠蓄積更多能量創作。', + supportResponseTitle: '试试输入「#」以代称支持者名称', + supportSetting: '支持号召', TAG_EDITORS_REACH_LIMIT: '一个标签最多仅可有 4 名协作者共同管理', TAG_NOT_FOUND: '标签不存在', TOO_MANY_TAGS_FOR_ARTICLE: '标签添加最多至 10 个', @@ -831,6 +849,7 @@ export const TEXT = { DISPLAYNAME_INVALID: 'Invalid display name', displayName: 'Display Name', donation: 'Support Author', + donateAgain: 'Donate Again', done: 'Done', downloadApp: 'Download App', DRAFT_NOT_FOUND: 'Draft not found', @@ -1040,6 +1059,7 @@ export const TEXT = { sendVerificationCode: 'Send verification code', setCover: 'Set Cover', setCollection: 'Set Collection', + setSupportSetting: 'Support Setting', settings: 'Settings', settingsAccount: 'Account Setting', settingsBlock: 'Block Users', @@ -1075,6 +1095,13 @@ export const TEXT = { successTopUp: 'Topped up successfully', successUnblock: 'User unblocked. User can now comment on your articles.', successUploadImage: 'Image uploaded', + supportFeedback: 'Support Reply', + supportRequestDescription: + '喜歡我的創作嗎?創作並不容易,別忘了給予支持與讚賞,讓我知道在創作的路上有你陪伴。', + supportResponseDescription: + '感謝 # 的支持 🥳,創作這條路不容易,有你的支持我將能夠蓄積更多能量創作。', + supportResponseTitle: '試試輸入「#」以代稱支持者名稱', + supportSetting: 'Support Calling', TAG_EDITORS_REACH_LIMIT: 'Maximum 4 editors allowed for each tag', TAG_NOT_FOUND: 'Tag not found', TOO_MANY_TAGS_FOR_ARTICLE: 'Add up to 10 tags', diff --git a/src/common/utils/form/validate.ts b/src/common/utils/form/validate.ts index 4a97326e8a..4a3675be95 100644 --- a/src/common/utils/form/validate.ts +++ b/src/common/utils/form/validate.ts @@ -201,6 +201,18 @@ export const validateDescription = (value: string, lang: Language) => { } } +export const validateSupportWords = (value: string, lang: Language) => { + if (!value) { + return translate({ id: 'required', lang }) + } else if (value.length > 140) { + return translate({ + zh_hant: `已超過 140 字,目前 ${value.length} 字`, + zh_hans: `已超过 140 字,目前 ${value.length} 字`, + lang, + }) + } +} + export const validateToS = (value: boolean, lang: Language) => { if (value === false) { return translate({ zh_hant: '請勾選', zh_hans: '请勾选', lang }) diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index f1ff653bd2..8875245454 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -54,6 +54,8 @@ type ButtonColor = | 'gold' | 'red' | 'likecoin-green' + | 'yellow-lighter' + | 'gold-linear-gradient' type ButtonTextColor = Extract< ButtonColor, @@ -70,8 +72,10 @@ export type ButtonBgColor = Extract< | 'gold' | 'red' | 'white' + | 'yellow-lighter' | 'half-black' | 'black' + | 'gold-linear-gradient' > type ButtonBgActiveColor = Extract< diff --git a/src/components/Button/styles.css b/src/components/Button/styles.css index 26b3cb453f..22c888808b 100644 --- a/src/components/Button/styles.css +++ b/src/components/Button/styles.css @@ -299,6 +299,18 @@ span.container { } } +.bg-yellow-lighter { + & .hotarea { + background: var(--color-yellow-lighter); + } +} + +.bg-gold-linear-gradient { + & .hotarea { + background: linear-gradient(93.62deg, #cda555 2.8%, #b48527 93%); + } +} + /* Background:hover */ .bg-active-grey-lighter { &:hover, diff --git a/src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx b/src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx new file mode 100644 index 0000000000..8027f60661 --- /dev/null +++ b/src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx @@ -0,0 +1,232 @@ +import { useFormik } from 'formik' +import gql from 'graphql-tag' +import _pickBy from 'lodash/pickBy' +import { useContext, useEffect, useState } from 'react' + +import { + Dialog, + Form, + LanguageContext, + Translate, + useMutation, + useRoute, +} from '~/components' + +import { ADD_TOAST } from '~/common/enums' +import { + parseFormSubmitErrors, + translate, + validateSupportWords, +} from '~/common/utils' + +import styles from './styles.css' +import SupportPreview from './SupportPreview' +import Tab, { TabType } from './Tab' + +import { UpdateSupportRequest } from './__generated__/UpdateSupportRequest' + +interface FormProps { + closeDialog: () => void + onBack?: () => any + onClose?: () => any +} + +interface FormValues { + supportRequest: string + supportResponse: string +} + +const UPDATE_SUPPORT_REQUEST = gql` + mutation UpdateSupportRequest($id: ID!) { + editArticle(input: { id: $id }) { + id + title + } + } +` + +const SupportSettingDialogContent: React.FC = ({ + closeDialog, + onClose, + onBack, +}) => { + const [update] = useMutation( + UPDATE_SUPPORT_REQUEST, + undefined, + { showToast: false } + ) + + const { lang } = useContext(LanguageContext) + const formId = 'edit-profile-form' + + const { getQuery, setQuery } = useRoute() + const qsType = getQuery('type') as TabType + const [tabType, setTanType] = useState(qsType || 'request') + const [wordCount, setWordCount] = useState(0) + + const { values, errors, touched, handleBlur, handleSubmit, setFieldValue } = + useFormik({ + initialValues: { + // TODO: wait for backend to query + supportRequest: '', + supportResponse: '', + }, + validate: ({ supportRequest, supportResponse }) => + _pickBy({ + supportRequest: validateSupportWords(supportRequest, lang), + supportResponse: validateSupportWords(supportResponse, lang), + }), + onSubmit: async ( + { supportRequest, supportResponse }, + { setSubmitting, setFieldError } + ) => { + try { + await update({ + variables: { + input: { + supportRequest, + supportResponse, + }, + }, + }) + + window.dispatchEvent( + new CustomEvent(ADD_TOAST, { + detail: { + color: 'green', + content: , + }, + }) + ) + + setSubmitting(false) + closeDialog() + } catch (error) { + setSubmitting(false) + + const [messages, codes] = parseFormSubmitErrors(error as any, lang) + codes.forEach((code) => { + if (code === 'DISPLAYNAME_INVALID') { + setFieldError( + 'displayName', + translate({ id: 'hintDisplayName', lang }) + ) + } else { + setFieldError('supportRequest', messages[code]) + } + }) + } + }, + }) + + const changeTabType = (newType: TabType) => { + setQuery('type', newType) + setTanType(newType) + } + + const onSave = async () => { + console.log('save') + } + + onBack = async () => { + console.log('back') + } + + useEffect(() => { + if (tabType === 'request') { + setWordCount(values.supportRequest.length) + } + if (tabType === 'response') { + setWordCount(values.supportResponse.length) + } + }, [values.supportRequest, values.supportResponse]) + + useEffect(() => { + setWordCount(0) + }, [tabType]) + + const InnerForm = (tab: string) => { + return ( +
+ {tab === 'request' && ( + + setFieldValue('supportRequest', e.currentTarget.value) + } + style={{ lineHeight: '1.5rem' }} + /> + )} + {tab === 'response' && ( + } + name="description" + required + placeholder={translate({ + id: 'supportResponseDescription', + lang, + })} + value={values.supportResponse} + error={touched.supportResponse && errors.supportResponse} + onBlur={handleBlur} + onChange={(e) => + setFieldValue('supportResponse', e.currentTarget.value) + } + style={{ lineHeight: '1.5rem' }} + /> + )} + +

{wordCount}/140

+ + + + ) + } + return ( + <> + + } + rightButton={ + } + /> + } + /> + + + +
+
{InnerForm(tabType)}
+
+ 效果预览 + +
+
+ +
+ + ) +} + +export default SupportSettingDialogContent diff --git a/src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx b/src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx new file mode 100644 index 0000000000..cbd7861c85 --- /dev/null +++ b/src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx @@ -0,0 +1,64 @@ +import { Button, IconDonate24, TextIcon, Translate } from '~/components' + +import styles from './styles.css' + +const SupportPreview = ({ + content, + tabType, +}: { + content: string + tabType: string +}) => { + // const [content, setContent] = useState('') + return ( +
+
+

+ {!content && + (tabType === 'request' ? ( + + ) : ( +

+

🎉 感謝支持!

+ {' '} +
+ ))} + + {} +

+
+ {tabType === 'request' && ( + + )} + {tabType === 'response' && ( + + )} +
+
+ + +
+ ) +} + +export default SupportPreview diff --git a/src/components/Editor/ToggleAccess/SetSupportSetting/Tab.tsx b/src/components/Editor/ToggleAccess/SetSupportSetting/Tab.tsx new file mode 100644 index 0000000000..0dd4e47590 --- /dev/null +++ b/src/components/Editor/ToggleAccess/SetSupportSetting/Tab.tsx @@ -0,0 +1,27 @@ +import { Tabs, Translate } from '~/components' + +export type TabType = 'request' | 'response' + +interface SortByProps { + tabType: TabType + setTabType: (sortBy: TabType) => void +} + +const SortBy: React.FC = ({ tabType, setTabType }) => { + const isRequest = tabType === 'request' + const isReply = tabType === 'response' + + return ( + + setTabType('request')} selected={isRequest}> + + + + setTabType('response')} selected={isReply}> + + + + ) +} + +export default SortBy diff --git a/src/components/Editor/ToggleAccess/SetSupportSetting/index.tsx b/src/components/Editor/ToggleAccess/SetSupportSetting/index.tsx new file mode 100644 index 0000000000..be9fb766ee --- /dev/null +++ b/src/components/Editor/ToggleAccess/SetSupportSetting/index.tsx @@ -0,0 +1,40 @@ +import _pickBy from 'lodash/pickBy' +import dynamic from 'next/dynamic' + +import { Dialog, Spinner, useDialogSwitch } from '~/components' +// import { ADD_TOAST } from '~/common/enums' + +// import Tab, { TabType } from './Tab' +// import styles from './styles.css' + +export type SetSupportSettingProps = { + onBack?: () => any + onClose?: () => any +} + +interface SupportSettingDialogProps { + children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode +} + +const DynamicContent = dynamic(() => import('./Content'), { loading: Spinner }) + +const BaseSupportSettingDialog = ({ children }: SupportSettingDialogProps) => { + const { show, openDialog, closeDialog } = useDialogSwitch(true) + + return ( + <> + {children({ openDialog })} + + + + + ) +} + +const SupportSettingDialog = (props: SupportSettingDialogProps) => ( + }> + {({ openDialog }) => <>{props.children({ openDialog })}} + +) + +export default SupportSettingDialog diff --git a/src/components/Editor/ToggleAccess/SetSupportSetting/styles.css b/src/components/Editor/ToggleAccess/SetSupportSetting/styles.css new file mode 100644 index 0000000000..77b77c5070 --- /dev/null +++ b/src/components/Editor/ToggleAccess/SetSupportSetting/styles.css @@ -0,0 +1,75 @@ +.support { + margin-top: var(--spacing-loose); + @mixin flex-center-space-between; + + & .hint { + margin-top: var(--spacing-xx-tight); + font-size: var(--font-size-xs); + color: var(--color-grey); + } + + & .right { + @mixin flex-center-end; + } +} + +.donation { + position: relative; + padding: var(--spacing-base); + margin: var(--spacing-tight) 0; + text-align: center; + background: var(--color-yellow-lighter); + border-radius: var(--spacing-x-tight); + + & p { + font-size: var(--font-size-sm); + font-weight: var(--font-weight-normal); + line-height: 1.5rem; + color: var(--color-black); + } +} + +.content { + padding: 0 var(--spacing-base); + & span { + font-size: var(--font-size-md-s); + } + + & .content-input { + @mixin flex-center-start; + + flex-direction: column; + } + + & h4 { + @mixin flex-center-end; + + font-size: var(--font-size-xs); + color: var(--color-matters-green); + } +} + +.preview { + margin-top: var(--spacing-base); + line-height: var(--line-height-base); +} + +.preview-response { + & p { + font-size: var(--font-size-md-s); + font-weight: var(--font-weight-medium); + } +} + +.preview-title { + font-size: var(--font-size-md); + font-weight: var(--font-weight-bold); +} + +.preview-button { + margin: var(--spacing-base) 0; + + & :global(button) { + width: 100%; + } +} diff --git a/src/components/Editor/ToggleAccess/index.tsx b/src/components/Editor/ToggleAccess/index.tsx index 94f94852aa..d15ec9d7e6 100644 --- a/src/components/Editor/ToggleAccess/index.tsx +++ b/src/components/Editor/ToggleAccess/index.tsx @@ -1,6 +1,15 @@ -import { CircleDigest, Switch, Translate } from '~/components' +import { + Button, + CircleDigest, + IconArrowRight16, + Switch, + Translate, +} from '~/components' import SelectLicense from './SelectLicense' +import SupportSettingDialog, { + SetSupportSettingProps, +} from './SetSupportSetting/index' import styles from './styles.css' import { @@ -45,6 +54,7 @@ const ToggleAccess: React.FC = ({ inSidebar, }) => { + const supportSettingProps: SetSupportSettingProps = {} return (
{canToggleCircle && ( @@ -106,6 +116,36 @@ const ToggleAccess: React.FC = ({ />
+
+ + {({ openDialog }) => ( + +
+ + + )} + +
diff --git a/src/components/Editor/ToggleAccess/styles.css b/src/components/Editor/ToggleAccess/styles.css index a8a701ee7f..5b6f081e25 100644 --- a/src/components/Editor/ToggleAccess/styles.css +++ b/src/components/Editor/ToggleAccess/styles.css @@ -62,3 +62,34 @@ h3 { } } } + +.support-setting { + & :global(button) { + @mixin flex-start-space-between; + + width: 100%; + } +} + +.support { + @mixin flex-start-space-between; + + width: 100%; + margin-top: var(--spacing-loose); + + & .hint { + margin-top: var(--spacing-xx-tight); + font-size: var(--font-size-xs); + color: var(--color-grey); + } + + & .left { + @mixin flex-start-center; + + flex-direction: column; + } + + & .right { + @mixin flex-center-end; + } +} diff --git a/src/components/TextIcon/index.tsx b/src/components/TextIcon/index.tsx index 1b253c4478..3b71d50df4 100644 --- a/src/components/TextIcon/index.tsx +++ b/src/components/TextIcon/index.tsx @@ -13,6 +13,7 @@ type TextIconColor = | 'white' | 'red' | 'likecoin-green' + | 'yellow-lighter' export interface TextIconProps { icon?: React.ReactNode diff --git a/src/components/TextIcon/styles.css b/src/components/TextIcon/styles.css index 79e34fe17a..99be620f61 100644 --- a/src/components/TextIcon/styles.css +++ b/src/components/TextIcon/styles.css @@ -103,6 +103,10 @@ color: var(--color-likecoin-green); } +.yellow-lighter { + color: var(--color-yellow-lighter); +} + /* spacing */ .spacing-xxxtight.hasIcon { &.text-right > .text { From a7d7794ebb3440a16ed49e97c095a93bed152756 Mon Sep 17 00:00:00 2001 From: Aka jazzy Date: Thu, 3 Nov 2022 00:45:01 +0800 Subject: [PATCH 02/72] feat(support-setting): integrate with backend --- src/common/enums/text.ts | 3 + .../SetSupportSetting/Content.tsx | 199 ++++++++++-------- .../SetSupportSetting/SupportPreview.tsx | 7 +- .../ToggleAccess/SetSupportSetting/index.tsx | 3 +- .../ToggleAccess/SetSupportSetting/styles.css | 2 +- src/views/ArticleDetail/gql.ts | 2 + src/views/Me/DraftDetail/gql.ts | 2 + 7 files changed, 126 insertions(+), 92 deletions(-) diff --git a/src/common/enums/text.ts b/src/common/enums/text.ts index 3b5da968c9..f4321b2521 100644 --- a/src/common/enums/text.ts +++ b/src/common/enums/text.ts @@ -311,6 +311,7 @@ export const TEXT = { successResetPassword: '密碼重置成功', successResetPaymentPassword: '交易密碼重置成功', successSubscribeCircle: '訂閱成功!🎉', + successSetSupportSetting: '支持反饋設置成功', successTopUp: '儲值成功', successUnblock: '已取消封鎖。該用戶現在可以評論你的作品和圍爐。', successUploadImage: '圖片上傳成功', @@ -691,6 +692,7 @@ export const TEXT = { successResetPassword: '密码重置成功', successResetPaymentPassword: '交易密码重置成功', successSubscribeCircle: '订阅成功!🎉', + successSetSupportSetting: '支持反馈设置成功', successTopUp: '储值成功', successUnblock: '已取消屏蔽。该用户现在可以评论你的作品和围炉。', successUploadImage: '图片上传成功', @@ -1095,6 +1097,7 @@ export const TEXT = { successResetPassword: 'Password successfully changed.', successResetPaymentPassword: 'Transaction Password successfully changed.', successSubscribeCircle: 'Circle successfully subscribed.', + successSetSupportSetting: 'Support setting updated', successTopUp: 'Topped up successfully', successUnblock: 'User unblocked. User can now comment on your articles.', successUploadImage: 'Image uploaded', diff --git a/src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx b/src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx index 8027f60661..1dccd0f1bd 100644 --- a/src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx +++ b/src/components/Editor/ToggleAccess/SetSupportSetting/Content.tsx @@ -1,3 +1,4 @@ +import { useQuery } from '@apollo/react-hooks' import { useFormik } from 'formik' import gql from 'graphql-tag' import _pickBy from 'lodash/pickBy' @@ -18,6 +19,8 @@ import { translate, validateSupportWords, } from '~/common/utils' +import { DRAFT_DETAIL } from '~/views/Me/DraftDetail/gql' +import { DraftDetailQuery } from '~/views/Me/DraftDetail/__generated__/DraftDetailQuery' import styles from './styles.css' import SupportPreview from './SupportPreview' @@ -32,15 +35,16 @@ interface FormProps { } interface FormValues { - supportRequest: string - supportResponse: string + requestForDonation: string | null + replyToDonator: string | null } const UPDATE_SUPPORT_REQUEST = gql` mutation UpdateSupportRequest($id: ID!) { editArticle(input: { id: $id }) { id - title + requestForDonation + replyToDonator } } ` @@ -53,7 +57,7 @@ const SupportSettingDialogContent: React.FC = ({ const [update] = useMutation( UPDATE_SUPPORT_REQUEST, undefined, - { showToast: false } + { showToast: true } ) const { lang } = useContext(LanguageContext) @@ -64,82 +68,93 @@ const SupportSettingDialogContent: React.FC = ({ const [tabType, setTanType] = useState(qsType || 'request') const [wordCount, setWordCount] = useState(0) - const { values, errors, touched, handleBlur, handleSubmit, setFieldValue } = - useFormik({ - initialValues: { - // TODO: wait for backend to query - supportRequest: '', - supportResponse: '', - }, - validate: ({ supportRequest, supportResponse }) => - _pickBy({ - supportRequest: validateSupportWords(supportRequest, lang), - supportResponse: validateSupportWords(supportResponse, lang), - }), - onSubmit: async ( - { supportRequest, supportResponse }, - { setSubmitting, setFieldError } - ) => { - try { - await update({ - variables: { - input: { - supportRequest, - supportResponse, - }, + const id = getQuery('draftId') + const { data } = useQuery(DRAFT_DETAIL, { + variables: { id }, + fetchPolicy: 'network-only', + }) + const draft = (data?.node?.__typename === 'Draft' && data.node) || undefined + + const { + values, + errors, + touched, + handleBlur, + handleSubmit, + setFieldValue, + isSubmitting = true, + } = useFormik({ + initialValues: { + // TODO: wait for backend to query + requestForDonation: draft ? draft.requestForDonation : '', + replyToDonator: draft ? draft.replyToDonator : '', + }, + validate: ({ requestForDonation, replyToDonator }) => + _pickBy({ + requestForDonation: validateSupportWords(requestForDonation!, lang), + replyToDonator: validateSupportWords(replyToDonator!, lang), + }), + onSubmit: async ( + { requestForDonation, replyToDonator }, + { setSubmitting, setFieldError } + ) => { + try { + const result = await update({ + variables: { + input: { + id: draft?.id!, + requestForDonation: values.requestForDonation, + replyToDonator: values.replyToDonator, + }, + }, + }) + console.log('result', result) + window.dispatchEvent( + new CustomEvent(ADD_TOAST, { + detail: { + color: 'green', + content: , }, }) + ) - window.dispatchEvent( - new CustomEvent(ADD_TOAST, { - detail: { - color: 'green', - content: , - }, - }) - ) - - setSubmitting(false) - closeDialog() - } catch (error) { - setSubmitting(false) - - const [messages, codes] = parseFormSubmitErrors(error as any, lang) - codes.forEach((code) => { - if (code === 'DISPLAYNAME_INVALID') { - setFieldError( - 'displayName', - translate({ id: 'hintDisplayName', lang }) - ) - } else { - setFieldError('supportRequest', messages[code]) - } - }) - } - }, - }) + setSubmitting(false) + closeDialog() + } catch (error) { + setSubmitting(false) + + const [messages, codes] = parseFormSubmitErrors(error as any, lang) + codes.forEach((code) => { + if (code === 'DISPLAYNAME_INVALID') { + setFieldError( + 'displayName', + translate({ id: 'hintDisplayName', lang }) + ) + } else { + setFieldError('requestForDonation', messages[code]) + } + }) + } + }, + }) const changeTabType = (newType: TabType) => { setQuery('type', newType) setTanType(newType) } - const onSave = async () => { - console.log('save') - } - onBack = async () => { console.log('back') } useEffect(() => { if (tabType === 'request') { - setWordCount(values.supportRequest.length) + setWordCount(values.requestForDonation!.length) } if (tabType === 'response') { - setWordCount(values.supportResponse.length) + setWordCount(values.replyToDonator!.length) } - }, [values.supportRequest, values.supportResponse]) + }, [values.requestForDonation, values.replyToDonator]) useEffect(() => { setWordCount(0) @@ -147,21 +162,25 @@ const SupportSettingDialogContent: React.FC = ({ const InnerForm = (tab: string) => { return ( -
+ {tab === 'request' && ( - setFieldValue('supportRequest', e.currentTarget.value) + setFieldValue('requestForDonation', e.currentTarget.value) } style={{ lineHeight: '1.5rem' }} /> @@ -171,15 +190,19 @@ const SupportSettingDialogContent: React.FC = ({ label={} name="description" required - placeholder={translate({ - id: 'supportResponseDescription', - lang, - })} - value={values.supportResponse} - error={touched.supportResponse && errors.supportResponse} + placeholder={ + draft + ? draft.replyToDonator! + : translate({ + id: 'supportResponseDescription', + lang, + }) + } + value={values.replyToDonator!} + error={touched.replyToDonator && errors.replyToDonator} onBlur={handleBlur} onChange={(e) => - setFieldValue('supportResponse', e.currentTarget.value) + setFieldValue('replyToDonator', e.currentTarget.value) } style={{ lineHeight: '1.5rem' }} /> @@ -191,6 +214,17 @@ const SupportSettingDialogContent: React.FC = ({ ) } + + const SubmitButton = ( + } + loading={isSubmitting} + /> + ) + return ( <> = ({ leftButton={ } - rightButton={ - } - /> - } + rightButton={SubmitButton} /> @@ -216,8 +245,8 @@ const SupportSettingDialogContent: React.FC = ({ diff --git a/src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx b/src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx index cbd7861c85..8a6562a2c0 100644 --- a/src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx +++ b/src/components/Editor/ToggleAccess/SetSupportSetting/SupportPreview.tsx @@ -9,11 +9,10 @@ const SupportPreview = ({ content: string tabType: string }) => { - // const [content, setContent] = useState('') return (
-

+ {!content && (tabType === 'request' ? ( ) : (

-

🎉 感謝支持!

+ 🎉 感謝支持! } -

+
{tabType === 'request' && ( diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 4dd716eadf..4ccd453cd5 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -1,9 +1,26 @@ import classNames from 'classnames' -import { useState } from 'react' +import { useContext, useState } from 'react' -import { CircleDigest, Translate, useEventListener } from '~/components' +import { + Button, + CircleDigest, + IconDollarCircle16, + TextIcon, + Translate, + useEventListener, + useMutation, + useRoute, + ViewerContext, +} from '~/components' +import PAY_TO from '~/components/GQL/mutations/payTo' +import updateDonation from '~/components/GQL/updates/donation' -import { SUPPORT_SUCCESS_ANIMATION } from '~/common/enums' +import { + CHAIN, + PATHS, + PAYMENT_CURRENCY as CURRENCY, + SUPPORT_SUCCESS_ANIMATION, +} from '~/common/enums' import { analytics } from '~/common/utils' import Animation from './Animation' @@ -12,6 +29,7 @@ import Donators from './Donators' import { fragments } from './gql' import styles from './styles.css' +import { PayTo as PayToMutate } from '~/components/GQL/mutations/__generated__/PayTo' import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' interface DonationProps { @@ -19,52 +37,132 @@ interface DonationProps { } const SupportWidget = ({ article }: DonationProps) => { + const { getQuery } = useRoute() + const mediaHash = getQuery('mediaHash') + const viewer = useContext(ViewerContext) + const [playShipWaiting, setPlayShipWaiting] = useState(false) const [showAnimation, setShowAnimation] = useState(false) + const [showAvatarAnimation, setShowAvatarAnimation] = useState(false) + const [showTransaction, setShowTransaction] = useState(false) + const [currency, setCurrency] = useState(CURRENCY.HKD) const supportWidgetClasses = classNames({ 'support-widget': true, hasCircle: article.access.circle, }) - useEventListener(SUPPORT_SUCCESS_ANIMATION, () => { - setShowAnimation(true) - }) + console.log({ article }) + + const [payTo] = useMutation(PAY_TO) + + useEventListener( + SUPPORT_SUCCESS_ANIMATION, + async (payload: { [key: string]: any }) => { + if (!payload || Object.keys(payload).length === 0) { + return + } + setCurrency(payload.currency) + setShowAvatarAnimation(true) + setShowTransaction(true) + + // HKD、LikeCoin + if (payload.currency !== CURRENCY.USDT) { + setShowAnimation(true) + return + } + + // USDT + setPlayShipWaiting(true) + setShowAnimation(true) + const { transactionResult, amount, recipientId, targetId } = + payload + + await payTo({ + variables: { + amount, + currency, + purpose: 'donation', + recipientId, + targetId, + chain: CHAIN.POLYGON, + txHash: transactionResult.hash, + }, + update: (cache) => { + updateDonation({ + cache, + mediaHash, + viewer, + }) + }, + }) + await transactionResult.wait() + setPlayShipWaiting(false) + } + ) return (
-
-
- -
- - {showAnimation && ( + {showAnimation && ( +
{ + playShipWaiting={playShipWaiting} + playEnd={() => { setShowAnimation(false) }} + currency={currency} /> - )} -

- -
- -

+
+ )} + {!showAnimation && ( +
+

+ +
+ +

+ +
+ +
-
- +
+ +
+ + {showTransaction && ( +

+ + + + +

+ )}
-
+ )} {article.access.circle && (
diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index 1c7ec59795..b9933fd2b6 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -13,9 +13,7 @@ .donation { position: relative; - padding: calc(var(--spacing-base) + var(--donation-area-button-height) / 2) - var(--spacing-base) - calc(var(--spacing-base) + var(--donation-area-avatar-height) / 2); + padding: var(--spacing-base); text-align: center; background: var(--color-yellow-lighter); border-radius: var(--spacing-x-tight); @@ -27,19 +25,25 @@ } & .donation-button { - position: absolute; - top: calc(var(--donation-area-button-height) / 2 * -1); - right: 0; - left: 0; + margin-top: var(--spacing-base); } & .donators { @mixin flex-center-all; - position: absolute; - right: 0; - bottom: calc(var(--donation-area-avatar-height) / 2 * -1); - left: 0; + margin-top: var(--spacing-loose); + } + + & .transaction { + @mixin flex-center-all; + + margin-top: var(--spacing-loose); + + & .transaction-button { + display: inline-block; + margin-left: var(--spacing-x-tight); + border-bottom: 1px solid var(--color-matters-gold); + } } } @@ -62,3 +66,8 @@ background: var(--color-grey-lighter); border-radius: 0 0 var(--spacing-x-tight) var(--spacing-x-tight); } + +.animation-hint { + height: 1.5rem; + margin: 0 auto; +} From cbc7e734c9708d046c8080088f8bd176b67d974b Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 31 Oct 2022 15:15:39 +0800 Subject: [PATCH 08/72] feat(Donation): revise donator add lazy load json in update avatar num to 8 update donator footer --- package-lock.json | 18 ++- package.json | 1 + .../ArticleDetail/SupportWidget/Animation.tsx | 6 +- .../SupportWidget/Donators/gql.ts | 2 +- .../SupportWidget/Donators/index.tsx | 130 ++++++++++-------- .../SupportWidget/Donators/styles.css | 41 +++++- .../ArticleDetail/SupportWidget/index.tsx | 15 +- .../ArticleDetail/SupportWidget/styles.css | 3 +- 8 files changed, 143 insertions(+), 73 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f4f8b872b..cf49a0b6f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "matters-web", - "version": "4.6.0", + "version": "4.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "matters-web", - "version": "4.6.0", + "version": "4.7.0", "license": "Apache-2.0", "dependencies": { "@apollo/react-common": "^3.1.3", @@ -74,6 +74,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^17.0.2", "react-focus-lock": "^2.7.1", + "react-intersection-observer": "^9.4.0", "react-lottie": "^1.2.3", "react-remove-scroll": "^2.4.3", "react-spring": "^9.5.4", @@ -35529,6 +35530,14 @@ "react": "^16.8.4 || ^17.0.0" } }, + "node_modules/react-intersection-observer": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.0.tgz", + "integrity": "sha512-v0403CmomOVlzhqFXlzOxg0ziLcVq8mfbP0AwAcEQWgZmR2OulOT79Ikznw4UlB3N+jlUYqLMe4SDHUOyp0t2A==", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0|| ^18.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -70279,6 +70288,11 @@ "prop-types": "^15.0.0" } }, + "react-intersection-observer": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.0.tgz", + "integrity": "sha512-v0403CmomOVlzhqFXlzOxg0ziLcVq8mfbP0AwAcEQWgZmR2OulOT79Ikznw4UlB3N+jlUYqLMe4SDHUOyp0t2A==" + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index 1c75cc5d5b..646b3be4f8 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^17.0.2", "react-focus-lock": "^2.7.1", + "react-intersection-observer": "^9.4.0", "react-lottie": "^1.2.3", "react-remove-scroll": "^2.4.3", "react-spring": "^9.5.4", diff --git a/src/views/ArticleDetail/SupportWidget/Animation.tsx b/src/views/ArticleDetail/SupportWidget/Animation.tsx index 80aed16d3b..e9990da7ed 100644 --- a/src/views/ArticleDetail/SupportWidget/Animation.tsx +++ b/src/views/ArticleDetail/SupportWidget/Animation.tsx @@ -1,4 +1,5 @@ import React, { useEffect } from 'react' +import { useInView } from 'react-intersection-observer' import Lottie, { EventListener } from 'react-lottie' import { Translate, useStep } from '~/components' @@ -64,11 +65,11 @@ const Animation: React.FC = ({ defaultStep = 'coinShip', }) => { const { currStep, forward } = useStep(defaultStep) - const isCoinShip = currStep === 'coinShip' const isShipWaiting = currStep === 'shipWaiting' const isShipSprinkHeart = currStep === 'shipSprinkleHeart' const isOpenHeart = currStep === 'openHeart' + const [ref, inView] = useInView() useEffect(() => { if (isShipWaiting) { @@ -101,10 +102,11 @@ const Animation: React.FC = ({ isClickToPauseDisabled: true, height: 136, width: 166, + isPaused: !inView, } return ( -
+

{isShipWaiting && currency === CURRENCY.LIKE && ( { const donators = ( edges?.map(({ node }) => node).filter((user) => !!user) || [] ).slice(0, 10) - console.log({ edges, donators }) const springStyles = useSpring({ // loop: true, @@ -36,71 +40,85 @@ const Donators = ({ article, showAvatarAnimation = false }: DonatorsProps) => { return ( {({ openDialog }) => ( -

+ {donatorsCount > 4 && ( -
- {donatorsCount} - 個人支持過・看全部 +
+
)} - +
)} ) diff --git a/src/views/ArticleDetail/SupportWidget/Donators/styles.css b/src/views/ArticleDetail/SupportWidget/Donators/styles.css index baeed4da3e..f40b39df6e 100644 --- a/src/views/ArticleDetail/SupportWidget/Donators/styles.css +++ b/src/views/ArticleDetail/SupportWidget/Donators/styles.css @@ -6,18 +6,38 @@ box-shadow: 0 0 0 2px var(--color-white); &:nth-child(1) { - z-index: 4; + z-index: 9; } &:nth-child(2) { - z-index: 3; + z-index: 8; } &:nth-child(3) { - z-index: 2; + z-index: 7; } &:nth-child(4) { + z-index: 6; + } + + &:nth-child(5) { + z-index: 5; + } + + &:nth-child(6) { + z-index: 4; + } + + &:nth-child(7) { + z-index: 3; + } + + &:nth-child(8) { + z-index: 2; + } + + &:nth-child(9) { z-index: 1; } } @@ -31,7 +51,20 @@ font-weight: var(--font-weight-semibold); line-height: 1.25rem; color: var(--color-white); - background: var(--color-matters-green); + background: var(--color-matters-gold); border-radius: 50%; } } + +.avatar-list-footer { + margin-top: var(--spacing-x-tight); + font-size: var(--font-size-xs); + line-height: 1.25rem; + color: var(--color-grey-dark); + + & .count { + padding-right: var(--spacing-xx-tight); + font-weight: var(--font-weight-bold); + color: var(--color-black); + } +} diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 4ccd453cd5..e03f478bd7 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -50,8 +50,6 @@ const SupportWidget = ({ article }: DonationProps) => { hasCircle: article.access.circle, }) - console.log({ article }) - const [payTo] = useMutation(PAY_TO) useEventListener( @@ -73,8 +71,7 @@ const SupportWidget = ({ article }: DonationProps) => { // USDT setPlayShipWaiting(true) setShowAnimation(true) - const { transactionResult, amount, recipientId, targetId } = - payload + const { transactionResult, amount, recipientId, targetId } = payload await payTo({ variables: { @@ -144,13 +141,17 @@ const SupportWidget = ({ article }: DonationProps) => {
{showTransaction && ( -

+

-

+
)}
)} diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index b9933fd2b6..f3bce7a7cb 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -38,10 +38,11 @@ @mixin flex-center-all; margin-top: var(--spacing-loose); + font-size: var(--font-size-xs); & .transaction-button { display: inline-block; - margin-left: var(--spacing-x-tight); + margin-left: var(--spacing-xx-tight); border-bottom: 1px solid var(--color-matters-gold); } } From 327bec73567a908778e750f037bb8046233c11c5 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 31 Oct 2022 15:22:03 +0800 Subject: [PATCH 09/72] style(Donation): remove unused code --- src/components/Dialogs/DonationDialog/index.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/Dialogs/DonationDialog/index.tsx b/src/components/Dialogs/DonationDialog/index.tsx index 9592e5d820..567a752afe 100644 --- a/src/components/Dialogs/DonationDialog/index.tsx +++ b/src/components/Dialogs/DonationDialog/index.tsx @@ -301,13 +301,6 @@ const BaseDonationDialog = ({ recipient={recipient} closeDialog={closeDialog} nextStep={() => { - // window.dispatchEvent( - // new CustomEvent(SUPPORT_SUCCESS_ANIMATION, { - // detail: { - // color: 'green', - // }, - // }) - // ) closeDialog() }} txId={payToTx?.id || ''} From a901929849b575581fccb6fed2e02228813de7b8 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Tue, 1 Nov 2022 16:21:51 +0800 Subject: [PATCH 10/72] feat(Donation): move to '~/components/Buttons/' --- src/common/enums/text.ts | 3 + src/components/Button/index.tsx | 4 + src/components/Button/styles.css | 12 +++ .../Buttons}/DonationButton/index.tsx | 89 +++++++++++++------ src/components/Buttons/index.tsx | 1 + .../ArticleDetail/SupportWidget/index.tsx | 2 +- 6 files changed, 81 insertions(+), 30 deletions(-) rename src/{views/ArticleDetail/SupportWidget => components/Buttons}/DonationButton/index.tsx (56%) diff --git a/src/common/enums/text.ts b/src/common/enums/text.ts index 3987e198be..400c6069b2 100644 --- a/src/common/enums/text.ts +++ b/src/common/enums/text.ts @@ -85,6 +85,7 @@ export const TEXT = { DISPLAYNAME_INVALID: '名稱不正確', displayName: '姓名', donation: '支持作者', + donationAgain: '再次支持', done: '完成', downloadApp: '下載應用', DRAFT_NOT_FOUND: '草稿不存在', @@ -456,6 +457,7 @@ export const TEXT = { DISPLAYNAME_INVALID: '名称不正确', displayName: '姓名', donation: '支持作者', + donationAgain: '再次支持', done: '完成', downloadApp: '下载应用', DRAFT_NOT_FOUND: '草稿不存在', @@ -833,6 +835,7 @@ export const TEXT = { DISPLAYNAME_INVALID: 'Invalid display name', displayName: 'Display Name', donation: 'Support Author', + donationAgain: 'Support Again', done: 'Done', downloadApp: 'Download App', DRAFT_NOT_FOUND: 'Draft not found', diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index f1ff653bd2..434d11753c 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -54,6 +54,8 @@ type ButtonColor = | 'gold' | 'red' | 'likecoin-green' + | 'yellow-lighter' + | 'gold-linear-gradient' type ButtonTextColor = Extract< ButtonColor, @@ -72,6 +74,8 @@ export type ButtonBgColor = Extract< | 'white' | 'half-black' | 'black' + | 'yellow-lighter' + | 'gold-linear-gradient' > type ButtonBgActiveColor = Extract< diff --git a/src/components/Button/styles.css b/src/components/Button/styles.css index 26b3cb453f..22c888808b 100644 --- a/src/components/Button/styles.css +++ b/src/components/Button/styles.css @@ -299,6 +299,18 @@ span.container { } } +.bg-yellow-lighter { + & .hotarea { + background: var(--color-yellow-lighter); + } +} + +.bg-gold-linear-gradient { + & .hotarea { + background: linear-gradient(93.62deg, #cda555 2.8%, #b48527 93%); + } +} + /* Background:hover */ .bg-active-grey-lighter { &:hover, diff --git a/src/views/ArticleDetail/SupportWidget/DonationButton/index.tsx b/src/components/Buttons/DonationButton/index.tsx similarity index 56% rename from src/views/ArticleDetail/SupportWidget/DonationButton/index.tsx rename to src/components/Buttons/DonationButton/index.tsx index 957be95a46..c28bedeb22 100644 --- a/src/views/ArticleDetail/SupportWidget/DonationButton/index.tsx +++ b/src/components/Buttons/DonationButton/index.tsx @@ -14,18 +14,22 @@ import { ADD_TOAST, REFETCH_DONATORS } from '~/common/enums' import { analytics } from '~/common/utils' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' -import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface DonationButtonProps { recipient: UserDonationRecipient targetId: string article: ArticleDetailPublic_article + supported?: boolean + disabled?: boolean } const DonationButton = ({ recipient, targetId, article, + supported = false, + disabled = false, }: DonationButtonProps) => { const viewer = useContext(ViewerContext) @@ -67,6 +71,31 @@ const DonationButton = ({ ) } + const onClick = (openDialog: () => void) => { + if (disabled) { + return + } + + analytics.trackEvent('click_button', { type: 'donate' }) + + if (!viewer.isAuthed) { + showLoginToast() + return + } + + if (viewer.isFrozen) { + forbid() + return + } + + if (recipient.id === viewer.id) { + forbid(true) + return + } + + openDialog() + } + return ( {({ openDialog }) => ( - + <> + {supported && ( + + )} + {!supported && ( + + )} + )} ) diff --git a/src/components/Buttons/index.tsx b/src/components/Buttons/index.tsx index 134c655549..f492c62f78 100644 --- a/src/components/Buttons/index.tsx +++ b/src/components/Buttons/index.tsx @@ -1,5 +1,6 @@ export * from './BackToHome' export * from './Bookmark' +export * from './DonationButton' export * from './FollowUser' export * from './Share' export * from './SignUp' diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index e03f478bd7..90fa3da6a9 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -12,6 +12,7 @@ import { useRoute, ViewerContext, } from '~/components' +import DonationButton from '~/components/Buttons/DonationButton' import PAY_TO from '~/components/GQL/mutations/payTo' import updateDonation from '~/components/GQL/updates/donation' @@ -24,7 +25,6 @@ import { import { analytics } from '~/common/utils' import Animation from './Animation' -import DonationButton from './DonationButton' import Donators from './Donators' import { fragments } from './gql' import styles from './styles.css' From 24133b0430b68d9116be72861fbc8c766fa2fd97 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Tue, 1 Nov 2022 16:38:17 +0800 Subject: [PATCH 11/72] feat(Donation): use Waypoint instead of react-intersection-observer --- package-lock.json | 14 --- package.json | 1 - .../ArticleDetail/SupportWidget/Animation.tsx | 85 ++++++++++--------- 3 files changed, 43 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf49a0b6f4..8694bc2b38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,6 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^17.0.2", "react-focus-lock": "^2.7.1", - "react-intersection-observer": "^9.4.0", "react-lottie": "^1.2.3", "react-remove-scroll": "^2.4.3", "react-spring": "^9.5.4", @@ -35530,14 +35529,6 @@ "react": "^16.8.4 || ^17.0.0" } }, - "node_modules/react-intersection-observer": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.0.tgz", - "integrity": "sha512-v0403CmomOVlzhqFXlzOxg0ziLcVq8mfbP0AwAcEQWgZmR2OulOT79Ikznw4UlB3N+jlUYqLMe4SDHUOyp0t2A==", - "peerDependencies": { - "react": "^15.0.0 || ^16.0.0 || ^17.0.0|| ^18.0.0" - } - }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -70288,11 +70279,6 @@ "prop-types": "^15.0.0" } }, - "react-intersection-observer": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.0.tgz", - "integrity": "sha512-v0403CmomOVlzhqFXlzOxg0ziLcVq8mfbP0AwAcEQWgZmR2OulOT79Ikznw4UlB3N+jlUYqLMe4SDHUOyp0t2A==" - }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index 646b3be4f8..1c75cc5d5b 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,6 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^17.0.2", "react-focus-lock": "^2.7.1", - "react-intersection-observer": "^9.4.0", "react-lottie": "^1.2.3", "react-remove-scroll": "^2.4.3", "react-spring": "^9.5.4", diff --git a/src/views/ArticleDetail/SupportWidget/Animation.tsx b/src/views/ArticleDetail/SupportWidget/Animation.tsx index e9990da7ed..27600b8aa5 100644 --- a/src/views/ArticleDetail/SupportWidget/Animation.tsx +++ b/src/views/ArticleDetail/SupportWidget/Animation.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react' -import { useInView } from 'react-intersection-observer' import Lottie, { EventListener } from 'react-lottie' +import { Waypoint } from 'react-waypoint' import { Translate, useStep } from '~/components' @@ -69,7 +69,7 @@ const Animation: React.FC = ({ const isShipWaiting = currStep === 'shipWaiting' const isShipSprinkHeart = currStep === 'shipSprinkleHeart' const isOpenHeart = currStep === 'openHeart' - const [ref, inView] = useInView() + // const [ref, inView] = useInView() useEffect(() => { if (isShipWaiting) { @@ -102,53 +102,54 @@ const Animation: React.FC = ({ isClickToPauseDisabled: true, height: 136, width: 166, - isPaused: !inView, } return ( -
-

- {isShipWaiting && currency === CURRENCY.LIKE && ( - +

+

+ {isShipWaiting && currency === CURRENCY.LIKE && ( + + )} + {isShipWaiting && currency === CURRENCY.USDT && ( + + )} +

+ {isCoinShip && ( + )} - {isShipWaiting && currency === CURRENCY.USDT && ( - + )} + {isShipSprinkHeart && ( + + )} + {isOpenHeart && ( + )} -

- {isCoinShip && ( - - )} - {isShipWaiting && ( - - )} - {isShipSprinkHeart && ( - - )} - {isOpenHeart && ( - - )} - -
+ +
+ ) } From 5fa1cb3048a91f60d1757d82b57727c991a806bb Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Tue, 1 Nov 2022 16:57:23 +0800 Subject: [PATCH 12/72] feat(SupportWidget): add supportRequest --- src/views/ArticleDetail/SupportWidget/gql.ts | 1 + .../ArticleDetail/SupportWidget/index.tsx | 31 +++++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/gql.ts b/src/views/ArticleDetail/SupportWidget/gql.ts index 55386771ba..10751e756a 100644 --- a/src/views/ArticleDetail/SupportWidget/gql.ts +++ b/src/views/ArticleDetail/SupportWidget/gql.ts @@ -18,6 +18,7 @@ export const fragments = { ...DigestRichCirclePublic } } + supportRequest ...DonatorsArticle } ${Donators.fragments.article} diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 90fa3da6a9..c85608dd86 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -50,6 +50,8 @@ const SupportWidget = ({ article }: DonationProps) => { hasCircle: article.access.circle, }) + const supportRequest = article.supportRequest + const [payTo] = useMutation(PAY_TO) useEventListener( @@ -111,19 +113,22 @@ const SupportWidget = ({ article }: DonationProps) => { )} {!showAnimation && (
-

- -
- -

+ {supportRequest &&

{supportRequest}

} + {!supportRequest && ( +

+ +
+ +

+ )}
Date: Tue, 1 Nov 2022 17:42:00 +0800 Subject: [PATCH 13/72] fix(DonationButton): Only reuse UI logic --- .../Buttons/DonationButton/index.tsx | 169 ++++-------------- .../SupportWidget/SupportButton/index.tsx | 108 +++++++++++ .../ArticleDetail/SupportWidget/index.tsx | 4 +- 3 files changed, 147 insertions(+), 134 deletions(-) create mode 100644 src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx diff --git a/src/components/Buttons/DonationButton/index.tsx b/src/components/Buttons/DonationButton/index.tsx index c28bedeb22..b5478895b9 100644 --- a/src/components/Buttons/DonationButton/index.tsx +++ b/src/components/Buttons/DonationButton/index.tsx @@ -1,141 +1,46 @@ -import { useContext } from 'react' - -import { - Button, - DonationDialog, - IconDonate24, - LoginButton, - TextIcon, - Translate, - ViewerContext, -} from '~/components' - -import { ADD_TOAST, REFETCH_DONATORS } from '~/common/enums' -import { analytics } from '~/common/utils' - -import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { Button, IconDonate24, TextIcon, Translate } from '~/components' interface DonationButtonProps { - recipient: UserDonationRecipient - targetId: string - article: ArticleDetailPublic_article - supported?: boolean - disabled?: boolean + supported: boolean + onClick?: () => void } -const DonationButton = ({ - recipient, - targetId, - article, - supported = false, - disabled = false, -}: DonationButtonProps) => { - const viewer = useContext(ViewerContext) - - const completeCallback = () => { - window.dispatchEvent(new CustomEvent(REFETCH_DONATORS, {})) - } - - const forbid = (isAuthor?: boolean) => { - window.dispatchEvent( - new CustomEvent(ADD_TOAST, { - detail: { - color: 'red', - content: isAuthor ? ( - - ) : ( - - ), - }, - }) - ) - } - - const showLoginToast = () => { - window.dispatchEvent( - new CustomEvent(ADD_TOAST, { - detail: { - color: 'green', - content: ( - - ), - customButton: , - buttonPlacement: 'center', - }, - }) - ) - } - - const onClick = (openDialog: () => void) => { - if (disabled) { - return - } - - analytics.trackEvent('click_button', { type: 'donate' }) - - if (!viewer.isAuthed) { - showLoginToast() - return - } - - if (viewer.isFrozen) { - forbid() - return - } - - if (recipient.id === viewer.id) { - forbid(true) - return - } - - openDialog() - } - +const DonationButton = ({ supported, onClick }: DonationButtonProps) => { return ( - - {({ openDialog }) => ( - <> - {supported && ( - - )} - {!supported && ( - - )} - + <> + {supported && ( + + )} + {!supported && ( + )} - + ) } diff --git a/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx b/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx new file mode 100644 index 0000000000..2a8f2de74b --- /dev/null +++ b/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx @@ -0,0 +1,108 @@ +import { useContext } from 'react' + +import { + DonationDialog, + LoginButton, + Translate, + ViewerContext, +} from '~/components' +import DonationButton from '~/components/Buttons/DonationButton' + +import { ADD_TOAST, REFETCH_DONATORS } from '~/common/enums' +import { analytics } from '~/common/utils' + +import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' +import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' + +interface SupportButtonProps { + recipient: UserDonationRecipient + targetId: string + article: ArticleDetailPublic_article + supported?: boolean +} + +const SupportButton = ({ + recipient, + targetId, + article, + supported = false, +}: SupportButtonProps) => { + const viewer = useContext(ViewerContext) + + const completeCallback = () => { + window.dispatchEvent(new CustomEvent(REFETCH_DONATORS, {})) + } + + const forbid = (isAuthor?: boolean) => { + window.dispatchEvent( + new CustomEvent(ADD_TOAST, { + detail: { + color: 'red', + content: isAuthor ? ( + + ) : ( + + ), + }, + }) + ) + } + + const showLoginToast = () => { + window.dispatchEvent( + new CustomEvent(ADD_TOAST, { + detail: { + color: 'green', + content: ( + + ), + customButton: , + buttonPlacement: 'center', + }, + }) + ) + } + + return ( + + {({ openDialog }) => ( + <> + { + analytics.trackEvent('click_button', { type: 'donate' }) + + if (!viewer.isAuthed) { + showLoginToast() + return + } + + if (viewer.isFrozen) { + forbid() + return + } + + if (recipient.id === viewer.id) { + forbid(true) + return + } + + openDialog() + }} + /> + + )} + + ) +} + +export default SupportButton diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index c85608dd86..9cdcc83c57 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -12,7 +12,6 @@ import { useRoute, ViewerContext, } from '~/components' -import DonationButton from '~/components/Buttons/DonationButton' import PAY_TO from '~/components/GQL/mutations/payTo' import updateDonation from '~/components/GQL/updates/donation' @@ -28,6 +27,7 @@ import Animation from './Animation' import Donators from './Donators' import { fragments } from './gql' import styles from './styles.css' +import SupportButton from './SupportButton' import { PayTo as PayToMutate } from '~/components/GQL/mutations/__generated__/PayTo' import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' @@ -131,7 +131,7 @@ const SupportWidget = ({ article }: DonationProps) => { )}
- Date: Wed, 2 Nov 2022 20:19:22 +0800 Subject: [PATCH 14/72] feat(SupportWidget): rename Support Setting API & add HasDonated GQL --- src/views/ArticleDetail/SupportWidget/gql.ts | 15 +++++++++++- .../ArticleDetail/SupportWidget/index.tsx | 24 +++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/gql.ts b/src/views/ArticleDetail/SupportWidget/gql.ts index 10751e756a..9467d4689c 100644 --- a/src/views/ArticleDetail/SupportWidget/gql.ts +++ b/src/views/ArticleDetail/SupportWidget/gql.ts @@ -18,7 +18,7 @@ export const fragments = { ...DigestRichCirclePublic } } - supportRequest + requestForDonation ...DonatorsArticle } ${Donators.fragments.article} @@ -34,8 +34,21 @@ export const fragments = { ...DigestRichCirclePrivate } } + replyToDonator } ${CircleDigest.Rich.fragments.circle.private} `, }, } + +export const HAS_DONATED = gql` + query HasDonated($mediaHash: String!, $senderId: ID) { + article(input: { mediaHash: $mediaHash }) { + donation: transactionsReceivedBy( + input: { senderId: $senderId, purpose: donation } + ) { + totalCount + } + } + } +` diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 9cdcc83c57..013ea85f5e 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -1,5 +1,6 @@ +import { useLazyQuery } from '@apollo/react-hooks' import classNames from 'classnames' -import { useContext, useState } from 'react' +import { useContext, useEffect, useState } from 'react' import { Button, @@ -25,12 +26,13 @@ import { analytics } from '~/common/utils' import Animation from './Animation' import Donators from './Donators' -import { fragments } from './gql' +import { fragments, HAS_DONATED } from './gql' import styles from './styles.css' import SupportButton from './SupportButton' import { PayTo as PayToMutate } from '~/components/GQL/mutations/__generated__/PayTo' import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' +import { HasDonated } from './__generated__/HasDonated' interface DonationProps { article: ArticleDetailPublic_article @@ -49,8 +51,20 @@ const SupportWidget = ({ article }: DonationProps) => { 'support-widget': true, hasCircle: article.access.circle, }) + const [getDonated, { called, loading, data: hasDonatedData }] = + useLazyQuery(HAS_DONATED, { + fetchPolicy: 'network-only', + }) - const supportRequest = article.supportRequest + useEffect(() => { + getDonated({ + variables: { mediaHash, senderId: viewer.id }, + }) + }, [viewer]) + + console.log({ called, loading, hasDonatedData }) + + const requestForDonation = article.requestForDonation const [payTo] = useMutation(PAY_TO) @@ -113,8 +127,8 @@ const SupportWidget = ({ article }: DonationProps) => { )} {!showAnimation && (
- {supportRequest &&

{supportRequest}

} - {!supportRequest && ( + {requestForDonation &&

{requestForDonation}

} + {!requestForDonation && (

Date: Wed, 2 Nov 2022 21:36:09 +0800 Subject: [PATCH 15/72] fix(SupportWidget): Fix the browser local cache cannot be updated in real time --- src/views/ArticleDetail/SupportWidget/gql.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/ArticleDetail/SupportWidget/gql.ts b/src/views/ArticleDetail/SupportWidget/gql.ts index 9467d4689c..979234c951 100644 --- a/src/views/ArticleDetail/SupportWidget/gql.ts +++ b/src/views/ArticleDetail/SupportWidget/gql.ts @@ -44,6 +44,7 @@ export const fragments = { export const HAS_DONATED = gql` query HasDonated($mediaHash: String!, $senderId: ID) { article(input: { mediaHash: $mediaHash }) { + id donation: transactionsReceivedBy( input: { senderId: $senderId, purpose: donation } ) { From 5ed897d8019f050bf2f2864a92c5a3e521687a6a Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 2 Nov 2022 21:39:38 +0800 Subject: [PATCH 16/72] feat(SupportWidget): update hasDonated query --- .../ArticleDetail/SupportWidget/index.tsx | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 013ea85f5e..b6b3ae6b01 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -1,4 +1,4 @@ -import { useLazyQuery } from '@apollo/react-hooks' +import { useQuery } from '@apollo/react-hooks' import classNames from 'classnames' import { useContext, useEffect, useState } from 'react' @@ -46,23 +46,25 @@ const SupportWidget = ({ article }: DonationProps) => { const [showAnimation, setShowAnimation] = useState(false) const [showAvatarAnimation, setShowAvatarAnimation] = useState(false) const [showTransaction, setShowTransaction] = useState(false) + const [supported, setSupported] = useState(false) const [currency, setCurrency] = useState(CURRENCY.HKD) const supportWidgetClasses = classNames({ 'support-widget': true, hasCircle: article.access.circle, }) - const [getDonated, { called, loading, data: hasDonatedData }] = - useLazyQuery(HAS_DONATED, { - fetchPolicy: 'network-only', - }) - useEffect(() => { - getDonated({ - variables: { mediaHash, senderId: viewer.id }, - }) - }, [viewer]) + const { data: hasDonatedData } = useQuery(HAS_DONATED, { + fetchPolicy: 'network-only', + variables: { mediaHash, senderId: viewer.id }, + }) - console.log({ called, loading, hasDonatedData }) + useEffect(() => { + if (hasDonatedData) { + if (hasDonatedData.article?.donation.totalCount === 1) { + setSupported(true) + } + } + }, [hasDonatedData]) const requestForDonation = article.requestForDonation @@ -149,6 +151,7 @@ const SupportWidget = ({ article }: DonationProps) => { recipient={article.author} targetId={article.id} article={article} + supported={supported} />

From 34073ca549a27de182334c1822d00c2753ac4b6f Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 2 Nov 2022 21:47:56 +0800 Subject: [PATCH 17/72] feat(SupportWidget): refetch hasDonated after donation --- src/views/ArticleDetail/SupportWidget/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index b6b3ae6b01..4f51ee6802 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -53,7 +53,7 @@ const SupportWidget = ({ article }: DonationProps) => { hasCircle: article.access.circle, }) - const { data: hasDonatedData } = useQuery(HAS_DONATED, { + const { data: hasDonatedData, refetch: hasDonatedRefetch } = useQuery(HAS_DONATED, { fetchPolicy: 'network-only', variables: { mediaHash, senderId: viewer.id }, }) @@ -83,6 +83,7 @@ const SupportWidget = ({ article }: DonationProps) => { // HKD、LikeCoin if (payload.currency !== CURRENCY.USDT) { setShowAnimation(true) + hasDonatedRefetch() return } @@ -111,6 +112,7 @@ const SupportWidget = ({ article }: DonationProps) => { }) await transactionResult.wait() setPlayShipWaiting(false) + hasDonatedRefetch() } ) From e5c17314896a7ca581900c4ea0dfbfead6b8aab2 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 3 Nov 2022 16:33:21 +0800 Subject: [PATCH 18/72] fix(SupportWidget): fix show Donation Again Button error when user is not sign-in --- src/views/ArticleDetail/SupportWidget/index.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 4f51ee6802..6f5b320242 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -53,14 +53,18 @@ const SupportWidget = ({ article }: DonationProps) => { hasCircle: article.access.circle, }) - const { data: hasDonatedData, refetch: hasDonatedRefetch } = useQuery(HAS_DONATED, { - fetchPolicy: 'network-only', - variables: { mediaHash, senderId: viewer.id }, - }) + const { data: hasDonatedData, refetch: hasDonatedRefetch } = + useQuery(HAS_DONATED, { + fetchPolicy: 'network-only', + variables: { mediaHash, senderId: viewer.id }, + }) useEffect(() => { if (hasDonatedData) { - if (hasDonatedData.article?.donation.totalCount === 1) { + if ( + viewer.id !== '' && + hasDonatedData.article?.donation.totalCount === 1 + ) { setSupported(true) } } From 81c27182ff821db6ce5062b722981dd1a5a23a1a Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 4 Nov 2022 17:02:17 +0800 Subject: [PATCH 19/72] feat(SupportWidget): revise SupportWidget add replyToDonator show Transaction when viewer has supported --- src/views/ArticleDetail/SupportWidget/gql.ts | 2 +- .../ArticleDetail/SupportWidget/index.tsx | 89 +++++++++++++++---- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/gql.ts b/src/views/ArticleDetail/SupportWidget/gql.ts index 979234c951..1f148a9cd0 100644 --- a/src/views/ArticleDetail/SupportWidget/gql.ts +++ b/src/views/ArticleDetail/SupportWidget/gql.ts @@ -34,7 +34,6 @@ export const fragments = { ...DigestRichCirclePrivate } } - replyToDonator } ${CircleDigest.Rich.fragments.circle.private} `, @@ -50,6 +49,7 @@ export const HAS_DONATED = gql` ) { totalCount } + replyToDonator } } ` diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 6f5b320242..496f3543c5 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -3,9 +3,11 @@ import classNames from 'classnames' import { useContext, useEffect, useState } from 'react' import { + Avatar, Button, CircleDigest, IconDollarCircle16, + Spacer, TextIcon, Translate, useEventListener, @@ -45,7 +47,6 @@ const SupportWidget = ({ article }: DonationProps) => { const [playShipWaiting, setPlayShipWaiting] = useState(false) const [showAnimation, setShowAnimation] = useState(false) const [showAvatarAnimation, setShowAvatarAnimation] = useState(false) - const [showTransaction, setShowTransaction] = useState(false) const [supported, setSupported] = useState(false) const [currency, setCurrency] = useState(CURRENCY.HKD) const supportWidgetClasses = classNames({ @@ -71,6 +72,10 @@ const SupportWidget = ({ article }: DonationProps) => { }, [hasDonatedData]) const requestForDonation = article.requestForDonation + const replyToDonator = hasDonatedData?.article?.replyToDonator?.replaceAll( + '#', + ` ${viewer.displayName} ` + ) const [payTo] = useMutation(PAY_TO) @@ -82,7 +87,6 @@ const SupportWidget = ({ article }: DonationProps) => { } setCurrency(payload.currency) setShowAvatarAnimation(true) - setShowTransaction(true) // HKD、LikeCoin if (payload.currency !== CURRENCY.USDT) { @@ -135,21 +139,70 @@ const SupportWidget = ({ article }: DonationProps) => { )} {!showAnimation && (
- {requestForDonation &&

{requestForDonation}

} - {!requestForDonation && ( -

- -
- -

+ {supported && ( + <> + {replyToDonator && ( +
+ +

+ + {article.author.displayName} + + +

+ +

{replyToDonator}

+
+ )} + {!replyToDonator && ( +
+

+ + + +

+ +

+ + {viewer.displayName} + +

+
+ )} + + )} + + {!supported && ( + <> + {requestForDonation &&

{requestForDonation}

} + {!requestForDonation && ( +

+ +
+ +

+ )} + )}
@@ -168,7 +221,7 @@ const SupportWidget = ({ article }: DonationProps) => { />
- {showTransaction && ( + {supported && (
From 50360e16c18163bfd5ce5e56478106e3f3b973f3 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 4 Nov 2022 17:07:16 +0800 Subject: [PATCH 20/72] feat(SupportWidget): show donators when articles have donors --- src/views/ArticleDetail/SupportWidget/index.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 496f3543c5..7590a8d0f3 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -214,12 +214,14 @@ const SupportWidget = ({ article }: DonationProps) => { />
-
- -
+ {article.donations.totalCount > 0 && ( +
+ +
+ )} {supported && (
From a601c9c43681362d9a1e72e0dd41fe3b923ef96a Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 4 Nov 2022 17:46:38 +0800 Subject: [PATCH 21/72] feat(SupportWidget): show spinner when query HAS_DONATED --- .../ArticleDetail/SupportWidget/index.tsx | 217 ++++++++++-------- .../ArticleDetail/SupportWidget/styles.css | 3 +- 2 files changed, 117 insertions(+), 103 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 7590a8d0f3..82b752b3f9 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -7,6 +7,7 @@ import { Button, CircleDigest, IconDollarCircle16, + IconSpinner16, Spacer, TextIcon, Translate, @@ -54,11 +55,14 @@ const SupportWidget = ({ article }: DonationProps) => { hasCircle: article.access.circle, }) - const { data: hasDonatedData, refetch: hasDonatedRefetch } = - useQuery(HAS_DONATED, { - fetchPolicy: 'network-only', - variables: { mediaHash, senderId: viewer.id }, - }) + const { + loading, + data: hasDonatedData, + refetch: hasDonatedRefetch, + } = useQuery(HAS_DONATED, { + fetchPolicy: 'network-only', + variables: { mediaHash, senderId: viewer.id }, + }) useEffect(() => { if (hasDonatedData) { @@ -139,111 +143,122 @@ const SupportWidget = ({ article }: DonationProps) => { )} {!showAnimation && (
- {supported && ( + {loading && } + {hasDonatedData && ( <> - {replyToDonator && ( -
- -

- - {article.author.displayName} - - -

- -

{replyToDonator}

-
+ {supported && ( + <> + {replyToDonator && ( +
+ +

+ + {article.author.displayName} + + + + +

+ +

{replyToDonator}

+
+ )} + {!replyToDonator && ( +
+

+ + + +

+ +

+ + {viewer.displayName} + +

+
+ )} + )} - {!replyToDonator && ( -
-

- + + {!supported && ( + <> + {requestForDonation &&

{requestForDonation}

} + {!requestForDonation && ( +

- -

- -

- - {viewer.displayName} - -

-
+
+ +

+ )} + )} - - )} - {!supported && ( - <> - {requestForDonation &&

{requestForDonation}

} - {!requestForDonation && ( -

- -
- + +

+ + {article.donations.totalCount > 0 && ( +
+ -

+
)} - - )} - -
- -
- {article.donations.totalCount > 0 && ( -
- -
- )} - - {supported && ( -
- - - - -
+ {supported && ( +
+ + + + +
+ )} + )}
)} diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index f3bce7a7cb..cd3405ec15 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -19,8 +19,7 @@ border-radius: var(--spacing-x-tight); & p { - font-size: var(--font-size-xs); - font-weight: var(--font-weight-light); + font-size: var(--font-size-sm); line-height: 1.25rem; } From b6fe29cf6560634e45c20c16dce100955ff8a995 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Fri, 4 Nov 2022 18:17:35 +0800 Subject: [PATCH 22/72] fix(SupportWidget): fix error when reload the page --- src/views/ArticleDetail/SupportWidget/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 82b752b3f9..98d0157d5e 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -144,7 +144,7 @@ const SupportWidget = ({ article }: DonationProps) => { {!showAnimation && (
{loading && } - {hasDonatedData && ( + {!loading && ( <> {supported && ( <> From f27f0421a647be76ae156ca649890de355f0bdeb Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 7 Nov 2022 08:59:08 +0800 Subject: [PATCH 23/72] style(DonationButton): return early --- .../Buttons/DonationButton/index.tsx | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/components/Buttons/DonationButton/index.tsx b/src/components/Buttons/DonationButton/index.tsx index b5478895b9..5d45b1ba71 100644 --- a/src/components/Buttons/DonationButton/index.tsx +++ b/src/components/Buttons/DonationButton/index.tsx @@ -6,41 +6,39 @@ interface DonationButtonProps { } const DonationButton = ({ supported, onClick }: DonationButtonProps) => { + if (supported) { + return ( + + ) + } return ( - <> - {supported && ( - - )} - {!supported && ( - - )} - + ) } From f19172926fe7cafcf78b641bb0888251683c067b Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 7 Nov 2022 09:01:17 +0800 Subject: [PATCH 24/72] style(Animation): remove unused code --- src/views/ArticleDetail/SupportWidget/Animation.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/views/ArticleDetail/SupportWidget/Animation.tsx b/src/views/ArticleDetail/SupportWidget/Animation.tsx index 27600b8aa5..73a81ef6cd 100644 --- a/src/views/ArticleDetail/SupportWidget/Animation.tsx +++ b/src/views/ArticleDetail/SupportWidget/Animation.tsx @@ -69,7 +69,6 @@ const Animation: React.FC = ({ const isShipWaiting = currStep === 'shipWaiting' const isShipSprinkHeart = currStep === 'shipSprinkleHeart' const isOpenHeart = currStep === 'openHeart' - // const [ref, inView] = useInView() useEffect(() => { if (isShipWaiting) { From 9d387fc8fc55f8c7cb45cf0771b223b03166202d Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 7 Nov 2022 09:43:07 +0800 Subject: [PATCH 25/72] feat(Donator): extract Avatar as a reusable component --- .../SupportWidget/Donators/index.tsx | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/Donators/index.tsx b/src/views/ArticleDetail/SupportWidget/Donators/index.tsx index 13bced8fe6..0137538f7b 100644 --- a/src/views/ArticleDetail/SupportWidget/Donators/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/Donators/index.tsx @@ -7,7 +7,7 @@ import { LanguageContext, TextIcon, } from '~/components' -import { Avatar } from '~/components/Avatar' +import { Avatar, AvatarProps } from '~/components/Avatar' import { IMAGE_PIXEL } from '~/common/enums' import { translate } from '~/common/utils' @@ -17,6 +17,18 @@ import styles from './styles.css' import { DonatorsArticle } from './__generated__/DonatorsArticle' +type AvatarItemPros = Pick + +const AvatarItem = ({ user }: AvatarItemPros) => { + return ( + + ) +} + interface DonatorsProps { article: DonatorsArticle showAvatarAnimation?: boolean @@ -32,7 +44,6 @@ const Donators = ({ article, showAvatarAnimation = false }: DonatorsProps) => { ).slice(0, 10) const springStyles = useSpring({ - // loop: true, from: { x: -50 }, to: { x: 0 }, }) @@ -64,31 +75,14 @@ const Donators = ({ article, showAvatarAnimation = false }: DonatorsProps) => { }} key={index} > - + )} - {index !== 0 && ( - - )} + {index !== 0 && } )} {!showAvatarAnimation && ( - + )} ) From b7b68433fe5ab7b3f5e83b3ba31cb6cd212caf77 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 7 Nov 2022 10:03:17 +0800 Subject: [PATCH 26/72] feat(SupportWidget): update border-radius --- src/views/ArticleDetail/SupportWidget/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index cd3405ec15..3292aa941e 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -16,7 +16,7 @@ padding: var(--spacing-base); text-align: center; background: var(--color-yellow-lighter); - border-radius: var(--spacing-x-tight); + border-radius: 1.25rem; & p { font-size: var(--font-size-sm); From 6858f111b18d2d92375e9a23d75e4aa77aceb5ac Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 7 Nov 2022 10:30:13 +0800 Subject: [PATCH 27/72] feat(SupportWidget): vertical align transaction --- src/views/ArticleDetail/SupportWidget/index.tsx | 2 +- src/views/ArticleDetail/SupportWidget/styles.css | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 98d0157d5e..831f42f8e6 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -238,7 +238,7 @@ const SupportWidget = ({ article }: DonationProps) => { {supported && (
- + - {donatorsCount > 4 && ( -
- -
- )} + 個人支持過・看全部 + + +
From 6257c1b20ccf3201bfe9ee360a85d1038a8b8d8b Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:53:51 +0800 Subject: [PATCH 29/72] feat(Donation): update size of DonationButton --- src/components/Button/index.tsx | 1 + src/components/Buttons/DonationButton/index.tsx | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 434d11753c..497ded5735 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -14,6 +14,7 @@ export type ButtonWidth = | '7rem' | '8rem' | '10.5rem' + | '19.5rem' | '100%' | undefined | null diff --git a/src/components/Buttons/DonationButton/index.tsx b/src/components/Buttons/DonationButton/index.tsx index 5d45b1ba71..291d5a6e15 100644 --- a/src/components/Buttons/DonationButton/index.tsx +++ b/src/components/Buttons/DonationButton/index.tsx @@ -9,7 +9,7 @@ const DonationButton = ({ supported, onClick }: DonationButtonProps) => { if (supported) { return ( @@ -27,7 +27,7 @@ const DonationButton = ({ supported, onClick }: DonationButtonProps) => { } return ( From 9e88e33889bdb09e07bf8132a84db41d206deef1 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:55:17 +0800 Subject: [PATCH 30/72] feat(SupportWidget): revise size of avatar list --- src/views/ArticleDetail/SupportWidget/Donators/index.tsx | 6 +++--- src/views/ArticleDetail/SupportWidget/Donators/styles.css | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/Donators/index.tsx b/src/views/ArticleDetail/SupportWidget/Donators/index.tsx index 4fa3c4e7bd..f2c9a05f67 100644 --- a/src/views/ArticleDetail/SupportWidget/Donators/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/Donators/index.tsx @@ -24,7 +24,7 @@ const AvatarItem = ({ user }: AvatarItemPros) => { ) } @@ -71,8 +71,8 @@ const Donators = ({ article, showAvatarAnimation = false }: DonatorsProps) => { {index === 0 && ( Date: Mon, 7 Nov 2022 17:22:43 +0800 Subject: [PATCH 31/72] feat(Animation): lazy load json data --- .../ArticleDetail/SupportWidget/Animation.tsx | 107 ++++++++++-------- 1 file changed, 62 insertions(+), 45 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/Animation.tsx b/src/views/ArticleDetail/SupportWidget/Animation.tsx index 73a81ef6cd..c89817b9e0 100644 --- a/src/views/ArticleDetail/SupportWidget/Animation.tsx +++ b/src/views/ArticleDetail/SupportWidget/Animation.tsx @@ -1,56 +1,15 @@ -import React, { useEffect } from 'react' +import React, { useEffect, useState } from 'react' import Lottie, { EventListener } from 'react-lottie' import { Waypoint } from 'react-waypoint' -import { Translate, useStep } from '~/components' +import { IconSpinner16, Translate, useStep } from '~/components' import { PAYMENT_CURRENCY as CURRENCY } from '~/common/enums' -import * as coinShip from '@/public/static/json/coin-ship.json' -import * as openHeart from '@/public/static/json/open-heart.json' -import * as shipSprinkleHeart from '@/public/static/json/ship-sprinkle-heart.json' -import * as shipWaiting from '@/public/static/json/ship-waiting.json' - import styles from './styles.css' type Step = 'coinShip' | 'shipWaiting' | 'shipSprinkleHeart' | 'openHeart' -const coinShipOptions = { - loop: false, - autoplay: true, - animationData: coinShip, - rendererSettings: { - preserveAspectRatio: 'xMidYMid slice', - }, -} - -const shipWaitingOptions = { - loop: true, - autoplay: true, - animationData: shipWaiting, - rendererSettings: { - preserveAspectRatio: 'xMidYMid slice', - }, -} - -const shipSprinkleHeartOptions = { - loop: false, - autoplay: true, - animationData: shipSprinkleHeart, - rendererSettings: { - preserveAspectRatio: 'xMidYMid slice', - }, -} - -const openHeartOptions = { - loop: false, - autoplay: true, - animationData: openHeart, - rendererSettings: { - preserveAspectRatio: 'xMidYMid slice', - }, -} - interface Props { playEnd: () => void playShipWaiting: boolean @@ -70,12 +29,45 @@ const Animation: React.FC = ({ const isShipSprinkHeart = currStep === 'shipSprinkleHeart' const isOpenHeart = currStep === 'openHeart' + const [coinShipData, setCoinShipData] = useState() + const [shipWaitingData, setShipWaitingData] = useState() + const [shipSprinkHeartData, setShipSprinkHeartData] = useState() + const [openHeartData, setOpenHeartData] = useState() + + useEffect(() => { + import('@/public/static/json/coin-ship.json').then((res) => + setCoinShipData(res.default) + ) + import('@/public/static/json/ship-waiting.json').then((res) => + setShipWaitingData(res.default) + ) + import('@/public/static/json/ship-sprinkle-heart.json').then((res) => + setShipSprinkHeartData(res.default) + ) + import('@/public/static/json/open-heart.json').then((res) => + setOpenHeartData(res.default) + ) + }, []) + useEffect(() => { if (isShipWaiting) { forward('shipSprinkleHeart') } }, [playShipWaiting]) + const defaultOptions = { + loop: false, + autoplay: true, + rendererSettings: { + preserveAspectRatio: 'xMidYMid slice', + }, + } + + const coinShipOptions = { + ...defaultOptions, + animationData: coinShipData, + } + const coinShipListener: EventListener = { eventName: 'complete', callback: () => { @@ -83,13 +75,29 @@ const Animation: React.FC = ({ }, } - const shiSprinkleHeartListener: EventListener = { + const shipWaitingOptions = { + ...defaultOptions, + loop: true, + animationData: shipSprinkHeartData, + } + + const shipSprinkleHeartOptions = { + ...defaultOptions, + animationData: shipSprinkHeartData, + } + + const shipSprinkleHeartListener: EventListener = { eventName: 'complete', callback: () => { forward('openHeart') }, } + const openHeartOptions = { + ...defaultOptions, + animationData: openHeartData, + } + const openHeartListener: EventListener = { eventName: 'complete', callback: () => { @@ -103,6 +111,15 @@ const Animation: React.FC = ({ width: 166, } + if ( + !coinShipData || + !shipWaitingData || + !shipSprinkHeartData || + !openHeartData + ) { + return + } + return (
@@ -135,7 +152,7 @@ const Animation: React.FC = ({ {isShipSprinkHeart && ( )} From cc21ac5107c6fa0e5ce659f1ca3d79bfba2537c0 Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Mon, 7 Nov 2022 17:42:44 +0800 Subject: [PATCH 32/72] feat(auth): revise authentication dialogs --- .../images/auth-source/appreciation.png | Bin 0 -> 31380 bytes public/static/images/auth-source/bookmark.png | Bin 0 -> 21008 bytes public/static/images/auth-source/circle.png | Bin 0 -> 24759 bytes public/static/images/auth-source/collect.png | Bin 0 -> 29461 bytes public/static/images/auth-source/comment.png | Bin 0 -> 26166 bytes public/static/images/auth-source/create.png | Bin 0 -> 32311 bytes public/static/images/auth-source/enter.png | Bin 0 -> 24204 bytes public/static/images/auth-source/follow.png | Bin 0 -> 23791 bytes public/static/images/auth-source/support.png | Bin 0 -> 24132 bytes src/common/enums/events.ts | 14 ++ src/common/enums/text.ts | 6 +- .../DropdownActions/ExtendButton.tsx | 21 +- .../ArticleDigest/Feed/FollowButton/index.tsx | 20 +- src/components/Buttons/Bookmark/Subscribe.tsx | 15 +- src/components/Buttons/FollowUser/Follow.tsx | 24 +- src/components/Buttons/Write/index.tsx | 20 +- src/components/CircleDigest/Price/index.tsx | 39 +-- .../FooterActions/ReplyButton/index.tsx | 7 +- .../Dialogs/MigrationDialog/Upload.tsx | 13 +- src/components/Editor/BottomBar/index.tsx | 2 +- .../Editor/SettingsDialog/index.tsx | 2 +- .../Editor/Sidebar/Collection/index.tsx | 4 +- .../SelectAuthMethodForm/SourceHeader.tsx | 231 ++++++++++++++++++ .../Forms/SelectAuthMethodForm/index.tsx | 9 +- .../Forms/SelectAuthMethodForm/styles.css | 21 ++ .../UniversalAuthDialog/index.tsx | 37 ++- .../TagDigest/Buttons/FollowButton/Follow.tsx | 31 ++- .../AppreciationButton/AnonymousButton.tsx | 21 +- src/views/ArticleDetail/Collection/index.tsx | 2 +- .../SupportWidget/DonationButton/index.tsx | 34 +-- .../Toolbar/CommentBar/index.tsx | 7 +- .../Toolbar/DonationButton/index.tsx | 33 +-- .../Circle/Profile/FollowButton/Follow.tsx | 20 +- src/views/Circle/SubscriptionBanner/index.tsx | 31 +-- .../Feed/FollowingRecommendCircle/index.tsx | 31 +-- .../TagDetail/Buttons/FollowButton/Follow.tsx | 20 +- 36 files changed, 537 insertions(+), 178 deletions(-) create mode 100644 public/static/images/auth-source/appreciation.png create mode 100644 public/static/images/auth-source/bookmark.png create mode 100644 public/static/images/auth-source/circle.png create mode 100644 public/static/images/auth-source/collect.png create mode 100644 public/static/images/auth-source/comment.png create mode 100644 public/static/images/auth-source/create.png create mode 100644 public/static/images/auth-source/enter.png create mode 100644 public/static/images/auth-source/follow.png create mode 100644 public/static/images/auth-source/support.png create mode 100644 src/components/Forms/SelectAuthMethodForm/SourceHeader.tsx diff --git a/public/static/images/auth-source/appreciation.png b/public/static/images/auth-source/appreciation.png new file mode 100644 index 0000000000000000000000000000000000000000..fe58d944d9c7e8689f1092a9a766d8dfef957b54 GIT binary patch literal 31380 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 Lz6M6kI_&=f_0Ck& literal 0 HcmV?d00001 diff --git a/public/static/images/auth-source/bookmark.png b/public/static/images/auth-source/bookmark.png new file mode 100644 index 0000000000000000000000000000000000000000..29be972676a796b4b9cbe3f710228abc36dc0aaa GIT binary patch literal 21008 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 literal 0 HcmV?d00001 diff --git a/public/static/images/auth-source/collect.png b/public/static/images/auth-source/collect.png new file mode 100644 index 0000000000000000000000000000000000000000..1515cad8e8f6d6484e4458381323902798c34c19 GIT binary patch literal 29461 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 H75qN{u6Srj literal 0 HcmV?d00001 diff --git a/public/static/images/auth-source/comment.png b/public/static/images/auth-source/comment.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c925f33e84252ed17821a3b1f696f3d760b591 GIT binary patch literal 26166 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 Bfo=c* literal 0 HcmV?d00001 diff --git a/public/static/images/auth-source/create.png b/public/static/images/auth-source/create.png new file mode 100644 index 0000000000000000000000000000000000000000..056c0a3b39534f7ec51a98cdea2a2b47582d08ea GIT binary patch literal 32311 zcmeFYXE1tM&`pf@RbO5acPl=n*dX=!dXvqZ4a<{z z!jum${m%5Q=I`5dLtqTW?5f5+xd^@aZ$AqWF9LWNb z7YnQXdwuyX2iDG`h%BZ38rubx7SDYLqs#002&%aRONo#-+0zIVjR(7tzJ|KE%|x?A*+PWA zJJ9x&k{pPL(3C6|H;m#^PUM#Z|GbG{ES!*?*wnk~ZD6>g6CB37DJ5XMelJ-b+-CiT z?`S?LoNnYv+jtpgJ8j)A0GDOM1*V@Aj1>0%4S%QMMqnaHEAd?s%VX3Pu&XBmjW4x{ zpbo@)NC913;G2Le2l%z+oW_}O@hzg;dvf~QyFp6eNj7060gJSAEQ7`uf~I*8PvDWwpdj!~6*U&rf$+Lp5I_>L~S8U^(3!fK&$v zxJ*O6v?5ej2cK&{%J4L_d30T72=e(?_SrxcSuBKVMYS& zhA%MML@%YZla>A{`&p^iDpO=-jWV9Q87 z5(_YXSV<(6OsUSmUET=_8nkAd`vOJK%7NBPQgi&q=lJm^RC)IpA3M%Q_T=v1+!%Zz z*|glgyXoh?^BE1VJK^0H4aWiUe?B!Mhx=JI(}3kN&irfXpP+laTt-uW6d~#xCWI4U zNr{Liq7I@OqVGiYN&W;Fm;Yu4@}zB#=L- zRsjC?PkkLj`w9x*{BB`OP{h*(I}^MhAO#$${{5Hl@3w0}O>vG}@}+qM4v^k~u>vp( zQ8bB#M;d_nU&rNu0I4WWU{}w$W^g+~i_vz|x=-5*4I!PCZ5C(i0hcU6(i(K*w~=6|UM|K=wQ0BhSGI^AOqr3uJ|X|~q8 zzP_WYg|CLW69^-tyEXn9mX%P|91SdIGS)a*A`_jlsc#SqEDkgPUvd=sa4?N zn4EI3J>Fnx+aCIOuM|&{sXY+mx%z17~AgS+L5=Oa3>Ww^0vTlYFkK6g5lc z6z%t#Vwzg7_LAm97q(l`XLl=k`vs)s&_7>Pj7(VCu`ym|dt?V|_<<;71Q~<3v~8uQ zvk|W@HC8_5yQwQh>Ya{WQ)m6f`7Wf+`Jf^Iy641+W~f`K zbk#fEJTTr!z4gIBmE50(R<`!-tfi)`f%;O%)XNj+_y{Ic!|z3S^hKU=XgK=N-!ypW7yGhd+R$k zddW7MIjd&?3L8+DBC=xQYH2;&OKC$W+IUh*=DZP_oq9}KK~%7Dn!qut%Aota=xQ_b zQaD1NIfLu;S|LxFEQ8#){2yo@7FV7-jO`oJ`Sq4bB7fM-a?RQOLVCaTpYLQl9YM$m zXiGeQP#X6I0uGJPr^I`Kq}3tJ#MS+meAMduR`*au$(?;+h;pJ(OOLBx36A@+_e{L7 zq^(X}2pu+urT=^0@E@y9j7gl2-9`M?1`%lukb7lIElO5HISDE-Agu}jh>9~Tnw&6r z#^)<#hi%f2(0i!8Mt?FGsxM7Ugui2&AHh{34gH$IRM}{E}l-%*ir>pSk_85XqywWi&9wD9B@`3 zT(XuZb)@?@vUgk47Y{Qto^xIEStu*k=R8PKK-t>@EWsBUWolCSXKwxfiUOJRPNiM# zQC;5HblOm;lUDK_58C($NX9I3?+@0g*_1SLckb)>%FIx(Q=B&@7T3Ak-rQOKtY5>T z$^if=7f8}+H2mDc)virNIx6G%@qBTMKy56Vn+D=z{15=V3J;((jw_~tQcijVujkH) zyfGd=7@x7h;)_ubu(IxrRahtb4Eg8xuMThNnCkatLj@v~in7xx27TR^C&D>dF?j`V zBC^8{2_JfyJ!G=eLE<3qO;Gj-BKB{AZ+x??WSjge@AMN}bi{mTC;8C2ZBGHfnY{&+ zphhr3If92qmx022uvf}4&onmf;wlF**s?7+BEldNV3s{iyD7e+`fb_^mAwHv!Qe0% zDR27l)(K#;PO4?*ZY3&5tB@D>3KvMbKU3&prj3gr>?^4UArsUSR4Q zEzkzZ(-g8YChyxeVwL=OaG3NRPkraB({Dy9CQJ-Xn}NLbiYo5@GWJU}1@b_RA5#GU zqH=HkYb~XSWy$fBq#C2~_k65Z7%Bw6eT38>O1zl|52jP&O=ivdW*u}|yijYkMSsLN zc-pNrW79kSylKNOT=TvDug{rs`;wy8ZyOB9==zBHNt0;8Ya8fMHZPH+B*hEKO)SQ# zRMT04*jrvUiPDlQpGxJle_h;@$*A=o_M)2&)n4 zozuY{?}Y0a|G@|7xlfG6*o~#%L27@;BYGst?T!AtsD(~?=N(c1tZ^b9^We`Dph0rLpB=Sm-t_z+-%znI0S9m=v-ePw(PqvN2v17 zd$PyZZja@;&&}+2$%>$+Q=McB0ns!kUH|AlBF^O3Kp_zTMy04mA)`Y6f3 z_#qJ<9D7IXBLpPxf4ljC&37;)uF)e{dTXr2dta#&l%Yq!`skzV6FOo(miGD&*kS7T zfa;HuxZ~C`CD>bCH_fYu20@x&1(2f5lfKNxaZ_X1(1qgN<^)1v_`!JuOxZ5Y;*@IaB~oq6qnlGt2>v!22I%iIkk@IHqxDtlYR19OAal44Hv z$h3hL+n?&~A>;d_e-GH$l+9-9bB77#ZZu5C@ypLT9kS?PS~d3oZG)0}Y`C=bqhx=P zc#dd>y6rgyY?@7vu^bYaw0+lP0F#FS2u@5bdvvjRTMU9!f>~sTNS_PQ>&c8I*l;Ey zw~45*+EV1snBpy#hQu)=t>5K!rt>5Hg?$ErH^l!fz$PuZ^;)7q4#x9xAU4x~Em!@} z_)cG$T#7+;1pB!qR{idfcn+o7-o6*TuPto;K54xC%j`VZ#yl%fyzTIqDoPe`mRjQb zJnY0chaG=QAc% zAJAPgnh=-Mpr4@F&7vqc_za}hX<%?30qcN1C{V5B^J5Wvlexm>~~7c=LxFQ^RLIDG2G)!V&}C~1%>h0*Ihq6GZrQiC{U>Gu_W z-e=-JK$YV!0X;kbL&mq6bMS=hC*rasZSpS}H;bac21m%wzSJKGJ?vo}-H{K2i@ZYI^dq+D1*|IIxF(N7{|P6N^4OE?QA$sCJ^AQTu2hUVtB zEcG*YAs}gxO%{e>@-@%521gT3<4GX_pwA|QuO7f;g4{hUE9!qIuNOGKR83gY= zUBUMLNY`n?ql^3GSD`fxz~E{s{W}@{Ml}4VY56^=mcBf5ApAEiiPVJ9;0lp3_DIcr zz*^1>>mHSd6@l(&Y+!xiHSo?1D|>+dxi}jBuTCYYB;S3e;kj5z20|bH!014Vq&L4l^HR2&1IC%0F0g=e zomGOzw^_|+eqr0Ymn|D=2fkVJUV7f~o*j{jdr;T*Z@)+Hbx0 zn@Mr*gWpQMmHIxEoGB^@A$LhaKHizKWfb1{9j-O?YL})((uXwJeJ_P4B+F-@X1qkT z(p{2l5=;x_b1wO8597+tsZ~y~?NhL@H?aGhjTL`i82}D=I>~7Vu+t^5;5&WOi#zXL z@UT&F;7Wbev`F62B_?ZAWkUy~Nu2xG%r7n-M@_guyOiyKF_LKz8zp7_!9w^FfOB^p)5@>gtQ^eIX&8aj^leeODzn@QJB`y;~U zIkf>69Kg8pANaP_AfLs4R(zVe8(LjCTUmc(E0)v}Sb9JZC_6mu>dZtF$sJvgP$F_J z^ldnw-}~DS7AGv@-H%sV_<+=>#4aQ06=8UvDAprBtDE}AZEuFBe-6Y9dQv@6#N~L< zYXPmv7M6fJyNhpDD}?pnwKR(ZJUA^budo22OORX(c3Xt5KW2yc z8!y-8PC^CSxtkceHvG*reMs-gnd|UxW5JtaN$GejQYOHjK?(o_tyTJ%v7#ybj6OFX zLL#j~jm(@26l|;OXr=LImx~;p7n&`OcW`Z^74lp5+#6wkw#afzb$~(OD<>c&{rJyz zHj~nuxWo<125df?o1QGW&5ivpR`tlhlahz|l4tC0I?qMpC-z&L5PH^F@Y|`?=Q)S> zr8*o)fi}5D5gPvvA^Hfgqp|SXFzbkAAY-7*ps?Tcfyya&|C$rH$UAjZ~MWQ zm*XH>`WEF0G%TM}JY#g;g897*1|c16cuSX-K6#ARQoveFoB8DW%QeFO{^`)56!+{R-0=&x6`yD)TVd52@?vm~jxiMW$C;l6`R zA8z}{QA~bkNYCb{-`ug!sa>bNwLW%A93I-asf;H*@fca#BW-Z4Fo+$dvauo86cOgr zHq&rPq$OsJ7x7ar}f9J4GGt>qJE_@6#^xU()9QokSyWd=udgQ;PeTcWM8GJ|4 z>uNqdUSM-aSL#<^e}<^o(?YI-^g;nj7Im3hYpD8~0(MB2R{ zeuQ~!oBS$e1_RNf$$eaq$bC}ngGI$q;R znb?$Zyx)aMvfs5$bc?|0$mXd;gT$oFCrIOkXrhDv*&1;3mx5G4{T{qt8bhP(c5a-~ zYiT37)wxjMisL`ywTcS1v7g@^{K@#qx;7jFyQr~O*s8g;zi^qQ z{nnk;vy_AD-}1t@GhRKZAOY{}uR0wuk|rQVF_JHNE_#6Xg_NGQu0B%~>B3yFvc7{Q&d>V6QAyAL zwlHcs4XLa9;yj6`N?kE_T23XHmV=u!XLwi>QCgaRdFg$NhDw24KCXs}=3-+aXPF3C zJcNk3xILwpc zJXp*2)-af^=0hPW&|&XB{jvMuWBTow#=WrPk+mW9m}$qowhfxXaZN-+g?i+oYfRmK zBXh|5S!tN0Jw(-O7*Kn>IN-}F5!p&`dwo5pe0jED;5}MWP0F7hV`EYlGo)^>r6*g` z#w~eY!&;$&Ogjm;wx;HkfgL5tr><&^m7%JZ|BPC72>m|h_0BWNI^&t4jOwdV`xKmz zA<8U}TnUS1NwGkLNF#D{+L+=ki4=?pBY}l{_-!N77~8!p89M@I<@GKQ!$)$MhiXrB~dMS0cYTacecOHbz$^9iF9k)n?aadaZwWzv`%zB(u~=U@;TYn62vJt(P5-EfyDT_RS#0Ol zUgr^9V-q*FGw~7{vUR>VEkCAI@?g;D<8)!Q-h@gnmFS=``SaDmgfaTi-b7zDWbhUy0!3ceHtU)5s0QMAm#N9 z$S0mzs@;QviPPIvc?0lH23REtNe=F7c{*VVmzlycChjTYiZXnos*ggT6REMv#F6`{j%uZtRbe!g1n+I2clu_opkAf}oIs1}oqS6zCdl@;^CO5xSrz+ft zt z73%OVd4+6Ymvy$~pARIPzqrb+-~#<*a}7M8?7Hlg3DNjRE;sf9<Bn-sS>ur>NFta;(JBP5!88rX6CN7vVXR zDp6Xw?gb+nko!tV=2BKdax+;14HuP26)!vcqtbNeSWb%sy^QU4>ypOY?v-3m7*$l* zvW5l&m7qEVT&fL|RY6WDa#peY+)ar7XN#f4G$*=YPhj7M-T zl=AfL#HQw{wXj>C#1UF45B<8D8@DQd`nyFJyh359R5NjykdByN#5F|?egqY6o}N*7 zq2k@(mdCh;t#eM$n?qofti)?%v<&{yU3ud;i0yq=b>^!*-Dc$f4a${+mHG1%H4gB5 zrR>K(qt@^^PX zbPo*V#pD>q6YGZT;0#Fg|Hi)B)8(4`*!G|;m@Q`7+}vWQ@a8w3WH za)_~j_H$%6PSu>MzHEq;O|Pvp6eue7Y22N)K--Zd4hsE%PItF=yc-F5UttkTK9KC~ zeV>;({~P*KKpdx#@urPn7;>PCQ;j-V-U)Os#Mf%g$9uIv_GHsG3~C{+r`a~KY+ET` zRV-0$ni&la*bn1u2Xp3NNj%4>cLgNS+0W)&BGOqc-@c|*3fZ|`7-Lyl?|kp;DK$6w zaC?2>M^5|Q!vjtCp@-18%WSH&44GR7E1qa}sYVJY^62^Akx`u3NcC zq$@yw_-o^6hsH2$B4OO}bG8W1a`*MxfK2!URnQ~C#D9JYz(}#_7^*%W-H|)3UzArH zo0m^))Om_R^P7E(u5GzHG9|W7I7k}2#v&-;H14AO(WQUORVa9QS{Ypn?$nT(XP{Dp z9yl-SOo6IPm4cucKNWDyZUUS|2VG zIh}g@H9)_g8^-!fta4-G>U}IXra84z);WWDgl==}AzMZs;@ys;y!Zaf`bgKE8(g=B zD4dkb5k@>vM+@zSyq=qAW&u3txOZ8^V{i5eVT5>Z31@WOMVgW+o8-=Jb7cv!n|^;~ zWQ)A;FQcNS^!vY_?p{g3e4|ChMJ_deOh`~iq*%!RdzkhPEFhQ3R&1rL{w=%*r=AAM z`Ycol$IN=Iv$S9A1%~!5#&1*Xi^Pu?CH7mIfN+(p9)B852&#EKl^#g+-PJZMi={@$ zixW)UsU@Q#!7n(jrKA*wCuUKKMn`scce9;cqZL3u)9cr?J+})8^EeJO2w7e~y|=vG zaowW^*=*40IoHeBN&bv)9LWht;9#&Sm`hdv*GP0nO(_@Z%a8d*LhQ=l?vTgk>~1Ng zzt@NgKsD&xoNnF91>P1SiDis&M04k z#zKNXR6!};p@Uu+TM}-0@$}~%aK~{yuGBpwxya0Yv+bTEcJ`q9OTTIFs^fAfOm5nA zGppdr@f=W}!ovNpY+K7DN-_A4rGJPvtNumr^g`rh`?DgaR&*Ne2el(zRwx(rHB^M! zuiEFerS;LJ4}A-RQBs+twK>+f8S8EZCt8+<;CFIshzRGilA3S99WFl}HNfsW1=V}w zEs*A8w25NWIEWX<^9uw#p{?AG?5FpTp(-l9UxfBy9I)q)FT?}0$k8HV&mL-}&_25> zm1vFF?)Nd(f^kMQ|IzW1GB#ekpSjc>p?Cdwt4QZEh1n$fl>*t%=T8a0ubjkn9Hyw0 zRVu3rb36DZ#mzY>a3$eZLl`LDBOk{mxDKN0$Kx#r1#!AY$EUeIYk`g~Z))BO*U;~= zXWycoFa4hUOOA|Pa;yM{g!|W~M6noY;Z+4O<|rwXXx&5t%IW;V;WFHc| zs`S-?S(YWssI^KYN$Bxr)!IR&2s~b{E-;}plXSA;A+)>~3ReI0mBlefnM7vviv4d> z&p@g5!+~PtauV8B6 z#nZbn(#Ub`k~U`)Dk4Tlbp)IUp8w1EYPZ0lEM0&Y>|~N?;Dkb>EqKzkr}ff=#@smk zxKMw`>;1k-oh~Cr?A)R1H73MctJK6LtMc$>|A})RznAT9v81$%LlCaQmu;tIhS1|n zOvP5gh%7j)jywPyL$JJz|JKu0z7^+uj)J{zTPeH0hEX(P0#BF;Bj9znP+b=JhhZBr zcXZOa%@0(+(CuiQGjkSIa%h4H3@+UZ__?_U>uaXjL3x!onyJG_n?7rNQ#mo$!qszaK^2h87qlr!6; zVO~vR4wA0NOW4x7zwlZUCyWnILt~&GDhmJKa{^hh9VF1sbGQ?~8KFjBEE)EUrMxMP zTUOI386jGKE|=K^biGv)^wj*+Cei1BnPty|3;7fbs^>(DeH;UAtwK@k?Cg{@Gzt$N zKBRgqTKOR2O&L9Bb}6C5R-S(#queZ=w-$ICTqtqM#{?-Yl9?T%~L#eTbl;Ql&dD!(?+~2s$|a}!>jjc+wxvoT3R8Wz?^Wu zEO$?2aXI-OPZ4Y$T;9px#rQkRyc&C6ev8DmnosMoGT#(E>2Fb~K5Vy7nX`Omed33IDu!BCr=%b~!ciky;ov0h^Nk zMqiGcA;|%|Q^v(5dFVo2xJanX9PKl=BFPAQqpoO&Gl7g{KJ9s%sHmu-Jh`au*A4!6 zenqieECAPM^p65u{7)-{cpC#*khFSd@(&d{%F5w2^{IDLQTJ~dKbaP?&s0#%alCnaf;xS%#6u@HW%{K^+cVr%tCNW{+PCu~#@)dU8^ z8n}hGSHwJ&fa z9H9ApFICtulAy~QzbgLG9R{p(D`SDg#TK$ZN zw_U|96(v4Ak(SPC%yJL*RiqOvEs){S>sC<9K5h_7)Y|%Mn5YG{k&(Fhob^6wt;Z<& zl@my;-sh$G(eP8%7tJy{3%ZI?E#y)UP|22u!su#-8g?`)n7oJt9BKAv@%txIqlL*y zHnY(`qi*SI*j&*s$LcF}RSWAYA2mKfQ?Y-j9XHA^-=@;S(6J>GQ0 zQ|AB3AG9+k*K%u0grSRkmRO4})#=a=js;9%J9-Oxf3v?ag%uH{i&jK+jM&u%1r6^V z{Hd1o=B5vsQ^WIu#;3(8T%G+Id`>q$!dccN9Y)Qq!;B8E`7KfH+`?5A)l!=rG``Zs zWfX;%P&N?Tz4a<=`_q7avj@R4f_qwtvAHhv$B!SBu7{#(Ft1UNq@|cpnoipqk-&W1 z&)1(;SIrJB`}8j;IM5&vh{_ga*gOq#auW>#nd+sSg#;xR)>z)-Ii-E=%~|4C-&NF2 zRL>=~#)2)cAA?a?^F=1eAheZ4YN!~BiP7YVRoaQ~<6I4sL+`S_*w=FATdHPdSI58Y z?o!MP9mYl=U*-wC|D-~D%C8-rWgD<}!cIgol?#JqJnLG4CF)Zt1Q!frQyGftN+#i@ zOe~&y8d%KkD}CJouV_GZ`!e>F63flLX{c=rJE^Ft74`S4Ztv|CW@a)pIIj_r+`m6K zI7l{E@APy1YMC;zY^Pg@D??QN7pVk$Hr|)ptiL`IusN~0+7;ELrks!ja-`is znd6DgD}Lo1*2x}k2LZ-K3So5WySI3KD`obiXG5s8XWG$8FY*)cv>(did2yAF%d_v| zuPtvEl-IkDJ}&16vb5x7*RcCLji+LVi;LMrTsNb+vPw!yj+g^dQ)zAN>ZTv}7~hgQLf_ma z8Jw&{O*Em$Pa|{&1pYd53di*Y39_?Xm#98h0sffzxu#%=sm6rbUvfj#)TATU zzO?PySYoI)rPQW#M=X46PIVWIP-xYs%lH9_32A(0hDoW1bVm7=pZk2WxGLy7^|r0- zm`66u9YbtPB(@}TNh$f6N%kqx5s@+LiX#S<2s#2L@Gl#>9QLA4@ z-C;sl$yEq)q?2oX$}($hp!c-M{&`QJ;~$1;3RJ=7$d@hkZuZa~Nwo&VeZ?JgJRb3r zh?_rOl$Nux%2xJU=XYZU0k>BQ#5jPow6w)zF)}S}UmIa1&IeG-HwnVGUVwqEYU~5r zuZElh_60qiPpho{p1FsOCfFK)!fbu*3Jjd)zP%T1AH#17lIR~zsJnzRi<3M!_dvEJ z$e9RVHgPpeE7w$LP?>t?@}>0C9D_NWr0lBRf9p>;eCJfa6PNWFzxWfOAsJBacXQe1 zwlhvMjy6zI_G#}KCxML~}(m zB#qC{&wrf%6+-d+af`oG?3mVoxJuUrjrP=#6iddbwqr$NWg|j7IvG2BR`bdPC+`9k4`A&p0Zqk2i85BC@3G;A%q9$)y-&_D2xsZM_{bz8;BuYl84TJ`e% zd@e)9jFCV2ZO0$K*Qk+=cQ2Z$6!!Mr^zfqpqrrjh>=gNm#Bl;gH#pO?dCaR>Z%@z8 zOJ7COmzVO4SDMzV#TD#FIwNW(Uy8j0%q`p+3!Nf2@f>plR95$}%gxZ3`2Ov6MNaLV)D94gi2H z*eJm~b|=?sKad*i2!`1rD@;CAT6~knpw4=l$Wvb4k%}g1Wh_>Zu?1%vru{aGJMnFr zd}2Vt<&G@C_Quyt6_!RvS%hX`38Hw3u7dRD6d7eHF``n`rptp|kHUiD-JZZ5uHx(Q z@$f3rBX{1S=$AyT?_y*slLd?#t(Xd}#V5N7=2JQ^zvi2U0ydbJb+`~;NcW0%d-?c7 zI2om1**n#+6tl=-d+G%moICloaDU~bprW$S(n-^g$ak=fP0Q*QImzc#;Gallb*GZ? zgsT-*w2UvFCN<_Uk<(@yvRX0y(+V{|>6DXAjOM?cuC~szX|JhlYA>mmz)(NEn`JQ~ z;!L%nte4Dl{j%D$JL>8*r^Kb$P9(Yw$(jCMEX@_`28yWOyxcIi_!+QFN)m#tpb;Az z2mba@N<4|uv#x!fpGCn6-jD*91%N+)@LOkh?`vtV8h(4YQ#GibLO)YSv5=ISF0{6+ zrvQ@mZZKJ+K zBwy``ScWytFSsud-Hw17^IQ@YU;}XXPv6T5D(21nBW>p5Lu|D!ylh@X7Is#v74s~y zyv{UOhw=H!8{a_i28SQ$4B9R+jx>H097_CInLK>h;QEyvh`Sdxc|`6+FJrJ%O@X1d z*49oM8YWB$35n{m(31OihML;#l10j}i}Ft^X?rWrEKw}O&vD%`EU?$~62k#cpwg5< zMT~{-FI|Ug-Y8=wbCHXLv9$>Q@)6Ce8x~zVO^SJf5u{03F>k9$H4c&ej-C8a{OnUp z@QK@)#d*s(>rH$pQpix?^|`-#?ReJqGF7pPF;gK24!m8dz_qX$u1ZtIu9~G-!B4&E zxaKuXm7XpB&8eF6>K>k**B6P|#*QTsqr1VfbuW}2A<4h!ECj(;^o;a{b&T|7BQEub zPin@rAzCH)PBl*?Ra9*b z;wyV7t(;5R;8y_dUC99 zJqR>&@-^F9$#+rby;YN3P}k?xiTaHH@2$B)`giXQvYCtC!xp+vOJOs5P{Vg)32R6D z1sxsjQDfTRVoexIYqERN%RbE7pmT=GGzz)hUg6XKKVF7tWm6mD>rLhJ znn_%>$8$<5;!n_O&CQy96!=e2R1r>}+j!BF!fk?V!fwu#(@`-d^!>S7vP!+O(#o!kYQu(ENOJKw??kb0S?bNRmLwa%cs_IFJe(fPLUUr=|u)sN~m2h8q@rkFjO_TG9Ym z1ul<{A_%*mPbOAo31m*Pgl*Z*NW>T6a~a$O#+UY6^0?uLA*bJ&zR^Qrn(A;GwA~A5 z5`>R*VnTg`xXKebBdH?Wkts7(0e~7P`g4_>bS6Vv9Ij_DC*wPH9nD4eVeb}!Pfs~rEl9^%hZWvaF;jU0d~cZe zPwAa*dbpo;k<%_x|hT~C4E<-1Y`Qw zWe3{9WCm`Dk$m~mrgL~R7xF4|#_O@duOGZTDY{x07g<|wIQj$8)%^1#>SIZLq{1(| zDu>lMwyQ(pdgcKS-3e<{j7pv zaFnS+UPY~L{nDEv{t>--Mry;0!Ur#W!uPTyT{LkMM<7(Xw_VsfHbgz9v`%cHb!Q#p zEqJHzK6M;Zqda3Xy^dw|S~=ST4dn8QZL`0;{OfTQSwByY5!vBeK|e5Gu=w*%=7|!g zQc*>Pp#)FZ1195hkD%w4Dk<%q{L8vZ!?|8ROwX#Gz z%JCN$ZhiP)tgSa&=<|Eja%KyOL?Eee2(;8<{(j)HlWd6+V4P(C*?R2z%Vj{zPl<*9 zf$Pv39nR>GM;B+uDYu853^SkcWez5WrSx5Vqbo}0ee@DrYNxRiAx?pbmzcJR+l40u zWhA@X{V-Ef&l&O{f~{&j z6D@mGw$)6duLju(cfn=kkgZ}n6y~(9rhT&xWcv$T+^nIy?i^afaTRcn{mXCtCMeJ9 z8Vi|Ij2vihe=qnaL|$C26^8h?CJjCHBWcZ?SUUBbYrVB0THTSi>iqQGIC*G%HkwPp zG77h%U4U-e?EGw;wHZMUIUV>aOQEeDLRwNnr=lM9(ks0qN~^D{M8i!o$XvsXEe$H` zb@D@$d!+y8)ut69au`9p>0`|bs+s7{p8yR{~=qhfo9$U~dfr?rS zQ;wCDT`3bNK~97L++UG3?W(8Yy8kc$6v)0BOQD(A(?zcP4)!xeU6c|c^ChP4#EWjh zTCY3m_}DY8b?wqTQ8%ncSL|3H(Yw=J<(o0*CS<-Ai$yj5Hw|KCwHrzF&m2vRIkDYO ze@p*1Wm_FpdKCA{QLl#`C7x1~$w9`z&@bt$3Il~tNK;U1Y9+p5N@*gIWDmUfy)5Y@ zji`4q`f!-l;FuWeGQ8E5lqqPm(giWh-k2xKO_DIQ!xEJ1^EO3W6;>)F|q8YC2mGy0pJOuSb>-FncOe@cLm^Ob_} zqyQ@FPx(Q4d8{w^%}ZQot;>{+v+jFm>XiDWWa^%l>a*{DkCQ8zf5WT&MuoNi(X`X)!s#DQ+5 zhLwds~-+m?SWW1PSz1I@Z;&Xno>{#jIfrMyYUZ#HCp{C*Oy zea6ohx4bDK_RsU1d;TAaAn+^JRm(1%H0o>v=$S zBw^p)D5jvQws2Sv_HBI3r4L&CMV2Cd<-KBp>rA7D9HKaFVU99U^pw7PeQ#1;L_b<_ zD#Cm{KfYj4gk|l@OIzD6D#lyolh~PdMLkjEMn+M8j9>T57tz1e4KB8WbN}4*eXJ9` z&ScQ9h3nw9+N^g?7-grZ_13(&&7_7rUcr8};5T42gJ}Dk|zig`*L6o(#j>u3I^40tW)_sjM%xQKI!kwhq8hUTp16F1I!2(SY53`Eis(_ZSmJfz*a&P|%ZSdh@X)5LIzE^`6qK&f))?62ub`Sh>iuS(NIMd^ zWvqCXIje1c_Ho(n>T~RU5r?3^t8bvLYr$o0-vsUme$d|X-i?e9H><;(;yK%5%A~NE zCrVQTXE||z1^+3TPt7W$)9Q+K!JaMi)|Sqx~iHnsSN=_CxG^f2!W5qlY>duuS zYP6^3+Rqw;oa)nb@LHD+KBit>$9^w)D7zf0RRO5>V-t~WZGYy| z4Pd93Xf{7QfkraR(HIR9gos+({n$9^pL&&YMqWEKy((TU!5=7HnakdEz$WRhI5Odq zA&XALRo>AXx%)K_^^l9Pv-6SoaYce|T-tm2Y&L*r_Eh!J&v#B9#Jprrt;(ZKq#eI5 z(U{E|7v1%@h>*fBvO`*2`c>;|Oi*d_0v=& zh`9<-8aOLiI3O6CgpSY#Jw$AjV?oXPwrwQqKN>rZNi2N$o{&g#WZ{AZ3m88=n><4& z;6XTvOQ~R%`$o8*gU2tQaU)3*=*R^fV#K1A{$OjXJTFTvfT&=NOtuY=f*IeUyxl0_ zeGNoP=KXVF2;}t#7X3e+$44O_O~Z@^M8sW?s=2wZ6iq@+=@<{In6b%dI%*|u3M1Nt zKOFsz_hbtRTXt94>JLvC1_z~ytEe}rwQi68n7}=qu}4J|ImzOoa}#}=`=D?RYWikI zhTj|PGUTxYkdaayPR_Iy8}opgi-4UUGGWgG#(mAbwzF)CL`2*y{BnWD92+%O$ByI# z-uH?DWQar!=|WP0H_w%^*nv=OSwYY$aq$z={F6r<@wE--ZC`V4kI$m$iOd5{Y2zij z`Q){=ZzlG&SX78tJ{(7RTR1BgoD6N{fhWFP(t_oM-H|PwiwH(Z2FFuX(81;XI0DEg zTr7-59L5Q+%Jt?N4Abt_S2jz!Y*fWaBR6-p#oRVWhueGgzJDL{QMNvcrojj+;K|ukWY-8xNLLF5>9&~d5Th!73$s&904~CSVU}YVG0`75$eQsXvG-^ zVll>MPY&6Ss`O0cn91p-mUD&h!DdFh@xsj8Su$pei0`hv1dy~R#^zdhrS~JpE?NuuPgAn;g(IN&$EBu^Bl%BSXzgg0aA~_d1 z-dtiW=T6S6Va&|mc`|Nq4EbaYdw3dW!=ugf2?@LAlX0ve#MT*4H($%SyC{nKGAL<= zb+os&qvp^_idHf-V*FUc@9xPDOyqdIm$ppXp80hsdR~>rCtFz9NDZC{=ziVxtZ&-- zfte}XG~8NyQBetKBP`8COYE#0wiic_M*OB0&y$kp_ z9LH4DodP*+wRc4O75z8IZX@5{6xt$P7rXH^a~HeMVoy`QmX-?lbl2joM&I5xdb}r? z5dNa`1%INiKn<&)>!^95L`=y;eE{gb3R;K=;b6#QVQ7P>!(|e9PjD=-LxvREC1kQ*2MMZPobsa1(qiXF> z;bk?lI8C*C3(%U)kvBI87vhcEND{b+?d`FB#rnCy>qVPBU7gxrV~Sch^?m|X3ZxIp zebL{)yWRa5T=cG-q%?AiA|=j^lhb>hCxT|UIui%~vM z!`}MSRe(<_Pqo|Tj|+pqK1!j~0e|Lk-R7@`!vnXp?XG#p4JPr_ght-CxvEG`Oe<_79qv`9kimT9~VNX#{)mkiQbF35b!WoKAp} zewly}{gq{z7h}H^mH0NQej4jHg154=k6nz%sQnA8z6eX`w=#$YaHYNnIs%s0T7zA7 z7u~mSO3inr7V)@}bO7A?21d%NHx^oY5r&2Kyam?@JS4QqB7Iv5e&ZlUp;Me##ea=E zvCNZ7OM`0ui;n7=6LN^&y$z57ICV}ZjDq5Nh#RfEW7>HR48k+PvMImoFW)3Y&HP+; zc|(M9a0rFE3nFS7Hk$9YY8OYqR)o5=F-#P-$}v0V#=n43JJwS_b+SS+U?V-jqR}N zRjEpyd;CX+G)~VW&+nXwKMN*RS7)CQ*1hkA`BM|+fZ8Jh4J|9B-%*?IkaT^NV9fW- z=hCB<*H^?JU*^X?jNzr4N?$&^TQDjpiUG|AP6&S-i+x$?EGWObmem>H*Rr}OSS`CO zb-}wm^5pGpbb`UD%Z$M0kI!dk;;;vGL~HZRLVGXJTRm0}d*Ej==sAfxZ9-WC7Hp}o z7gXQmjQr=-S^tPta1Klj*;e*94fA7T7XutI-C*4Rp$C5cR5J>MgZxk!wwU=x5XF=) z1|72K=vL334n3=wjr?u8YOY$1-W@o5FQOzMzz?YQ4zvKczGB+wzWpVeY4^7yd~pAM z&*_yUPvmsrbu{MeR40M9=_kDDUfBFZG(BnU0;)={Sf@s+u<;~`gRWYMPHJp2lO34)@ou9&=< zN6??cYk&7Tg^KOem%8OmMqF@=83rnEmbXkGMW0>xIOU*4d8vj>#Wc0^GdE#7^}paQ z+IMQFCz_3Dw$*19XSbh2Ov0l~wR8nN&C4=q+?FRV&;OKjVn6OgOQ$r)31Om$gQT<< zI$3Y#qvAne)8Ai8O%F$L*(lMIS~kox)c1{=)*o?S`NK~~-{||6X$;~}`AxRNcx`J$ zlqFZq;Q?4oJ09vY!KF9D_l?w6HGC-Z%E(K%BzI!e_0`mVt&G>zX;au~Pvs^$=lWU2 z58PX<(WENgho#$Z1@!%EYyBfOItgpfNPrpPqZP-czsg-)^5HE8B5>MU=`au?CrKRLRfYA4&ETA;bE) z=)BhD(2qplP7pBKRK}7ri5vaY<9-u|#XWy|PW)JnT)n<%DE=KEz4H-LU{p(W zVsM;LKtPBb-^rFjA*Vl0Qa~#WvOR|0^J?_P3;OXGa*!$FCRA1Z(hNCHND~lp`i*)0 zE?H);L~`P#A2$Xw6-=y+g%bLyir|8qwikrQ2OWPd54wVIGQ0N1$178t=_isct~5lI z96!!<0k*P>Yut8ztcgrAqV*=ZmSy@Y4AMiI=qT*m-yCx~P&4c!yQFYhqlwc6jSpCDYFzaw%_>Glrwv@j0x)q{fPbHtm z9L+qDrpV$bcPss0Pn(IDgpMcQvW-V?-o$tL$5e5m_Oh-uoAxiQ5ix@ICLKao5SOb_ zYcZF@9(a7z4(}W@wmBQ_RG^?N4FSrdElf%b^}w*y_@~I{+5*d~X!^&k;wBg*Na0>u zz?p`XP_?umq3G>qTmAqGVlxA{f*CfSH<6dQW2fyNt|1rRRm^~07Os}djj=ZQyC7d6Hq0Yj5j|Lp>5b6?Gt6s@z^$wqpaYh~UL z)IiEag1SQBGL<&%&1ThKyQg!wcpU(KAi#BPS))zSBMPB#5N!Oy!HByBbRiWX=iAAR zHaOCoBTWrLeA*8q?Wfhdcvz=Mt@QXMzQh~dQeb~9Lkbx+Q#+v$KWQ%JRW7{l+r}1~HIPi~NL^zPk7N>p9=` zbeC)CEB`$nK$x!ZX5ib=aqSa&qtHIksg4v| z`dTg+rB);nz7G|pt)cGv{Q5Mj!DJI@)g7{a)A^Oi59U6Gh`Bd!`tR6QcJlU~j}2)NGKN#hc|R-e-p*pYjS>&b0f;1Y0*zL2rhaVZlM*8@GfDc1k!6=< zO5Mf^&(iQ9-Th%nmBC>q6LMAdc^f zn%eOdm6VUBlJ$&!htKK3tY(3)wVATG9azaw+pgkLDD$AEhGmx`G|y&_u?khQ*V4~) z9zMVm&lAtE9&yjhlj$Dg;@TCwDf-RLSiC9zrqaV`L~y4wtrvP^>~W9rJ|jAmC5^c) z$BZ|?1Ni8x+aY$vxFns4QD}HnZp8TY0Ew@r1S>>W*30l*BFtD*xcRmcbka3;sdtp)+}bh~nM~`N2tf<8PndY00Yj1V@b)nw8r| z0BtU_e7!>tlvO7mmSaNKE`*)<@A4Fu1do@vE>#@1)sMSkrSnz?2ZyCt27_aD(z@j; z$O~uoRGz=zlRMBSMO|*OllrUIM<~;t(^tD}fC)!zF&NQk7jFgK>wS zj5nXK05YKSPI4*d+n%y7!K9QTgA*Mc1ro>UOYxyy7riV5e`vhWzB&$}%pcHwxA`;e zgc7wUZpq8Cu7U1fap1+qsunn9&RE~7G`8oL5aAaeKCShL>jZVY_${tv=GD|N>e6F8 z^|_(c=tbTb^0LwV#WHw-1E%$_pCA(q-NvN%x*(`@!C{6}aG3%7`dQ$@++$0YQ@{O| z-K8e1y%571oE4Pn!}82m58D!htIkU30d;Ffui^`u z{GVvB&o2%b3nqLu#0c#mw!C3rLyb?(u66qx4t3^YLG%rl!4o*i?&Hik6ClIzB<`Y{ zK2B2M!E_$S1R*)^NM~bQrCTG81(FEGcU!uEm#Mqqx%UiD&GCgG`oX0MKSn-L+wZP8 zt?f~W_LnB>U_Xd~A@a+}*im3DPEzE5^1!0#)l%f$Un;`bp@+~_$m=arZ4#)Y(XO+| zGMKNpqT6`Ck?Q#aR8p-nT|1aC=)v$vK*w)dL+Fj$Qe&Sk+$eA#yMC`GJnQ#$TYsZMpvEeic(wo8vl!!n+5Vrt}ld0%)Ev|-9_|f`Fg~= z&TNKZJDzQyCV4ZXUgO1K@q7gt68C>0e7P-D*k)*!+Y(Y_7dsnLr&svJ9rixVP>_Q1 z;Nf5gY2gFQQpnSu zPhf+eQI`vEh&&4i1;$=DUnhKtAODR zj|=tOl`Ki>JK-{qb9umz$xeWt$?-)nQA$VTNu8EmU~&(-&76@LHIA4seij;DY@xDT zWl4Ei5Yv_DpAa?_a+@ENdd_^X<_q_yG_59`{8g&!iB%7%el^v`jlnMW$ASfv=444v zsiB$sw5)m{KN{s%yg@teU)ulAGwAiS*HWidmlU@$5Ki)QWsBudB=06~Xd} zV0$f@uK66Z6+rMlQ@(>Z{c~UVx8uY148MJvTJ`4Bf2$b3#Y1H-PDhk!Y-mByrqft* zp2-B)0v)_cvW?fmSkrZtWYAu{twk>{{2ewQ{jtbvPX$Puhe_3!tAqx;1t)*c?Y-P- z9wapu25E^fBGhAcvVHsNVZ7G;-AOG^=dC0Eu)j0??5mJPp!a~HX&>5Z#e!BX)nF~2 z4uKQs?XBW6z2I4ywvFCCzlce;xEZLmT%I%)XP#*6C^)+Xs&wG9eb_v5SsonuMhg{x zzD8^06V=O=tk;fLQYDWLtK|A29ONdkPf>tHqk3#2sCO(`lbXod`sjTkPKQJ6DZ48V zwU@)y!-2@vuQGS{*tM@R*x$dyg&?NQajN-HwXg1r65MC4TjCTTw(B zn%HS!MFD_0^zL;c4%4eK2_ETlVLfG{59JH@&tbw`7D8difIFuj|PK%AlJt)e}LjiRH^XWC*Kf7Ji6=|$?dy!##ekq4CQa< zz_@Mmtjq6O^_}~fCx|l?+MaNeGq=DCNka5G%UMFy?t{18hpeobVUF^ze}zQd`iVrp z4i)x$Dzu60j<`T}($>m%k%^}tX5T9{FIqKKRhjmnABH{VwS`K}l8Ifpy1 z?O4_F@Nj<5kxoa7MA1U1E(5ZcFki?z#MLHf0;EL0<&^X=Nd?j|&~sAaCyn@83crm> z1dFXH!(haE+;6$OhIa643j}CQMV&~bMRgd@&CQx?l0~6xZW7!^yYL!czdL3j^cc2NcI@VZE&#FM>Y%Z-M*Am z8H^RMO^k%5jmu^>i!c|g>@O{&yU|7k3npn%2)6+juI10m7a7ybA*aJ{49@(1kL_$| z1yf2^9K|FWFb$=ty2CqqNIrg=N_RGOe+PW7-)l)}C9U{PISEb29OtdFElC zsJ17U;I(6$A4zY64If@pwS_7$K)DYSf924kUP}bFu1DfRyJm`<7vsJhaC_o7JQL~3 zwscsLpA0(cnKO958Bd9DgX~Xl%V)i4s2M(+nW_rI-ej~IY@N6_so7iR*<|?4#bCbP1TT-)g!hwqn?)fE0qaEVGaT0wSH6_R=0D&WA1GoS(FDX+EqFfS|FZ5t` z>)Sxz_aU{HcnZwb@+~o4;W1NJ9M}+F3vE0ku$rcGIt4cJ9(&3J_8O3BXdw8cS(NG} z6&7(WK8y%|YBaaN{?gs<4|0m1z?4xf~1L0ItVDT zQJ0M>c$3kxE?cDA>~V7V`+)+ABz5*H>4gYmBvlvf8}GzH^RZiU?8rLK+Crepp97(2lz6K+c$m`Y3jj+ z&=tSOgJA4y_}GIDWxNPWE+x)#@39yN#NW@I&2&ex5o)I`^j8U79}VV-&8l;lLxay} z)454Jf|vMz9Mk46qjcTo+kF>T3+I3O?zzmD<9G4Z?aFfl8KTq+$6sj%1_&tF(QKnD z@rRT*mNqOs^v(}lM7+dj=1s7t?4!`#r+4zYld#VN*9z8pPNI_D&Tc;InAfrU72?fp$?ac0Ik!k0cB7@=Sj^%l^(AY9pzuG+L3T#J zn9yA#9G8)f)y3?Z;735r(#;r*Y5hn=<4BfVSsg>-QxrbW4UTUcXA!6dBk^iEu%}p4 zhulx!MeV$9oP*l%6L{r?2X%mv3;B^1c!jd_JI)^8{Mlt%(e!@EkPe9t9^Rk(_0LZA zMF)W59%i4GiS@KYKP3Z^Jb%~;kl$u-`pUTbl8><=Dev@Q4=4aZ(3;g^FC#nDsT-GF z8|?s4<~#Q@a|hm)LoNJe^LPE61*-?s!pCKk)DI5<5L_EZnr3N)k6aJ>U#LiLxI4?- zmy}o*^-2a;bILE)01#1#`Cc!Q^|I%S!~PWpFcX*(uIAJhn?e=whZGPt%!bd)Uy1aY z7{3?Qt!K{upPa%60EqrE({A(|tBCErZ(L$-M>{|N!iTJb6*89^*UG#t!dKX5-rsG- z9NnU&ma;~WQ>e}$<{_x7$Xs+iVcEODfJhxc^^@5_Ig<5opHitygT>4p^*r#{wmdQP z7K@te46`c)!G;(PE?=R!u;u@+e(k)|UGGr$N!xrqa#3ECW<{9o=gO8hG(X?rq@#hI zIDcbVH$M3BIsVj3q14By&tAz-XIDaZW2ny`gOT03Yub8YO9Fqx$~6hy=_z@A96V}! z6_xE+k`ipyu?xOdh|)k8rU}R&#OKF-OFfd8k2oB@)^WV_LY7pz|6B>=(oIPJ`!WnQ zf?a3-{H8&(wFu0w+3ppWlVM%FvfA4-44DC%9p-Z0;{-MpQWrG`QiL6B&HDQ1y`7qrMUQozsx3db zH_Yjs`tyf6Jv}>>+|>1UO0DvKUxvZ=PZ(`}StsT^MqTMp2?dFl26?5eTVNax6Epm8 z(Q-WP@)Ad-sP)jJ9I)79{JN#>30Ze9T(Z2EDy+*@>8DgQCgcYMaT{-Qt7?9Z3~0fDqRC)-}zeM%v_p$ne$)=jOGTQl&%qJ|AE3$~)iwKJ%}d=k2Ik zMIncfew~_=m;I}U9aaz5WKKQ&dg!4GJ7W~kg$>SPLFX9Whf~Ga5Yix3&X)Q4uAt+g z@I1uCH>1e(JpwKE*$)oObj+s2(6JT6b)I&CN7Y=`2nUpw-_`47hv-O7`49#jyerJs81cSvLl6T|Fer7ue7 zZ$xqsJ}t^(ZqYs^gu^2mbcZT8$d1NwJmj5^WG2f(D^R=NT*i~NsR;3*M5O4AW1W^jOYH4ex3Ts8h(?9yEP3;3aZ zeeX}J&T?79$M1nESkndo$hjwWsy5N%OLMcvAEzVd+xyKSt@W2BIFh8dfp9viS}pE^ zZu`Qi1HU&FidWq(%iBNw7lOhIz_q(fJMSb=p84q;x#0FxB*KiYaZq#gKDbLD0wpBO7zQvT+9RhVc! zhtn7QU_qpxXyG*xk|Cv5JD>8qIHcg!@oea9g*g=Rqdg<2AC0j^$bb85iCN)ngmW87 z1|Cv1JMi>h%AqR6Q7%>C866asrTfvYaVMtqJGI{>TE^#?55U)U#J%IIC0@WIL0regAg@rA~RB&RIuN{_Sk$tU#HQGobR+AL?K{|ESRu zaUipv=dcxx0M@+%uzMvIJF0uLatanuR1di!%5W_ptq!+B--j{VL^q1%VoHZidK;Vm z5PPHV`733E+lIZ@UnMp8y?U1XD^@+Cc>=uHw~H7D0$Fj^FWyK063*GcOXU6GlE+iG zcZ9TAZw*8^Z*A@N%$Lx|Y+aiKA`MDb;M@xoA2e{F+L8#LT3209Vv(sOZE`(gD7hpf zu@yIN87VU4^(PGU$7N*N6R^B{_X>g9Js_dWu^)(d>0EHGjydxNGn^!Kj|TENd%efw z!aF#=jGOYMFS6(Add`8XH@mqT1JMnxc{-FUO_`xdb$|~|o5wN!w9JF#ogzp`J71$) zqYbl8KM%Hk%C(POfgyZ62W z{dQaj-VJ;^<76<}LI#Ql{_+v|=+!>cu!%ic@&^uy1@1$820Ac2EeJn!-TMkw(wNse0 zGloyCs(kW8RTw4v66PQGP*rF#{+k9>DpjoHkE_Io&N^*#4ajLTVmcHvkqI$cMp%~O zdf_3FuQRlXGZ-xhyXjCITq4f1$#3adZNOxGxz>XhoXg4Mt$#aojWC4EiN2cg%w9wM zJHA$mk}V(iGtRiLvD;dM$H@(sjLON~jlcTg-T z_q%eY7On`d^`LmAgFBXbgg|ZfR?x zSgHr@{>e2t*Y*4SuVNe{Om9Haio0&t5&ETA9%Y6tq`-=*IP&(Z;h)QSKjw&`J1?bs z?AWXmI#j_RzqX^a0BB02U%c(vjI8PcJBQJY2 z{a;uLr5|;q?-9NwP4!-{4`V95Zy3xIS5vK7tS_CNQuavCj7!=bv)JU?TB7pwls;hc z(rlzOGjSks^U>Bbn5|X79Lq3D2-R?ARy6L{*s{E_A1h7l%Kz4l$>NkZch~pEGOpIz zkypE%Jo_t&uiEOWer){|CN?Y@Fio4G{@n1XnW&P4 zQ=pq;7KeR+-^EKcDULO9P>i6kDR$x4x6<&jE8eykG!0J!?DIjdN%+t7D8%>frcUvf z;rI5=Sh-s?T`0!t%6YQIy3$^d<6ko}hD)0_QLaZn2)MkdiTsd+nlqh>2U_x(+tnH9 z9&zx?etgI#st*^rkuOskj*aOg3@V%~6fYIS8a^ps3RgZ87wImpr)rF85p>5)22un0 z?WKD#DegbYp12*k+Uu}C)i7f!bdadTD~aDQ@b^l_%O;RiDg`6?_b?-E-Vmd83WWi{ zUbhiWF;c(ax^L5>P7}!8WEy+Ao8D$pfMkIQ0#fp#A0a~aD+qCUCsh?lhB~f@PXdE$ z5n0|N6!;M}JL>4RrM+c!!LDxjB!@94gCW;J|d=0BTBCQC4e4c9YZ5xaYC@=gUPzY#2@?EHf)BOL#fG)x)*?cZJ7?`i<=O zG9)rT;VijjFRFKmeT&V#b0oYr@}BKyF$C&9)@+K2;E=HmL`4p z#PdB@zK97CU&wWtKpQpKbH<5m z5?3Hgq>to~5WBZ>vp6L6_F9PSs~^$@J-N#5{6NQrqzi_`De+`|vwzLqIWnX2s;SO3(-Q#pK!U@>wd{x|e_RMzci*?+jLl*`9i9GWB=4i(anEfT#gasB!&I%4v|RaFxY%zd zs6N285;b~f(3!xi=npm+UGf1MeVc!tl#NSo>aB{?qt6c4e^cvZc4jJP9Gx(5y#eBR z*wy(nLsyOM9lQzqamEbB(vdp#MEe8}5^B*G*5+bX6Sd5OZ(FE0OHkW_oTEz?DMT)# zy~f`qc}i&qYxP+iPSY<9kAv-ofWn_0nz_tmj2DwVIpn_!R?{)PGkq*|Kz8#=+k7^) z#F7zdi<4%~!KMb|akGl&{m@m?YCRLjm!Bg}u8e#9L*dp$s27g@l}gBidz$sy+xF#9 zoc+0-iY+ewm!}60k+31E`N7hvI@Hfh&n%3J&NyDCzA|_qqq+H-)%*4wonNv;@PA{VDmD4>aM z6Z8I4Jv3hBD2NBwIHqAGt`|)GPl41FoVF4EgPg4bDoJ2GO%{hZ^8uo(9X@03%^AGm z#>gsB_0`{-P|~PZFDnIsq+@+8_MzpQAN2mBKAesmS0*k>FmjV0mQYNk_|U6KAN;_eNGs%SWTLwBZcKc-L(-z4Mb z>%zhE9EB^0nLegHNHH4irYlr$mQAK)>YaR5wA|@_bEp+&x9YtjPW|UXUTtQCzLsOM zxCj0wx>*WCc$5zwxzy!zoQY{;KuV$(;Z_;#F(Cwa)cI-f2_ft}Lmn1vFeh6id5sKQ;jdYBDK zCa*xRjHkd#axzC8WD3 zQLHBfeP1Bem9PFRGxNzK7eT9}|Eu?n@iej-a1nW1EqR_s&fVT;2C`AIZS|3rm1ZyhI94rDW`rs=Hdj2U@kMkcyL^un*E zmJmZ}69N%h1c#P-!b2a!G~uSrjnZQb3EZ61blmkIZ$i=@A*T5~dBq-9tHZ4!yA`9k z9Q8i*L$*<>X-=1CMV~1uB*VYa;_w6DkkcTAxgmWGJz=ZC1B~1FUmR_b8HF{(P37!I zUro%F^gh4be5yCK?@Au3>lRbU(G?l;gpi$@#p5>%E#47wz6#D}>aR`5#%1}DnN4p9 z+D`!6@B#Mm5-!5Jj}GOF3d^3>TJrwaD8;?AS!>%y>O+y8kYYRY*_G`ia#?-j2a~i| zy~ObTBpk9t@ZHf7nRsxwJ1!cr7cOoEMjL{w)uj`=lk2{h0*&N5{)Wj(WRmD1Vf(Fi=wT#h8%oL3DHyF14ZrOG8i?DS_%F zrSdFISb-zHLfd((>L5S~jgJ`qSDR%PT5U+|imFKI<|McG_R6(w;JHryor)2k3`)NA zr2TjiJk}Ym)DI+lR98ax=8c3J;4PfbnJvw0!{=Refp^W2ong zxA^Pve-)Fii;Gv6S+$2e*4JJLsj5*>Kh>~Va9cMJeQ{VJMmE>1H>ToGk+OWMnvOQ~ zEG%T&-6lJ<;MD49EXGt?4Of|D9samPWzcFy;Fiyx2eUIMVWw$Q5C7qi^oVN+TE#hha<-{Js$6#Hc!i zrSIvIPw;nk;gk-z6T(aL%{d8Hr=&5YSX$^vBgU-BX9@bvf&&_KeZYmx2lI{6nBLYv z-=Z7Rd5>-I6>yE8LfaA^X9&a|kOA>pT;FwyeUez#76JhgK6MejAdo)ejWo>!%_39A zhnSnmgmE%Z6<+S9hSUID=vd<_TIcr>Ke`jlr{=u7^`VrdZm-1$D-J|w$MrJ&MNIlN zx#1qJ|K9s|w(&O?9&=>mZ<;#}5A5U}Yd6E$-w_6oJpZqC6oUw1Jsb36U_a;!?vo2~ z9B~4t^Px?~Q!_s0>D)eN>{za-z95Ek;7&w(My+r(B!^Q}t()Yo8oWJG_O94xhO4~L zu@`@rqBk$+S&-zZ(tJJP;|!92b<%lHY!UlN_YGcZAwjiTlA>J`--{Td2TBVaGc4r- ztz)gP&)=n?ZaL#iu~}qe$zX@9BJwsle!}G7zZrSPv&m2!bawr$MJvGm+bS(qQK1NH z_jjNSnGV$>R!5o-9JR5)IaDOv?m^VOMJpLwkn>njKd61UKqlbejkTUX8xZH0H;O9F zYn?Z$odgv*XO*@6<vXxwP-k`IMzd z5+B_R{{aZA+8lSn3)Z4uNlGxk6FnErjRi9*HIPlU&i&USg< zM4%U><+`DKYNQb9VnY)Nl0u)A{h1XugGw0&$VZ20CXZ-hka~wqeFfvMF67xwS9XzK5@CSqSeu)`3Bv z-fHmm%PBGF|30b1y!X2r4z7Bt_v8r&LFl=dcf`G$_hGlJ_wMw)LYZg8=r+D zy}{?xQjYkePeZ`cC;?Fr0Sh_q-X!5rdq>UCZ*rSye}}VqD&gf8FMB2_T082Ws+>|7 zBtAO@_*`>6D%svt)IiT0-Y}&aI-O3$S>9Z7R4n^l$Buw7H=(R^E4#Z9>#KxXYznugJnN2ND_dsOW*uEdA%P2#biQJ?YF0(@XR)w;sKZ)O6x zV^T`SZ5PMddToK)R8D6<$u^e?5IEv&9@g{yZC?fdqjegkn!5r{@79@z5@Tue)ICMK zd1~^`Ut8Kik>GFXs<`v_?$W1(dWT2+YA}yLu*)Kdr|M=~xQlmXQ}SrB5cME|_mI)) z3|_~Lh>S9Zqmy9Wds6MDxpH>_YR0Dagr|L~k-QKXEXdne%uHUF_Q6A^Vb7YCu(YapkWz#Y$P=gE*dMRUh4rw*_#~)J=J!&Cj;e+ zb(>$ZC9UGB*M49s{tmFRQp8YXUTN~9L7xXFn$FgF9SFpT#|~K#Jf9cfeP)q8duUKmW6=VreNAT32 zCY=x7PaR^7yH08F;o_KpP4cFIZCA@+@3oh9{RUVwm=OG?5+_yT8~bAlw4RZwK8DL# zS&^9_f=B`1C&4<+DdiGfct_N)mBm?8uqgZYhwJ{?y5-8M>;9|DhgD^kUZ0ivZkMES4SBetI^XxUf$J+;A;hWUxeVFt^}1Dio2u=WB8Zel z`?>tO_4kDjx9st7O7=QRG{mwbVzo~{`)eaFLU(7yIW3fd1W%jD;7{39 z-uY-a<7TFa%TrDvICH*Us+3RNz5h>uiPn4`hm+AdiOuRrnriA1R285#Ho8q-uZ2r( zj2M7L5UocAaRZ3>q*PB|rp8)_gLXR9u_Fqb$up&m#$k$=I(bL$_s zzZjHmEQK+pf?&pVx|46Ixp5}VjI}jB23MOl`zJ^R_R`E4piM!{Rqx9ZD;r(tQh#!n z<4ct`g^u`@qc}SEhljovUE!G7ZYhIEqwE>MZg=Xuidx-f#;R0J_LqJ&t!1g`{^Ybz z_Gs*Ps;bm^M{(2_{H0Zz*2Y@z(8MVp49tb^23cx;!y#19SbMuS_>})L*T?fJe54|( z;*00mnxL94LVxW$@oyAk!@B#y$CFdxQ#?yh^vYgYB2B#lr~r}ce3N=slfH6Zn*KVH zZ4#5fRQ~>@)*^%Dmf;@N%F)c)huJ95H?~LDNhgxw9DbEkOB}D#BR0ZR?{v{SbQ6^5Z1ry>?e2#^vTih@^ zRFCc*q#`rruJNCFFpb8C=-I@ZP)wHN{dkl?a^l{Cn-rd!6O zd)xgNYZ6|V51Xm4u4h0k_V3oTkX`e5IPpK6Mf~2}R(;~z;Ol-6zoHqtM+ugB36kjL z_?HV_6AOYDeel?p2W=uFqV@XdFe<-X;I;jbP<4dEW0-xzXLM>M)|K?seSM%{g*$^c z!@wpe6o;|r*(kXm4ztp;4}_FI8_5XQ=;NM60baS6WE@#pq5D0yi_&dVi4&>d(RJ#Z zPL5!5dso$zg_&C*GgnP1E!KKY*WD8~Eek9T z_c6ud3RV+|Wz!ho1XjCEfhg^)KMOlR7zpj~isOD#{w!c*>CxDIl9fUo+J&l)Yq>+> zR^MNB_Hp8Q85TGJJcfaE9}A5pcm$}L!Pmg?n4 zbyFh42Fw+IFdoNJz(`qGx=-h4yMsVjq4yDAwy@=+?+9chBmgsj%vJ0EI6k_y1lF%||?##O+MNM}bVlC~9(90XkHGgDdQjjE~2amZ=_zrl|g5L5eqzv1sp=$a$QDw<9jLz2rH^DD6=ho)oP zBR*f9FQnvt)%XOge8UUaMMfNuZ$CZR79XoZ8KbtvwX6dvra-8l%VNLK=mJkO{72?d z$k)6ukrwP4>b_(xhi~Cp6Iquz9b>n@hLG&mF8+aV9V?Tp0n`xF$L0 zJnx3?-_Do~+P2MjoZjsfpXw%}k>?-T()@I_|Imdz*6$5BGt5DrF58OuEaHg{ZC z(-iPz2ID<~V*OnU@o={pl~0h_4RC4d<~2w*y4?f&gr9cZoDO9<>8v}itLZXZ>WE21 zzS>#DTziWE0(O8=>e!SK**{&(D+|$U4aCNh2paC}UTV}iN1v-phBw98;+s?mJHib#ldoLWc?tJ!|(xzUH$3U(Dz z$=0Xkidd!MKpj@8_*`z@4;YF?FMv1rhrr(#9bx$hQnnF*`@ox21^|pB=1rVwG&(Po zg9^Z`JPrV;@bO~VU@q>0iA@nOEtqmr9N0`b@yPk9)5Gw(-Bq l|G%RDrxE`*2K;{%#eqJREgs)r_Wajz>Z&>_NM)Po{{=5#%i;h4 literal 0 HcmV?d00001 diff --git a/public/static/images/auth-source/enter.png b/public/static/images/auth-source/enter.png new file mode 100644 index 0000000000000000000000000000000000000000..b6b45dc308bf44b108b2de506ac816df1e8772a6 GIT binary patch literal 24204 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 literal 0 HcmV?d00001 diff --git a/public/static/images/auth-source/follow.png b/public/static/images/auth-source/follow.png new file mode 100644 index 0000000000000000000000000000000000000000..b7baaf355b23030fb8b9d90de47a9144aa556862 GIT binary patch literal 23791 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 { const router = useRouter() const viewer = useContext(ViewerContext) const { lang } = useContext(LanguageContext) - const [extendArticle] = useMutation(EXTEND_ARTICLE, { + const [collectArticle] = useMutation(EXTEND_ARTICLE, { variables: { title: translate({ id: 'untitle', lang }), collection: [article.id], @@ -50,6 +54,15 @@ const ExtendButton = ({ article }: { article: ExtendButtonArticle }) => { return ( { + if (!viewer.isAuthed) { + window.dispatchEvent( + new CustomEvent(OPEN_UNIVERSAL_AUTH_DIALOG, { + detail: { source: UNIVERSAL_AUTH_SOURCE.collectArticle }, + }) + ) + return + } + if (viewer.isInactive) { window.dispatchEvent( new CustomEvent(ADD_TOAST, { @@ -62,7 +75,7 @@ const ExtendButton = ({ article }: { article: ExtendButtonArticle }) => { return } - const { data } = await extendArticle() + const { data } = await collectArticle() const { slug, id } = data?.putDraft || {} if (slug && id) { @@ -72,7 +85,7 @@ const ExtendButton = ({ article }: { article: ExtendButtonArticle }) => { }} > } size="md" spacing="base"> - + ) diff --git a/src/components/ArticleDigest/Feed/FollowButton/index.tsx b/src/components/ArticleDigest/Feed/FollowButton/index.tsx index 575fd2c075..1181954d2e 100644 --- a/src/components/ArticleDigest/Feed/FollowButton/index.tsx +++ b/src/components/ArticleDigest/Feed/FollowButton/index.tsx @@ -14,6 +14,11 @@ import TOGGLE_FOLLOW_USER from '~/components/GQL/mutations/toggleFollowUser' import updateUserFollowerCount from '~/components/GQL/updates/userFollowerCount' import updateViewerFolloweeCount from '~/components/GQL/updates/viewerFolloweeCount' +import { + OPEN_UNIVERSAL_AUTH_DIALOG, + UNIVERSAL_AUTH_SOURCE, +} from '~/common/enums' + import { ToggleFollowUser } from '~/components/GQL/mutations/__generated__/ToggleFollowUser' import { ArticleFeedFollowButtonUserPrivate } from './__generated__/ArticleFeedFollowButtonUserPrivate' @@ -55,6 +60,19 @@ const FollowButton = ({ user }: FollowButtonProps) => { }, }) + const onClick = () => { + if (!viewer.isAuthed) { + window.dispatchEvent( + new CustomEvent(OPEN_UNIVERSAL_AUTH_DIALOG, { + detail: { source: UNIVERSAL_AUTH_SOURCE.bookmark }, + }) + ) + return + } + + follow() + } + if (viewer.isInactive || viewer.id === user.id) { return null } @@ -70,7 +88,7 @@ const FollowButton = ({ user }: FollowButtonProps) => { size="sm" spacing={0} > - diff --git a/src/components/Buttons/Bookmark/Subscribe.tsx b/src/components/Buttons/Bookmark/Subscribe.tsx index 0eab5bd675..63ab187caf 100644 --- a/src/components/Buttons/Bookmark/Subscribe.tsx +++ b/src/components/Buttons/Bookmark/Subscribe.tsx @@ -10,7 +10,11 @@ import { ViewerContext, } from '~/components' -import { ADD_TOAST } from '~/common/enums' +import { + ADD_TOAST, + OPEN_UNIVERSAL_AUTH_DIALOG, + UNIVERSAL_AUTH_SOURCE, +} from '~/common/enums' import { translate } from '~/common/utils' import TOGGLE_SUBSCRIBE_ARTICLE from '../../GQL/mutations/toggleSubscribeArticle' @@ -45,6 +49,15 @@ const Subscribe = ({ articleId, size, disabled, inCard }: SubscribeProps) => { ) const onClick = async () => { + if (!viewer.isAuthed) { + window.dispatchEvent( + new CustomEvent(OPEN_UNIVERSAL_AUTH_DIALOG, { + detail: { source: UNIVERSAL_AUTH_SOURCE.bookmark }, + }) + ) + return + } + if (viewer.isFrozen) { window.dispatchEvent( new CustomEvent(ADD_TOAST, { diff --git a/src/components/Buttons/FollowUser/Follow.tsx b/src/components/Buttons/FollowUser/Follow.tsx index 0893a3cf1e..f55e1b679b 100644 --- a/src/components/Buttons/FollowUser/Follow.tsx +++ b/src/components/Buttons/FollowUser/Follow.tsx @@ -1,5 +1,6 @@ import _get from 'lodash/get' import _isNil from 'lodash/isNil' +import { useContext } from 'react' import { Button, @@ -8,11 +9,17 @@ import { TextIcon, Translate, useMutation, + ViewerContext, } from '~/components' import TOGGLE_FOLLOW_USER from '~/components/GQL/mutations/toggleFollowUser' import updateUserFollowerCount from '~/components/GQL/updates/userFollowerCount' import updateViewerFolloweeCount from '~/components/GQL/updates/viewerFolloweeCount' +import { + OPEN_UNIVERSAL_AUTH_DIALOG, + UNIVERSAL_AUTH_SOURCE, +} from '~/common/enums' + import { FollowUserButtonSize } from './index' import { ToggleFollowUser } from '~/components/GQL/mutations/__generated__/ToggleFollowUser' @@ -24,6 +31,8 @@ interface FollowUserProps { } const FollowUser = ({ user, size }: FollowUserProps) => { + const viewer = useContext(ViewerContext) + const [follow] = useMutation(TOGGLE_FOLLOW_USER, { variables: { id: user.id, enabled: true }, optimisticResponse: @@ -50,6 +59,19 @@ const FollowUser = ({ user, size }: FollowUserProps) => { 'md-s': ['3rem', '1.5rem'], } + const onClick = () => { + if (!viewer.isAuthed) { + window.dispatchEvent( + new CustomEvent(OPEN_UNIVERSAL_AUTH_DIALOG, { + detail: { source: UNIVERSAL_AUTH_SOURCE.followUser }, + }) + ) + return + } + + follow() + } + return (
From ac956ff32f020e222233912eda9290e1b3478e7a Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 9 Nov 2022 17:00:31 +0800 Subject: [PATCH 59/72] feat(SupportWidget): adjust reply style --- src/views/ArticleDetail/SupportWidget/styles.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index d8f16242d3..d8bc48d82f 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -12,13 +12,17 @@ } .donation { + @mixin flex-center-all; + position: relative; + flex-direction: column; padding: var(--spacing-base); text-align: center; background: var(--color-yellow-lighter); border-radius: 1.25rem; & p { + width: 25rem; font-size: var(--font-size-sm); line-height: 1.25rem; } From 70df12e1b2e7f6fa6f9034625cbf96257292a652 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 9 Nov 2022 17:08:21 +0800 Subject: [PATCH 60/72] feat(SupportWidget): use max-width --- src/views/ArticleDetail/SupportWidget/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index d8bc48d82f..4e7590df64 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -22,7 +22,7 @@ border-radius: 1.25rem; & p { - width: 25rem; + max-width: 25rem; font-size: var(--font-size-sm); line-height: 1.25rem; } From 3a4198f445295561aedce0ead511acd9d8a07a30 Mon Sep 17 00:00:00 2001 From: Aka jazzy Date: Wed, 9 Nov 2022 17:32:28 +0800 Subject: [PATCH 61/72] fix(support-setting): fix copy --- 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 dca96d08a0..8a6e4c01f3 100644 --- a/src/common/enums/text.ts +++ b/src/common/enums/text.ts @@ -188,7 +188,7 @@ export const TEXT = { authEntries: '進入', authMethod: '選擇進入方式', successLinkWallet: '綁定成功', - supportSettingHint: '建議 50 字以內,最長 140 字', + supportSettingHint: '最長 140 字', loginPassword: '登入密碼', logout: '登出', manageCircle: '管理圍爐', @@ -571,7 +571,7 @@ export const TEXT = { authEntries: '进入', authMethod: '选择进入方式', successLinkWallet: '绑定成功', - supportSettingHint: '建议 50 字以内,最长 140 字', + supportSettingHint: '最长 140 字', loginPassword: '登录密码', logout: '登出', manageCircle: '管理围炉', From 098dfae90236d69fa4b11d0fa4389fd0072829c6 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 9 Nov 2022 18:04:18 +0800 Subject: [PATCH 62/72] fix(Donation): add local cache --- src/components/Forms/PaymentForm/Processing/index.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/Forms/PaymentForm/Processing/index.tsx b/src/components/Forms/PaymentForm/Processing/index.tsx index 90c4948fc4..95b4250870 100644 --- a/src/components/Forms/PaymentForm/Processing/index.tsx +++ b/src/components/Forms/PaymentForm/Processing/index.tsx @@ -11,9 +11,11 @@ import { Translate, useBalanceUSDT, useMutation, + useRoute, ViewerContext, } from '~/components' import PAY_TO from '~/components/GQL/mutations/payTo' +import updateDonation from '~/components/GQL/updates/donation' import { CHAIN, @@ -182,6 +184,8 @@ const USDTProcessingForm: React.FC = ({ switchToCurrencyChoice, }) => { const [payTo] = useMutation(PAY_TO) + const { getQuery } = useRoute() + const mediaHash = getQuery('mediaHash') const viewer = useContext(ViewerContext) const { address } = useAccount() const { data: balanceUSDTData } = useBalanceUSDT({}) @@ -229,6 +233,13 @@ const USDTProcessingForm: React.FC = ({ chain: CHAIN.POLYGON, txHash: data.hash, }, + update: (cache) => { + updateDonation({ + cache, + mediaHash, + viewer, + }) + }, }) await data.wait() From 91a89df755a3af1261860b687436d7577cc95bb4 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Wed, 9 Nov 2022 18:44:27 +0800 Subject: [PATCH 63/72] fix(Donation): use article.id to query local cache --- src/components/Dialogs/DonationDialog/index.tsx | 2 ++ .../Forms/PaymentForm/PayTo/Confirm/index.tsx | 8 ++++---- .../Forms/PaymentForm/PayTo/SetAmount/index.tsx | 8 ++++---- .../Forms/PaymentForm/Processing/index.tsx | 8 +++----- src/components/GQL/updates/donation.ts | 14 +++++++------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/components/Dialogs/DonationDialog/index.tsx b/src/components/Dialogs/DonationDialog/index.tsx index 567a752afe..2d465133d4 100644 --- a/src/components/Dialogs/DonationDialog/index.tsx +++ b/src/components/Dialogs/DonationDialog/index.tsx @@ -265,6 +265,7 @@ const BaseDonationDialog = ({ { forward('currencyChoice') @@ -280,6 +281,7 @@ const BaseDonationDialog = ({ {isConfirm && ( = ({ amount, + article, currency, recipient, targetId, @@ -72,8 +74,6 @@ const Confirm: React.FC = ({ }) => { const formId = 'pay-to-confirm-form' - const { getQuery } = useRoute() - const mediaHash = getQuery('mediaHash') const viewer = useContext(ViewerContext) const { lang } = useContext(LanguageContext) const [payTo] = useMutation(PAY_TO, undefined, { @@ -132,7 +132,7 @@ const Confirm: React.FC = ({ update: (cache) => { updateDonation({ cache, - mediaHash, + id: article.id, viewer, }) }, diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index ff03a061af..46c2527c86 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -15,7 +15,6 @@ import { useApproveUSDT, useBalanceUSDT, useMutation, - useRoute, ViewerContext, } from '~/components' import PAY_TO from '~/components/GQL/mutations/payTo' @@ -44,6 +43,7 @@ import { PayTo_payTo_transaction as PayToTx, } from '~/components/GQL/mutations/__generated__/PayTo' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface SetAmountCallbackValues { amount: number @@ -53,6 +53,7 @@ interface SetAmountCallbackValues { interface FormProps { currency: CURRENCY recipient: UserDonationRecipient + article: ArticleDetailPublic_article submitCallback: (values: SetAmountCallbackValues) => void switchToCurrencyChoice: () => void switchToAddCredit: () => void @@ -81,6 +82,7 @@ const AMOUNT_OPTIONS = { const SetAmount: React.FC = ({ currency, recipient, + article, submitCallback, switchToCurrencyChoice, switchToAddCredit, @@ -100,8 +102,6 @@ const SetAmount: React.FC = ({ const { address } = useAccount() const { chain } = useNetwork() const { chains, switchNetwork } = useSwitchNetwork() - const { getQuery } = useRoute() - const mediaHash = getQuery('mediaHash') const isConnectedAddress = viewer.info.ethAddress?.toLowerCase() === address?.toLowerCase() @@ -184,7 +184,7 @@ const SetAmount: React.FC = ({ update: (cache) => { updateDonation({ cache, - mediaHash, + id: article.id, viewer, }) }, diff --git a/src/components/Forms/PaymentForm/Processing/index.tsx b/src/components/Forms/PaymentForm/Processing/index.tsx index 95b4250870..0ca7589f11 100644 --- a/src/components/Forms/PaymentForm/Processing/index.tsx +++ b/src/components/Forms/PaymentForm/Processing/index.tsx @@ -11,7 +11,6 @@ import { Translate, useBalanceUSDT, useMutation, - useRoute, ViewerContext, } from '~/components' import PAY_TO from '~/components/GQL/mutations/payTo' @@ -37,7 +36,7 @@ interface Props { amount: number currency: CURRENCY recipient: UserDonationRecipient - article?: ArticleDetailPublic_article + article: ArticleDetailPublic_article targetId: string txId: string nextStep: () => void @@ -184,8 +183,6 @@ const USDTProcessingForm: React.FC = ({ switchToCurrencyChoice, }) => { const [payTo] = useMutation(PAY_TO) - const { getQuery } = useRoute() - const mediaHash = getQuery('mediaHash') const viewer = useContext(ViewerContext) const { address } = useAccount() const { data: balanceUSDTData } = useBalanceUSDT({}) @@ -236,7 +233,7 @@ const USDTProcessingForm: React.FC = ({ update: (cache) => { updateDonation({ cache, - mediaHash, + id: article.id, viewer, }) }, @@ -357,6 +354,7 @@ const PaymentProcessingForm: React.FC = ({ amount={amount} currency={currency} recipient={recipient} + article={article} txId={txId} targetId={targetId} nextStep={nextStep} diff --git a/src/components/GQL/updates/donation.ts b/src/components/GQL/updates/donation.ts index 941cf70a36..e8985fcdc6 100644 --- a/src/components/GQL/updates/donation.ts +++ b/src/components/GQL/updates/donation.ts @@ -2,7 +2,7 @@ import { DataProxy } from 'apollo-cache' import _cloneDeep from 'lodash/cloneDeep' import _remove from 'lodash/remove' import _some from 'lodash/some' -import { ARTICLE_DETAIL_PUBLIC } from '~/views/ArticleDetail/gql' +import { ARTICLE_DETAIL_PUBLIC_BY_NODE_ID } from '~/views/ArticleDetail/gql' import { ERROR_CODES } from '~/common/enums' @@ -10,23 +10,23 @@ import { ArticleDetailPublic } from '~/views/ArticleDetail/__generated__/Article const update = ({ cache, - mediaHash, + id, viewer, }: { cache: DataProxy - mediaHash: string + id: string viewer: any }) => { try { - if (!mediaHash) { + if (!id) { return } // read from local cache - const variables = { mediaHash } + const variables = { id } const cacheData = _cloneDeep( cache.readQuery({ - query: ARTICLE_DETAIL_PUBLIC, + query: ARTICLE_DETAIL_PUBLIC_BY_NODE_ID, variables, }) ) @@ -73,7 +73,7 @@ const update = ({ // write to local cache cache.writeQuery({ - query: ARTICLE_DETAIL_PUBLIC, + query: ARTICLE_DETAIL_PUBLIC_BY_NODE_ID, data: cacheData, variables, }) From 938076450840e8d8042b7e75ae340a40fd00230f Mon Sep 17 00:00:00 2001 From: 49659410+tx0c <> Date: Tue, 8 Nov 2022 17:03:56 +0000 Subject: [PATCH 64/72] fix(use-article-node-id): use articleNodeId to query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(fallback-empty-string): fallback mediaHash/dataHash to '' empty s… related thematters/matters-server#2912 resolves #2882 --- .../Dialogs/DonationDialog/index.tsx | 4 +- .../Dialogs/DonatorsDialog/Content.tsx | 15 ++++--- src/components/Dialogs/DonatorsDialog/gql.ts | 40 ++++++++++--------- .../SupportSettingDialog/Content.tsx | 4 +- .../SupportSettingDialog/index.tsx | 4 +- src/components/Editor/ToggleAccess/index.tsx | 4 +- .../Forms/PaymentForm/PayTo/Confirm/index.tsx | 4 +- .../PaymentForm/PayTo/SetAmount/index.tsx | 4 +- .../Forms/PaymentForm/Processing/index.tsx | 4 +- src/components/GQL/updates/appreciation.ts | 30 ++++++++------ src/components/GQL/updates/donation.ts | 18 +++++---- .../AppreciationButton/index.tsx | 1 + src/views/ArticleDetail/Collection/index.tsx | 28 +++++++------ .../ArticleDetail/EditMode/Header/index.tsx | 4 +- src/views/ArticleDetail/EditMode/index.tsx | 6 +-- src/views/ArticleDetail/MetaInfo/index.tsx | 4 +- .../SupportWidget/SupportButton/index.tsx | 4 +- .../ArticleDetail/SupportWidget/index.tsx | 4 +- .../Toolbar/DonationButton/index.tsx | 4 +- src/views/ArticleDetail/Toolbar/index.tsx | 4 +- src/views/ArticleDetail/gql.ts | 8 ++-- src/views/ArticleDetail/index.tsx | 6 +-- 22 files changed, 112 insertions(+), 92 deletions(-) diff --git a/src/components/Dialogs/DonationDialog/index.tsx b/src/components/Dialogs/DonationDialog/index.tsx index 2d465133d4..800128ac01 100644 --- a/src/components/Dialogs/DonationDialog/index.tsx +++ b/src/components/Dialogs/DonationDialog/index.tsx @@ -16,7 +16,7 @@ import { PAYMENT_CURRENCY as CURRENCY } from '~/common/enums' import { analytics } from '~/common/utils' import { PayTo_payTo_transaction as PayToTx } from '~/components/GQL/mutations/__generated__/PayTo' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { UserDonationRecipient } from './__generated__/UserDonationRecipient' type Step = @@ -45,7 +45,7 @@ interface DonationDialogProps { completeCallback?: () => void defaultStep?: Step recipient: UserDonationRecipient - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article targetId: string } diff --git a/src/components/Dialogs/DonatorsDialog/Content.tsx b/src/components/Dialogs/DonatorsDialog/Content.tsx index f17513f6ae..785b88d828 100644 --- a/src/components/Dialogs/DonatorsDialog/Content.tsx +++ b/src/components/Dialogs/DonatorsDialog/Content.tsx @@ -18,7 +18,9 @@ import styles from './styles.css' import { ArticleDonators, - ArticleDonators_article_donations_edges, + ArticleDonators_article_Article, + // ArticleDonators_article_donations_edges, + ArticleDonators_article_Article_donations_edges, } from './__generated__/ArticleDonators' import { DonatorDialogArticle } from './__generated__/DonatorDialogArticle' @@ -34,11 +36,12 @@ const DonatorsDialogContent = ({ const isSmallUp = useResponsive('sm-up') const { data, loading, error, fetchMore } = useQuery( ARTICLE_DONATORS, - { variables: { mediaHash: article.mediaHash } } + { variables: { id: article.id } } ) const connectionPath = 'article.donations' - const { edges, pageInfo } = data?.article?.donations || {} + const { edges, pageInfo } = + (data?.article as ArticleDonators_article_Article)?.donations || {} if (loading) { return @@ -55,7 +58,7 @@ const DonatorsDialogContent = ({ const ListRow = ({ index, datum, - }: RowRendererProps) => { + }: RowRendererProps) => { const { node, cursor } = datum return ( @@ -96,7 +99,9 @@ const DonatorsDialogContent = ({ }) } - const totalCount = data?.article?.donations.totalCount || 0 + const totalCount = + (data?.article as ArticleDonators_article_Article)?.donations.totalCount || + 0 // estimate a safe default height const calcContentMaxHeight = () => { diff --git a/src/components/Dialogs/DonatorsDialog/gql.ts b/src/components/Dialogs/DonatorsDialog/gql.ts index 7530503f0a..afcc3eec42 100644 --- a/src/components/Dialogs/DonatorsDialog/gql.ts +++ b/src/components/Dialogs/DonatorsDialog/gql.ts @@ -3,25 +3,27 @@ import gql from 'graphql-tag' import { UserDigest } from '~/components/UserDigest' export const ARTICLE_DONATORS = gql` - query ArticleDonators($mediaHash: String!, $after: String) { - article(input: { mediaHash: $mediaHash }) { - id - donations: transactionsReceivedBy( - input: { first: 10, purpose: donation, after: $after } - ) { - totalCount - pageInfo { - startCursor - endCursor - hasNextPage - } - edges { - cursor - node { - ... on User { - id - ...UserDigestRichUserPublic - ...UserDigestRichUserPrivate + query ArticleDonators($id: ID!, $after: String) { + article: node(input: { id: $id }) { + ... on Article { + id + donations: transactionsReceivedBy( + input: { first: 10, purpose: donation, after: $after } + ) { + totalCount + pageInfo { + startCursor + endCursor + hasNextPage + } + edges { + cursor + node { + ... on User { + id + ...UserDigestRichUserPublic + ...UserDigestRichUserPrivate + } } } } diff --git a/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx b/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx index ac48ee9ccb..9c19692a44 100644 --- a/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx +++ b/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx @@ -18,14 +18,14 @@ import styles from './styles.css' import SupportPreview from './SupportPreview' import Tab, { TabType } from './Tab' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { EditMetaDraft } from '~/views/Me/DraftDetail/__generated__/EditMetaDraft' interface FormProps { closeDialog: () => void onBack?: () => any draft?: EditMetaDraft - article?: ArticleDetailPublic_article + article?: ArticleDetailPublic_article_Article editSupportSetting: ( requestForDonation: string | null, replyToDonator: string | null diff --git a/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx b/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx index 5bb1521410..6d6f62691d 100644 --- a/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx +++ b/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx @@ -3,11 +3,11 @@ import dynamic from 'next/dynamic' import { Dialog, Spinner, useDialogSwitch } from '~/components' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { EditMetaDraft } from '~/views/Me/DraftDetail/__generated__/EditMetaDraft' interface SupportSettingDialogProps { - article?: ArticleDetailPublic_article + article?: ArticleDetailPublic_article_Article draft?: EditMetaDraft editSupportSetting: ( requestForDonation: string | null, diff --git a/src/components/Editor/ToggleAccess/index.tsx b/src/components/Editor/ToggleAccess/index.tsx index 2829f86f8d..67b499a70b 100644 --- a/src/components/Editor/ToggleAccess/index.tsx +++ b/src/components/Editor/ToggleAccess/index.tsx @@ -14,7 +14,7 @@ import { ArticleLicenseType, } from '@/__generated__/globalTypes' import { DigestRichCirclePublic } from '~/components/CircleDigest/Rich/__generated__/DigestRichCirclePublic' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { EditMetaDraft } from '~/views/Me/DraftDetail/__generated__/EditMetaDraft' export type ToggleAccessProps = { @@ -32,7 +32,7 @@ export type ToggleAccessProps = { canToggleCircle: boolean draft?: EditMetaDraft - article?: ArticleDetailPublic_article + article?: ArticleDetailPublic_article_Article editSupportSetting: ( requestForDonation: string | null, replyToDonator: string | null diff --git a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx index 32bc0024af..b91eab25a2 100644 --- a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx @@ -32,7 +32,7 @@ import { PayTo_payTo_transaction as PayToTx, } from '~/components/GQL/mutations/__generated__/PayTo' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface SetAmountOpenTabCallbackValues { window: Window @@ -41,7 +41,7 @@ interface SetAmountOpenTabCallbackValues { interface FormProps { amount: number - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article currency: CURRENCY recipient: UserDonationRecipient targetId: string diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index 46c2527c86..6b26f06d9a 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -43,7 +43,7 @@ import { PayTo_payTo_transaction as PayToTx, } from '~/components/GQL/mutations/__generated__/PayTo' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface SetAmountCallbackValues { amount: number @@ -53,7 +53,7 @@ interface SetAmountCallbackValues { interface FormProps { currency: CURRENCY recipient: UserDonationRecipient - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article submitCallback: (values: SetAmountCallbackValues) => void switchToCurrencyChoice: () => void switchToAddCredit: () => void diff --git a/src/components/Forms/PaymentForm/Processing/index.tsx b/src/components/Forms/PaymentForm/Processing/index.tsx index 0ca7589f11..7c9472c2a3 100644 --- a/src/components/Forms/PaymentForm/Processing/index.tsx +++ b/src/components/Forms/PaymentForm/Processing/index.tsx @@ -29,14 +29,14 @@ import styles from './styles.css' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' import { PayTo as PayToMutate } from '~/components/GQL/mutations/__generated__/PayTo' -import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { ViewerTxState } from './__generated__/ViewerTxState' interface Props { amount: number currency: CURRENCY recipient: UserDonationRecipient - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article targetId: string txId: string nextStep: () => void diff --git a/src/components/GQL/updates/appreciation.ts b/src/components/GQL/updates/appreciation.ts index 1086683423..f31a7645a8 100644 --- a/src/components/GQL/updates/appreciation.ts +++ b/src/components/GQL/updates/appreciation.ts @@ -5,11 +5,15 @@ import { ARTICLE_DETAIL_PUBLIC } from '~/views/ArticleDetail/gql' import { ERROR_CODES } from '~/common/enums' -import { ArticleDetailPublic } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { + ArticleDetailPublic, + ArticleDetailPublic_article_Article, +} from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' const update = ({ cache, left, + id, mediaHash, total, viewer, @@ -17,18 +21,19 @@ const update = ({ }: { cache: DataProxy left: number + id: string mediaHash: string total: number viewer: any canSuperLike?: boolean }) => { try { - if (!mediaHash) { + if (!id && !mediaHash) { return } // read from local cache - const variables = { mediaHash } + const variables = { id, mediaHash } const cacheData = _cloneDeep( cache.readQuery({ query: ARTICLE_DETAIL_PUBLIC, @@ -36,28 +41,29 @@ const update = ({ }) ) - if (!cacheData || !cacheData.article) { + if (!cacheData?.article) { return } // update counts - cacheData.article.appreciateLeft = left - cacheData.article.appreciationsReceivedTotal = total - cacheData.article.hasAppreciate = true + const article = cacheData.article as ArticleDetailPublic_article_Article + article.appreciateLeft = left + article.appreciationsReceivedTotal = total + article.hasAppreciate = true // update SuperLike if (typeof canSuperLike === 'boolean') { - cacheData.article.canSuperLike = canSuperLike + article.canSuperLike = canSuperLike } // inject viewer into appreciators - const appreciators = cacheData.article?.received?.edges || [] - const appreciatorsCount = cacheData.article?.received?.totalCount || 0 + const appreciators = article?.received?.edges || [] + const appreciatorsCount = article?.received?.totalCount || 0 const hasApprecaitor = _some(appreciators, { node: { sender: { id: viewer.id } }, }) if (!hasApprecaitor) { - cacheData.article.received.totalCount = appreciatorsCount + 1 + article.received.totalCount = appreciatorsCount + 1 appreciators.push({ cursor: window.btoa(`arrayconnection:${appreciators.length}`) || '', @@ -80,7 +86,7 @@ const update = ({ __typename: 'AppreciationEdge', }) - cacheData.article.received.edges = appreciators + article.received.edges = appreciators } // write to local cache diff --git a/src/components/GQL/updates/donation.ts b/src/components/GQL/updates/donation.ts index e8985fcdc6..255ccb855d 100644 --- a/src/components/GQL/updates/donation.ts +++ b/src/components/GQL/updates/donation.ts @@ -6,7 +6,10 @@ import { ARTICLE_DETAIL_PUBLIC_BY_NODE_ID } from '~/views/ArticleDetail/gql' import { ERROR_CODES } from '~/common/enums' -import { ArticleDetailPublic } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { + ArticleDetailPublic, + ArticleDetailPublic_article_Article, +} from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' const update = ({ cache, @@ -31,12 +34,13 @@ const update = ({ }) ) - if (!cacheData || !cacheData.article) { + if (!cacheData?.article) { return } // unshift viewer into donations - const donators = cacheData.article?.donations?.edges || [] + const article = cacheData.article as ArticleDetailPublic_article_Article + const donators = article?.donations?.edges || [] let existed = false _remove(donators, (d) => { if (d.node.id !== viewer.id) { @@ -45,11 +49,9 @@ const update = ({ existed = true return true }) - const donatorsCount = cacheData.article?.donations?.totalCount || 0 + const donatorsCount = article?.donations?.totalCount || 0 - cacheData.article.donations.totalCount = existed - ? donatorsCount - : donatorsCount + 1 + article.donations.totalCount = existed ? donatorsCount : donatorsCount + 1 donators.unshift({ cursor: window.btoa(`arrayconnection:${donators.length}`) || '', @@ -69,7 +71,7 @@ const update = ({ __typename: 'UserEdge', }) - cacheData.article.donations.edges = donators + article.donations.edges = donators // write to local cache cache.writeQuery({ diff --git a/src/views/ArticleDetail/AppreciationButton/index.tsx b/src/views/ArticleDetail/AppreciationButton/index.tsx index 8573061866..fa20face4f 100644 --- a/src/views/ArticleDetail/AppreciationButton/index.tsx +++ b/src/views/ArticleDetail/AppreciationButton/index.tsx @@ -96,6 +96,7 @@ const AppreciationButton = ({ updateAppreciation({ cache, left, + id: article.id, mediaHash, total, viewer, diff --git a/src/views/ArticleDetail/Collection/index.tsx b/src/views/ArticleDetail/Collection/index.tsx index 76aac5b699..ffd7edab66 100644 --- a/src/views/ArticleDetail/Collection/index.tsx +++ b/src/views/ArticleDetail/Collection/index.tsx @@ -20,25 +20,26 @@ import { analytics, mergeConnections, translate } from '~/common/utils' import styles from './styles.css' -import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' -import { CollectionList as CollectionListTypes } from './__generated__/CollectionList' +import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' +import { + CollectionList as CollectionListTypes, + CollectionList_article_Article, +} from './__generated__/CollectionList' const COLLECTION_LIST = gql` - query CollectionList( - $mediaHash: String! - $after: String - $first: first_Int_min_0 - ) { - article(input: { mediaHash: $mediaHash }) { - id - ...ArticleCollection + query CollectionList($id: ID!, $after: String, $first: first_Int_min_0) { + article: node(input: { id: $id }) { + ... on Article { + id + ...ArticleCollection + } } } ${articleFragments.articleCollection} ` const Collection: React.FC<{ - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article collectionCount?: number }> = ({ article, collectionCount }) => { const { lang } = useContext(LanguageContext) @@ -46,10 +47,11 @@ const Collection: React.FC<{ const isMediumUp = useResponsive('md-up') const { data, loading, error, fetchMore } = useQuery( COLLECTION_LIST, - { variables: { mediaHash: article.mediaHash, first: 3 } } + { variables: { id: article.id, first: 3 } } ) const connectionPath = 'article.collection' - const { edges, pageInfo } = data?.article?.collection || {} + const { edges, pageInfo } = + (data?.article as CollectionList_article_Article)?.collection || {} const loadAll = () => fetchMore({ variables: { diff --git a/src/views/ArticleDetail/EditMode/Header/index.tsx b/src/views/ArticleDetail/EditMode/Header/index.tsx index c93805c6b4..e02d3a1cf7 100644 --- a/src/views/ArticleDetail/EditMode/Header/index.tsx +++ b/src/views/ArticleDetail/EditMode/Header/index.tsx @@ -12,11 +12,11 @@ import ConfirmRevisedPublishDialogContent from './ConfirmRevisedPublishDialogCon import { EDIT_ARTICLE } from './gql' import styles from './styles.css' -import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '../../__generated__/ArticleDetailPublic' import { EditArticle } from './__generated__/EditArticle' type EditModeHeaderProps = { - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article editData: Record coverId?: string diff --git a/src/views/ArticleDetail/EditMode/index.tsx b/src/views/ArticleDetail/EditMode/index.tsx index f5d3573598..3969eee9a3 100644 --- a/src/views/ArticleDetail/EditMode/index.tsx +++ b/src/views/ArticleDetail/EditMode/index.tsx @@ -43,19 +43,19 @@ import { ArticleDigestDropdownArticle } from '~/components/ArticleDigest/Dropdow import { DigestRichCirclePublic } from '~/components/CircleDigest/Rich/__generated__/DigestRichCirclePublic' import { Asset } from '~/components/GQL/fragments/__generated__/Asset' import { DigestTag } from '~/components/Tag/__generated__/DigestTag' -import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' import { EditArticleSupportSetting } from './__generated__/EditArticleSupportSetting' import { EditModeArticle } from './__generated__/EditModeArticle' import { EditModeArticleAssets } from './__generated__/EditModeArticleAssets' interface EditModeProps { - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article onCancel: () => void onSaved: () => void } export const useEditArticleDetailSupportSetting = ( - article?: ArticleDetailPublic_article + article?: ArticleDetailPublic_article_Article ) => { const articleId = article?.id const [update, { loading: saving }] = useMutation( diff --git a/src/views/ArticleDetail/MetaInfo/index.tsx b/src/views/ArticleDetail/MetaInfo/index.tsx index bcf3c097e7..240a92846e 100644 --- a/src/views/ArticleDetail/MetaInfo/index.tsx +++ b/src/views/ArticleDetail/MetaInfo/index.tsx @@ -5,10 +5,10 @@ import { fragments } from './gql' import styles from './styles.css' import TranslationButton from './TranslationButton' -import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' type MetaInfoProps = { - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article translated: boolean canTranslate: boolean toggleTranslate: () => any diff --git a/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx b/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx index 1eb8438da1..8a6983ba4c 100644 --- a/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx @@ -12,12 +12,12 @@ import { import { analytics } from '~/common/utils' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' -import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '../../__generated__/ArticleDetailPublic' interface SupportButtonProps { recipient: UserDonationRecipient targetId: string - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article supported?: boolean } diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 6995fc761f..35df1ed7e3 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -28,14 +28,14 @@ import { fragments, HAS_DONATED } from './gql' import styles from './styles.css' import SupportButton from './SupportButton' -import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' import { HasDonated, HasDonated_article_Article, } from './__generated__/HasDonated' interface DonationProps { - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article } const SupportWidget = ({ article }: DonationProps) => { diff --git a/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx b/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx index ef4f2ed7b8..40c21e9d91 100644 --- a/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx +++ b/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx @@ -19,13 +19,13 @@ import { } from '~/common/enums' import { analytics, numAbbr, translate } from '~/common/utils' -import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '../../__generated__/ArticleDetailPublic' import { DonationButtonArticle } from './__generated__/DonationButtonArticle' interface DonationButtonProps { article: DonationButtonArticle disabled: boolean - articleDetail: ArticleDetailPublic_article + articleDetail: ArticleDetailPublic_article_Article } const fragments = { diff --git a/src/views/ArticleDetail/Toolbar/index.tsx b/src/views/ArticleDetail/Toolbar/index.tsx index e34ff57c6e..c97f297f48 100644 --- a/src/views/ArticleDetail/Toolbar/index.tsx +++ b/src/views/ArticleDetail/Toolbar/index.tsx @@ -18,13 +18,13 @@ import CommentBar from './CommentBar' import DonationButton from './DonationButton' import styles from './styles.css' -import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' import { ToolbarArticlePrivate } from './__generated__/ToolbarArticlePrivate' import { ToolbarArticlePublic } from './__generated__/ToolbarArticlePublic' export type ToolbarProps = { article: ToolbarArticlePublic & Partial - articleDetails: ArticleDetailPublic_article + articleDetails: ArticleDetailPublic_article_Article translated: boolean translatedLanguage?: string | null privateFetched: boolean diff --git a/src/views/ArticleDetail/gql.ts b/src/views/ArticleDetail/gql.ts index b2b0fd6a19..329b7c1e01 100644 --- a/src/views/ArticleDetail/gql.ts +++ b/src/views/ArticleDetail/gql.ts @@ -105,13 +105,15 @@ export const ARTICLE_AVAILABLE_TRANSLATIONS_BY_NODE_ID = gql` export const ARTICLE_DETAIL_PUBLIC = gql` query ArticleDetailPublic( - $mediaHash: String! + $id: ID! $language: UserLanguage! $includeTranslation: Boolean = false $includeCanSuperLike: Boolean = true ) { - article(input: { mediaHash: $mediaHash }) { - ...ArticlePublicArticle + article: node(input: { id: $id }) { + ... on Article { + ...ArticlePublicArticle + } } } ${articlePublicFragment} diff --git a/src/views/ArticleDetail/index.tsx b/src/views/ArticleDetail/index.tsx index a46ef10676..77e91c0798 100644 --- a/src/views/ArticleDetail/index.tsx +++ b/src/views/ArticleDetail/index.tsx @@ -65,7 +65,7 @@ import { ClientPreference } from '~/components/GQL/queries/__generated__/ClientP import { ArticleAvailableTranslations } from './__generated__/ArticleAvailableTranslations' import { ArticleDetailPublic, - ArticleDetailPublic_article, + ArticleDetailPublic_article_Article, } from './__generated__/ArticleDetailPublic' import { ArticleTranslation } from './__generated__/ArticleTranslation' @@ -100,7 +100,7 @@ const BaseArticleDetail = ({ article, privateFetched, }: { - article: ArticleDetailPublic_article + article: ArticleDetailPublic_article_Article privateFetched: boolean }) => { const { getQuery, router } = useRoute() @@ -399,7 +399,7 @@ const ArticleDetail = ({ const loading = resultByHash.loading || resultByNodeId.loading const error = resultByHash.error || resultByNodeId.error - const article = data?.article + const article = data?.article as ArticleDetailPublic_article_Article const authorId = article?.author?.id const isAuthor = viewer.id === authorId From b01d8d328a454f9b964226871d8a5e4cbe1cdcdf Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Thu, 10 Nov 2022 12:02:43 +0800 Subject: [PATCH 65/72] Revert "fix(use-article-node-id): use articleNodeId to query" This reverts commit 938076450840e8d8042b7e75ae340a40fd00230f. --- .../Dialogs/DonationDialog/index.tsx | 4 +- .../Dialogs/DonatorsDialog/Content.tsx | 15 +++---- src/components/Dialogs/DonatorsDialog/gql.ts | 40 +++++++++---------- .../SupportSettingDialog/Content.tsx | 4 +- .../SupportSettingDialog/index.tsx | 4 +- src/components/Editor/ToggleAccess/index.tsx | 4 +- .../Forms/PaymentForm/PayTo/Confirm/index.tsx | 4 +- .../PaymentForm/PayTo/SetAmount/index.tsx | 4 +- .../Forms/PaymentForm/Processing/index.tsx | 4 +- src/components/GQL/updates/appreciation.ts | 30 ++++++-------- src/components/GQL/updates/donation.ts | 18 ++++----- .../AppreciationButton/index.tsx | 1 - src/views/ArticleDetail/Collection/index.tsx | 28 ++++++------- .../ArticleDetail/EditMode/Header/index.tsx | 4 +- src/views/ArticleDetail/EditMode/index.tsx | 6 +-- src/views/ArticleDetail/MetaInfo/index.tsx | 4 +- .../SupportWidget/SupportButton/index.tsx | 4 +- .../ArticleDetail/SupportWidget/index.tsx | 4 +- .../Toolbar/DonationButton/index.tsx | 4 +- src/views/ArticleDetail/Toolbar/index.tsx | 4 +- src/views/ArticleDetail/gql.ts | 8 ++-- src/views/ArticleDetail/index.tsx | 6 +-- 22 files changed, 92 insertions(+), 112 deletions(-) diff --git a/src/components/Dialogs/DonationDialog/index.tsx b/src/components/Dialogs/DonationDialog/index.tsx index 800128ac01..2d465133d4 100644 --- a/src/components/Dialogs/DonationDialog/index.tsx +++ b/src/components/Dialogs/DonationDialog/index.tsx @@ -16,7 +16,7 @@ import { PAYMENT_CURRENCY as CURRENCY } from '~/common/enums' import { analytics } from '~/common/utils' import { PayTo_payTo_transaction as PayToTx } from '~/components/GQL/mutations/__generated__/PayTo' -import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { UserDonationRecipient } from './__generated__/UserDonationRecipient' type Step = @@ -45,7 +45,7 @@ interface DonationDialogProps { completeCallback?: () => void defaultStep?: Step recipient: UserDonationRecipient - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article targetId: string } diff --git a/src/components/Dialogs/DonatorsDialog/Content.tsx b/src/components/Dialogs/DonatorsDialog/Content.tsx index 785b88d828..f17513f6ae 100644 --- a/src/components/Dialogs/DonatorsDialog/Content.tsx +++ b/src/components/Dialogs/DonatorsDialog/Content.tsx @@ -18,9 +18,7 @@ import styles from './styles.css' import { ArticleDonators, - ArticleDonators_article_Article, - // ArticleDonators_article_donations_edges, - ArticleDonators_article_Article_donations_edges, + ArticleDonators_article_donations_edges, } from './__generated__/ArticleDonators' import { DonatorDialogArticle } from './__generated__/DonatorDialogArticle' @@ -36,12 +34,11 @@ const DonatorsDialogContent = ({ const isSmallUp = useResponsive('sm-up') const { data, loading, error, fetchMore } = useQuery( ARTICLE_DONATORS, - { variables: { id: article.id } } + { variables: { mediaHash: article.mediaHash } } ) const connectionPath = 'article.donations' - const { edges, pageInfo } = - (data?.article as ArticleDonators_article_Article)?.donations || {} + const { edges, pageInfo } = data?.article?.donations || {} if (loading) { return @@ -58,7 +55,7 @@ const DonatorsDialogContent = ({ const ListRow = ({ index, datum, - }: RowRendererProps) => { + }: RowRendererProps) => { const { node, cursor } = datum return ( @@ -99,9 +96,7 @@ const DonatorsDialogContent = ({ }) } - const totalCount = - (data?.article as ArticleDonators_article_Article)?.donations.totalCount || - 0 + const totalCount = data?.article?.donations.totalCount || 0 // estimate a safe default height const calcContentMaxHeight = () => { diff --git a/src/components/Dialogs/DonatorsDialog/gql.ts b/src/components/Dialogs/DonatorsDialog/gql.ts index afcc3eec42..7530503f0a 100644 --- a/src/components/Dialogs/DonatorsDialog/gql.ts +++ b/src/components/Dialogs/DonatorsDialog/gql.ts @@ -3,27 +3,25 @@ import gql from 'graphql-tag' import { UserDigest } from '~/components/UserDigest' export const ARTICLE_DONATORS = gql` - query ArticleDonators($id: ID!, $after: String) { - article: node(input: { id: $id }) { - ... on Article { - id - donations: transactionsReceivedBy( - input: { first: 10, purpose: donation, after: $after } - ) { - totalCount - pageInfo { - startCursor - endCursor - hasNextPage - } - edges { - cursor - node { - ... on User { - id - ...UserDigestRichUserPublic - ...UserDigestRichUserPrivate - } + query ArticleDonators($mediaHash: String!, $after: String) { + article(input: { mediaHash: $mediaHash }) { + id + donations: transactionsReceivedBy( + input: { first: 10, purpose: donation, after: $after } + ) { + totalCount + pageInfo { + startCursor + endCursor + hasNextPage + } + edges { + cursor + node { + ... on User { + id + ...UserDigestRichUserPublic + ...UserDigestRichUserPrivate } } } diff --git a/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx b/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx index 9c19692a44..ac48ee9ccb 100644 --- a/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx +++ b/src/components/Editor/ToggleAccess/SupportSettingDialog/Content.tsx @@ -18,14 +18,14 @@ import styles from './styles.css' import SupportPreview from './SupportPreview' import Tab, { TabType } from './Tab' -import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { EditMetaDraft } from '~/views/Me/DraftDetail/__generated__/EditMetaDraft' interface FormProps { closeDialog: () => void onBack?: () => any draft?: EditMetaDraft - article?: ArticleDetailPublic_article_Article + article?: ArticleDetailPublic_article editSupportSetting: ( requestForDonation: string | null, replyToDonator: string | null diff --git a/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx b/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx index 6d6f62691d..5bb1521410 100644 --- a/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx +++ b/src/components/Editor/ToggleAccess/SupportSettingDialog/index.tsx @@ -3,11 +3,11 @@ import dynamic from 'next/dynamic' import { Dialog, Spinner, useDialogSwitch } from '~/components' -import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { EditMetaDraft } from '~/views/Me/DraftDetail/__generated__/EditMetaDraft' interface SupportSettingDialogProps { - article?: ArticleDetailPublic_article_Article + article?: ArticleDetailPublic_article draft?: EditMetaDraft editSupportSetting: ( requestForDonation: string | null, diff --git a/src/components/Editor/ToggleAccess/index.tsx b/src/components/Editor/ToggleAccess/index.tsx index 67b499a70b..2829f86f8d 100644 --- a/src/components/Editor/ToggleAccess/index.tsx +++ b/src/components/Editor/ToggleAccess/index.tsx @@ -14,7 +14,7 @@ import { ArticleLicenseType, } from '@/__generated__/globalTypes' import { DigestRichCirclePublic } from '~/components/CircleDigest/Rich/__generated__/DigestRichCirclePublic' -import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { EditMetaDraft } from '~/views/Me/DraftDetail/__generated__/EditMetaDraft' export type ToggleAccessProps = { @@ -32,7 +32,7 @@ export type ToggleAccessProps = { canToggleCircle: boolean draft?: EditMetaDraft - article?: ArticleDetailPublic_article_Article + article?: ArticleDetailPublic_article editSupportSetting: ( requestForDonation: string | null, replyToDonator: string | null diff --git a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx index b91eab25a2..32bc0024af 100644 --- a/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/Confirm/index.tsx @@ -32,7 +32,7 @@ import { PayTo_payTo_transaction as PayToTx, } from '~/components/GQL/mutations/__generated__/PayTo' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' -import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface SetAmountOpenTabCallbackValues { window: Window @@ -41,7 +41,7 @@ interface SetAmountOpenTabCallbackValues { interface FormProps { amount: number - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article currency: CURRENCY recipient: UserDonationRecipient targetId: string diff --git a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx index 6b26f06d9a..46c2527c86 100644 --- a/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/SetAmount/index.tsx @@ -43,7 +43,7 @@ import { PayTo_payTo_transaction as PayToTx, } from '~/components/GQL/mutations/__generated__/PayTo' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' -import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface SetAmountCallbackValues { amount: number @@ -53,7 +53,7 @@ interface SetAmountCallbackValues { interface FormProps { currency: CURRENCY recipient: UserDonationRecipient - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article submitCallback: (values: SetAmountCallbackValues) => void switchToCurrencyChoice: () => void switchToAddCredit: () => void diff --git a/src/components/Forms/PaymentForm/Processing/index.tsx b/src/components/Forms/PaymentForm/Processing/index.tsx index 7c9472c2a3..0ca7589f11 100644 --- a/src/components/Forms/PaymentForm/Processing/index.tsx +++ b/src/components/Forms/PaymentForm/Processing/index.tsx @@ -29,14 +29,14 @@ import styles from './styles.css' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' import { PayTo as PayToMutate } from '~/components/GQL/mutations/__generated__/PayTo' -import { ArticleDetailPublic_article_Article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' import { ViewerTxState } from './__generated__/ViewerTxState' interface Props { amount: number currency: CURRENCY recipient: UserDonationRecipient - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article targetId: string txId: string nextStep: () => void diff --git a/src/components/GQL/updates/appreciation.ts b/src/components/GQL/updates/appreciation.ts index f31a7645a8..1086683423 100644 --- a/src/components/GQL/updates/appreciation.ts +++ b/src/components/GQL/updates/appreciation.ts @@ -5,15 +5,11 @@ import { ARTICLE_DETAIL_PUBLIC } from '~/views/ArticleDetail/gql' import { ERROR_CODES } from '~/common/enums' -import { - ArticleDetailPublic, - ArticleDetailPublic_article_Article, -} from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' const update = ({ cache, left, - id, mediaHash, total, viewer, @@ -21,19 +17,18 @@ const update = ({ }: { cache: DataProxy left: number - id: string mediaHash: string total: number viewer: any canSuperLike?: boolean }) => { try { - if (!id && !mediaHash) { + if (!mediaHash) { return } // read from local cache - const variables = { id, mediaHash } + const variables = { mediaHash } const cacheData = _cloneDeep( cache.readQuery({ query: ARTICLE_DETAIL_PUBLIC, @@ -41,29 +36,28 @@ const update = ({ }) ) - if (!cacheData?.article) { + if (!cacheData || !cacheData.article) { return } // update counts - const article = cacheData.article as ArticleDetailPublic_article_Article - article.appreciateLeft = left - article.appreciationsReceivedTotal = total - article.hasAppreciate = true + cacheData.article.appreciateLeft = left + cacheData.article.appreciationsReceivedTotal = total + cacheData.article.hasAppreciate = true // update SuperLike if (typeof canSuperLike === 'boolean') { - article.canSuperLike = canSuperLike + cacheData.article.canSuperLike = canSuperLike } // inject viewer into appreciators - const appreciators = article?.received?.edges || [] - const appreciatorsCount = article?.received?.totalCount || 0 + const appreciators = cacheData.article?.received?.edges || [] + const appreciatorsCount = cacheData.article?.received?.totalCount || 0 const hasApprecaitor = _some(appreciators, { node: { sender: { id: viewer.id } }, }) if (!hasApprecaitor) { - article.received.totalCount = appreciatorsCount + 1 + cacheData.article.received.totalCount = appreciatorsCount + 1 appreciators.push({ cursor: window.btoa(`arrayconnection:${appreciators.length}`) || '', @@ -86,7 +80,7 @@ const update = ({ __typename: 'AppreciationEdge', }) - article.received.edges = appreciators + cacheData.article.received.edges = appreciators } // write to local cache diff --git a/src/components/GQL/updates/donation.ts b/src/components/GQL/updates/donation.ts index 255ccb855d..e8985fcdc6 100644 --- a/src/components/GQL/updates/donation.ts +++ b/src/components/GQL/updates/donation.ts @@ -6,10 +6,7 @@ import { ARTICLE_DETAIL_PUBLIC_BY_NODE_ID } from '~/views/ArticleDetail/gql' import { ERROR_CODES } from '~/common/enums' -import { - ArticleDetailPublic, - ArticleDetailPublic_article_Article, -} from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' +import { ArticleDetailPublic } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' const update = ({ cache, @@ -34,13 +31,12 @@ const update = ({ }) ) - if (!cacheData?.article) { + if (!cacheData || !cacheData.article) { return } // unshift viewer into donations - const article = cacheData.article as ArticleDetailPublic_article_Article - const donators = article?.donations?.edges || [] + const donators = cacheData.article?.donations?.edges || [] let existed = false _remove(donators, (d) => { if (d.node.id !== viewer.id) { @@ -49,9 +45,11 @@ const update = ({ existed = true return true }) - const donatorsCount = article?.donations?.totalCount || 0 + const donatorsCount = cacheData.article?.donations?.totalCount || 0 - article.donations.totalCount = existed ? donatorsCount : donatorsCount + 1 + cacheData.article.donations.totalCount = existed + ? donatorsCount + : donatorsCount + 1 donators.unshift({ cursor: window.btoa(`arrayconnection:${donators.length}`) || '', @@ -71,7 +69,7 @@ const update = ({ __typename: 'UserEdge', }) - article.donations.edges = donators + cacheData.article.donations.edges = donators // write to local cache cache.writeQuery({ diff --git a/src/views/ArticleDetail/AppreciationButton/index.tsx b/src/views/ArticleDetail/AppreciationButton/index.tsx index fa20face4f..8573061866 100644 --- a/src/views/ArticleDetail/AppreciationButton/index.tsx +++ b/src/views/ArticleDetail/AppreciationButton/index.tsx @@ -96,7 +96,6 @@ const AppreciationButton = ({ updateAppreciation({ cache, left, - id: article.id, mediaHash, total, viewer, diff --git a/src/views/ArticleDetail/Collection/index.tsx b/src/views/ArticleDetail/Collection/index.tsx index ffd7edab66..76aac5b699 100644 --- a/src/views/ArticleDetail/Collection/index.tsx +++ b/src/views/ArticleDetail/Collection/index.tsx @@ -20,26 +20,25 @@ import { analytics, mergeConnections, translate } from '~/common/utils' import styles from './styles.css' -import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' -import { - CollectionList as CollectionListTypes, - CollectionList_article_Article, -} from './__generated__/CollectionList' +import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' +import { CollectionList as CollectionListTypes } from './__generated__/CollectionList' const COLLECTION_LIST = gql` - query CollectionList($id: ID!, $after: String, $first: first_Int_min_0) { - article: node(input: { id: $id }) { - ... on Article { - id - ...ArticleCollection - } + query CollectionList( + $mediaHash: String! + $after: String + $first: first_Int_min_0 + ) { + article(input: { mediaHash: $mediaHash }) { + id + ...ArticleCollection } } ${articleFragments.articleCollection} ` const Collection: React.FC<{ - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article collectionCount?: number }> = ({ article, collectionCount }) => { const { lang } = useContext(LanguageContext) @@ -47,11 +46,10 @@ const Collection: React.FC<{ const isMediumUp = useResponsive('md-up') const { data, loading, error, fetchMore } = useQuery( COLLECTION_LIST, - { variables: { id: article.id, first: 3 } } + { variables: { mediaHash: article.mediaHash, first: 3 } } ) const connectionPath = 'article.collection' - const { edges, pageInfo } = - (data?.article as CollectionList_article_Article)?.collection || {} + const { edges, pageInfo } = data?.article?.collection || {} const loadAll = () => fetchMore({ variables: { diff --git a/src/views/ArticleDetail/EditMode/Header/index.tsx b/src/views/ArticleDetail/EditMode/Header/index.tsx index e02d3a1cf7..c93805c6b4 100644 --- a/src/views/ArticleDetail/EditMode/Header/index.tsx +++ b/src/views/ArticleDetail/EditMode/Header/index.tsx @@ -12,11 +12,11 @@ import ConfirmRevisedPublishDialogContent from './ConfirmRevisedPublishDialogCon import { EDIT_ARTICLE } from './gql' import styles from './styles.css' -import { ArticleDetailPublic_article_Article } from '../../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' import { EditArticle } from './__generated__/EditArticle' type EditModeHeaderProps = { - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article editData: Record coverId?: string diff --git a/src/views/ArticleDetail/EditMode/index.tsx b/src/views/ArticleDetail/EditMode/index.tsx index 3969eee9a3..f5d3573598 100644 --- a/src/views/ArticleDetail/EditMode/index.tsx +++ b/src/views/ArticleDetail/EditMode/index.tsx @@ -43,19 +43,19 @@ import { ArticleDigestDropdownArticle } from '~/components/ArticleDigest/Dropdow import { DigestRichCirclePublic } from '~/components/CircleDigest/Rich/__generated__/DigestRichCirclePublic' import { Asset } from '~/components/GQL/fragments/__generated__/Asset' import { DigestTag } from '~/components/Tag/__generated__/DigestTag' -import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' import { EditArticleSupportSetting } from './__generated__/EditArticleSupportSetting' import { EditModeArticle } from './__generated__/EditModeArticle' import { EditModeArticleAssets } from './__generated__/EditModeArticleAssets' interface EditModeProps { - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article onCancel: () => void onSaved: () => void } export const useEditArticleDetailSupportSetting = ( - article?: ArticleDetailPublic_article_Article + article?: ArticleDetailPublic_article ) => { const articleId = article?.id const [update, { loading: saving }] = useMutation( diff --git a/src/views/ArticleDetail/MetaInfo/index.tsx b/src/views/ArticleDetail/MetaInfo/index.tsx index 240a92846e..bcf3c097e7 100644 --- a/src/views/ArticleDetail/MetaInfo/index.tsx +++ b/src/views/ArticleDetail/MetaInfo/index.tsx @@ -5,10 +5,10 @@ import { fragments } from './gql' import styles from './styles.css' import TranslationButton from './TranslationButton' -import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' type MetaInfoProps = { - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article translated: boolean canTranslate: boolean toggleTranslate: () => any diff --git a/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx b/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx index 8a6983ba4c..1eb8438da1 100644 --- a/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/SupportButton/index.tsx @@ -12,12 +12,12 @@ import { import { analytics } from '~/common/utils' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' -import { ArticleDetailPublic_article_Article } from '../../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' interface SupportButtonProps { recipient: UserDonationRecipient targetId: string - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article supported?: boolean } diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 35df1ed7e3..6995fc761f 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -28,14 +28,14 @@ import { fragments, HAS_DONATED } from './gql' import styles from './styles.css' import SupportButton from './SupportButton' -import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' import { HasDonated, HasDonated_article_Article, } from './__generated__/HasDonated' interface DonationProps { - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article } const SupportWidget = ({ article }: DonationProps) => { diff --git a/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx b/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx index 40c21e9d91..ef4f2ed7b8 100644 --- a/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx +++ b/src/views/ArticleDetail/Toolbar/DonationButton/index.tsx @@ -19,13 +19,13 @@ import { } from '~/common/enums' import { analytics, numAbbr, translate } from '~/common/utils' -import { ArticleDetailPublic_article_Article } from '../../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '../../__generated__/ArticleDetailPublic' import { DonationButtonArticle } from './__generated__/DonationButtonArticle' interface DonationButtonProps { article: DonationButtonArticle disabled: boolean - articleDetail: ArticleDetailPublic_article_Article + articleDetail: ArticleDetailPublic_article } const fragments = { diff --git a/src/views/ArticleDetail/Toolbar/index.tsx b/src/views/ArticleDetail/Toolbar/index.tsx index c97f297f48..e34ff57c6e 100644 --- a/src/views/ArticleDetail/Toolbar/index.tsx +++ b/src/views/ArticleDetail/Toolbar/index.tsx @@ -18,13 +18,13 @@ import CommentBar from './CommentBar' import DonationButton from './DonationButton' import styles from './styles.css' -import { ArticleDetailPublic_article_Article } from '../__generated__/ArticleDetailPublic' +import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' import { ToolbarArticlePrivate } from './__generated__/ToolbarArticlePrivate' import { ToolbarArticlePublic } from './__generated__/ToolbarArticlePublic' export type ToolbarProps = { article: ToolbarArticlePublic & Partial - articleDetails: ArticleDetailPublic_article_Article + articleDetails: ArticleDetailPublic_article translated: boolean translatedLanguage?: string | null privateFetched: boolean diff --git a/src/views/ArticleDetail/gql.ts b/src/views/ArticleDetail/gql.ts index 329b7c1e01..b2b0fd6a19 100644 --- a/src/views/ArticleDetail/gql.ts +++ b/src/views/ArticleDetail/gql.ts @@ -105,15 +105,13 @@ export const ARTICLE_AVAILABLE_TRANSLATIONS_BY_NODE_ID = gql` export const ARTICLE_DETAIL_PUBLIC = gql` query ArticleDetailPublic( - $id: ID! + $mediaHash: String! $language: UserLanguage! $includeTranslation: Boolean = false $includeCanSuperLike: Boolean = true ) { - article: node(input: { id: $id }) { - ... on Article { - ...ArticlePublicArticle - } + article(input: { mediaHash: $mediaHash }) { + ...ArticlePublicArticle } } ${articlePublicFragment} diff --git a/src/views/ArticleDetail/index.tsx b/src/views/ArticleDetail/index.tsx index 77e91c0798..a46ef10676 100644 --- a/src/views/ArticleDetail/index.tsx +++ b/src/views/ArticleDetail/index.tsx @@ -65,7 +65,7 @@ import { ClientPreference } from '~/components/GQL/queries/__generated__/ClientP import { ArticleAvailableTranslations } from './__generated__/ArticleAvailableTranslations' import { ArticleDetailPublic, - ArticleDetailPublic_article_Article, + ArticleDetailPublic_article, } from './__generated__/ArticleDetailPublic' import { ArticleTranslation } from './__generated__/ArticleTranslation' @@ -100,7 +100,7 @@ const BaseArticleDetail = ({ article, privateFetched, }: { - article: ArticleDetailPublic_article_Article + article: ArticleDetailPublic_article privateFetched: boolean }) => { const { getQuery, router } = useRoute() @@ -399,7 +399,7 @@ const ArticleDetail = ({ const loading = resultByHash.loading || resultByNodeId.loading const error = resultByHash.error || resultByNodeId.error - const article = data?.article as ArticleDetailPublic_article_Article + const article = data?.article const authorId = article?.author?.id const isAuthor = viewer.id === authorId From c241a13cc03b603230833dfacba40a706aeeea3d Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 10 Nov 2022 13:23:55 +0800 Subject: [PATCH 66/72] fix(SupportWidget): fix copywriting truncate error --- src/views/ArticleDetail/SupportWidget/index.tsx | 2 +- src/views/ArticleDetail/SupportWidget/styles.css | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/views/ArticleDetail/SupportWidget/index.tsx b/src/views/ArticleDetail/SupportWidget/index.tsx index 6995fc761f..d9d70bf9db 100644 --- a/src/views/ArticleDetail/SupportWidget/index.tsx +++ b/src/views/ArticleDetail/SupportWidget/index.tsx @@ -112,7 +112,7 @@ const SupportWidget = ({ article }: DonationProps) => {
)} {!showAnimation && ( -
+
{loading && } {!loading && ( <> diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index 4e7590df64..71d60546e5 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -22,11 +22,14 @@ border-radius: 1.25rem; & p { - max-width: 25rem; font-size: var(--font-size-sm); line-height: 1.25rem; } + &.note p { + max-width: 25rem; + } + & .donation-button { margin-top: var(--spacing-base); } From 6020efd612f29b777ac38b57a0575951cbd5091f Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 10 Nov 2022 13:41:34 +0800 Subject: [PATCH 67/72] fix(SupportSetting): fix copy --- src/components/Editor/ToggleAccess/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Editor/ToggleAccess/index.tsx b/src/components/Editor/ToggleAccess/index.tsx index 2829f86f8d..43ba4fc1ee 100644 --- a/src/components/Editor/ToggleAccess/index.tsx +++ b/src/components/Editor/ToggleAccess/index.tsx @@ -148,8 +148,8 @@ const ToggleAccess: React.FC = ({

From 68016e6207307530c35275baaecbf39c6ec7ecd5 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 10 Nov 2022 14:49:19 +0800 Subject: [PATCH 68/72] feat(Donation): disable USDT donate without mediaHash --- .../Dialogs/DonationDialog/index.tsx | 1 + .../PayTo/CurrencyChoice/USDTChoice.tsx | 28 +++++++++++++++++++ .../PayTo/CurrencyChoice/index.tsx | 4 +++ 3 files changed, 33 insertions(+) diff --git a/src/components/Dialogs/DonationDialog/index.tsx b/src/components/Dialogs/DonationDialog/index.tsx index 2d465133d4..03e6cf0128 100644 --- a/src/components/Dialogs/DonationDialog/index.tsx +++ b/src/components/Dialogs/DonationDialog/index.tsx @@ -238,6 +238,7 @@ const BaseDonationDialog = ({ {isCurrencyChoice && ( { setCurrency(c) forward('setAmount') diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx index 7bdee373bc..89ccc4b515 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/USDTChoice.tsx @@ -19,19 +19,23 @@ import { formatAmount } from '~/common/utils' import styles from './styles.css' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface FormProps { + article: ArticleDetailPublic_article recipient: UserDonationRecipient switchToSetAmount: () => void switchToWalletSelect: () => void } const USDTChoice: React.FC = ({ + article, recipient, switchToSetAmount, switchToWalletSelect, }) => { const viewer = useContext(ViewerContext) + const mediaHash = article.mediaHash const { address } = useAccount() const { data: balanceUSDTData, isLoading: balanceUSDTLoading } = @@ -41,6 +45,30 @@ const USDTChoice: React.FC = ({ const curatorAddress = viewer.info.ethAddress const creatorAddress = recipient.info.ethAddress + if (mediaHash === '') { + return ( +
+ } + size="md" + spacing="xtight" + color="grey" + > + Tether + + + + + + +
+ ) + } + if (!creatorAddress) { return (
diff --git a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx index e39391b12a..0457fbaa6f 100644 --- a/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx +++ b/src/components/Forms/PaymentForm/PayTo/CurrencyChoice/index.tsx @@ -22,14 +22,17 @@ import USDTChoice from './USDTChoice' import { UserDonationRecipient } from '~/components/Dialogs/DonationDialog/__generated__/UserDonationRecipient' import { WalletBalance } from '~/components/GQL/queries/__generated__/WalletBalance' +import { ArticleDetailPublic_article } from '~/views/ArticleDetail/__generated__/ArticleDetailPublic' interface FormProps { + article: ArticleDetailPublic_article recipient: UserDonationRecipient switchToSetAmount: (c: CURRENCY) => void switchToWalletSelect: () => void } const CurrencyChoice: React.FC = ({ + article, recipient, switchToSetAmount, switchToWalletSelect, @@ -67,6 +70,7 @@ const CurrencyChoice: React.FC = ({ {/* USDT */} switchToSetAmount(CURRENCY.USDT)} switchToWalletSelect={switchToWalletSelect} From ec5863aada878e983b98dda9f7eb6b494b15342b Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Thu, 10 Nov 2022 15:36:40 +0800 Subject: [PATCH 69/72] feat(article): use `id` instead of `mediaHash` for GraphQL queries --- .../Dialogs/AppreciatorsDialog/Content.tsx | 57 ++++++------- .../Dialogs/AppreciatorsDialog/index.tsx | 7 +- .../Dialogs/DonatorsDialog/Content.tsx | 14 ++-- src/components/Dialogs/DonatorsDialog/gql.ts | 40 ++++----- .../FingerprintDialog/ArticleSecret.tsx | 31 ++++--- .../FingerprintDialog/ArticleSecretDesc.tsx | 20 +++-- .../Dialogs/FingerprintDialog/Content.tsx | 2 +- .../Dialogs/FingerprintDialog/index.tsx | 24 ++++-- src/components/GQL/updates/appreciation.ts | 44 +++++----- .../AppreciationButton/index.tsx | 5 +- src/views/ArticleDetail/Collection/index.tsx | 26 +++--- .../ArticleDetail/EditMode/Header/gql.ts | 2 - .../ArticleDetail/EditMode/Header/index.tsx | 1 - .../EditMode/PublishState/PendingState.tsx | 12 +-- .../EditMode/PublishState/PublishedState.tsx | 3 +- .../EditMode/PublishState/gql.ts | 26 +++--- .../EditMode/PublishState/index.tsx | 5 +- src/views/ArticleDetail/EditMode/gql.ts | 81 ++++++++++--------- src/views/ArticleDetail/EditMode/index.tsx | 30 ++++--- .../Responses/FeaturedComments/index.tsx | 2 - .../Responses/LatestResponses/index.tsx | 4 +- src/views/ArticleDetail/Responses/index.tsx | 3 - 22 files changed, 235 insertions(+), 204 deletions(-) diff --git a/src/components/Dialogs/AppreciatorsDialog/Content.tsx b/src/components/Dialogs/AppreciatorsDialog/Content.tsx index 9911b2c4a8..72820a4c17 100644 --- a/src/components/Dialogs/AppreciatorsDialog/Content.tsx +++ b/src/components/Dialogs/AppreciatorsDialog/Content.tsx @@ -18,34 +18,37 @@ import styles from './styles.css' import { ArticleAppreciators, - ArticleAppreciators_article_appreciationsReceived_edges, + ArticleAppreciators_article_Article, + ArticleAppreciators_article_Article_appreciationsReceived_edges, } from './__generated__/ArticleAppreciators' interface AppreciatorsDialogContentProps { - mediaHash: string + id: string closeDialog: () => void } const ARTICLE_APPRECIATORS = gql` - query ArticleAppreciators($mediaHash: String!, $after: String) { - article(input: { mediaHash: $mediaHash }) { - id - appreciationsReceived(input: { first: 10, after: $after }) { - totalCount - pageInfo { - startCursor - endCursor - hasNextPage - } - edges { - cursor - node { - ... on Appreciation { - amount - sender { - id - ...UserDigestRichUserPublic - ...UserDigestRichUserPrivate + query ArticleAppreciators($id: ID!, $after: String) { + article: node(input: { id: $id }) { + ... on Article { + id + appreciationsReceived(input: { first: 10, after: $after }) { + totalCount + pageInfo { + startCursor + endCursor + hasNextPage + } + edges { + cursor + node { + ... on Appreciation { + amount + sender { + id + ...UserDigestRichUserPublic + ...UserDigestRichUserPrivate + } } } } @@ -58,18 +61,18 @@ const ARTICLE_APPRECIATORS = gql` ` const AppreciatorsDialogContent = ({ - mediaHash, + id, closeDialog, }: AppreciatorsDialogContentProps) => { const isSmallUp = useResponsive('sm-up') const { data, loading, error, fetchMore } = useQuery( ARTICLE_APPRECIATORS, - { variables: { mediaHash } } + { variables: { id } } ) - const article = data?.article + const article = data?.article as ArticleAppreciators_article_Article const connectionPath = 'article.appreciationsReceived' - const { edges, pageInfo } = data?.article?.appreciationsReceived || {} + const { edges, pageInfo } = article?.appreciationsReceived || {} if (loading) { return @@ -86,7 +89,7 @@ const AppreciatorsDialogContent = ({ const ListRow = ({ index, datum, - }: RowRendererProps) => { + }: RowRendererProps) => { const { node, cursor } = datum return ( @@ -130,7 +133,7 @@ const AppreciatorsDialogContent = ({ }) } - const totalCount = data?.article?.appreciationsReceived.totalCount || 0 + const totalCount = article?.appreciationsReceived.totalCount || 0 // estimate a safe default height const calcContentMaxHeight = () => { diff --git a/src/components/Dialogs/AppreciatorsDialog/index.tsx b/src/components/Dialogs/AppreciatorsDialog/index.tsx index 4a3dc36823..1218345839 100644 --- a/src/components/Dialogs/AppreciatorsDialog/index.tsx +++ b/src/components/Dialogs/AppreciatorsDialog/index.tsx @@ -14,7 +14,7 @@ const fragments = { article: gql` fragment AppreciatorsDialogArticle on Article { id - mediaHash + id appreciationsReceived(input: { first: 0 }) { totalCount } @@ -35,10 +35,7 @@ const BaseAppreciatorsDialog = ({ {children({ openDialog })} - + ) diff --git a/src/components/Dialogs/DonatorsDialog/Content.tsx b/src/components/Dialogs/DonatorsDialog/Content.tsx index f17513f6ae..7a3bdef663 100644 --- a/src/components/Dialogs/DonatorsDialog/Content.tsx +++ b/src/components/Dialogs/DonatorsDialog/Content.tsx @@ -18,7 +18,8 @@ import styles from './styles.css' import { ArticleDonators, - ArticleDonators_article_donations_edges, + ArticleDonators_article_Article, + ArticleDonators_article_Article_donations_edges, } from './__generated__/ArticleDonators' import { DonatorDialogArticle } from './__generated__/DonatorDialogArticle' @@ -34,11 +35,12 @@ const DonatorsDialogContent = ({ const isSmallUp = useResponsive('sm-up') const { data, loading, error, fetchMore } = useQuery( ARTICLE_DONATORS, - { variables: { mediaHash: article.mediaHash } } + { variables: { id: article.id } } ) const connectionPath = 'article.donations' - const { edges, pageInfo } = data?.article?.donations || {} + const { edges, pageInfo } = + (data?.article as ArticleDonators_article_Article)?.donations || {} if (loading) { return @@ -55,7 +57,7 @@ const DonatorsDialogContent = ({ const ListRow = ({ index, datum, - }: RowRendererProps) => { + }: RowRendererProps) => { const { node, cursor } = datum return ( @@ -96,7 +98,9 @@ const DonatorsDialogContent = ({ }) } - const totalCount = data?.article?.donations.totalCount || 0 + const totalCount = + (data?.article as ArticleDonators_article_Article)?.donations.totalCount || + 0 // estimate a safe default height const calcContentMaxHeight = () => { diff --git a/src/components/Dialogs/DonatorsDialog/gql.ts b/src/components/Dialogs/DonatorsDialog/gql.ts index 7530503f0a..afcc3eec42 100644 --- a/src/components/Dialogs/DonatorsDialog/gql.ts +++ b/src/components/Dialogs/DonatorsDialog/gql.ts @@ -3,25 +3,27 @@ import gql from 'graphql-tag' import { UserDigest } from '~/components/UserDigest' export const ARTICLE_DONATORS = gql` - query ArticleDonators($mediaHash: String!, $after: String) { - article(input: { mediaHash: $mediaHash }) { - id - donations: transactionsReceivedBy( - input: { first: 10, purpose: donation, after: $after } - ) { - totalCount - pageInfo { - startCursor - endCursor - hasNextPage - } - edges { - cursor - node { - ... on User { - id - ...UserDigestRichUserPublic - ...UserDigestRichUserPrivate + query ArticleDonators($id: ID!, $after: String) { + article: node(input: { id: $id }) { + ... on Article { + id + donations: transactionsReceivedBy( + input: { first: 10, purpose: donation, after: $after } + ) { + totalCount + pageInfo { + startCursor + endCursor + hasNextPage + } + edges { + cursor + node { + ... on User { + id + ...UserDigestRichUserPublic + ...UserDigestRichUserPrivate + } } } } diff --git a/src/components/Dialogs/FingerprintDialog/ArticleSecret.tsx b/src/components/Dialogs/FingerprintDialog/ArticleSecret.tsx index 85d688f9cb..3c7893bf69 100644 --- a/src/components/Dialogs/FingerprintDialog/ArticleSecret.tsx +++ b/src/components/Dialogs/FingerprintDialog/ArticleSecret.tsx @@ -8,31 +8,38 @@ import { IconLocked24, Spinner, Translate, - useRoute, } from '~/components' import styles from './styles.css' -import { ArticleSecret } from './__generated__/ArticleSecret' +import { + ArticleSecret, + ArticleSecret_article_Article, +} from './__generated__/ArticleSecret' + +type ArticleSecretSectionProps = { + id: string +} export const QUERY_SECRET = gql` - query ArticleSecret($mediaHash: String!) { - article(input: { mediaHash: $mediaHash }) { - id - access { - secret + query ArticleSecret($id: ID!) { + article: node(input: { id: $id }) { + ... on Article { + id + access { + secret + } } } } ` -const ArticleSecretSection = () => { - const { getQuery } = useRoute() - const mediaHash = getQuery('mediaHash') +const ArticleSecretSection: React.FC = ({ id }) => { const { data, loading, error } = useQuery(QUERY_SECRET, { - variables: { mediaHash }, + variables: { id }, }) - const secret = data?.article?.access?.secret // || 'default-no-secret' + const article = data?.article as ArticleSecret_article_Article + const secret = article?.access?.secret // || 'default-no-secret' return (
diff --git a/src/components/Dialogs/FingerprintDialog/ArticleSecretDesc.tsx b/src/components/Dialogs/FingerprintDialog/ArticleSecretDesc.tsx index 90ff1bf2db..072767740b 100644 --- a/src/components/Dialogs/FingerprintDialog/ArticleSecretDesc.tsx +++ b/src/components/Dialogs/FingerprintDialog/ArticleSecretDesc.tsx @@ -1,30 +1,36 @@ import { useApolloClient } from '@apollo/react-hooks' import { useEffect, useState } from 'react' -import { Translate, useRoute } from '~/components' +import { Translate } from '~/components' import { QUERY_SECRET } from './ArticleSecret' import styles from './styles.css' -import { ArticleSecret } from './__generated__/ArticleSecret' +import { + ArticleSecret, + ArticleSecret_article_Article, +} from './__generated__/ArticleSecret' -const ArticleSecretDesc = () => { +type ArticleSecretDescProps = { + id: string +} + +const ArticleSecretDesc: React.FC = ({ id }) => { const client = useApolloClient() - const { getQuery } = useRoute() - const mediaHash = getQuery('mediaHash') const [secret, setSecret] = useState() useEffect(() => { const watcher = client.watchQuery({ query: QUERY_SECRET, - variables: { mediaHash }, + variables: { id }, fetchPolicy: 'network-only', }) watcher.subscribe({ next: (result) => { - const key = result?.data?.article?.access.secret + const key = (result?.data?.article as ArticleSecret_article_Article) + ?.access.secret setSecret(key) }, error: (e) => { diff --git a/src/components/Dialogs/FingerprintDialog/Content.tsx b/src/components/Dialogs/FingerprintDialog/Content.tsx index e754ae1468..425491a809 100644 --- a/src/components/Dialogs/FingerprintDialog/Content.tsx +++ b/src/components/Dialogs/FingerprintDialog/Content.tsx @@ -232,7 +232,7 @@ const FingerprintDialogContent = ({
{/* secret */} - {showSecret && } + {showSecret && articleId && }
diff --git a/src/components/Dialogs/FingerprintDialog/index.tsx b/src/components/Dialogs/FingerprintDialog/index.tsx index e808091012..fd088a3da3 100644 --- a/src/components/Dialogs/FingerprintDialog/index.tsx +++ b/src/components/Dialogs/FingerprintDialog/index.tsx @@ -12,7 +12,10 @@ import { } from '~/components' import { ArticleAccessType } from '@/__generated__/globalTypes' -import { ArticleFingerprintPublic } from './__generated__/ArticleFingerprintPublic' +import { + ArticleFingerprintPublic, + ArticleFingerprintPublic_article_Article, +} from './__generated__/ArticleFingerprintPublic' import { FingerprintArticle } from './__generated__/FingerprintArticle' interface FingerprintDialogProps { @@ -43,10 +46,12 @@ const fragments = { } const ArticleFingerprintGQL = gql` - query ArticleFingerprintPublic($mediaHash: String!) { - article(input: { mediaHash: $mediaHash }) { - id - ...FingerprintArticle + query ArticleFingerprintPublic($id: ID!) { + article: node(input: { id: $id }) { + ... on Article { + id + ...FingerprintArticle + } } } ${fragments.article} @@ -66,7 +71,7 @@ const BaseFingerprintDialog = ({ loading, // error, refetch, } = usePublicQuery(ArticleFingerprintGQL, { - variables: { mediaHash: article.mediaHash }, + variables: { id: article.id }, skip: true, // skip first call }) @@ -95,7 +100,12 @@ const BaseFingerprintDialog = ({ { try { - if (!mediaHash) { + if (!id) { return } // read from local cache - const variables = { mediaHash } const cacheData = _cloneDeep( - cache.readQuery({ - query: ARTICLE_DETAIL_PUBLIC, - variables, + cache.readQuery({ + query: ARTICLE_DETAIL_PUBLIC_BY_NODE_ID, + variables: { id }, }) ) - if (!cacheData || !cacheData.article) { + if (!cacheData?.article) { return } // update counts - cacheData.article.appreciateLeft = left - cacheData.article.appreciationsReceivedTotal = total - cacheData.article.hasAppreciate = true + const article = + cacheData.article as ArticleDetailPublicByNodeId_article_Article + article.appreciateLeft = left + article.appreciationsReceivedTotal = total + article.hasAppreciate = true // update SuperLike if (typeof canSuperLike === 'boolean') { - cacheData.article.canSuperLike = canSuperLike + article.canSuperLike = canSuperLike } // inject viewer into appreciators - const appreciators = cacheData.article?.received?.edges || [] - const appreciatorsCount = cacheData.article?.received?.totalCount || 0 + const appreciators = article?.received?.edges || [] + const appreciatorsCount = article?.received?.totalCount || 0 const hasApprecaitor = _some(appreciators, { node: { sender: { id: viewer.id } }, }) if (!hasApprecaitor) { - cacheData.article.received.totalCount = appreciatorsCount + 1 + article.received.totalCount = appreciatorsCount + 1 appreciators.push({ cursor: window.btoa(`arrayconnection:${appreciators.length}`) || '', @@ -80,14 +84,14 @@ const update = ({ __typename: 'AppreciationEdge', }) - cacheData.article.received.edges = appreciators + article.received.edges = appreciators } // write to local cache cache.writeQuery({ - query: ARTICLE_DETAIL_PUBLIC, + query: ARTICLE_DETAIL_PUBLIC_BY_NODE_ID, data: cacheData, - variables, + variables: { id }, }) } catch (e) { if ((e as any).message.startsWith("Can't find field")) { diff --git a/src/views/ArticleDetail/AppreciationButton/index.tsx b/src/views/ArticleDetail/AppreciationButton/index.tsx index 8573061866..66c27a8f14 100644 --- a/src/views/ArticleDetail/AppreciationButton/index.tsx +++ b/src/views/ArticleDetail/AppreciationButton/index.tsx @@ -7,7 +7,6 @@ import { Tooltip, Translate, useMutation, - useRoute, ViewerContext, } from '~/components' import CLIENT_PREFERENCE from '~/components/GQL/queries/clientPreference' @@ -41,8 +40,6 @@ const AppreciationButton = ({ privateFetched, disabled, }: AppreciationButtonProps) => { - const { getQuery } = useRoute() - const mediaHash = getQuery('mediaHash') const viewer = useContext(ViewerContext) const { token, refreshToken } = useContext(ReCaptchaContext) const { data, client } = useQuery(CLIENT_PREFERENCE, { @@ -96,7 +93,7 @@ const AppreciationButton = ({ updateAppreciation({ cache, left, - mediaHash, + id: article.id, total, viewer, canSuperLike: false, diff --git a/src/views/ArticleDetail/Collection/index.tsx b/src/views/ArticleDetail/Collection/index.tsx index 76aac5b699..870338cd16 100644 --- a/src/views/ArticleDetail/Collection/index.tsx +++ b/src/views/ArticleDetail/Collection/index.tsx @@ -21,17 +21,18 @@ import { analytics, mergeConnections, translate } from '~/common/utils' import styles from './styles.css' import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' -import { CollectionList as CollectionListTypes } from './__generated__/CollectionList' +import { + CollectionList as CollectionListTypes, + CollectionList_article_Article, +} from './__generated__/CollectionList' const COLLECTION_LIST = gql` - query CollectionList( - $mediaHash: String! - $after: String - $first: first_Int_min_0 - ) { - article(input: { mediaHash: $mediaHash }) { - id - ...ArticleCollection + query CollectionList($id: ID!, $after: String, $first: first_Int_min_0) { + article: node(input: { id: $id }) { + ... on Article { + id + ...ArticleCollection + } } } ${articleFragments.articleCollection} @@ -46,14 +47,15 @@ const Collection: React.FC<{ const isMediumUp = useResponsive('md-up') const { data, loading, error, fetchMore } = useQuery( COLLECTION_LIST, - { variables: { mediaHash: article.mediaHash, first: 3 } } + { variables: { id: article.id, first: 3 } } ) const connectionPath = 'article.collection' - const { edges, pageInfo } = data?.article?.collection || {} + const { edges, pageInfo } = + (data?.article as CollectionList_article_Article)?.collection || {} const loadAll = () => fetchMore({ variables: { - mediaHash: article.mediaHash, + id: article.id, after: pageInfo?.endCursor, first: null, }, diff --git a/src/views/ArticleDetail/EditMode/Header/gql.ts b/src/views/ArticleDetail/EditMode/Header/gql.ts index ab79ed25e8..d3cd940516 100644 --- a/src/views/ArticleDetail/EditMode/Header/gql.ts +++ b/src/views/ArticleDetail/EditMode/Header/gql.ts @@ -13,7 +13,6 @@ import articleFragments from '~/components/GQL/fragments/article' export const EDIT_ARTICLE = gql` mutation EditArticle( $id: ID! - $mediaHash: String! $content: String $cover: ID $tags: [String!] @@ -46,7 +45,6 @@ export const EDIT_ARTICLE = gql` cover tags { ...DigestTag - selected(input: { mediaHash: $mediaHash }) } access { type diff --git a/src/views/ArticleDetail/EditMode/Header/index.tsx b/src/views/ArticleDetail/EditMode/Header/index.tsx index c93805c6b4..b7b13d8139 100644 --- a/src/views/ArticleDetail/EditMode/Header/index.tsx +++ b/src/views/ArticleDetail/EditMode/Header/index.tsx @@ -65,7 +65,6 @@ const EditModeHeader = ({ await editArticle({ variables: { id: article.id, - mediaHash: article.mediaHash, cover: coverId || null, tags: tags.map((tag) => tag.content), collection: collection.map(({ id: articleId }) => articleId), diff --git a/src/views/ArticleDetail/EditMode/PublishState/PendingState.tsx b/src/views/ArticleDetail/EditMode/PublishState/PendingState.tsx index e307a0719b..cff2934d23 100644 --- a/src/views/ArticleDetail/EditMode/PublishState/PendingState.tsx +++ b/src/views/ArticleDetail/EditMode/PublishState/PendingState.tsx @@ -4,18 +4,12 @@ import { Toast, Translate } from '~/components' import EDIT_MODE_ARTICLE_DRAFTS from './gql' -import { EditModeArticle_article_drafts as EditModeDraft } from '../__generated__/EditModeArticle' +import { EditModeArticle_article_Article_drafts as EditModeDraft } from '../__generated__/EditModeArticle' import { EditModeArticleDrafts } from './__generated__/EditModeArticleDrafts' -const PendingState = ({ - draft, - mediaHash, -}: { - draft: EditModeDraft - mediaHash: string -}) => { +const PendingState = ({ draft, id }: { draft: EditModeDraft; id: string }) => { useQuery(EDIT_MODE_ARTICLE_DRAFTS, { - variables: { mediaHash }, + variables: { id }, pollInterval: 1000 * 2, errorPolicy: 'none', fetchPolicy: 'network-only', diff --git a/src/views/ArticleDetail/EditMode/PublishState/PublishedState.tsx b/src/views/ArticleDetail/EditMode/PublishState/PublishedState.tsx index 5ea38616ee..4c8b21b5b6 100644 --- a/src/views/ArticleDetail/EditMode/PublishState/PublishedState.tsx +++ b/src/views/ArticleDetail/EditMode/PublishState/PublishedState.tsx @@ -5,10 +5,11 @@ import { Dialog, ShareDialog, Translate } from '~/components' import { toPath } from '~/common/utils' -import { EditModeArticle_article_drafts as EditModeDraft } from '../__generated__/EditModeArticle' +import { EditModeArticle_article_Article_drafts as EditModeDraft } from '../__generated__/EditModeArticle' interface Props { article: { + id: string title: string slug: string author: { diff --git a/src/views/ArticleDetail/EditMode/PublishState/gql.ts b/src/views/ArticleDetail/EditMode/PublishState/gql.ts index 86b8993536..1cf31df7d9 100644 --- a/src/views/ArticleDetail/EditMode/PublishState/gql.ts +++ b/src/views/ArticleDetail/EditMode/PublishState/gql.ts @@ -3,20 +3,22 @@ import gql from 'graphql-tag' import { fragments as EditorFragments } from '~/components/Editor/fragments' const EDIT_MODE_ARTICLE_DRAFTS = gql` - query EditModeArticleDrafts($mediaHash: String!) { - article(input: { mediaHash: $mediaHash }) { - id - content - mediaHash - tags { - content - } - drafts { + query EditModeArticleDrafts($id: ID!) { + article: node(input: { id: $id }) { + ... on Article { id + content mediaHash - tags - publishState - ...EditorDraft + tags { + content + } + drafts { + id + mediaHash + tags + publishState + ...EditorDraft + } } } } diff --git a/src/views/ArticleDetail/EditMode/PublishState/index.tsx b/src/views/ArticleDetail/EditMode/PublishState/index.tsx index 7a031c862f..5093de1db2 100644 --- a/src/views/ArticleDetail/EditMode/PublishState/index.tsx +++ b/src/views/ArticleDetail/EditMode/PublishState/index.tsx @@ -2,10 +2,11 @@ import PendingState from './PendingState' import PublishedState from './PublishedState' import styles from './styles.css' -import { EditModeArticle_article_drafts as EditModeDraft } from '../__generated__/EditModeArticle' +import { EditModeArticle_article_Article_drafts as EditModeDraft } from '../__generated__/EditModeArticle' interface Props { article: { + id: string title: string slug: string mediaHash: string @@ -39,7 +40,7 @@ const PublishState = ({ return (
{(isPending || isPublished) && !isValidHash && ( - + )} {isPublished && !isSameHash && isValidHash && ( diff --git a/src/views/ArticleDetail/EditMode/gql.ts b/src/views/ArticleDetail/EditMode/gql.ts index acfa59acad..ce4ab8f7aa 100644 --- a/src/views/ArticleDetail/EditMode/gql.ts +++ b/src/views/ArticleDetail/EditMode/gql.ts @@ -7,48 +7,49 @@ import assetFragment from '~/components/GQL/fragments/asset' export const EDIT_MODE_ARTICLE = gql` query EditModeArticle( - $mediaHash: String! + $id: ID! $after: String $first: first_Int_min_0 = null ) { - article(input: { mediaHash: $mediaHash }) { - id - slug - mediaHash - cover - assets { - ...Asset - } - tags { - ...DigestTag - selected(input: { mediaHash: $mediaHash }) - } - author { + article: node(input: { id: $id }) { + ... on Article { id - ownCircles { - ...DigestRichCirclePublic + slug + mediaHash + cover + assets { + ...Asset } - displayName - avatar - } - access { - type - circle { + tags { + ...DigestTag + } + author { id - ...DigestRichCirclePublic + ownCircles { + ...DigestRichCirclePublic + } + displayName + avatar } + access { + type + circle { + id + ...DigestRichCirclePublic + } + } + license + requestForDonation + replyToDonator + revisionCount + drafts { + id + mediaHash + publishState + ...EditorDraft + } + ...ArticleCollection } - license - requestForDonation - replyToDonator - revisionCount - drafts { - id - mediaHash - publishState - ...EditorDraft - } - ...ArticleCollection } } ${assetFragment} @@ -59,11 +60,13 @@ export const EDIT_MODE_ARTICLE = gql` ` export const EDIT_MODE_ARTICLE_ASSETS = gql` - query EditModeArticleAssets($mediaHash: String!) { - article(input: { mediaHash: $mediaHash }) { - id - assets { - ...Asset + query EditModeArticleAssets($id: ID!) { + article: node(input: { id: $id }) { + ... on Article { + id + assets { + ...Asset + } } } } diff --git a/src/views/ArticleDetail/EditMode/index.tsx b/src/views/ArticleDetail/EditMode/index.tsx index f5d3573598..61a1f7f252 100644 --- a/src/views/ArticleDetail/EditMode/index.tsx +++ b/src/views/ArticleDetail/EditMode/index.tsx @@ -45,7 +45,10 @@ import { Asset } from '~/components/GQL/fragments/__generated__/Asset' import { DigestTag } from '~/components/Tag/__generated__/DigestTag' import { ArticleDetailPublic_article } from '../__generated__/ArticleDetailPublic' import { EditArticleSupportSetting } from './__generated__/EditArticleSupportSetting' -import { EditModeArticle } from './__generated__/EditModeArticle' +import { + EditModeArticle, + EditModeArticle_article_Article, +} from './__generated__/EditModeArticle' import { EditModeArticleAssets } from './__generated__/EditModeArticleAssets' interface EditModeProps { @@ -88,18 +91,19 @@ const EditMode: React.FC = ({ article, onCancel, onSaved }) => { const { data, loading, error } = useQuery( EDIT_MODE_ARTICLE, { - variables: { mediaHash: article.mediaHash }, + variables: { id: article.id }, fetchPolicy: 'network-only', } ) + const editModeArticle = data?.article as EditModeArticle_article_Article // cover - const assets = data?.article?.assets || [] + const assets = editModeArticle?.assets || [] const [cover, editCover] = useState() const refetchAssets = useImperativeQuery( EDIT_MODE_ARTICLE_ASSETS, { - variables: { mediaHash: article.mediaHash }, + variables: { id: article.id }, fetchPolicy: 'network-only', } ) @@ -119,7 +123,7 @@ const EditMode: React.FC = ({ article, onCancel, onSaved }) => { ) const [license, editLicense] = useState(article.license) - const ownCircles = data?.article?.author.ownCircles + const ownCircles = editModeArticle?.author.ownCircles const hasOwnCircle = ownCircles && ownCircles.length >= 1 const editAccess = ( addToCircle: boolean, @@ -139,19 +143,23 @@ const EditMode: React.FC = ({ article, onCancel, onSaved }) => { // update cover & collection from retrieved data useEffect(() => { - if (!data?.article) { + if (!editModeArticle) { return } // cover, find from `article.assets` since `article.cover` isn't a `Asset` - const currCover = assets.find((asset) => asset.path === data.article?.cover) + const currCover = assets.find( + (asset) => asset.path === editModeArticle?.cover + ) if (currCover) { editCover(currCover) } // collection - editCollection(data.article.collection.edges?.map(({ node }) => node) || []) - }, [data?.article?.id]) + editCollection( + editModeArticle?.collection.edges?.map(({ node }) => node) || [] + ) + }, [editModeArticle?.id]) const { edit: editSupport, saving: supportSaving } = useEditArticleDetailSupportSetting(article) @@ -177,10 +185,10 @@ const EditMode: React.FC = ({ article, onCancel, onSaved }) => { ) } - const drafts = data?.article?.drafts + const drafts = editModeArticle?.drafts const draft = drafts?.[0] const revisionCountLeft = - MAX_ARTICLE_REVISION_COUNT - (data?.article?.revisionCount || 0) + MAX_ARTICLE_REVISION_COUNT - (editModeArticle?.revisionCount || 0) const isOverRevisionLimit = revisionCountLeft <= 0 const isSameHash = draft?.mediaHash === article.mediaHash const isPending = draft?.publishState === 'pending' diff --git a/src/views/ArticleDetail/Responses/FeaturedComments/index.tsx b/src/views/ArticleDetail/Responses/FeaturedComments/index.tsx index 269bb3311f..749f1f1049 100644 --- a/src/views/ArticleDetail/Responses/FeaturedComments/index.tsx +++ b/src/views/ArticleDetail/Responses/FeaturedComments/index.tsx @@ -33,8 +33,6 @@ type Comment = CommentPublic & Partial const FeaturedComments = ({ id, lock }: { id: string; lock: boolean }) => { const viewer = useContext(ViewerContext) - // const { getQuery } = useRoute() - // const mediaHash = getQuery('mediaHash') /** * Data Fetching diff --git a/src/views/ArticleDetail/Responses/LatestResponses/index.tsx b/src/views/ArticleDetail/Responses/LatestResponses/index.tsx index ef8dd7aa00..70dea04cf5 100644 --- a/src/views/ArticleDetail/Responses/LatestResponses/index.tsx +++ b/src/views/ArticleDetail/Responses/LatestResponses/index.tsx @@ -50,8 +50,6 @@ type Response = ResponsePublic & Partial> const LatestResponses = ({ id, lock }: { id: string; lock: boolean }) => { const viewer = useContext(ViewerContext) const isMediumUp = useResponsive('md-up') - // const { getQuery } = useRoute() - // const mediaHash = getQuery('mediaHash') const [articleOnlyMode, setArticleOnlyMode] = useState(false) const storedCursorRef = useRef(null) @@ -85,7 +83,7 @@ const LatestResponses = ({ id, lock }: { id: string; lock: boolean }) => { client, } = usePublicQuery(LATEST_RESPONSES_PUBLIC, { variables: { - id, // mediaHash, + id, first: RESPONSES_COUNT, articleOnly: articleOnlyMode, }, diff --git a/src/views/ArticleDetail/Responses/index.tsx b/src/views/ArticleDetail/Responses/index.tsx index 80452d0dfa..7df3456af3 100644 --- a/src/views/ArticleDetail/Responses/index.tsx +++ b/src/views/ArticleDetail/Responses/index.tsx @@ -29,9 +29,6 @@ const ARTICLE_RESPONSE = gql` ` const Responses = ({ id, lock }: { id: string; lock: boolean }) => { - // const { getQuery } = useRoute() - // const mediaHash = getQuery('mediaHash') - const { data, loading } = useQuery(ARTICLE_RESPONSE, { variables: { id }, }) From fd3dfe320ef1a5ed83b082fa29bb8c08db5fe038 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 10 Nov 2022 16:59:22 +0800 Subject: [PATCH 70/72] fix(SupportWidget): fix hint styles error in mobile --- src/views/ArticleDetail/SupportWidget/styles.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css index 71d60546e5..8ac7182e94 100644 --- a/src/views/ArticleDetail/SupportWidget/styles.css +++ b/src/views/ArticleDetail/SupportWidget/styles.css @@ -80,6 +80,10 @@ } .animation-hint { - height: 1.5rem; + height: 2.5rem; margin: 0 auto; + + @media (--sm-up) { + height: 1.5rem; + } } From 193fc3331682b02d96873621b5bc938f6f464028 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 10 Nov 2022 17:00:57 +0800 Subject: [PATCH 71/72] fix(Donation): fix padding error --- src/components/Forms/PaymentForm/Processing/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Forms/PaymentForm/Processing/styles.css b/src/components/Forms/PaymentForm/Processing/styles.css index 3c0fb173ab..e1a73ef431 100644 --- a/src/components/Forms/PaymentForm/Processing/styles.css +++ b/src/components/Forms/PaymentForm/Processing/styles.css @@ -1,4 +1,5 @@ .hint { + padding: 0 var(--spacing-base); margin-top: var(--spacing-base); text-align: center; } From 7029f411d6a443f92574e23e31dc8915d84f0477 Mon Sep 17 00:00:00 2001 From: bluecloud <96812901+pitb2022@users.noreply.github.com> Date: Thu, 10 Nov 2022 18:27:22 +0800 Subject: [PATCH 72/72] chore(release): v4.9.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c75cc5d5b..d295398e78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matters-web", - "version": "4.8.1", + "version": "4.9.0", "description": "codebase of Matters' website", "sideEffects": false, "author": "Matters ",