From 2ff37f15f1d7185e04bdb4f8f674758be5bfd778 Mon Sep 17 00:00:00 2001 From: Zeck Li <11781254+zeckli@users.noreply.github.com> Date: Tue, 2 Jun 2026 01:39:20 +0800 Subject: [PATCH 1/3] feat(moment-feed): add the support of the moment feed --- lang/default.json | 32 ++++ lang/en.json | 32 ++++ lang/zh-Hans.json | 32 ++++ lang/zh-Hant.json | 32 ++++ src/common/enums/events.ts | 1 + src/common/enums/route.ts | 2 + src/components/Context/Viewer/index.tsx | 1 + .../Layout/SideChannelNav/index.tsx | 20 +++ src/components/Layout/index.tsx | 1 + .../DropdownActions/RevokeMomentFeed.tsx | 35 ++++ .../DropdownActions/ToggleAdMoment.tsx | 85 +++++++++ .../MomentDigest/DropdownActions/index.tsx | 133 ++++++++++++++- .../Notice/UserNotice/MomentFeedApproved.tsx | 49 ++++++ src/components/Notice/UserNotice/index.tsx | 5 + src/pages/moments.tsx | 7 + src/stories/mocks/index.ts | 1 + .../HottestMoments/Apply/Button/index.tsx | 48 ++++++ .../HottestMoments/Apply/Dialog/index.tsx | 138 +++++++++++++++ src/views/HottestMoments/Apply/index.tsx | 9 + src/views/HottestMoments/gql.ts | 46 +++++ src/views/HottestMoments/index.tsx | 161 ++++++++++++++++++ src/views/HottestMoments/styles.module.css | 17 ++ 22 files changed, 878 insertions(+), 9 deletions(-) create mode 100644 src/components/MomentDigest/DropdownActions/RevokeMomentFeed.tsx create mode 100644 src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx create mode 100644 src/components/Notice/UserNotice/MomentFeedApproved.tsx create mode 100644 src/pages/moments.tsx create mode 100644 src/views/HottestMoments/Apply/Button/index.tsx create mode 100644 src/views/HottestMoments/Apply/Dialog/index.tsx create mode 100644 src/views/HottestMoments/Apply/index.tsx create mode 100644 src/views/HottestMoments/gql.ts create mode 100644 src/views/HottestMoments/index.tsx create mode 100644 src/views/HottestMoments/styles.module.css diff --git a/lang/default.json b/lang/default.json index ac7d1f53e1..530c34adde 100644 --- a/lang/default.json +++ b/lang/default.json @@ -603,6 +603,9 @@ "defaultMessage": "Edit", "description": "src/components/CircleComment/DropdownActions/EditButton.tsx" }, + "6wdAti": { + "defaultMessage": "No moments yet" + }, "73iajM": { "defaultMessage": "Oops. Something went wrong. Please try again later.", "description": "BAD_USER_INPUT" @@ -614,6 +617,9 @@ "defaultMessage": "Payout Canceled", "description": "src/components/Transaction/index.tsx" }, + "7DJ8wF": { + "defaultMessage": "Join the Moments channel" + }, "7HPPqs": { "defaultMessage": ". {SuggestButton}?" }, @@ -1321,6 +1327,9 @@ "HzB4Lk": { "defaultMessage": "Tell readers why you edited this time..." }, + "I1eVEY": { + "defaultMessage": "Application submitted, pending review" + }, "IJ9YcQ": { "defaultMessage": "Unlink", "description": "src/components/Editor" @@ -1515,6 +1524,9 @@ "LWE7oq": { "defaultMessage": "Saving draft, are you sure you want to leave?" }, + "LXZyce": { + "defaultMessage": "You have already applied, please wait for the review." + }, "Lb0JsC": { "defaultMessage": "You have blocked that user" }, @@ -1765,6 +1777,9 @@ "Q8Qw5B": { "defaultMessage": "Description" }, + "QHRze5": { + "defaultMessage": "Moments" + }, "QKJWqd": { "defaultMessage": "Bookmark", "description": "src/components/Buttons/TagBookmark/Bookmark.tsx" @@ -2068,6 +2083,9 @@ "VBve8d": { "defaultMessage": "Settled in Matters" }, + "VDclc3": { + "defaultMessage": "You have joined the Moments channel. The moments you post will now appear in this channel." + }, "VMQPwZ": { "defaultMessage": "Ended", "description": "src/views/Campaigns/Feeds/Tabs/index.tsx" @@ -2529,6 +2547,10 @@ "d5bM8A": { "defaultMessage": "Select Date..." }, + "d95AX1": { + "defaultMessage": "Let me think about it", + "description": "src/views/HottestMoments/Apply/Dialog/index.tsx" + }, "dAPUJp": { "defaultMessage": "The dazzling light of a meteor shower is enough to illuminate the night sky. The Meteor Canoe badge signifies your participation in the Nomad Matters.", "description": "src/views/User/UserProfile/BadgeNomadLabel/index.tsx" @@ -2802,6 +2824,10 @@ "defaultMessage": "Insufficient:", "description": "src/components/Balance/index.tsx" }, + "hdbKK1": { + "defaultMessage": "Moments", + "description": "src/components/Layout/SideChannelNav/index.tsx" + }, "hgtWIO": { "defaultMessage": "Articles have been collected", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -3463,6 +3489,9 @@ "tWCQCd": { "defaultMessage": "The contract has sent {amount} USDT to the connected wallet" }, + "tYDhrI": { + "defaultMessage": "Once you request to join and are approved, the moments you post will appear in this channel." + }, "tZKvnZ": { "defaultMessage": "Unlike moment" }, @@ -3824,6 +3853,9 @@ "z3uIHQ": { "defaultMessage": "Undo upvote" }, + "z5UXPc": { + "defaultMessage": "Apply to join" + }, "z91BKe": { "defaultMessage": "Archived Work", "description": "src/components/Notice/NoticeArticleTitle.tsx" diff --git a/lang/en.json b/lang/en.json index 73115686c0..aecc921dc3 100644 --- a/lang/en.json +++ b/lang/en.json @@ -603,6 +603,9 @@ "defaultMessage": "Edit", "description": "src/components/CircleComment/DropdownActions/EditButton.tsx" }, + "6wdAti": { + "defaultMessage": "No moments yet" + }, "73iajM": { "defaultMessage": "Oops. Something went wrong. Please try again later.", "description": "BAD_USER_INPUT" @@ -614,6 +617,9 @@ "defaultMessage": "Payout Canceled", "description": "src/components/Transaction/index.tsx" }, + "7DJ8wF": { + "defaultMessage": "Join the Moments channel" + }, "7HPPqs": { "defaultMessage": ". {SuggestButton}?" }, @@ -1321,6 +1327,9 @@ "HzB4Lk": { "defaultMessage": "Tell readers why you edited this time..." }, + "I1eVEY": { + "defaultMessage": "Application submitted, pending review" + }, "IJ9YcQ": { "defaultMessage": "Unlink", "description": "src/components/Editor" @@ -1515,6 +1524,9 @@ "LWE7oq": { "defaultMessage": "Saving draft, are you sure you want to leave?" }, + "LXZyce": { + "defaultMessage": "You have already applied, please wait for the review." + }, "Lb0JsC": { "defaultMessage": "You have blocked that user" }, @@ -1765,6 +1777,9 @@ "Q8Qw5B": { "defaultMessage": "Description" }, + "QHRze5": { + "defaultMessage": "Moments" + }, "QKJWqd": { "defaultMessage": "Bookmark", "description": "src/components/Buttons/TagBookmark/Bookmark.tsx" @@ -2068,6 +2083,9 @@ "VBve8d": { "defaultMessage": "Settled in Matters" }, + "VDclc3": { + "defaultMessage": "You have joined the Moments channel. The moments you post will now appear in this channel." + }, "VMQPwZ": { "defaultMessage": "Ended", "description": "src/views/Campaigns/Feeds/Tabs/index.tsx" @@ -2529,6 +2547,10 @@ "d5bM8A": { "defaultMessage": "Select Date..." }, + "d95AX1": { + "defaultMessage": "Let me think about it", + "description": "src/views/HottestMoments/Apply/Dialog/index.tsx" + }, "dAPUJp": { "defaultMessage": "The dazzling light of a meteor shower is enough to illuminate the night sky. The Meteor Canoe badge signifies your participation in the Nomad Matters.", "description": "src/views/User/UserProfile/BadgeNomadLabel/index.tsx" @@ -2802,6 +2824,10 @@ "defaultMessage": "Insufficient: ", "description": "src/components/Balance/index.tsx" }, + "hdbKK1": { + "defaultMessage": "Moments", + "description": "src/components/Layout/SideChannelNav/index.tsx" + }, "hgtWIO": { "defaultMessage": "Articles have been collected", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -3463,6 +3489,9 @@ "tWCQCd": { "defaultMessage": "The contract has sent {amount} USDT to the connected wallet" }, + "tYDhrI": { + "defaultMessage": "Once you request to join and are approved, the moments you post will appear in this channel." + }, "tZKvnZ": { "defaultMessage": "Unlike moment" }, @@ -3824,6 +3853,9 @@ "z3uIHQ": { "defaultMessage": "Undo upvote" }, + "z5UXPc": { + "defaultMessage": "Apply to join" + }, "z91BKe": { "defaultMessage": "Archived Work", "description": "src/components/Notice/NoticeArticleTitle.tsx" diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index c6076211e4..8b50357292 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -603,6 +603,9 @@ "defaultMessage": "编辑评论", "description": "src/components/CircleComment/DropdownActions/EditButton.tsx" }, + "6wdAti": { + "defaultMessage": "还没有动态" + }, "73iajM": { "defaultMessage": "出错了,请检查你输入的内容", "description": "BAD_USER_INPUT" @@ -614,6 +617,9 @@ "defaultMessage": "提现撤销", "description": "src/components/Transaction/index.tsx" }, + "7DJ8wF": { + "defaultMessage": "加入动态频道" + }, "7HPPqs": { "defaultMessage": "。{SuggestButton}?" }, @@ -1321,6 +1327,9 @@ "HzB4Lk": { "defaultMessage": "告知读者你此次编辑的更动有哪些⋯" }, + "I1eVEY": { + "defaultMessage": "已送出申请,待审核" + }, "IJ9YcQ": { "defaultMessage": "取消链接", "description": "src/components/Editor" @@ -1515,6 +1524,9 @@ "LWE7oq": { "defaultMessage": "草稿保存中,确定要离开吗?" }, + "LXZyce": { + "defaultMessage": "你已经申请过了,请耐心等候审核" + }, "Lb0JsC": { "defaultMessage": "你屏蔽了该用户" }, @@ -1765,6 +1777,9 @@ "Q8Qw5B": { "defaultMessage": "描述" }, + "QHRze5": { + "defaultMessage": "动态" + }, "QKJWqd": { "defaultMessage": "收藏", "description": "src/components/Buttons/TagBookmark/Bookmark.tsx" @@ -2068,6 +2083,9 @@ "VBve8d": { "defaultMessage": "搬家到 Matters" }, + "VDclc3": { + "defaultMessage": "你已加入动态频道,即日起发出的动态将显示于此频道" + }, "VMQPwZ": { "defaultMessage": "过往活动", "description": "src/views/Campaigns/Feeds/Tabs/index.tsx" @@ -2529,6 +2547,10 @@ "d5bM8A": { "defaultMessage": "投稿日程⋯" }, + "d95AX1": { + "defaultMessage": "我再想想", + "description": "src/views/HottestMoments/Apply/Dialog/index.tsx" + }, "dAPUJp": { "defaultMessage": "流星雨的绚烂光芒足以点亮夜空。流星号徽章纪念你曾参与「游牧者计划」。", "description": "src/views/User/UserProfile/BadgeNomadLabel/index.tsx" @@ -2802,6 +2824,10 @@ "defaultMessage": "余额不足:", "description": "src/components/Balance/index.tsx" }, + "hdbKK1": { + "defaultMessage": "动态", + "description": "src/components/Layout/SideChannelNav/index.tsx" + }, "hgtWIO": { "defaultMessage": "作品被关联", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -3463,6 +3489,9 @@ "tWCQCd": { "defaultMessage": "交易合約已将 {amount} USDT 发送至绑定钱包" }, + "tYDhrI": { + "defaultMessage": "申请通过之后,个人发出的动态将显示于此频道" + }, "tZKvnZ": { "defaultMessage": "取消喜欢动态" }, @@ -3824,6 +3853,9 @@ "z3uIHQ": { "defaultMessage": "取消点赞" }, + "z5UXPc": { + "defaultMessage": "申请加入" + }, "z91BKe": { "defaultMessage": "已归档作品", "description": "src/components/Notice/NoticeArticleTitle.tsx" diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 95fb7b2f4f..38526a2e64 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -603,6 +603,9 @@ "defaultMessage": "編輯", "description": "src/components/CircleComment/DropdownActions/EditButton.tsx" }, + "6wdAti": { + "defaultMessage": "還沒有動態" + }, "73iajM": { "defaultMessage": "出錯了,請檢查你輸入的內容", "description": "BAD_USER_INPUT" @@ -614,6 +617,9 @@ "defaultMessage": "提現撤銷", "description": "src/components/Transaction/index.tsx" }, + "7DJ8wF": { + "defaultMessage": "加入動態頻道" + }, "7HPPqs": { "defaultMessage": "。{SuggestButton}?" }, @@ -1321,6 +1327,9 @@ "HzB4Lk": { "defaultMessage": "告知讀者你此次編輯的更動有哪些⋯" }, + "I1eVEY": { + "defaultMessage": "已送出申請,待審核" + }, "IJ9YcQ": { "defaultMessage": "取消連結", "description": "src/components/Editor" @@ -1515,6 +1524,9 @@ "LWE7oq": { "defaultMessage": "草稿儲存中,確定要離開嗎?" }, + "LXZyce": { + "defaultMessage": "你已經申請過了,請耐心等候審核" + }, "Lb0JsC": { "defaultMessage": "你封鎖了該用戶" }, @@ -1765,6 +1777,9 @@ "Q8Qw5B": { "defaultMessage": "描述" }, + "QHRze5": { + "defaultMessage": "動態" + }, "QKJWqd": { "defaultMessage": "收藏", "description": "src/components/Buttons/TagBookmark/Bookmark.tsx" @@ -2068,6 +2083,9 @@ "VBve8d": { "defaultMessage": "搬家到 Matters" }, + "VDclc3": { + "defaultMessage": "你已加入動態頻道,即日起發出的動態將顯示於此頻道" + }, "VMQPwZ": { "defaultMessage": "過往活動", "description": "src/views/Campaigns/Feeds/Tabs/index.tsx" @@ -2529,6 +2547,10 @@ "d5bM8A": { "defaultMessage": "投稿日程⋯" }, + "d95AX1": { + "defaultMessage": "我再想想", + "description": "src/views/HottestMoments/Apply/Dialog/index.tsx" + }, "dAPUJp": { "defaultMessage": "流星雨的絢爛光芒足以點亮夜空。流星號徽章紀念你曾參與「遊牧者計畫」。", "description": "src/views/User/UserProfile/BadgeNomadLabel/index.tsx" @@ -2802,6 +2824,10 @@ "defaultMessage": "餘額不足:", "description": "src/components/Balance/index.tsx" }, + "hdbKK1": { + "defaultMessage": "動態", + "description": "src/components/Layout/SideChannelNav/index.tsx" + }, "hgtWIO": { "defaultMessage": "作品被關聯", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" @@ -3463,6 +3489,9 @@ "tWCQCd": { "defaultMessage": "交易合約已將 {amount} USDT 發送至綁定錢包" }, + "tYDhrI": { + "defaultMessage": "申請通過之後,個人發出的動態將顯示於此頻道" + }, "tZKvnZ": { "defaultMessage": "取消喜歡動態" }, @@ -3824,6 +3853,9 @@ "z3uIHQ": { "defaultMessage": "取消點讚" }, + "z5UXPc": { + "defaultMessage": "申請加入" + }, "z91BKe": { "defaultMessage": "已封存作品", "description": "src/components/Notice/NoticeArticleTitle.tsx" diff --git a/src/common/enums/events.ts b/src/common/enums/events.ts index 31bf840057..d4a3ca8e8f 100644 --- a/src/common/enums/events.ts +++ b/src/common/enums/events.ts @@ -81,6 +81,7 @@ export enum UNIVERSAL_AUTH_TRIGGER { momentLike = 'momentLike', applyCampaign = 'applyCampaign', collectionLike = 'collectionLike', + applyMomentFeed = 'applyMomentFeed', } // Editor diff --git a/src/common/enums/route.ts b/src/common/enums/route.ts index 4601366bb8..f73762dbc9 100644 --- a/src/common/enums/route.ts +++ b/src/common/enums/route.ts @@ -9,6 +9,7 @@ type ROUTE_KEY = | 'HOME' | 'FEATURED' | 'HOTTEST' + | 'HOTTEST_MOMENTS' | 'NEWEST' | 'CHANNEL' | 'FOLLOW' @@ -151,6 +152,7 @@ export const ROUTES: { { key: 'HOME', pathname: '/' }, { key: 'FEATURED', pathname: '/featured' }, { key: 'HOTTEST', pathname: '/hottest' }, + { key: 'HOTTEST_MOMENTS', pathname: '/moments' }, { key: 'NEWEST', pathname: '/newest' }, { key: 'CHANNEL', pathname: '/c/[shortHash]' }, { key: 'FOLLOW', pathname: '/follow' }, diff --git a/src/components/Context/Viewer/index.tsx b/src/components/Context/Viewer/index.tsx index b3812c9b8e..529b5264e5 100644 --- a/src/components/Context/Viewer/index.tsx +++ b/src/components/Context/Viewer/index.tsx @@ -65,6 +65,7 @@ const ViewerFragments = { private: gql` fragment ViewerUserPrivate on User { id + isMomentFeedApplied info { socialAccounts { type diff --git a/src/components/Layout/SideChannelNav/index.tsx b/src/components/Layout/SideChannelNav/index.tsx index d787aac570..9b424aac6e 100644 --- a/src/components/Layout/SideChannelNav/index.tsx +++ b/src/components/Layout/SideChannelNav/index.tsx @@ -114,6 +114,26 @@ const SideChannelNav = () => { + onTabClick('hottest_moments')} + > + + + + + + + {channels.map((c) => ( ))} diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 9d0302de4a..240d89e768 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -95,6 +95,7 @@ const useLayoutType = () => { isHome || isInPath('FEATURED') || isInPath('HOTTEST') || + isInPath('HOTTEST_MOMENTS') || isInPath('NEWEST') || isInPath('CHANNEL') || isInPath('FOLLOW') || diff --git a/src/components/MomentDigest/DropdownActions/RevokeMomentFeed.tsx b/src/components/MomentDigest/DropdownActions/RevokeMomentFeed.tsx new file mode 100644 index 0000000000..fbdd40e963 --- /dev/null +++ b/src/components/MomentDigest/DropdownActions/RevokeMomentFeed.tsx @@ -0,0 +1,35 @@ +import gql from 'graphql-tag' + +import IconCircleMinus from '@/public/static/icons/24px/circle-minus.svg' +import { Icon, Menu, toast, useMutation } from '~/components' +import { RevokeMomentFeedMutation } from '~/gql/graphql' + +const REVOKE_MOMENT_FEED = gql` + mutation RevokeMomentFeed($id: ID!) { + updateMomentFeedApplicationState(input: { id: $id, state: revoked }) { + id + isMomentFeedApplied + } + } +` + +const RevokeMomentFeed = ({ userId }: { userId: string }) => { + const [revoke] = useMutation(REVOKE_MOMENT_FEED, { + variables: { id: userId }, + }) + + return ( + } + onClick={async () => { + try { + await revoke() + toast.success({ message: '已撤銷資格' }) + } catch {} + }} + /> + ) +} + +export default RevokeMomentFeed diff --git a/src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx b/src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx new file mode 100644 index 0000000000..2a12824abb --- /dev/null +++ b/src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx @@ -0,0 +1,85 @@ +import { useQuery } from '@apollo/client' +import gql from 'graphql-tag' + +import IconPin from '@/public/static/icons/24px/pin.svg' +import IconUnpin from '@/public/static/icons/24px/unpin.svg' +import { Icon, Menu, Spinner, toast, useMutation } from '~/components' +import { + FetchMomentAdStatusQuery, + ToggleAdMomentMutation, +} from '~/gql/graphql' + +const fragments = { + moment: gql` + fragment ToggleAdMomentMoment on Moment { + id + adStatus { + isAd + } + } + `, +} + +const TOGGLE_AD_MOMENT = gql` + mutation ToggleAdMoment($momentId: ID!, $isAd: Boolean!) { + setWritingAdStatus(input: { id: $momentId, isAd: $isAd }) { + ... on Moment { + id + ...ToggleAdMomentMoment + } + } + } + ${fragments.moment} +` + +const FETCH_MOMENT_AD_STATUS = gql` + query FetchMomentAdStatus($shortHash: String!) { + moment(input: { shortHash: $shortHash }) { + ...ToggleAdMomentMoment + } + } + ${fragments.moment} +` + +const ToggleAdMoment = ({ shortHash }: { shortHash: string }) => { + const { data, loading } = useQuery( + FETCH_MOMENT_AD_STATUS, + { + variables: { + shortHash, + }, + } + ) + + const isAd = data?.moment?.adStatus.isAd + const momentId = data?.moment?.id + + const [update] = useMutation(TOGGLE_AD_MOMENT, { + variables: { + momentId, + isAd: !isAd, + }, + }) + + if (loading) { + return + } + + return ( + } + onClick={async () => { + await update() + + toast.success({ + message: isAd ? '已取消標記廣告' : '已標記廣告', + }) + }} + /> + ) +} + +ToggleAdMoment.fragments = fragments + +export default ToggleAdMoment diff --git a/src/components/MomentDigest/DropdownActions/index.tsx b/src/components/MomentDigest/DropdownActions/index.tsx index 7fe7c107ef..fa4036fea4 100644 --- a/src/components/MomentDigest/DropdownActions/index.tsx +++ b/src/components/MomentDigest/DropdownActions/index.tsx @@ -20,6 +20,15 @@ import { } from '~/components' import { SubmitReportDialogProps } from '~/components/Dialogs/SubmitReportDialog/Dialog' import { MomentDigestDropdownActionsMomentFragment } from '~/gql/graphql' +import { ArchiveUserDialogProps } from '~/views/User/UserProfile/DropdownActions/ArchiveUser/Dialog' +import { + OpenToggleFreezeUserDialogWithProps, + ToggleFreezeUserDialogProps, +} from '~/views/User/UserProfile/DropdownActions/ToggleFreezeUser/Dialog' +import { + OpenToggleRestrictUserDialogWithProps, + ToggleRestrictUserDialogProps, +} from '~/views/User/UserProfile/DropdownActions/ToggleRestrictUser/Dialog' import DeleteMoment from './DeleteMoment' import { DeleteMomentDialogProps } from './DeleteMoment/Dialog' @@ -33,10 +42,55 @@ const DynamicToggleSpamButton = dynamic( } ) +const DynamicToggleAdMomentButton = dynamic(() => import('./ToggleAdMoment'), { + loading: () => , +}) + +const DynamicRevokeMomentFeedButton = dynamic( + () => import('./RevokeMomentFeed'), + { + loading: () => , + } +) + +const DynamicToggleFreezeUserButton = dynamic( + () => + import('~/views/User/UserProfile/DropdownActions/ToggleFreezeUser/Button'), + { loading: () => } +) +const DynamicToggleFreezeUserDialog = dynamic( + () => + import('~/views/User/UserProfile/DropdownActions/ToggleFreezeUser/Dialog'), + { loading: () => } +) +const DynamicToggleRestrictUserButton = dynamic( + () => + import( + '~/views/User/UserProfile/DropdownActions/ToggleRestrictUser/Button' + ), + { loading: () => } +) +const DynamicToggleRestrictUserDialog = dynamic( + () => + import( + '~/views/User/UserProfile/DropdownActions/ToggleRestrictUser/Dialog' + ), + { loading: () => } +) +const DynamicArchiveUserButton = dynamic( + () => import('~/views/User/UserProfile/DropdownActions/ArchiveUser/Button'), + { loading: () => } +) +const DynamicArchiveUserDialog = dynamic( + () => import('~/views/User/UserProfile/DropdownActions/ArchiveUser/Dialog'), + { loading: () => } +) + const fragments = { moment: gql` fragment MomentDigestDropdownActionsMoment on Moment { id + shortHash state author { id @@ -58,6 +112,13 @@ interface Controls { interface DialogProps { openDeleteMomentDialog: () => void openSubmitReportDialog: () => void + openToggleRestrictUserDialog: ( + props: OpenToggleRestrictUserDialogWithProps + ) => void + openToggleFreezeUserDialog: ( + props: OpenToggleFreezeUserDialogWithProps + ) => void + openArchiveUserDialog: () => void } type BaseDropdownActionsProps = DropdownActionsProps & Controls & DialogProps @@ -69,6 +130,9 @@ const BaseDropdownActions = ({ openDeleteMomentDialog, openSubmitReportDialog, + openToggleRestrictUserDialog, + openToggleFreezeUserDialog, + openArchiveUserDialog, }: BaseDropdownActionsProps) => { const viewer = useContext(ViewerContext) @@ -84,6 +148,17 @@ const BaseDropdownActions = ({ <> + + + + + )} @@ -154,17 +229,57 @@ const DropdownActions = (props: DropdownActionsProps) => { }) ) - const WithDeleteMoment = withDialog< - Omit - >(WithReport, DeleteMoment.Dialog, { moment }, ({ openDialog }) => { - return { - ...props, - ...controls, - openDeleteMomentDialog: isFrozen ? forbid : openDialog, + const WithDeleteMoment = withDialog>( + WithReport, + DeleteMoment.Dialog, + { moment }, + ({ openDialog }) => { + return { + ...props, + ...controls, + openDeleteMomentDialog: isFrozen ? forbid : openDialog, + } } - }) + ) + + const WithToggleRestrictUser = withDialog< + Omit + >( + WithDeleteMoment, + DynamicToggleRestrictUserDialog as React.ComponentType< + Omit & { + children: (props: { openDialog: () => void }) => React.ReactNode + } + >, + { id: moment.author.id, userName: moment.author.userName! }, + ({ openDialog }) => ({ + openToggleRestrictUserDialog: openDialog, + }) + ) + + const WithToggleFreezeUser = withDialog< + Omit + >( + WithToggleRestrictUser, + DynamicToggleFreezeUserDialog as React.ComponentType< + Omit & { + children: (props: { openDialog: () => void }) => React.ReactNode + } + >, + { id: moment.author.id, userName: moment.author.userName! }, + ({ openDialog }) => ({ + openToggleFreezeUserDialog: openDialog, + }) + ) + + const WithArchiveUser = withDialog>( + WithToggleFreezeUser, + DynamicArchiveUserDialog, + { id: moment.author.id, userName: moment.author.userName! }, + ({ openDialog }) => ({ openArchiveUserDialog: openDialog }) + ) - return + return } DropdownActions.fragments = fragments diff --git a/src/components/Notice/UserNotice/MomentFeedApproved.tsx b/src/components/Notice/UserNotice/MomentFeedApproved.tsx new file mode 100644 index 0000000000..4ad0286e81 --- /dev/null +++ b/src/components/Notice/UserNotice/MomentFeedApproved.tsx @@ -0,0 +1,49 @@ +import gql from 'graphql-tag' +import Link from 'next/link' +import { FormattedMessage } from 'react-intl' + +import { PATHS } from '~/common/enums' +import { MomentFeedApprovedFragment } from '~/gql/graphql' + +import NoticeCard from '../NoticeCard' +import NoticeDate from '../NoticeDate' +import officialStyles from '../OfficialNotice/styles.module.css' + +const MomentFeedApproved = ({ + notice, +}: { + notice: MomentFeedApprovedFragment +}) => { + const Message = () => ( +

+ +

+ ) + + return ( + + + + } + /> + ) +} + +MomentFeedApproved.fragments = { + notice: gql` + fragment MomentFeedApproved on UserNotice { + id + ...NoticeDate + } + ${NoticeDate.fragments.notice} + `, +} + +export default MomentFeedApproved diff --git a/src/components/Notice/UserNotice/index.tsx b/src/components/Notice/UserNotice/index.tsx index 7b9ef667ec..116cb72be0 100644 --- a/src/components/Notice/UserNotice/index.tsx +++ b/src/components/Notice/UserNotice/index.tsx @@ -2,12 +2,15 @@ import gql from 'graphql-tag' import { UserNoticeFragment } from '~/gql/graphql' +import MomentFeedApproved from './MomentFeedApproved' import UserNewFollower from './UserNewFollower' const UserNotice = ({ notice }: { notice: UserNoticeFragment }) => { switch (notice.userNoticeType) { case 'UserNewFollower': return + case 'MomentFeedApproved': + return default: return null } @@ -21,8 +24,10 @@ UserNotice.fragments = { __typename userNoticeType: type ...UserNewFollower + ...MomentFeedApproved } ${UserNewFollower.fragments.notice} + ${MomentFeedApproved.fragments.notice} `, } diff --git a/src/pages/moments.tsx b/src/pages/moments.tsx new file mode 100644 index 0000000000..9186f57316 --- /dev/null +++ b/src/pages/moments.tsx @@ -0,0 +1,7 @@ +import HottestMomentsView from '~/views/HottestMoments' + +const HottestMoments = () => { + return +} + +export default HottestMoments diff --git a/src/stories/mocks/index.ts b/src/stories/mocks/index.ts index d7e2ad7711..33c7deb3cc 100644 --- a/src/stories/mocks/index.ts +++ b/src/stories/mocks/index.ts @@ -6,6 +6,7 @@ export const MOCK_USER = { id: 'VXNlcjox', // User:1 userName: 'matty', displayName: 'Matty', + isMomentFeedApplied: false, avatar: 'https://imagedelivery.net/kDRCweMmqLnTPNlbum-pYA/prod/avatar/19b36f6e-6311-4cd6-b703-c143a4a49113.png/public', liker: { diff --git a/src/views/HottestMoments/Apply/Button/index.tsx b/src/views/HottestMoments/Apply/Button/index.tsx new file mode 100644 index 0000000000..498a7b3374 --- /dev/null +++ b/src/views/HottestMoments/Apply/Button/index.tsx @@ -0,0 +1,48 @@ +import { useContext, useState } from 'react' +import { FormattedMessage } from 'react-intl' + +import { + OPEN_UNIVERSAL_AUTH_DIALOG, + UNIVERSAL_AUTH_TRIGGER, +} from '~/common/enums' +import { Button, TextIcon, ViewerContext } from '~/components' + +import Dialog from '../Dialog' + +const ApplyMomentFeedButton = () => { + const viewer = useContext(ViewerContext) + const [applied, setApplied] = useState(false) + + if (viewer.isMomentFeedApplied || applied) { + return null + } + + const openAuthDialog = () => { + window.dispatchEvent( + new CustomEvent(OPEN_UNIVERSAL_AUTH_DIALOG, { + detail: { trigger: UNIVERSAL_AUTH_TRIGGER.applyMomentFeed }, + }) + ) + } + + return ( + setApplied(true)}> + {({ openDialog }) => ( + + )} + + ) +} + +export default ApplyMomentFeedButton diff --git a/src/views/HottestMoments/Apply/Dialog/index.tsx b/src/views/HottestMoments/Apply/Dialog/index.tsx new file mode 100644 index 0000000000..4c37c8ca5b --- /dev/null +++ b/src/views/HottestMoments/Apply/Dialog/index.tsx @@ -0,0 +1,138 @@ +import gql from 'graphql-tag' +import { FormattedMessage } from 'react-intl' + +import { ERROR_CODES } from '~/common/enums' +import { Dialog, toast, useDialogSwitch, useMutation } from '~/components' +import { ApplyMomentFeedMutation } from '~/gql/graphql' + +const APPLY_MOMENT_FEED = gql` + mutation ApplyMomentFeed { + applyMomentFeed { + id + isMomentFeedApplied + } + } +` + +export interface ApplyMomentFeedDialogProps { + onApplied?: () => void + children: ({ openDialog }: { openDialog: () => void }) => React.ReactNode +} + +const ApplyMomentFeedDialog = ({ + onApplied, + children, +}: ApplyMomentFeedDialogProps) => { + const { show, openDialog, closeDialog } = useDialogSwitch(true) + + const [applyMomentFeed, { loading }] = useMutation( + APPLY_MOMENT_FEED, + undefined, + { + customErrors: { + [ERROR_CODES.BAD_USER_INPUT]: ( + + ), + }, + } + ) + + const onConfirm = async () => { + try { + await applyMomentFeed() + closeDialog() + onApplied?.() + toast.success({ + message: ( + + ), + }) + } catch {} + } + + return ( + <> + {children({ openDialog })} + + + + } + /> + + + +

+ +

+
+
+ + + } + loading={loading} + onClick={onConfirm} + /> + + } + color="greyDarker" + onClick={closeDialog} + /> + + } + smUpBtns={ + <> + + } + color="greyDarker" + onClick={closeDialog} + /> + } + loading={loading} + color="green" + onClick={onConfirm} + /> + + } + /> +
+ + ) +} + +const LazyApplyMomentFeedDialog = (props: ApplyMomentFeedDialogProps) => ( + }> + {({ openDialog }) => <>{props.children({ openDialog })}} + +) + +export default LazyApplyMomentFeedDialog diff --git a/src/views/HottestMoments/Apply/index.tsx b/src/views/HottestMoments/Apply/index.tsx new file mode 100644 index 0000000000..e67e169975 --- /dev/null +++ b/src/views/HottestMoments/Apply/index.tsx @@ -0,0 +1,9 @@ +import Button from './Button' +import Dialog from './Dialog' + +const Apply = { + Button, + Dialog, +} + +export default Apply diff --git a/src/views/HottestMoments/gql.ts b/src/views/HottestMoments/gql.ts new file mode 100644 index 0000000000..0a3e8c40f1 --- /dev/null +++ b/src/views/HottestMoments/gql.ts @@ -0,0 +1,46 @@ +import gql from 'graphql-tag' + +import { MomentDigestFeed } from '~/components/MomentDigest/Feed' + +const momentConnectionFragment = gql` + fragment HottestMomentConnection on MomentConnection { + pageInfo { + startCursor + endCursor + hasNextPage + } + edges { + cursor + node { + ...MomentDigestFeedMomentPublic + } + } + } + ${MomentDigestFeed.fragments.moment.public} +` + +export const HOTTEST_MOMENTS_PUBLIC = gql` + query HottestMomentsPublic($after: String) { + viewer { + id + recommendation { + hottestMoments(input: { first: 20, after: $after }) { + ...HottestMomentConnection + } + } + } + } + ${momentConnectionFragment} +` + +export const HOTTEST_MOMENTS_PRIVATE = gql` + query HottestMomentsPrivate($ids: [ID!]!) { + nodes(input: { ids: $ids }) { + id + ... on Moment { + ...MomentDigestFeedMomentPrivate + } + } + } + ${MomentDigestFeed.fragments.moment.private} +` diff --git a/src/views/HottestMoments/index.tsx b/src/views/HottestMoments/index.tsx new file mode 100644 index 0000000000..2f572ccf41 --- /dev/null +++ b/src/views/HottestMoments/index.tsx @@ -0,0 +1,161 @@ +import { useContext, useEffect, useRef } from 'react' +import { FormattedMessage, useIntl } from 'react-intl' + +import { mergeConnections } from '~/common/utils' +import { + Announcements, + ArticleFeedPlaceholder, + EmptyWork, + Head, + InfiniteScroll, + Layout, + List, + QueryError, + Spacer, + useFetchPolicy, + usePublicQuery, + ViewerContext, +} from '~/components' +import { MomentDigestFeed } from '~/components/MomentDigest/Feed' +import type { HottestMomentsPublicQuery } from '~/gql/graphql' + +import Sidebar from '../Home/Sidebar' +import Apply from './Apply' +import { HOTTEST_MOMENTS_PRIVATE, HOTTEST_MOMENTS_PUBLIC } from './gql' +import styles from './styles.module.css' + +const HottestMoments = () => { + const intl = useIntl() + const viewer = useContext(ViewerContext) + const { fetchPolicy } = useFetchPolicy() + + const { data, loading, error, fetchMore, client } = + usePublicQuery(HOTTEST_MOMENTS_PUBLIC, { + fetchPolicy, + }) + + const connectionPath = 'viewer.recommendation.hottestMoments' + const result = data?.viewer?.recommendation?.hottestMoments + const { edges, pageInfo } = result || {} + const fetchedPrivateRef = useRef(false) + + const loadPrivate = (publicData?: HottestMomentsPublicQuery) => { + if (!viewer.isAuthed || !publicData) { + return + } + + const publicEdges = + publicData.viewer?.recommendation?.hottestMoments?.edges || [] + const publicIds = publicEdges.map(({ node }) => node.id) + + if (publicIds.length === 0) { + return + } + + client.query({ + query: HOTTEST_MOMENTS_PRIVATE, + fetchPolicy: 'network-only', + variables: { ids: publicIds }, + }) + } + + useEffect(() => { + if (loading || !edges || fetchedPrivateRef.current || !viewer.isAuthed) { + return + } + + loadPrivate(data) + fetchedPrivateRef.current = true + }, [!!edges, loading, viewer.id]) + + const loadMore = async () => { + if (loading) { + return + } + + const { data: newData } = await fetchMore({ + variables: { after: pageInfo?.endCursor }, + updateQuery: (previousResult, { fetchMoreResult }) => + mergeConnections({ + oldData: previousResult, + newData: fetchMoreResult, + path: connectionPath, + dedupe: true, + }), + }) + + loadPrivate(newData) + } + + const renderContent = () => { + if (loading) { + return + } + + if (error) { + return + } + + if (!edges || edges.length <= 0 || !pageInfo) { + return ( + + } + /> + ) + } + + return ( + } + eof + > + + {edges.map(({ node, cursor }) => ( + + + + ))} + + + ) + } + + return ( + + + + + + + + + } + > + + +
+
+ +
+
+ +
+
+ + {renderContent()} +
+ ) +} + +export default HottestMoments diff --git a/src/views/HottestMoments/styles.module.css b/src/views/HottestMoments/styles.module.css new file mode 100644 index 0000000000..67a790d9c5 --- /dev/null +++ b/src/views/HottestMoments/styles.module.css @@ -0,0 +1,17 @@ +.headers { + @mixin flex-center-space-between; + + padding-top: var(--sp20); + background-color: var(--color-white); + + & .title { + font-size: var(--text18); + font-weight: var(--font-medium); + line-height: 1.75rem; + color: var(--color-black); + } +} + +.apply { + flex-shrink: 0; +} From d7276d761d44a86f450c2667877509e427cfd185 Mon Sep 17 00:00:00 2001 From: Zeck Li <11781254+zeckli@users.noreply.github.com> Date: Tue, 2 Jun 2026 01:48:18 +0800 Subject: [PATCH 2/3] feat(moment-feed): add the support of the moment feed --- .../DropdownActions/ToggleAdMoment.tsx | 5 +---- .../MomentDigest/DropdownActions/index.tsx | 19 ++++++++----------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx b/src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx index 2a12824abb..f261af2682 100644 --- a/src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx +++ b/src/components/MomentDigest/DropdownActions/ToggleAdMoment.tsx @@ -4,10 +4,7 @@ import gql from 'graphql-tag' import IconPin from '@/public/static/icons/24px/pin.svg' import IconUnpin from '@/public/static/icons/24px/unpin.svg' import { Icon, Menu, Spinner, toast, useMutation } from '~/components' -import { - FetchMomentAdStatusQuery, - ToggleAdMomentMutation, -} from '~/gql/graphql' +import { FetchMomentAdStatusQuery, ToggleAdMomentMutation } from '~/gql/graphql' const fragments = { moment: gql` diff --git a/src/components/MomentDigest/DropdownActions/index.tsx b/src/components/MomentDigest/DropdownActions/index.tsx index fa4036fea4..bcc1614ddb 100644 --- a/src/components/MomentDigest/DropdownActions/index.tsx +++ b/src/components/MomentDigest/DropdownActions/index.tsx @@ -229,18 +229,15 @@ const DropdownActions = (props: DropdownActionsProps) => { }) ) - const WithDeleteMoment = withDialog>( - WithReport, - DeleteMoment.Dialog, - { moment }, - ({ openDialog }) => { - return { - ...props, - ...controls, - openDeleteMomentDialog: isFrozen ? forbid : openDialog, - } + const WithDeleteMoment = withDialog< + Omit + >(WithReport, DeleteMoment.Dialog, { moment }, ({ openDialog }) => { + return { + ...props, + ...controls, + openDeleteMomentDialog: isFrozen ? forbid : openDialog, } - ) + }) const WithToggleRestrictUser = withDialog< Omit From 32fcd9eceb8b258d74e31683fce71b589fdc0161 Mon Sep 17 00:00:00 2001 From: Zeck Li <11781254+zeckli@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:25:57 +0800 Subject: [PATCH 3/3] chore(conflict): resolve conflicts --- lang/default.json | 30 ++++++++++++++++++------------ lang/en.json | 30 ++++++++++++++++++------------ lang/zh-Hans.json | 30 ++++++++++++++++++------------ lang/zh-Hant.json | 30 ++++++++++++++++++------------ 4 files changed, 72 insertions(+), 48 deletions(-) diff --git a/lang/default.json b/lang/default.json index 669283c7c7..b540a94307 100644 --- a/lang/default.json +++ b/lang/default.json @@ -376,9 +376,6 @@ "3EeDnu": { "defaultMessage": "Paste JSFiddle or CodePen link, and press enter" }, - "3HKaQ4": { - "defaultMessage": "The next slice mounts the zkID in-browser worker here and submits the proof to Matters." - }, "3KNMbJ": { "defaultMessage": "Articles" }, @@ -493,6 +490,9 @@ "5XFd/5": { "defaultMessage": "Manage Circle" }, + "5YuSaZ": { + "defaultMessage": "After TW FidO signs, continue here on desktop, or copy the Mac proof link to a desktop browser." + }, "5fjmnA": { "defaultMessage": "碳基生物" }, @@ -1080,6 +1080,9 @@ "DtO278": { "defaultMessage": "We’ve detected that several of your recent works have been recommended to related channels. They may not appear at the same time" }, + "Dx5Sas": { + "defaultMessage": "Copy Mac proof link" + }, "DyuHBH": { "defaultMessage": "Unpin from profile", "description": "src/components/CollectionDigest/DropdownActions/PinButton.tsx" @@ -1184,6 +1187,9 @@ "defaultMessage": "Switch to Optimism network now?", "description": "src/components/Forms/PaymentForm/SwitchNetwork/index.tsx" }, + "FXgOAP": { + "defaultMessage": "Browser handoff is ready. Browser proving is pending until the prover runs in a cross-origin isolated page." + }, "Fe682o": { "defaultMessage": "Next Month (Estimation)", "description": "src/views/Circle/Analytics/IncomeAnalytics/index.tsx" @@ -2114,9 +2120,6 @@ "defaultMessage": "Publishing, please wait...", "description": "src/components/Editor/PreviewDialog/index.tsx" }, - "V3oaoZ": { - "defaultMessage": "After TW FidO signs, continue in this browser. No native proof helper is required for this PWA path." - }, "V5OMr4": { "defaultMessage": "What is a digital wallet?", "description": "src/components/Forms/SelectAuthMethodForm/WalletFeed.tsx" @@ -2358,9 +2361,6 @@ "Z39z+x": { "defaultMessage": "{displayName} won't be able to comment your article. Besides, he or she can't @ you and subscribe your circle. You can manage blocked list in settings." }, - "Z4R3Lq": { - "defaultMessage": "This browser page is missing a required PWA proving capability." - }, "Z7JXlF": { "defaultMessage": "Archived for violation.", "description": "src/views/ArticleDetail/StickyTopBanner/index.tsx" @@ -2464,6 +2464,9 @@ "defaultMessage": "go to the homepage", "description": "src/views/Callback/UI.tsx" }, + "atmn17": { + "defaultMessage": "Open isolated prover" + }, "awW+lk": { "defaultMessage": "Processing", "description": "src/components/Transaction/State/index.tsx" @@ -2641,6 +2644,9 @@ "defaultMessage": "Comments and replies", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "dWt8c/": { + "defaultMessage": "Open the isolated browser container. It does not load the normal Matters bundle, so cross-origin isolation can be enabled for the zkID worker." + }, "dZlT9q": { "defaultMessage": "Your work has been recommended to the channels: {channelNames}. Are you satisfied with the result?" }, @@ -3289,6 +3295,9 @@ "defaultMessage": "Following", "description": "src/components/UserProfile/index.tsx" }, + "ol0msv": { + "defaultMessage": "Copy TW FidO link" + }, "on+DYO": { "defaultMessage": "Confirm application" }, @@ -3945,9 +3954,6 @@ "defaultMessage": "The login link has been sent to {email}", "description": "src/components/Forms/Verification/LinkSent.tsx" }, - "zCCJPu": { - "defaultMessage": "Run browser proof" - }, "zE51j6": { "defaultMessage": "Failed to publish, please try again." }, diff --git a/lang/en.json b/lang/en.json index 0fa7f695df..7b8296a987 100644 --- a/lang/en.json +++ b/lang/en.json @@ -376,9 +376,6 @@ "3EeDnu": { "defaultMessage": "Paste JSFiddle or CodePen link, and press enter" }, - "3HKaQ4": { - "defaultMessage": "The next slice mounts the zkID in-browser worker here and submits the proof to Matters." - }, "3KNMbJ": { "defaultMessage": "Articles" }, @@ -493,6 +490,9 @@ "5XFd/5": { "defaultMessage": "Manage Circle" }, + "5YuSaZ": { + "defaultMessage": "After TW FidO signs, continue here on desktop, or copy the Mac proof link to a desktop browser." + }, "5fjmnA": { "defaultMessage": "碳基生物" }, @@ -1080,6 +1080,9 @@ "DtO278": { "defaultMessage": "We’ve detected that several of your recent works have been recommended to related channels. They may not appear at the same time" }, + "Dx5Sas": { + "defaultMessage": "Copy Mac proof link" + }, "DyuHBH": { "defaultMessage": "Unpin from profile", "description": "src/components/CollectionDigest/DropdownActions/PinButton.tsx" @@ -1184,6 +1187,9 @@ "defaultMessage": "Switch to Optimism network now?", "description": "src/components/Forms/PaymentForm/SwitchNetwork/index.tsx" }, + "FXgOAP": { + "defaultMessage": "Browser handoff is ready. Browser proving is pending until the prover runs in a cross-origin isolated page." + }, "Fe682o": { "defaultMessage": "Next Month (Estimation)", "description": "src/views/Circle/Analytics/IncomeAnalytics/index.tsx" @@ -2114,9 +2120,6 @@ "defaultMessage": "Publishing, please wait...", "description": "src/components/Editor/PreviewDialog/index.tsx" }, - "V3oaoZ": { - "defaultMessage": "After TW FidO signs, continue in this browser. No native proof helper is required for this PWA path." - }, "V5OMr4": { "defaultMessage": "What is a digital wallet?", "description": "src/components/Forms/SelectAuthMethodForm/WalletFeed.tsx" @@ -2358,9 +2361,6 @@ "Z39z+x": { "defaultMessage": "{displayName} won't be able to comment your article. Besides, he or she can't @ you and subscribe your circle. You can manage blocked list in settings." }, - "Z4R3Lq": { - "defaultMessage": "This browser page is missing a required PWA proving capability." - }, "Z7JXlF": { "defaultMessage": "Archived for violation.", "description": "src/views/ArticleDetail/StickyTopBanner/index.tsx" @@ -2464,6 +2464,9 @@ "defaultMessage": "go to the homepage", "description": "src/views/Callback/UI.tsx" }, + "atmn17": { + "defaultMessage": "Open isolated prover" + }, "awW+lk": { "defaultMessage": "Processing", "description": "src/components/Transaction/State/index.tsx" @@ -2641,6 +2644,9 @@ "defaultMessage": "Comments and replies", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "dWt8c/": { + "defaultMessage": "Open the isolated browser container. It does not load the normal Matters bundle, so cross-origin isolation can be enabled for the zkID worker." + }, "dZlT9q": { "defaultMessage": "Your work has been recommended to the channels: {channelNames}. Are you satisfied with the result?" }, @@ -3289,6 +3295,9 @@ "defaultMessage": "Following", "description": "src/components/UserProfile/index.tsx" }, + "ol0msv": { + "defaultMessage": "Copy TW FidO link" + }, "on+DYO": { "defaultMessage": "Confirm application" }, @@ -3945,9 +3954,6 @@ "defaultMessage": "The login link has been sent to {email}", "description": "src/components/Forms/Verification/LinkSent.tsx" }, - "zCCJPu": { - "defaultMessage": "Run browser proof" - }, "zE51j6": { "defaultMessage": "Failed to publish, please try again." }, diff --git a/lang/zh-Hans.json b/lang/zh-Hans.json index be04555d99..5548f213c8 100644 --- a/lang/zh-Hans.json +++ b/lang/zh-Hans.json @@ -376,9 +376,6 @@ "3EeDnu": { "defaultMessage": "贴上 JSFiddle 或 CodePen 链接后,Enter 进行新增" }, - "3HKaQ4": { - "defaultMessage": "The next slice mounts the zkID in-browser worker here and submits the proof to Matters." - }, "3KNMbJ": { "defaultMessage": "作品" }, @@ -493,6 +490,9 @@ "5XFd/5": { "defaultMessage": "管理围炉" }, + "5YuSaZ": { + "defaultMessage": "After TW FidO signs, continue here on desktop, or copy the Mac proof link to a desktop browser." + }, "5fjmnA": { "defaultMessage": "碳基生物" }, @@ -1080,6 +1080,9 @@ "DtO278": { "defaultMessage": "检测到近期你的多篇文章被推荐到相关频道,他们有可能不会同时出现" }, + "Dx5Sas": { + "defaultMessage": "Copy Mac proof link" + }, "DyuHBH": { "defaultMessage": "取消代表作", "description": "src/components/CollectionDigest/DropdownActions/PinButton.tsx" @@ -1184,6 +1187,9 @@ "defaultMessage": "目前非 Optimism 网络,立即切换?", "description": "src/components/Forms/PaymentForm/SwitchNetwork/index.tsx" }, + "FXgOAP": { + "defaultMessage": "Browser handoff is ready. Browser proving is pending until the prover runs in a cross-origin isolated page." + }, "Fe682o": { "defaultMessage": "下月预期营收", "description": "src/views/Circle/Analytics/IncomeAnalytics/index.tsx" @@ -2114,9 +2120,6 @@ "defaultMessage": "发布中,请稍候⋯", "description": "src/components/Editor/PreviewDialog/index.tsx" }, - "V3oaoZ": { - "defaultMessage": "After TW FidO signs, continue in this browser. No native proof helper is required for this PWA path." - }, "V5OMr4": { "defaultMessage": "什么是数字钱包?", "description": "src/components/Forms/SelectAuthMethodForm/WalletFeed.tsx" @@ -2358,9 +2361,6 @@ "Z39z+x": { "defaultMessage": "封锁之后,{displayName} 将无法评论你的作品,不能 @ 你,并且不能加入你的围炉。你可以在设置里管理你的封锁用户列表" }, - "Z4R3Lq": { - "defaultMessage": "This browser page is missing a required PWA proving capability." - }, "Z7JXlF": { "defaultMessage": "因违反用户协定而被封存,", "description": "src/views/ArticleDetail/StickyTopBanner/index.tsx" @@ -2464,6 +2464,9 @@ "defaultMessage": "前往首页", "description": "src/views/Callback/UI.tsx" }, + "atmn17": { + "defaultMessage": "Open isolated prover" + }, "awW+lk": { "defaultMessage": "进行中…", "description": "src/components/Transaction/State/index.tsx" @@ -2641,6 +2644,9 @@ "defaultMessage": "评论和回复", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "dWt8c/": { + "defaultMessage": "Open the isolated browser container. It does not load the normal Matters bundle, so cross-origin isolation can be enabled for the zkID worker." + }, "dZlT9q": { "defaultMessage": "已推荐你的这篇作品到频道:{channelNames},你对结果满意吗?" }, @@ -3289,6 +3295,9 @@ "defaultMessage": "关注中", "description": "src/components/UserProfile/index.tsx" }, + "ol0msv": { + "defaultMessage": "Copy TW FidO link" + }, "on+DYO": { "defaultMessage": "确认报名" }, @@ -3945,9 +3954,6 @@ "defaultMessage": "登录链接已发送至 {email}", "description": "src/components/Forms/Verification/LinkSent.tsx" }, - "zCCJPu": { - "defaultMessage": "Run browser proof" - }, "zE51j6": { "defaultMessage": "发布失败" }, diff --git a/lang/zh-Hant.json b/lang/zh-Hant.json index 789d8682de..baf85330f7 100644 --- a/lang/zh-Hant.json +++ b/lang/zh-Hant.json @@ -376,9 +376,6 @@ "3EeDnu": { "defaultMessage": "貼上 JSFiddle 或 CodePen 連結後,Enter 進行新增" }, - "3HKaQ4": { - "defaultMessage": "The next slice mounts the zkID in-browser worker here and submits the proof to Matters." - }, "3KNMbJ": { "defaultMessage": "作品" }, @@ -493,6 +490,9 @@ "5XFd/5": { "defaultMessage": "管理圍爐" }, + "5YuSaZ": { + "defaultMessage": "After TW FidO signs, continue here on desktop, or copy the Mac proof link to a desktop browser." + }, "5fjmnA": { "defaultMessage": "碳基生物" }, @@ -1080,6 +1080,9 @@ "DtO278": { "defaultMessage": "檢測到近期你的多篇文章被推薦到相關頻道,它們有可能不會同時出現" }, + "Dx5Sas": { + "defaultMessage": "Copy Mac proof link" + }, "DyuHBH": { "defaultMessage": "取消代表作", "description": "src/components/CollectionDigest/DropdownActions/PinButton.tsx" @@ -1184,6 +1187,9 @@ "defaultMessage": "目前非 Optimism 網路,立即切換?", "description": "src/components/Forms/PaymentForm/SwitchNetwork/index.tsx" }, + "FXgOAP": { + "defaultMessage": "Browser handoff is ready. Browser proving is pending until the prover runs in a cross-origin isolated page." + }, "Fe682o": { "defaultMessage": "下月預期營收", "description": "src/views/Circle/Analytics/IncomeAnalytics/index.tsx" @@ -2114,9 +2120,6 @@ "defaultMessage": "發布中,請稍候⋯", "description": "src/components/Editor/PreviewDialog/index.tsx" }, - "V3oaoZ": { - "defaultMessage": "After TW FidO signs, continue in this browser. No native proof helper is required for this PWA path." - }, "V5OMr4": { "defaultMessage": "什麼是數字錢包?", "description": "src/components/Forms/SelectAuthMethodForm/WalletFeed.tsx" @@ -2358,9 +2361,6 @@ "Z39z+x": { "defaultMessage": "封鎖之後,{displayName} 將無法評論你的作品,不能 @ 你,並且不能加入你的圍爐。你可以在設置裏管理你的封鎖用戶列表。`" }, - "Z4R3Lq": { - "defaultMessage": "This browser page is missing a required PWA proving capability." - }, "Z7JXlF": { "defaultMessage": "因違反用戶協定而被封存,", "description": "src/views/ArticleDetail/StickyTopBanner/index.tsx" @@ -2464,6 +2464,9 @@ "defaultMessage": "前往首頁", "description": "src/views/Callback/UI.tsx" }, + "atmn17": { + "defaultMessage": "Open isolated prover" + }, "awW+lk": { "defaultMessage": "進行中…", "description": "src/components/Transaction/State/index.tsx" @@ -2641,6 +2644,9 @@ "defaultMessage": "評論和回覆", "description": "src/views/Me/Settings/Notifications/GeneralSettings/index.tsx" }, + "dWt8c/": { + "defaultMessage": "Open the isolated browser container. It does not load the normal Matters bundle, so cross-origin isolation can be enabled for the zkID worker." + }, "dZlT9q": { "defaultMessage": "已推薦你的這篇作品到頻道:{channelNames},你對結果滿意嗎?" }, @@ -3289,6 +3295,9 @@ "defaultMessage": "追蹤中", "description": "src/components/UserProfile/index.tsx" }, + "ol0msv": { + "defaultMessage": "Copy TW FidO link" + }, "on+DYO": { "defaultMessage": "確認報名" }, @@ -3945,9 +3954,6 @@ "defaultMessage": "登入連結已發送至 {email}", "description": "src/components/Forms/Verification/LinkSent.tsx" }, - "zCCJPu": { - "defaultMessage": "Run browser proof" - }, "zE51j6": { "defaultMessage": "發布失敗" },