From 28e71b4d4ba3f3e4398ccc5f4890c964d05a085f Mon Sep 17 00:00:00 2001 From: Innei Date: Wed, 27 Dec 2023 22:54:05 +0800 Subject: [PATCH] feat: add comment source Signed-off-by: Innei --- src/components/icons/platform/AppleIcon.tsx | 18 ++++++++ .../icons/platform/FacebookIcon.tsx | 22 ++++++++++ .../icons/platform/MicrosoftIcon.tsx | 18 ++++++++ .../header/internal/UserAuthFromIcon.tsx | 14 +------ .../ui/user/UserAuthStrategyIcon.tsx | 41 +++++++++++++++++++ src/components/widgets/comment/Comment.tsx | 8 ++++ .../comment/CommentBox/AuthedInput.tsx | 10 +++-- .../widgets/comment/CommentBox/hooks.tsx | 13 +++--- .../widgets/comment/CommentBox/providers.tsx | 12 +++--- 9 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 src/components/icons/platform/AppleIcon.tsx create mode 100644 src/components/icons/platform/FacebookIcon.tsx create mode 100644 src/components/icons/platform/MicrosoftIcon.tsx create mode 100644 src/components/ui/user/UserAuthStrategyIcon.tsx diff --git a/src/components/icons/platform/AppleIcon.tsx b/src/components/icons/platform/AppleIcon.tsx new file mode 100644 index 0000000000..577fa9fed1 --- /dev/null +++ b/src/components/icons/platform/AppleIcon.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' + +export function AppleIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/src/components/icons/platform/FacebookIcon.tsx b/src/components/icons/platform/FacebookIcon.tsx new file mode 100644 index 0000000000..8594cc23e0 --- /dev/null +++ b/src/components/icons/platform/FacebookIcon.tsx @@ -0,0 +1,22 @@ +import type { SVGProps } from 'react' + +export function LogosFacebook(props: SVGProps) { + return ( + + + + + ) +} diff --git a/src/components/icons/platform/MicrosoftIcon.tsx b/src/components/icons/platform/MicrosoftIcon.tsx new file mode 100644 index 0000000000..c53b05adab --- /dev/null +++ b/src/components/icons/platform/MicrosoftIcon.tsx @@ -0,0 +1,18 @@ +import type { SVGProps } from 'react' + +export function LogosMicrosoftIcon(props: SVGProps) { + return ( + + + + + + + ) +} diff --git a/src/components/layout/header/internal/UserAuthFromIcon.tsx b/src/components/layout/header/internal/UserAuthFromIcon.tsx index fdb7af173d..85217044fa 100644 --- a/src/components/layout/header/internal/UserAuthFromIcon.tsx +++ b/src/components/layout/header/internal/UserAuthFromIcon.tsx @@ -4,9 +4,7 @@ import React from 'react' import { useUser } from '@clerk/nextjs' -import { GitHubBrandIcon } from '~/components/icons/platform/GitHubBrandIcon' -import { GoogleBrandIcon } from '~/components/icons/platform/GoogleBrandIcon' -import { MailIcon } from '~/components/icons/platform/MailIcon' +import { getStrategyIconComponent } from '~/components/ui/user/UserAuthStrategyIcon' import { clsxm } from '~/lib/helper' export const UserAuthFromIcon: Component = ({ className }) => { @@ -16,15 +14,7 @@ export const UserAuthFromIcon: Component = ({ className }) => { if (!strategy) { return null } - - switch (strategy) { - case 'from_oauth_github': - return GitHubBrandIcon - case 'from_oauth_google': - return GoogleBrandIcon - default: - return MailIcon - } + return getStrategyIconComponent(strategy) }, [user?.primaryEmailAddress?.verification.strategy]) if (!StrategyIcon) { diff --git a/src/components/ui/user/UserAuthStrategyIcon.tsx b/src/components/ui/user/UserAuthStrategyIcon.tsx new file mode 100644 index 0000000000..0d1ca360ef --- /dev/null +++ b/src/components/ui/user/UserAuthStrategyIcon.tsx @@ -0,0 +1,41 @@ +import type { FC } from 'react' + +import { AppleIcon } from '~/components/icons/platform/AppleIcon' +import { LogosFacebook } from '~/components/icons/platform/FacebookIcon' +import { GitHubBrandIcon } from '~/components/icons/platform/GitHubBrandIcon' +import { GoogleBrandIcon } from '~/components/icons/platform/GoogleBrandIcon' +import { LogosMicrosoftIcon } from '~/components/icons/platform/MicrosoftIcon' +import { TwitterIcon } from '~/components/icons/platform/Twitter' + +export const UserAuthStrategyIcon: FC<{ + strategy: string + className?: string +}> = ({ strategy, className }) => { + const Icon = getStrategyIconComponent(strategy) + + if (!strategy) { + return null + } + + if (!Icon) return null + return +} + +export const getStrategyIconComponent = (strategy: string) => { + switch (strategy) { + case 'from_oauth_github': + return GitHubBrandIcon + case 'from_oauth_google': + return GoogleBrandIcon + case 'from_oauth_apple': + return AppleIcon + case 'from_oauth_microsoft': + return LogosMicrosoftIcon + case 'from_oauth_facebook': + return LogosFacebook + case 'from_oauth_twitter': + return TwitterIcon + default: + return null + } +} diff --git a/src/components/widgets/comment/Comment.tsx b/src/components/widgets/comment/Comment.tsx index 50705a5389..503f9e0e8b 100644 --- a/src/components/widgets/comment/Comment.tsx +++ b/src/components/widgets/comment/Comment.tsx @@ -17,6 +17,7 @@ import type { PropsWithChildren } from 'react' import { Avatar } from '~/components/ui/avatar' import { RelativeTime } from '~/components/ui/relative-time' +import { UserAuthStrategyIcon } from '~/components/ui/user/UserAuthStrategyIcon' import { softSpringPreset } from '~/constants/spring' import { jotaiStore } from '~/lib/store' @@ -40,6 +41,7 @@ export const Comment: Component<{ location, isWhispers, url, + source, } = comment const parentId = typeof comment.parent === 'string' ? comment.parent : comment.parent?.id @@ -93,6 +95,12 @@ export const Comment: Component<{ width={24} height={24} /> + {source && ( + + )} {/* Header */} diff --git a/src/components/widgets/comment/CommentBox/AuthedInput.tsx b/src/components/widgets/comment/CommentBox/AuthedInput.tsx index a82ef99a8a..34d7404bb7 100644 --- a/src/components/widgets/comment/CommentBox/AuthedInput.tsx +++ b/src/components/widgets/comment/CommentBox/AuthedInput.tsx @@ -21,9 +21,13 @@ export const CommentBoxAuthedInput = () => { useEffect(() => { if (!user) return setter('author', displayName) - setter('avatar', user.profileImageUrl) + setter('avatar', user.imageUrl) setter('mail', user.primaryEmailAddress?.emailAddress || '') - }, [displayName, user]) + + const strategy = user.primaryEmailAddress?.verification.strategy + + strategy && setter('source', strategy) + }, [displayName, setter, user]) if (!user) return return ( @@ -37,7 +41,7 @@ export const CommentBoxAuthedInput = () => { > {`${displayName}'s() => { const ctx = useContext(CommentBoxContext) - return (key: T, value: ExtractAtomValue) => { - const atom = ctx[key] - if (!atom) throw new Error(`atom ${key} not found`) - jotaiStore.set(atom as any, value) - } + return useCallback( + (key: T, value: ExtractAtomValue) => { + const atom = ctx[key] + if (!atom) throw new Error(`atom ${key} not found`) + jotaiStore.set(atom as any, value) + }, + [ctx], + ) } // Comment Mode diff --git a/src/components/widgets/comment/CommentBox/providers.tsx b/src/components/widgets/comment/CommentBox/providers.tsx index 178d14a962..3baf69d54e 100644 --- a/src/components/widgets/comment/CommentBox/providers.tsx +++ b/src/components/widgets/comment/CommentBox/providers.tsx @@ -7,7 +7,6 @@ import type { CommentModel } from '@mx-space/api-client' import type { FC, PropsWithChildren } from 'react' import { useBeforeMounted } from '~/hooks/common/use-before-mounted' -import { useRefValue } from '~/hooks/common/use-ref-value' import { jotaiStore } from '~/lib/store' import { setCommentActionLeftSlot, useCommentActionLeftSlot } from './hooks' @@ -48,10 +47,13 @@ export const CommentBoxProvider = ( ) => { const { refId, children, afterSubmit, initialValue } = props - const ctxValue = useRefValue(() => ({ - ...createInitialValue(), - refId: atom(refId), - })) + const ctxValue = useMemo( + () => ({ + ...createInitialValue(), + refId: atom(refId), + }), + [refId], + ) useBeforeMounted(() => { if (initialValue) { jotaiStore.set(ctxValue.text, initialValue)