添加静音按钮,默认静音,设置保存到本地存储,图标灰度显示
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3be055608e
commit
5f6c7531e3
33
src/App.css
33
src/App.css
@ -185,11 +185,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Settings button */
|
/* Top buttons group */
|
||||||
.settings-button {
|
.top-buttons {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 8px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Settings button */
|
||||||
|
.settings-button {
|
||||||
|
position: static;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
@ -209,6 +218,26 @@
|
|||||||
background-color: rgba(255, 255, 255, 0.15);
|
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 */
|
||||||
.settings-overlay {
|
.settings-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
42
src/App.tsx
42
src/App.tsx
@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect, useRef } from 'react'
|
||||||
import { FlipClock } from './components/FlipClock'
|
import { FlipClock } from './components/FlipClock'
|
||||||
import { RollClock } from './components/RollClock'
|
import { RollClock } from './components/RollClock'
|
||||||
import './App.css'
|
import './App.css'
|
||||||
@ -109,6 +109,11 @@ function App() {
|
|||||||
return saved === 'up' ? 'up' : 'down'
|
return saved === 'up' ? 'up' : 'down'
|
||||||
})
|
})
|
||||||
const [showSettings, setShowSettings] = useState(false)
|
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(() => {
|
const [showDate, setShowDate] = useState(() => {
|
||||||
// 从 localStorage 读取,默认显示日期 (true)
|
// 从 localStorage 读取,默认显示日期 (true)
|
||||||
const saved = localStorage.getItem('clock-showDate')
|
const saved = localStorage.getItem('clock-showDate')
|
||||||
@ -147,6 +152,13 @@ function App() {
|
|||||||
localStorage.setItem('clock-showDate', String(newValue))
|
localStorage.setItem('clock-showDate', String(newValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleMute = () => {
|
||||||
|
const newValue = !isMuted
|
||||||
|
setIsMuted(newValue)
|
||||||
|
isMutedRef.current = newValue
|
||||||
|
localStorage.setItem('clock-isMuted', String(newValue))
|
||||||
|
}
|
||||||
|
|
||||||
// 切换显示时区时保存到 localStorage
|
// 切换显示时区时保存到 localStorage
|
||||||
const toggleShowTimezone = () => {
|
const toggleShowTimezone = () => {
|
||||||
const newValue = !showTimezone
|
const newValue = !showTimezone
|
||||||
@ -155,8 +167,13 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const audio = new Audio('/tick1.mp3')
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
setTime(new Date())
|
setTime(new Date())
|
||||||
|
if (!isMutedRef.current) {
|
||||||
|
audio.currentTime = 0
|
||||||
|
audio.play().catch(() => {})
|
||||||
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
return () => clearInterval(timer)
|
return () => clearInterval(timer)
|
||||||
}, [])
|
}, [])
|
||||||
@ -226,13 +243,22 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app">
|
<div className="app">
|
||||||
<button
|
<div className="top-buttons">
|
||||||
className="settings-button"
|
<button
|
||||||
onClick={() => setShowSettings(true)}
|
className="settings-button"
|
||||||
aria-label="设置"
|
onClick={() => setShowSettings(true)}
|
||||||
>
|
aria-label="设置"
|
||||||
⚙️
|
>
|
||||||
</button>
|
⚙️
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="mute-button"
|
||||||
|
onClick={toggleMute}
|
||||||
|
aria-label={isMuted ? '取消静音' : '静音'}
|
||||||
|
>
|
||||||
|
{isMuted ? '🔇' : '🔊'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{showSettings && (
|
{showSettings && (
|
||||||
<div className="settings-overlay" onClick={() => setShowSettings(false)}>
|
<div className="settings-overlay" onClick={() => setShowSettings(false)}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user