From 31c087ebc8e66220d488226029dcc1435667ce04 Mon Sep 17 00:00:00 2001 From: MAZE Date: Fri, 6 Oct 2023 18:30:54 +0330 Subject: [PATCH] feat: add play button --- src/components/categories/categories.tsx | 28 ++++++++++------- src/components/play-button/index.ts | 1 + .../play-button/play-button.module.css | 25 +++++++++++++++ src/components/play-button/play-button.tsx | 29 +++++++++++++++++ src/components/sound/sound.tsx | 9 ++++-- src/contexts/play.tsx | 31 +++++++++++++++++++ src/pages/index.astro | 1 - 7 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 src/components/play-button/index.ts create mode 100644 src/components/play-button/play-button.module.css create mode 100644 src/components/play-button/play-button.tsx create mode 100644 src/contexts/play.tsx diff --git a/src/components/categories/categories.tsx b/src/components/categories/categories.tsx index 49ec3e2..80b1df8 100644 --- a/src/components/categories/categories.tsx +++ b/src/components/categories/categories.tsx @@ -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 ( - -
- {categories.map(category => ( - - ))} -
-
+ + +
+ {categories.map(category => ( + + ))} +
+ + +
+
); } diff --git a/src/components/play-button/index.ts b/src/components/play-button/index.ts new file mode 100644 index 0000000..b646911 --- /dev/null +++ b/src/components/play-button/index.ts @@ -0,0 +1 @@ +export { PlayButton } from './play-button'; diff --git a/src/components/play-button/play-button.module.css b/src/components/play-button/play-button.module.css new file mode 100644 index 0000000..0beb0de --- /dev/null +++ b/src/components/play-button/play-button.module.css @@ -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); + } +} diff --git a/src/components/play-button/play-button.tsx b/src/components/play-button/play-button.tsx new file mode 100644 index 0000000..61aabe5 --- /dev/null +++ b/src/components/play-button/play-button.tsx @@ -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 ( + + ); +} diff --git a/src/components/sound/sound.tsx b/src/components/sound/sound.tsx index a435ba2..1ca6c10 100644 --- a/src/components/sound/sound.tsx +++ b/src/components/sound/sound.tsx @@ -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 (
{}, + 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 ( + + {children} + + ); +} diff --git a/src/pages/index.astro b/src/pages/index.astro index 82e2d57..a099b17 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -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'; ---