mirror of
https://github.com/remvze/moodist.git
synced 2025-12-17 00:44:14 +00:00
feat: add play button
This commit is contained in:
parent
5a7a58e883
commit
31c087ebc8
7 changed files with 109 additions and 15 deletions
|
|
@ -3,6 +3,8 @@ import { FaCity } from 'react-icons/fa';
|
|||
|
||||
import { Container } from '@/components/container';
|
||||
import { Category } from '@/components/category';
|
||||
import { PlayButton } from '@/components/play-button';
|
||||
import { PlayProvider } from '@/contexts/play';
|
||||
|
||||
interface CategoriesProps {
|
||||
categories: Array<{
|
||||
|
|
@ -22,16 +24,20 @@ export function Categories({ categories }: CategoriesProps) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div>
|
||||
{categories.map(category => (
|
||||
<Category
|
||||
{...category}
|
||||
icon={idToIcon[category.id] || idToIcon.nature}
|
||||
key={category.id}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Container>
|
||||
<PlayProvider>
|
||||
<Container>
|
||||
<div>
|
||||
{categories.map(category => (
|
||||
<Category
|
||||
{...category}
|
||||
icon={idToIcon[category.id] || idToIcon.nature}
|
||||
key={category.id}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<PlayButton />
|
||||
</Container>
|
||||
</PlayProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
1
src/components/play-button/index.ts
Normal file
1
src/components/play-button/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { PlayButton } from './play-button';
|
||||
25
src/components/play-button/play-button.module.css
Normal file
25
src/components/play-button/play-button.module.css
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
.playButton {
|
||||
position: sticky;
|
||||
bottom: 30px;
|
||||
display: flex;
|
||||
width: 150px;
|
||||
height: 45px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
border-radius: 100px;
|
||||
border-top: 2px solid #818cf8;
|
||||
border-bottom: 3px solid #4f46e5;
|
||||
margin: 40px auto 0;
|
||||
background-color: #6366f1;
|
||||
color: var(--color-foreground);
|
||||
cursor: pointer;
|
||||
font-family: var(--font-heading);
|
||||
font-size: var(--font-base);
|
||||
line-height: 0;
|
||||
outline: none;
|
||||
|
||||
& span {
|
||||
font-size: var(--font-lg);
|
||||
}
|
||||
}
|
||||
29
src/components/play-button/play-button.tsx
Normal file
29
src/components/play-button/play-button.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { BiPause, BiPlay } from 'react-icons/bi';
|
||||
|
||||
import { usePlay } from '@/contexts/play';
|
||||
|
||||
import styles from './play-button.module.css';
|
||||
|
||||
export function PlayButton() {
|
||||
const { isPlaying, toggle } = usePlay();
|
||||
|
||||
return (
|
||||
<button className={styles.playButton} onClick={toggle}>
|
||||
{isPlaying ? (
|
||||
<>
|
||||
<span>
|
||||
<BiPause />
|
||||
</span>{' '}
|
||||
Pause
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span>
|
||||
<BiPlay />
|
||||
</span>{' '}
|
||||
Play
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
|
||||
import { useSound } from '@/hooks/use-sound';
|
||||
import { usePlay } from '@/contexts/play';
|
||||
import { cn } from '@/helpers/styles';
|
||||
|
||||
import styles from './sound.module.css';
|
||||
|
|
@ -11,6 +12,7 @@ interface SoundProps {
|
|||
}
|
||||
|
||||
export function Sound({ label, src }: SoundProps) {
|
||||
const { isPlaying } = usePlay();
|
||||
const [isSelected, setIsSelected] = useState(false);
|
||||
const [volume, setVolume] = useState(0.5);
|
||||
|
||||
|
|
@ -18,14 +20,15 @@ export function Sound({ label, src }: SoundProps) {
|
|||
|
||||
useEffect(() => {
|
||||
if (!isSelected) {
|
||||
sound?.pause();
|
||||
setVolume(0.5);
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
if (isSelected && isPlaying) {
|
||||
sound?.play();
|
||||
} else {
|
||||
sound?.pause();
|
||||
}
|
||||
}, [isSelected, sound]);
|
||||
}, [isSelected, sound, isPlaying]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
31
src/contexts/play.tsx
Normal file
31
src/contexts/play.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { createContext, useContext, useState, useCallback } from 'react';
|
||||
|
||||
export const PlayContext = createContext({
|
||||
isPlaying: false,
|
||||
pause: () => {},
|
||||
play: () => {},
|
||||
toggle: () => {},
|
||||
});
|
||||
|
||||
export const usePlay = () => useContext(PlayContext);
|
||||
|
||||
interface PlayProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function PlayProvider({ children }: PlayProviderProps) {
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
||||
const play = useCallback(() => setIsPlaying(true), []);
|
||||
const pause = useCallback(() => setIsPlaying(false), []);
|
||||
const toggle = useCallback(
|
||||
() => (isPlaying ? pause() : play()),
|
||||
[isPlaying, play, pause],
|
||||
);
|
||||
|
||||
return (
|
||||
<PlayContext.Provider value={{ isPlaying, pause, play, toggle }}>
|
||||
{children}
|
||||
</PlayContext.Provider>
|
||||
);
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ import Layout from '@/layouts/layout.astro';
|
|||
import { Hero } from '@/components/hero';
|
||||
import { Categories } from '@/components/categories';
|
||||
|
||||
// import sounds from '@/data/sounds.json';
|
||||
import { sounds } from '@/data/sounds';
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue