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 { Container } from '@/components/container';
|
||||||
import { Category } from '@/components/category';
|
import { Category } from '@/components/category';
|
||||||
|
import { PlayButton } from '@/components/play-button';
|
||||||
|
import { PlayProvider } from '@/contexts/play';
|
||||||
|
|
||||||
interface CategoriesProps {
|
interface CategoriesProps {
|
||||||
categories: Array<{
|
categories: Array<{
|
||||||
|
|
@ -22,16 +24,20 @@ export function Categories({ categories }: CategoriesProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<PlayProvider>
|
||||||
<div>
|
<Container>
|
||||||
{categories.map(category => (
|
<div>
|
||||||
<Category
|
{categories.map(category => (
|
||||||
{...category}
|
<Category
|
||||||
icon={idToIcon[category.id] || idToIcon.nature}
|
{...category}
|
||||||
key={category.id}
|
icon={idToIcon[category.id] || idToIcon.nature}
|
||||||
/>
|
key={category.id}
|
||||||
))}
|
/>
|
||||||
</div>
|
))}
|
||||||
</Container>
|
</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 { useState, useEffect } from 'react';
|
||||||
|
|
||||||
import { useSound } from '@/hooks/use-sound';
|
import { useSound } from '@/hooks/use-sound';
|
||||||
|
import { usePlay } from '@/contexts/play';
|
||||||
import { cn } from '@/helpers/styles';
|
import { cn } from '@/helpers/styles';
|
||||||
|
|
||||||
import styles from './sound.module.css';
|
import styles from './sound.module.css';
|
||||||
|
|
@ -11,6 +12,7 @@ interface SoundProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Sound({ label, src }: SoundProps) {
|
export function Sound({ label, src }: SoundProps) {
|
||||||
|
const { isPlaying } = usePlay();
|
||||||
const [isSelected, setIsSelected] = useState(false);
|
const [isSelected, setIsSelected] = useState(false);
|
||||||
const [volume, setVolume] = useState(0.5);
|
const [volume, setVolume] = useState(0.5);
|
||||||
|
|
||||||
|
|
@ -18,14 +20,15 @@ export function Sound({ label, src }: SoundProps) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isSelected) {
|
if (!isSelected) {
|
||||||
sound?.pause();
|
|
||||||
setVolume(0.5);
|
setVolume(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected && isPlaying) {
|
||||||
sound?.play();
|
sound?.play();
|
||||||
|
} else {
|
||||||
|
sound?.pause();
|
||||||
}
|
}
|
||||||
}, [isSelected, sound]);
|
}, [isSelected, sound, isPlaying]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<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 { Hero } from '@/components/hero';
|
||||||
import { Categories } from '@/components/categories';
|
import { Categories } from '@/components/categories';
|
||||||
|
|
||||||
// import sounds from '@/data/sounds.json';
|
|
||||||
import { sounds } from '@/data/sounds';
|
import { sounds } from '@/data/sounds';
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue