mirror of
https://github.com/remvze/moodist.git
synced 2025-12-17 00:44:14 +00:00
feat: add lock while fading
This commit is contained in:
parent
c893e2a6ad
commit
d9246b692b
8 changed files with 48 additions and 9 deletions
|
|
@ -23,6 +23,8 @@ export function App() {
|
|||
|
||||
const favorites = useSoundStore(useShallow(state => state.getFavorites()));
|
||||
const pause = useSoundStore(state => state.pause);
|
||||
const lock = useSoundStore(state => state.lock);
|
||||
const unlock = useSoundStore(state => state.unlock);
|
||||
|
||||
const favoriteSounds = useMemo(() => {
|
||||
const favoriteSounds = categories
|
||||
|
|
@ -56,13 +58,16 @@ export function App() {
|
|||
|
||||
useEffect(() => {
|
||||
const unsubscribe = subscribe('fadeOut', (e: { duration: number }) => {
|
||||
lock();
|
||||
|
||||
setTimeout(() => {
|
||||
pause();
|
||||
unlock();
|
||||
}, e.duration);
|
||||
});
|
||||
|
||||
return unsubscribe;
|
||||
}, [pause]);
|
||||
}, [pause, lock, unlock]);
|
||||
|
||||
const allCategories = useMemo(() => {
|
||||
const favorites = [];
|
||||
|
|
|
|||
|
|
@ -12,14 +12,17 @@ export function PlayButton() {
|
|||
const pause = useSoundStore(state => state.pause);
|
||||
const toggle = useSoundStore(state => state.togglePlay);
|
||||
const noSelected = useSoundStore(state => state.noSelected());
|
||||
const locked = useSoundStore(state => state.locked);
|
||||
|
||||
const showSnackbar = useSnackbar();
|
||||
|
||||
const handleToggle = useCallback(() => {
|
||||
if (locked) return;
|
||||
|
||||
if (noSelected) return showSnackbar('Please first select a sound to play.');
|
||||
|
||||
toggle();
|
||||
}, [showSnackbar, toggle, noSelected]);
|
||||
}, [showSnackbar, toggle, noSelected, locked]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying && noSelected) pause();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ export function UnselectButton() {
|
|||
const restoreHistory = useSoundStore(state => state.restoreHistory);
|
||||
const hasHistory = useSoundStore(state => !!state.history);
|
||||
const unselectAll = useSoundStore(state => state.unselectAll);
|
||||
const locked = useSoundStore(state => state.locked);
|
||||
|
||||
const variants = {
|
||||
...mix(fade(), slideX(15)),
|
||||
|
|
@ -22,9 +23,10 @@ export function UnselectButton() {
|
|||
};
|
||||
|
||||
const handleToggle = useCallback(() => {
|
||||
if (locked) return;
|
||||
if (hasHistory) restoreHistory();
|
||||
else if (!noSelected) unselectAll(true);
|
||||
}, [hasHistory, noSelected, unselectAll, restoreHistory]);
|
||||
}, [hasHistory, noSelected, unselectAll, restoreHistory, locked]);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (e: KeyboardEvent) => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,14 @@ import { Item } from '../item';
|
|||
|
||||
export function Shuffle() {
|
||||
const shuffle = useSoundStore(state => state.shuffle);
|
||||
const locked = useSoundStore(state => state.locked);
|
||||
|
||||
return <Item icon={<BiShuffle />} label="Shuffle Sounds" onClick={shuffle} />;
|
||||
return (
|
||||
<Item
|
||||
disabled={locked}
|
||||
icon={<BiShuffle />}
|
||||
label="Shuffle Sounds"
|
||||
onClick={shuffle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export function Range({ id, label }: RangeProps) {
|
|||
const setVolume = useSoundStore(state => state.setVolume);
|
||||
const volume = useSoundStore(state => state.sounds[id].volume);
|
||||
const isSelected = useSoundStore(state => state.sounds[id].isSelected);
|
||||
const locked = useSoundStore(state => state.locked);
|
||||
|
||||
return (
|
||||
<input
|
||||
|
|
@ -22,8 +23,10 @@ export function Range({ id, label }: RangeProps) {
|
|||
min={0}
|
||||
type="range"
|
||||
value={volume * 100}
|
||||
onChange={e => isSelected && setVolume(id, Number(e.target.value) / 100)}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onChange={e =>
|
||||
!locked && isSelected && setVolume(id, Number(e.target.value) / 100)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,18 +32,21 @@ export const Sound = forwardRef<HTMLDivElement, SoundProps>(function Sound(
|
|||
const setVolume = useSoundStore(state => state.setVolume);
|
||||
const volume = useSoundStore(state => state.sounds[id].volume);
|
||||
const isSelected = useSoundStore(state => state.sounds[id].isSelected);
|
||||
const locked = useSoundStore(state => state.locked);
|
||||
|
||||
const isLoading = useLoadingStore(state => state.loaders[src]);
|
||||
|
||||
const sound = useSound(src, { loop: true, volume });
|
||||
|
||||
useEffect(() => {
|
||||
if (locked) return;
|
||||
|
||||
if (isSelected && isPlaying && functional) {
|
||||
sound?.play();
|
||||
} else {
|
||||
sound?.pause();
|
||||
}
|
||||
}, [isSelected, sound, isPlaying, functional]);
|
||||
}, [isSelected, sound, isPlaying, functional, locked]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hidden && isSelected) selectHidden(label);
|
||||
|
|
@ -51,19 +54,22 @@ export const Sound = forwardRef<HTMLDivElement, SoundProps>(function Sound(
|
|||
}, [label, isSelected, hidden, selectHidden, unselectHidden]);
|
||||
|
||||
const _select = useCallback(() => {
|
||||
if (locked) return;
|
||||
select(id);
|
||||
play();
|
||||
}, [select, play, id]);
|
||||
}, [select, play, id, locked]);
|
||||
|
||||
const _unselect = useCallback(() => {
|
||||
if (locked) return;
|
||||
unselect(id);
|
||||
setVolume(id, 0.5);
|
||||
}, [unselect, setVolume, id]);
|
||||
}, [unselect, setVolume, id, locked]);
|
||||
|
||||
const toggle = useCallback(() => {
|
||||
if (locked) return;
|
||||
if (isSelected) _unselect();
|
||||
else _select();
|
||||
}, [isSelected, _select, _unselect]);
|
||||
}, [isSelected, _select, _unselect, locked]);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
toggle();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import type { SoundState } from './sound.state';
|
|||
import { pickMany, random } from '@/helpers/random';
|
||||
|
||||
export interface SoundActions {
|
||||
lock: () => void;
|
||||
override: (sounds: Record<string, number>) => void;
|
||||
pause: () => void;
|
||||
play: () => void;
|
||||
|
|
@ -14,6 +15,7 @@ export interface SoundActions {
|
|||
shuffle: () => void;
|
||||
toggleFavorite: (id: string) => void;
|
||||
togglePlay: () => void;
|
||||
unlock: () => void;
|
||||
unselect: (id: string) => void;
|
||||
unselectAll: (pushToHistory?: boolean) => void;
|
||||
}
|
||||
|
|
@ -25,6 +27,10 @@ export const createActions: StateCreator<
|
|||
SoundActions
|
||||
> = (set, get) => {
|
||||
return {
|
||||
lock() {
|
||||
set({ locked: true });
|
||||
},
|
||||
|
||||
override(newSounds) {
|
||||
get().unselectAll();
|
||||
|
||||
|
|
@ -111,6 +117,10 @@ export const createActions: StateCreator<
|
|||
set({ isPlaying: !get().isPlaying });
|
||||
},
|
||||
|
||||
unlock() {
|
||||
set({ locked: false });
|
||||
},
|
||||
|
||||
unselect(id) {
|
||||
set({
|
||||
sounds: {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export interface SoundState {
|
|||
};
|
||||
} | null;
|
||||
isPlaying: boolean;
|
||||
locked: boolean;
|
||||
noSelected: () => boolean;
|
||||
sounds: {
|
||||
[id: string]: {
|
||||
|
|
@ -40,6 +41,7 @@ export const createState: StateCreator<
|
|||
},
|
||||
history: null,
|
||||
isPlaying: false,
|
||||
locked: false,
|
||||
noSelected() {
|
||||
const { sounds } = get();
|
||||
const keys = Object.keys(sounds);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue