From 9dbbe7665a476a7546861e166485ef395dff8162 Mon Sep 17 00:00:00 2001 From: 6512345 Date: Sun, 8 Feb 2026 23:52:14 -0500 Subject: [PATCH 1/4] feat: Bell rings when toast --- frontend/app/globals.css | 19 +++++++ frontend/app/layout.tsx | 7 ++- frontend/components/layout/header.tsx | 6 ++- frontend/components/ui/sonner.tsx | 68 +++++++++++++++++-------- frontend/contexts/bell-ring-context.tsx | 54 ++++++++++++++++++++ 5 files changed, 129 insertions(+), 25 deletions(-) create mode 100644 frontend/contexts/bell-ring-context.tsx diff --git a/frontend/app/globals.css b/frontend/app/globals.css index 5b192e7d..33d51423 100644 --- a/frontend/app/globals.css +++ b/frontend/app/globals.css @@ -174,4 +174,23 @@ 0% { transform: translateY(0) scale(1); opacity: 1; } 100% { transform: translateY(-100px) scale(0); opacity: 0; } } + + /* + * 铃铛响铃动画配置 + * 使用微妙的摆动效果,优雅且不过度 + */ + --animate-bell-ring: bell-ring 0.6s cubic-bezier(0.36, 0.07, 0.19, 0.97); + + @keyframes bell-ring { + 0% { transform: rotate(0deg); } + 10% { transform: rotate(14deg); } + 20% { transform: rotate(-12deg); } + 30% { transform: rotate(10deg); } + 40% { transform: rotate(-8deg); } + 50% { transform: rotate(6deg); } + 60% { transform: rotate(-4deg); } + 70% { transform: rotate(2deg); } + 80% { transform: rotate(-1deg); } + 100% { transform: rotate(0deg); } + } } \ No newline at end of file diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 88a5e337..4a244e00 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -3,6 +3,7 @@ import { Inter, Noto_Sans_SC, Geist_Mono } from 'next/font/google'; import { Toaster } from "@/components/ui/sonner"; import { ThemeProvider } from "@/components/layout/theme-provider"; import { CustomThemeProvider } from "@/lib/theme"; +import { BellRingProvider } from "@/contexts/bell-ring-context"; import "./globals.css"; const inter = Inter({ @@ -49,8 +50,10 @@ export default function RootLayout({ disableTransitionOnChange > - {children} - + + {children} + + diff --git a/frontend/components/layout/header.tsx b/frontend/components/layout/header.tsx index 859f3ab3..ee71f8f6 100644 --- a/frontend/components/layout/header.tsx +++ b/frontend/components/layout/header.tsx @@ -5,6 +5,7 @@ import { AnimatePresence, motion } from "motion/react" import { Button } from "@/components/ui/button" import { Bell, Plus, Settings, Search, Moon, Sun, Maximize2, Minimize2 } from "lucide-react" import { useUser } from "@/contexts/user-context" +import { useBellRing } from "@/contexts/bell-ring-context" import { SidebarTrigger } from "@/components/ui/sidebar" import { useTheme } from "next-themes" import { useRouter } from "next/navigation" @@ -22,6 +23,7 @@ import { SearchDialog } from "@/components/layout/search-dialog" */ export function SiteHeader({ isFullWidth = false, onToggleFullWidth }: { isFullWidth?: boolean, onToggleFullWidth?: (value: boolean) => void }) { const { user } = useUser() + const { isRinging } = useBellRing() const { setTheme, resolvedTheme } = useTheme() const router = useRouter() const [mounted, setMounted] = useState(false) @@ -53,7 +55,7 @@ export function SiteHeader({ isFullWidth = false, onToggleFullWidth }: { isFullW 搜索 - + {showBell && ( + + )} + {showBell && ( + + )} + ) +}) + + /** * 站点头部组件 * 用于显示站点头部 @@ -24,8 +46,6 @@ import { SearchDialog } from "@/components/layout/search-dialog" */ export function SiteHeader({ isFullWidth = false, onToggleFullWidth }: { isFullWidth?: boolean, onToggleFullWidth?: (value: boolean) => void }) { const { user } = useUser() - const { isRinging } = useBellRing() - const { showBell } = useNotificationSettings() const { setTheme, resolvedTheme } = useTheme() const router = useRouter() const [mounted, setMounted] = useState(false) @@ -56,12 +76,7 @@ export function SiteHeader({ isFullWidth = false, onToggleFullWidth }: { isFullW 搜索 - {showBell && ( - - )} + - )} +