From c1c4d894bc59ec3e0f1a8ec3d0550de0f120b1b2 Mon Sep 17 00:00:00 2001 From: zl Date: Mon, 17 Nov 2025 12:51:06 +0800 Subject: [PATCH] feat: add selected sounds display module with complete functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create SelectedSoundsDisplay component to show selected sounds at the top of the page - Add displayMode parameter to Sound component for functionality in display mode - Implement complete audio controls including volume, speed, and rate progress bars - Add random effects support with proper interval management - Integrate multi-language support (Chinese: "当前声音", English: "Current Sounds") - Update App component to include the new display module - Use consistent styling with existing sound categories for seamless integration - Upgrade version to 2.3.0 for this feature release --- package.json | 2 +- src/components/app/app.tsx | 2 + .../selected-sounds-display/index.ts | 1 + .../selected-sounds-display.tsx | 56 +++++++++++++++++++ src/components/sounds/sound/sound.tsx | 13 +++-- src/data/i18n.ts | 3 + 6 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 src/components/selected-sounds-display/index.ts create mode 100644 src/components/selected-sounds-display/selected-sounds-display.tsx diff --git a/package.json b/package.json index 6d17727..2deb35f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "moodist", "type": "module", - "version": "2.2.0", + "version": "2.3.0", "scripts": { "dev": "astro dev", "start": "astro dev", diff --git a/src/components/app/app.tsx b/src/components/app/app.tsx index de62692..93222d2 100644 --- a/src/components/app/app.tsx +++ b/src/components/app/app.tsx @@ -10,6 +10,7 @@ import { useTranslation } from '@/hooks/useTranslation'; import { Container } from '@/components/container'; import { StoreConsumer } from '@/components/store-consumer'; import { Buttons } from '@/components/buttons'; +import { SelectedSoundsDisplay } from '@/components/selected-sounds-display'; import { Categories } from '@/components/categories'; import { SharedModal } from '@/components/modals/shared'; import { Toolbar } from '@/components/toolbar'; @@ -99,6 +100,7 @@ export function App() {
+ diff --git a/src/components/selected-sounds-display/index.ts b/src/components/selected-sounds-display/index.ts new file mode 100644 index 0000000..865cf33 --- /dev/null +++ b/src/components/selected-sounds-display/index.ts @@ -0,0 +1 @@ +export { SelectedSoundsDisplay } from './selected-sounds-display'; \ No newline at end of file diff --git a/src/components/selected-sounds-display/selected-sounds-display.tsx b/src/components/selected-sounds-display/selected-sounds-display.tsx new file mode 100644 index 0000000..bc6bf9c --- /dev/null +++ b/src/components/selected-sounds-display/selected-sounds-display.tsx @@ -0,0 +1,56 @@ +import { useMemo } from 'react'; +import { AnimatePresence } from 'motion/react'; + +import { useSoundStore } from '@/stores/sound'; +import { useLocalizedSounds } from '@/hooks/useLocalizedSounds'; +import { useTranslation } from '@/hooks/useTranslation'; + +import { Sound } from '@/components/sounds/sound'; +import styles from '../sounds/sounds.module.css'; + +export function SelectedSoundsDisplay() { + const { t } = useTranslation(); + const localizedCategories = useLocalizedSounds(); + + // 获取选中的声音 + const selectedSoundIds = useSoundStore(state => + Object.keys(state.sounds).filter(id => state.sounds[id].isSelected) + ); + + // 获取选中的声音详细信息 + const selectedSounds = useMemo(() => { + const allSounds = localizedCategories + .map(category => category.sounds) + .flat(); + + return selectedSoundIds + .map(id => allSounds.find(sound => sound.id === id)) + .filter(Boolean); + }, [selectedSoundIds, localizedCategories]); + + // 如果没有选中任何声音,不显示组件 + if (selectedSounds.length === 0) { + return null; + } + + return ( +
+ + {selectedSounds.map((sound) => ( + +
+ ); +} \ No newline at end of file diff --git a/src/components/sounds/sound/sound.tsx b/src/components/sounds/sound/sound.tsx index 80fa69a..92e683d 100644 --- a/src/components/sounds/sound/sound.tsx +++ b/src/components/sounds/sound/sound.tsx @@ -21,10 +21,11 @@ interface SoundProps extends SoundType { hidden: boolean; selectHidden: (key: string) => void; unselectHidden: (key: string) => void; + displayMode?: boolean; // 新增:展示模式参数 } export const Sound = forwardRef(function Sound( - { functional, hidden, icon, id, label, selectHidden, src, unselectHidden }, + { functional, hidden, icon, id, label, selectHidden, src, unselectHidden, displayMode = false }, ref, ) { const isPlaying = useSoundStore(state => state.isPlaying); @@ -60,12 +61,15 @@ export const Sound = forwardRef(function Sound( useEffect(() => { if (locked) return; - if (isSelected && isPlaying && functional) { + // 在展示模式下或者功能模式下,只要选中且在播放就应该播放 + const shouldPlay = isSelected && isPlaying && (functional || displayMode); + + if (shouldPlay) { sound?.play(); } else { sound?.pause(); } - }, [isSelected, sound, isPlaying, functional, locked]); + }, [isSelected, sound, isPlaying, functional, displayMode, locked]); useEffect(() => { if (hidden && isSelected) selectHidden(label); @@ -75,7 +79,8 @@ export const Sound = forwardRef(function Sound( // 改进的随机逻辑 - 每次只随机调整一个参数,频率为1分钟 useEffect(() => { const hasAnyRandom = isRandomSpeed || isRandomVolume || isRandomRate; - if (!hasAnyRandom || !isSelected || !isPlaying) return; + const isActiveMode = functional || displayMode; + if (!hasAnyRandom || !isSelected || !isPlaying || !isActiveMode) return; const interval = setInterval(() => { // 获取当前启用的随机选项列表 diff --git a/src/data/i18n.ts b/src/data/i18n.ts index 9e5fbc7..6ff4de9 100644 --- a/src/data/i18n.ts +++ b/src/data/i18n.ts @@ -39,6 +39,7 @@ export interface Translations { pause: string; favorite: string; volume: string; + selected_sounds: string; // Support & Donate supportMe: string; @@ -261,6 +262,7 @@ export const translations: Record = { pause: 'Pause', favorite: 'Favorite', volume: 'Volume', + selected_sounds: 'Current Sounds', // Support & Donate supportMe: 'Support Me', @@ -483,6 +485,7 @@ export const translations: Record = { pause: '暂停', favorite: '收藏', volume: '音量', + selected_sounds: '当前声音', // Support & Donate supportMe: '支持我',