fix: resolve nested button HTML hydration errors (#4688)

* fix: remove nested button from ai shortcut

* fix: UserAvatar should not show login

* chore: ensure userId is accessed safely
This commit is contained in:
Whitewater 2025-11-11 14:41:19 +08:00 committed by GitHub
parent cfefb5a120
commit 4b0afb4f99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 9 additions and 25 deletions

View File

@ -171,7 +171,6 @@ const ShortcutMenuButton: React.FC<ShortcutMenuButtonProps> = ({
return (
<div {...contextMenuProps}>
<ShortcutTooltip
asChild={false}
name={shortcut.name}
prompt={shortcut.prompt || shortcut.defaultPrompt}
hotkey={shortcut.hotkey}

View File

@ -2,8 +2,8 @@ import { Spring } from "@follow/components/constants/spring.js"
import { cn } from "@follow/utils/utils"
import type { VariantProps } from "class-variance-authority"
import { cva } from "class-variance-authority"
import type { HTMLMotionProps } from "motion/react"
import { m } from "motion/react"
import type { ReactNode } from "react"
const aiShortcutButtonVariants = cva(
[
@ -38,27 +38,21 @@ const aiShortcutButtonVariants = cva(
)
export interface AIShortcutButtonProps extends VariantProps<typeof aiShortcutButtonVariants> {
children: ReactNode
onClick: () => void
className?: string
animationDelay?: number
title?: string
style?: React.CSSProperties
ref?: React.Ref<HTMLButtonElement>
}
export const AIShortcutButton: React.FC<AIShortcutButtonProps> = ({
export const AIShortcutButton = ({
children,
onClick,
className,
animationDelay = 0,
title,
size,
variant,
disabled,
style,
ref,
}) => {
...rest
}: AIShortcutButtonProps & HTMLMotionProps<"button">) => {
return (
<m.button
initial={{ opacity: 0, scale: 0.9 }}
@ -67,12 +61,13 @@ export const AIShortcutButton: React.FC<AIShortcutButtonProps> = ({
transition={{ delay: animationDelay, ...Spring.presets.snappy }}
onClick={onClick}
disabled={disabled ?? false}
title={title}
className={cn(aiShortcutButtonVariants({ size, variant, disabled }), className)}
style={style}
ref={ref}
{...rest}
>
{children}
</m.button>
)
}
AIShortcutButton.displayName = "AIShortcutButton"

View File

@ -53,7 +53,7 @@ export const ProfileButton: FC<ProfileButtonProps> = memo((props) => {
const role = useUserRole()
const isInMASReview = useIsInMASReview()
if (status === "unauthenticated") {
if (status !== "authenticated") {
return <LoginButton {...props} />
}

View File

@ -7,10 +7,8 @@ import { cn } from "@follow/utils/utils"
import { useServerConfigs } from "~/atoms/server-configs"
import { replaceImgUrlIfNeed } from "~/lib/img-proxy"
import { usePresentUserProfileModal } from "~/modules/profile/hooks"
import { useSession } from "~/queries/auth"
import type { LoginProps } from "./LoginButton"
import { LoginButton } from "./LoginButton"
import { UserProBadge } from "./UserProBadge"
export const UserAvatar = ({
@ -32,10 +30,6 @@ export const UserAvatar = ({
} & LoginProps &
React.HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement | null> }) => {
const serverConfig = useServerConfigs()
const { status } = useSession({
enabled: !userId,
})
const whoami = useWhoami()
const role = useUserRole()
const presentUserProfile = usePresentUserProfileModal("drawer")
@ -43,10 +37,6 @@ export const UserAvatar = ({
usePrefetchUser(userId)
const profile = useUserById(userId)
if (!userId && status !== "authenticated") {
return <LoginButton {...props} />
}
const renderUserData = userId ? profile : whoami
const randomColor = stringToHue(renderUserData?.name || "")
return (

View File

@ -18,7 +18,7 @@ export const UserGallery = ({ users, limit = 18 }: UserGalleryProps) => {
<UserAvatar
className="h-auto p-0"
avatarClassName="size-8"
userId={user?.id}
userId={user.id}
enableModal={true}
hideName={true}
/>