89 lines
3.2 KiB
TypeScript
89 lines
3.2 KiB
TypeScript
"use client";
|
||
/**
|
||
* ChatHeader 顶部栏
|
||
*
|
||
* 图标:lucide-react <Lock />(游客 banner)+ <Menu />(菜单按钮)
|
||
* tree-shakable,currentColor 继承父 color
|
||
*/
|
||
import type { ReactNode } from "react";
|
||
import { Lock, Menu } from "lucide-react";
|
||
|
||
import { BackButton } from "@/app/_components";
|
||
import { useActiveCharacterRoutes } from "@/providers/character-provider";
|
||
import { useAppNavigator } from "@/router/use-app-navigator";
|
||
|
||
import { BrowserHintOverlay } from "./browser-hint-overlay";
|
||
|
||
export interface ChatHeaderProps {
|
||
isGuest: boolean;
|
||
offerBanner?: ReactNode;
|
||
showBrowserHint?: boolean;
|
||
}
|
||
|
||
export function ChatHeader({
|
||
isGuest,
|
||
offerBanner,
|
||
showBrowserHint = false,
|
||
}: ChatHeaderProps) {
|
||
const navigator = useAppNavigator();
|
||
const characterRoutes = useActiveCharacterRoutes();
|
||
|
||
return (
|
||
<header className="flex shrink-0 flex-col items-stretch bg-transparent p-0">
|
||
{isGuest ? (
|
||
<button
|
||
type="button"
|
||
data-analytics-key="chat.open_signup"
|
||
data-analytics-label="Open sign up"
|
||
className="flex w-full cursor-pointer items-center justify-center gap-(--spacing-sm,8px) border-0 bg-accent px-(--spacing-md,12px) py-(--spacing-sm,8px) text-center text-(length:--responsive-caption,var(--font-size-sm,12px)) font-medium text-white"
|
||
onClick={() => navigator.openAuth(characterRoutes.chat)}
|
||
aria-label="Sign up to unlock more features"
|
||
>
|
||
<Lock
|
||
className="size-(--icon-size-sm,16px)"
|
||
size={16}
|
||
aria-hidden="true"
|
||
/>
|
||
<span>Sign up to unlock more features</span>
|
||
</button>
|
||
) : (
|
||
offerBanner
|
||
)}
|
||
|
||
<div
|
||
className={
|
||
isGuest
|
||
? "flex items-center px-(--chat-inline-padding,16px) py-(--spacing-sm,8px)"
|
||
: "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-(--spacing-sm,8px) px-(--chat-inline-padding,16px) py-(--spacing-sm,8px)"
|
||
}
|
||
>
|
||
<BackButton
|
||
href={characterRoutes.splash}
|
||
variant="dark"
|
||
ariaLabel="Back to home"
|
||
analyticsKey="chat.back_to_home"
|
||
/>
|
||
|
||
{!isGuest ? (
|
||
<>
|
||
<div className="flex min-w-0 justify-center">
|
||
{showBrowserHint ? <BrowserHintOverlay /> : null}
|
||
</div>
|
||
|
||
<button
|
||
type="button"
|
||
data-analytics-key="chat.open_menu"
|
||
data-analytics-label="Open chat menu"
|
||
className="flex size-(--responsive-icon-button-size,42px) cursor-pointer items-center justify-center rounded-full border border-[rgba(255,255,255,0.12)] bg-[rgba(13,11,20,0.7)] text-(--color-text-primary,#fff) shadow-[0_10px_24px_rgba(0,0,0,0.2)] backdrop-blur-md transition-[background,transform] duration-150 hover:bg-[rgba(28,24,39,0.82)] active:scale-96 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-[#f657a0]"
|
||
onClick={() => navigator.push(characterRoutes.sidebar)}
|
||
aria-label="Menu"
|
||
>
|
||
<Menu size={24} aria-hidden="true" />
|
||
</button>
|
||
</>
|
||
) : null}
|
||
</div>
|
||
</header>
|
||
);
|
||
}
|