feat: add play button

This commit is contained in:
MAZE 2023-10-06 18:30:54 +03:30
parent 5a7a58e883
commit 31c087ebc8
7 changed files with 109 additions and 15 deletions

View file

@ -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,6 +24,7 @@ export function Categories({ categories }: CategoriesProps) {
};
return (
<PlayProvider>
<Container>
<div>
{categories.map(category => (
@ -32,6 +35,9 @@ export function Categories({ categories }: CategoriesProps) {
/>
))}
</div>
<PlayButton />
</Container>
</PlayProvider>
);
}

View file

@ -0,0 +1 @@
export { PlayButton } from './play-button';

View 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);
}
}

View 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>
);
}

View file

@ -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
View 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>
);
}

View file

@ -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';
---