Skip to content

Commit

Permalink
feat: implement unselect all functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
remvze committed Oct 11, 2023
1 parent 6d02cfb commit 8966d59
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 57 deletions.
25 changes: 24 additions & 1 deletion src/components/buttons/buttons.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@
line-height: 0;
outline: none;

&:disabled {
cursor: default;
}

& span {
font-size: var(--font-lg);
}
}

& .shuffleButton {
& .smallButton {
display: flex;
width: 45px;
height: 45px;
Expand All @@ -47,5 +51,24 @@
font-size: var(--font-md);
line-height: 0;
outline: none;
transition: 0.2s;

&:disabled {
cursor: default;
}

&.restore {
border-top-color: #34d399;
border-bottom-color: #047857;
background-color: #10b981;
color: var(--color-foreground);
}

&.delete {
border-top-color: #fb7185;
border-bottom-color: #be123c;
background-color: #f43f5e;
color: var(--color-foreground);
}
}
}
31 changes: 22 additions & 9 deletions src/components/buttons/buttons.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { useEffect } from 'react';
import { BiPause, BiPlay, BiShuffle } from 'react-icons/bi/index';
import { BiPause, BiPlay, BiUndo, BiTrash } from 'react-icons/bi/index';

import { useSoundStore } from '@/store';
import { usePlay } from '@/contexts/play';
import { cn } from '@/helpers/styles';

import styles from './buttons.module.css';

export function Buttons() {
const { isPlaying, pause, play, toggle } = usePlay();
const { isPlaying, pause, toggle } = usePlay();
const noSelected = useSoundStore(state => state.noSelected());
const shuffle = useSoundStore(state => state.shuffle);
const restoreHistory = useSoundStore(state => state.restoreHistory);
const hasHistory = useSoundStore(state => !!state.history);
const unselectAll = useSoundStore(state => state.unselectAll);

const handleClick = () => {
if (noSelected) return pause();
Expand All @@ -23,7 +26,11 @@ export function Buttons() {

return (
<div className={styles.buttons}>
<button className={styles.playButton} onClick={handleClick}>
<button
className={styles.playButton}
disabled={noSelected}
onClick={handleClick}
>
{isPlaying ? (
<>
<span>
Expand All @@ -42,14 +49,20 @@ export function Buttons() {
</button>

<button
aria-label="Shuffle Sounds"
className={styles.shuffleButton}
disabled={noSelected && !hasHistory}
aria-label={
hasHistory ? 'Restore Unselected Sounds' : 'Unselect All Sounds'
}
className={cn(
styles.smallButton,
hasHistory ? styles.restore : styles.delete,
)}
onClick={() => {
shuffle();
play();
if (hasHistory) restoreHistory();
else if (!noSelected) unselectAll(true);
}}
>
<BiShuffle />
{hasHistory ? <BiUndo /> : <BiTrash />}
</button>
</div>
);
Expand Down
26 changes: 0 additions & 26 deletions src/helpers/random.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/store/sound/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const useSoundStore = create<SoundState & SoundActions>()(
}),
{
name: 'moodist-sounds',
partialize: state => ({ sounds: state.sounds }),
skipHydration: true,
storage: createJSONStorage(() => localStorage),
version: 0,
Expand Down
41 changes: 21 additions & 20 deletions src/store/sound/sound.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import type { StateCreator } from 'zustand';

import type { SoundState } from './sound.state';

import { pickMany, random } from '@/helpers/random';

export interface SoundActions {
select: (id: string) => void;
unselect: (id: string) => void;
setVolume: (id: string, volume: number) => void;
unselectAll: () => void;
shuffle: () => void;
unselectAll: (pushToHistory?: boolean) => void;
restoreHistory: () => void;
}

export const createActions: StateCreator<
Expand All @@ -19,6 +17,14 @@ export const createActions: StateCreator<
SoundActions
> = (set, get) => {
return {
restoreHistory() {
const history = get().history;

if (!history) return;

set({ history: null, sounds: history });
},

select(id) {
set({
sounds: {
Expand All @@ -37,21 +43,6 @@ export const createActions: StateCreator<
});
},

shuffle() {
get().unselectAll();

const sounds = get().sounds;
const ids = Object.keys(sounds);
const randomIDs = pickMany(ids, 4);

randomIDs.forEach(id => {
sounds[id].isSelected = true;
sounds[id].volume = random(0.2, 0.8);
});

set({ sounds });
},

unselect(id) {
set({
sounds: {
Expand All @@ -61,8 +52,18 @@ export const createActions: StateCreator<
});
},

unselectAll() {
unselectAll(pushToHistory = false) {
const noSelected = get().noSelected();

if (noSelected) return;

const sounds = get().sounds;

if (pushToHistory) {
const history = JSON.parse(JSON.stringify(sounds));
set({ history });
}

const ids = Object.keys(sounds);

ids.forEach(id => {
Expand Down
8 changes: 7 additions & 1 deletion src/store/sound/sound.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ export interface SoundState {
volume: number;
};
};
history: {
[id: string]: {
isSelected: boolean;
volume: number;
};
} | null;
noSelected: () => boolean;
}

Expand All @@ -21,13 +27,13 @@ export const createState: StateCreator<
SoundState
> = (set, get) => {
const state: SoundState = {
history: null,
noSelected() {
const { sounds } = get();
const keys = Object.keys(sounds);

return keys.every(key => !sounds[key].isSelected);
},

sounds: {},
};

Expand Down

0 comments on commit 8966d59

Please sign in to comment.