From 5f6c7531e358fefcd4def993670f866e3feb3eb0 Mon Sep 17 00:00:00 2001 From: ysm Date: Fri, 27 Mar 2026 18:11:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9D=99=E9=9F=B3=E6=8C=89?= =?UTF-8?q?=E9=92=AE=EF=BC=8C=E9=BB=98=E8=AE=A4=E9=9D=99=E9=9F=B3=EF=BC=8C?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=BF=9D=E5=AD=98=E5=88=B0=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E5=AD=98=E5=82=A8=EF=BC=8C=E5=9B=BE=E6=A0=87=E7=81=B0=E5=BA=A6?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/App.css | 33 +++++++++++++++++++++++++++++++-- src/App.tsx | 42 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/App.css b/src/App.css index 33959a4..ce09332 100644 --- a/src/App.css +++ b/src/App.css @@ -185,11 +185,20 @@ } } -/* Settings button */ -.settings-button { +/* Top buttons group */ +.top-buttons { position: absolute; top: 20px; left: 20px; + display: flex; + flex-direction: row; + gap: 8px; + z-index: 1000; +} + +/* Settings button */ +.settings-button { + position: static; width: 40px; height: 40px; padding: 8px; @@ -209,6 +218,26 @@ background-color: rgba(255, 255, 255, 0.15); } +.mute-button { + width: 40px; + height: 40px; + padding: 8px; + font-size: 20px; + background-color: rgba(255, 255, 255, 0.05); + border: none; + border-radius: 8px; + cursor: pointer; + transition: all 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + filter: grayscale(100%); +} + +.mute-button:hover { + background-color: rgba(255, 255, 255, 0.15); +} + /* Settings overlay */ .settings-overlay { position: fixed; diff --git a/src/App.tsx b/src/App.tsx index 2bee6fc..288e073 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, useRef } from 'react' import { FlipClock } from './components/FlipClock' import { RollClock } from './components/RollClock' import './App.css' @@ -109,6 +109,11 @@ function App() { return saved === 'up' ? 'up' : 'down' }) const [showSettings, setShowSettings] = useState(false) + const [isMuted, setIsMuted] = useState(() => { + const saved = localStorage.getItem('clock-isMuted') + return saved === null ? true : saved === 'true' + }) + const isMutedRef = useRef(isMuted) const [showDate, setShowDate] = useState(() => { // 从 localStorage 读取,默认显示日期 (true) const saved = localStorage.getItem('clock-showDate') @@ -147,6 +152,13 @@ function App() { localStorage.setItem('clock-showDate', String(newValue)) } + const toggleMute = () => { + const newValue = !isMuted + setIsMuted(newValue) + isMutedRef.current = newValue + localStorage.setItem('clock-isMuted', String(newValue)) + } + // 切换显示时区时保存到 localStorage const toggleShowTimezone = () => { const newValue = !showTimezone @@ -155,8 +167,13 @@ function App() { } useEffect(() => { + const audio = new Audio('/tick1.mp3') const timer = setInterval(() => { setTime(new Date()) + if (!isMutedRef.current) { + audio.currentTime = 0 + audio.play().catch(() => {}) + } }, 1000) return () => clearInterval(timer) }, []) @@ -226,13 +243,22 @@ function App() { return (
- +
+ + +
{showSettings && (
setShowSettings(false)}>