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 (
+
+ 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={
+ }
+ />
+ }
+ />
+
+
+
+
+
+
+ >
+ )
+}
+
+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 (
-
- 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}
- 個人支持過・看全部
+
+
+ {donatorsCount}
+ }
+ textPlacement="left"
+ >
+ 個人支持過・看全部
+
+
)}
-
+
)}
)
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 && (
-
+
- } color="gold">
+ }
+ color="gold"
+ size="xs"
+ >
{
-
+
)}
)}
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 }) => (
- {
- 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()
- }}
- >
- } weight="md" color="white">
-
-
-
+ <>
+ {supported && (
+ {
+ onClick(openDialog)
+ }}
+ >
+ } weight="md" color="gold">
+
+
+
+ )}
+ {!supported && (
+ {
+ onClick(openDialog)
+ }}
+ >
+ } weight="md" color="white">
+
+
+
+ )}
+ >
)}
)
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 && (
- {
- onClick(openDialog)
- }}
- >
- } weight="md" color="gold">
-
-
-
- )}
- {!supported && (
- {
- onClick(openDialog)
- }}
- >
- } weight="md" color="white">
-
-
-
- )}
- >
+ <>
+ {supported && (
+ {
+ if (onClick) {
+ onClick()
+ }
+ }}
+ >
+ } weight="md" color="gold">
+
+
+
+ )}
+ {!supported && (
+ {
+ if (onClick) {
+ onClick()
+ }
+ }}
+ >
+ } weight="md" color="white">
+
+
+
)}
-
+ >
)
}
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 && (
-
-
-
-
-
-
- }
- color="gold"
- size="xs"
- >
-
-
-
-
-
+ {supported && (
+
+
+
+
+
+
+ }
+ color="gold"
+ size="xs"
+ >
+
+
+
+
+
+ )}
+ >
)}
)}
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 (
+ {
+ if (onClick) {
+ onClick()
+ }
+ }}
+ >
+ } weight="md" color="gold">
+
+
+
+ )
+ }
return (
- <>
- {supported && (
- {
- if (onClick) {
- onClick()
- }
- }}
- >
- } weight="md" color="gold">
-
-
-
- )}
- {!supported && (
- {
- if (onClick) {
- onClick()
- }
- }}
- >
- } weight="md" color="white">
-
-
-
- )}
- >
+ {
+ if (onClick) {
+ onClick()
+ }
+ }}
+ >
+ } weight="md" color="white">
+
+
+
)
}
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 && (
-
+
diff --git a/src/views/ArticleDetail/SupportWidget/styles.css b/src/views/ArticleDetail/SupportWidget/styles.css
index 3292aa941e..d8f16242d3 100644
--- a/src/views/ArticleDetail/SupportWidget/styles.css
+++ b/src/views/ArticleDetail/SupportWidget/styles.css
@@ -39,8 +39,13 @@
margin-top: var(--spacing-loose);
font-size: var(--font-size-xs);
- & .transaction-button {
+ & .transaction-left {
display: inline-block;
+ border-bottom: 1px solid transparent;
+ }
+
+ & .transaction-button {
+ display: inline-flex;
margin-left: var(--spacing-xx-tight);
border-bottom: 1px solid var(--color-matters-gold);
}
From 7fb26c3138f309dcf525405bda27f838c559567b Mon Sep 17 00:00:00 2001
From: bluecloud <96812901+pitb2022@users.noreply.github.com>
Date: Mon, 7 Nov 2022 11:25:09 +0800
Subject: [PATCH 28/72] feat(Donators): revise avatar list UI
---
.../SupportWidget/Donators/gql.ts | 2 +-
.../SupportWidget/Donators/index.tsx | 53 +++++++++++--------
2 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/src/views/ArticleDetail/SupportWidget/Donators/gql.ts b/src/views/ArticleDetail/SupportWidget/Donators/gql.ts
index b3d46c59f4..536cf99460 100644
--- a/src/views/ArticleDetail/SupportWidget/Donators/gql.ts
+++ b/src/views/ArticleDetail/SupportWidget/Donators/gql.ts
@@ -8,7 +8,7 @@ export const fragments = {
fragment DonatorsArticle on Article {
id
donations: transactionsReceivedBy(
- input: { first: 8, purpose: donation }
+ input: { first: 9, purpose: donation }
) {
totalCount
edges {
diff --git a/src/views/ArticleDetail/SupportWidget/Donators/index.tsx b/src/views/ArticleDetail/SupportWidget/Donators/index.tsx
index 0137538f7b..4fa3c4e7bd 100644
--- a/src/views/ArticleDetail/SupportWidget/Donators/index.tsx
+++ b/src/views/ArticleDetail/SupportWidget/Donators/index.tsx
@@ -37,11 +37,14 @@ interface DonatorsProps {
const Donators = ({ article, showAvatarAnimation = false }: DonatorsProps) => {
const { lang } = useContext(LanguageContext)
+ const maxAvatarNum = 9
+
const edges = article.donations.edges
const donatorsCount = article.donations.totalCount
const donators = (
edges?.map(({ node }) => node).filter((user) => !!user) || []
- ).slice(0, 10)
+ ).slice(0, maxAvatarNum)
+ const frontDonators = donators.slice(0, maxAvatarNum - 1)
const springStyles = useSpring({
from: { x: -50 },
@@ -60,7 +63,7 @@ const Donators = ({ article, showAvatarAnimation = false }: DonatorsProps) => {
aria-haspopup="true"
>
- {donators.map((user, index) => {
+ {frontDonators.map((user, index) => {
return (
<>
{showAvatarAnimation && (
@@ -87,29 +90,37 @@ const Donators = ({ article, showAvatarAnimation = false }: DonatorsProps) => {
>
)
})}
- {donatorsCount > 4 && (
- {donatorsCount}
+
+ {donatorsCount === maxAvatarNum && (
+
+ )}
+
+ {donatorsCount > maxAvatarNum && (
+
+ {donatorsCount - (maxAvatarNum - 1)}
+
)}
- {donatorsCount > 4 && (
-
-
+
+ {donatorsCount}
+ }
+ textPlacement="left"
>
- {donatorsCount}
- }
- textPlacement="left"
- >
- 個人支持過・看全部
-
-
-
- )}
+ 個人支持過・看全部
+
+
+
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 (
{
}
}}
>
- } weight="md" color="gold">
+ } weight="md" color="gold" size="md">
@@ -27,7 +27,7 @@ const DonationButton = ({ supported, onClick }: DonationButtonProps) => {
}
return (
{
if (onClick) {
@@ -35,7 +35,7 @@ const DonationButton = ({ supported, onClick }: DonationButtonProps) => {
}
}}
>
- } weight="md" color="white">
+ } weight="md" color="white" size="md">
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 (