simplify sound effects to only youtube

main
btahir89 11 months ago
parent ee979b213c
commit c154ddab71
No known key found for this signature in database
GPG Key ID: DAE64C74772C4C92

@ -80,9 +80,7 @@ const EnhancedLofiPlayer = () => {
>('customSoundEffects', [])
const playerRef = useRef<any>(null)
const audioRefs = useRef<{ [key: string]: AudioCache }>({})
const [activeEffects, setActiveEffects] = useState<Set<string>>(new Set())
const [loadingEffects, setLoadingEffects] = useState<Set<string>>(new Set())
const [isAddingChannel, setIsAddingChannel] = useState(false)
const [newChannel, setNewChannel] = useState<Channel>({
name: '',
@ -112,126 +110,26 @@ const EnhancedLofiPlayer = () => {
}, [isBrowser])
useEffect(() => {
Object.entries(audioRefs.current).forEach(([effectId, cache]) => {
if (cache?.audio) {
cache.audio.volume = effectVolumes[effectId] * effectsVolume
}
})
}, [effectVolumes, effectsVolume])
// Function to load audio on demand
const loadAudio = async (effectId: string) => {
const effect = soundEffects.find((e) => e.id === effectId)
if (!effect || effect.isYoutube) return
if (loadingEffects.has(effectId) || audioRefs.current[effectId]?.loaded) {
return
}
setLoadingEffects((prev) => new Set(prev).add(effectId))
try {
const audio = new Audio()
const loadPromise = new Promise<void>((resolve, reject) => {
audio.addEventListener('canplaythrough', () => resolve(), {
once: true,
})
audio.addEventListener(
'error',
(error: ErrorEvent) => {
reject(
new Error(
`Audio loading error: ${error.message || 'Unknown error'}`
)
)
},
{ once: true }
)
audio.src = effect.file
audio.load()
})
await loadPromise
audio.loop = true
audio.volume = effectVolumes[effectId] * effectsVolume
audioRefs.current[effectId] = {
audio,
loaded: true,
if (typeof window !== 'undefined') {
// Get theme from localStorage directly to ensure immediate application
const savedTheme = localStorage.getItem('lofi-theme') || 'dark'
document.documentElement.dataset.theme = savedTheme
if (currentTheme !== savedTheme) {
setCurrentTheme(savedTheme)
}
} catch (error) {
console.error(`Failed to load audio for ${effectId}:`, error)
} finally {
setLoadingEffects((prev) => {
const next = new Set(prev)
next.delete(effectId)
return next
})
}
}
// Toggle effect function
const toggleEffect = async (effectId: string) => {
const effect =
soundEffects.find((e) => e.id === effectId) ||
customEffects.find((e) => e.id === effectId)
if (!effect) return
try {
if (effect.isYoutube) {
// For YouTube effects, just toggle the active state
setActiveEffects((prev) => {
const newEffects = new Set(prev)
if (newEffects.has(effectId)) {
newEffects.delete(effectId)
} else {
newEffects.add(effectId)
}
return newEffects
})
return
}
}, [])
// Handle native audio effects
if (!audioRefs.current[effectId]?.loaded) {
await loadAudio(effectId)
const toggleEffect = (effectId: string) => {
setActiveEffects((prev) => {
const newEffects = new Set(prev)
if (newEffects.has(effectId)) {
newEffects.delete(effectId)
} else {
newEffects.add(effectId)
}
const audioCache = audioRefs.current[effectId]
if (!audioCache?.audio) return
setActiveEffects((prev) => {
const newEffects = new Set(prev)
if (newEffects.has(effectId)) {
newEffects.delete(effectId)
audioCache.audio.pause()
} else {
newEffects.add(effectId)
audioCache.audio.play().catch((error) => {
console.error('Error playing audio:', error)
newEffects.delete(effectId)
})
}
return newEffects
})
} catch (error) {
console.error('Error toggling effect:', error)
// Clear loading state and active state on error
setLoadingEffects((prev) => {
const next = new Set(prev)
next.delete(effectId)
return next
})
setActiveEffects((prev) => {
const next = new Set(prev)
next.delete(effectId)
return next
})
}
return newEffects
})
}
const handleProgress = (state: { played: number }) => {
@ -250,12 +148,6 @@ const EnhancedLofiPlayer = () => {
const handleEffectsVolumeChange = (newVolume: number) => {
setEffectsVolume(newVolume)
// Update all active effect volumes
Object.entries(audioRefs.current).forEach(([effectId, cache]) => {
if (cache?.audio) {
cache.audio.volume = effectVolumes[effectId] * newVolume
}
})
}
const handleThemeChange = (theme: string) => {
@ -441,75 +333,6 @@ const EnhancedLofiPlayer = () => {
}
}
// Add useEffect to initialize and handle theme changes
useEffect(() => {
if (typeof window !== 'undefined') {
// Get theme from localStorage directly to ensure immediate application
const savedTheme = localStorage.getItem('lofi-theme') || 'dark'
// Apply theme to root element
document.documentElement.dataset.theme = savedTheme
// Update state if different
if (currentTheme !== savedTheme) {
setCurrentTheme(savedTheme)
}
}
}, []) // Run only on mount
// Add useEffect to handle theme changes
useEffect(() => {
if (currentTheme) {
// Update root element when theme changes
document.documentElement.dataset.theme = currentTheme
// Also update localStorage directly
localStorage.setItem('lofi-theme', currentTheme)
}
}, [currentTheme])
const handleLoadEffect = async (effectId: string, file: string) => {
if (audioRefs.current[effectId]?.loaded) return
setLoadingEffects((prev) => new Set([...prev, effectId]))
try {
const audio = new Audio(file)
await audio.load()
audio.loop = true
audioRefs.current[effectId] = { audio, loaded: true }
} catch (error) {
console.error(`Error loading effect ${effectId}:`, error)
} finally {
setLoadingEffects((prev) => {
const next = new Set(prev)
next.delete(effectId)
return next
})
}
}
const handleToggleEffect = async (effectId: string, file: string) => {
if (!audioRefs.current[effectId]?.loaded) {
await handleLoadEffect(effectId, file)
}
const audio = audioRefs.current[effectId]?.audio
if (!audio) return
if (activeEffects.has(effectId)) {
audio.pause()
setActiveEffects((prev) => {
const next = new Set(prev)
next.delete(effectId)
return next
})
} else {
audio.volume = effectVolumes[effectId] * effectsVolume
audio.play()
setActiveEffects((prev) => new Set([...prev, effectId]))
}
}
return (
<div
className={styles['theme-container']}
@ -679,7 +502,7 @@ const EnhancedLofiPlayer = () => {
currentTheme={currentTheme}
customEffects={customEffects}
setCustomEffects={setCustomEffects}
loadingEffects={loadingEffects}
loadingEffects={new Set()}
/>
</div>
)}

@ -38,14 +38,12 @@ const SoundEffectsControls: React.FC<SoundEffectsControlsProps> = ({
id: '',
name: '',
file: '',
isYoutube: true,
})
const [urlError, setUrlError] = useState('')
const allEffects = [
...soundEffects.map((effect) => ({
...effect,
isYoutube: false,
})),
...customEffects.map((effect) => ({
...effect,
@ -83,7 +81,6 @@ const SoundEffectsControls: React.FC<SoundEffectsControlsProps> = ({
id: effectId,
name: newEffect.name,
file: newEffect.file,
isYoutube: true,
}
setCustomEffects([...customEffects, newCustomEffect])
@ -93,7 +90,7 @@ const SoundEffectsControls: React.FC<SoundEffectsControlsProps> = ({
[effectId]: defaultVolume,
})
setIsAddingEffect(false)
setNewEffect({ id: '', name: '', file: '', isYoutube: true })
setNewEffect({ id: '', name: '', file: '' })
}
const handleDeleteEffect = (effectId: string) => {
@ -119,7 +116,7 @@ const SoundEffectsControls: React.FC<SoundEffectsControlsProps> = ({
: 'bg-[var(--lofi-card-hover)]'
}`}
>
{effect.isYoutube && isActive && (
{isActive && (
<div className="hidden">
<ReactPlayer
url={effect.file}

@ -1,4 +1,16 @@
import { Cloud, Wind, Coffee, Flame, Monitor, Power } from 'lucide-react'
import {
Cloud,
Wind,
Coffee,
Flame,
Monitor,
Power,
Bird,
Radio,
Keyboard,
Car,
Waves,
} from 'lucide-react'
import { Channel, SoundEffect } from '@/types/lofi'
export const DEFAULT_CHANNELS: Channel[] = [
@ -46,37 +58,55 @@ export const soundEffects: SoundEffect[] = [
{
id: 'rain',
name: 'Rain',
file: 'https://www.youtube.com/watch?v=mPZkdNFkNps',
icon: Cloud,
file: '/sounds/rain.mp3',
},
{
id: 'wind',
name: 'Soft Wind',
icon: Wind,
file: '/sounds/wind.mp3',
id: 'fire',
name: 'Fireplace',
file: 'https://www.youtube.com/watch?v=L_LUpnjgPso',
icon: Flame,
},
{
id: 'cafe',
name: 'Cafe Ambience',
name: 'Cafe Ambiance',
file: 'https://www.youtube.com/watch?v=h2zkV-l_TbY',
icon: Coffee,
file: '/sounds/cafe.mp3',
},
{
id: 'fireplace',
name: 'Fireplace Crackling',
icon: Flame,
file: '/sounds/fireplace.mp3',
id: 'wind',
name: 'Wind',
file: 'https://youtu.be/sGkh1W5cbH4?si=L3aMNvyIYASQlYll',
icon: Wind,
},
{
id: 'birds',
name: 'Birds',
file: 'https://www.youtube.com/watch?v=Qm846KdZN_c',
icon: Bird,
},
{
id: 'keyboard',
name: 'Keyboard Typing',
icon: Monitor,
file: '/sounds/keyboard.mp3',
name: 'Keyboard',
file: 'https://youtu.be/-2RiNR2fqRY?si=Er2L4D8MufctAgeE',
icon: Keyboard,
},
{
id: 'city',
name: 'City Traffic',
file: 'https://www.youtube.com/watch?v=8s5H76F3SIs',
icon: Car,
},
{
id: 'waves',
name: 'Ocean Waves',
file: 'https://www.youtube.com/watch?v=bn9F19Hi1Lk',
icon: Waves,
},
{
id: 'whitenoise',
name: 'White Noise',
icon: Power,
file: '/sounds/whitenoise.mp3',
file: 'https://www.youtube.com/watch?v=nMfPqeZjc2c',
icon: Radio,
},
]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -10,16 +10,13 @@ export interface Channel {
export interface SoundEffect {
id: string
name: string
icon: any
file: string
icon: any
isCustom?: boolean
isYoutube?: boolean
}
export interface CustomSoundEffect {
id: string
name: string
file: string
isCustom?: boolean
isYoutube?: boolean
}

Loading…
Cancel
Save