diff --git a/src/components/buttons/buttons.module.css b/src/components/buttons/buttons.module.css
index e53a005..34f0e9a 100644
--- a/src/components/buttons/buttons.module.css
+++ b/src/components/buttons/buttons.module.css
@@ -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;
@@ -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);
+ }
}
}
diff --git a/src/components/buttons/buttons.tsx b/src/components/buttons/buttons.tsx
index 8d9d694..8e879f8 100644
--- a/src/components/buttons/buttons.tsx
+++ b/src/components/buttons/buttons.tsx
@@ -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();
@@ -23,7 +26,11 @@ export function Buttons() {
return (
-
);
diff --git a/src/helpers/random.ts b/src/helpers/random.ts
deleted file mode 100644
index 8e577c2..0000000
--- a/src/helpers/random.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-export function random(min: number, max: number): number {
- return Math.random() * (max - min) + min;
-}
-
-export function randomInt(min: number, max: number): number {
- return Math.floor(random(min, max));
-}
-
-export function pickOne(array: Array): T {
- const randomIndex = random(0, array.length);
-
- return array[randomIndex];
-}
-
-export function shuffle(array: Array): Array {
- return array
- .map(value => ({ sort: Math.random(), value }))
- .sort((a, b) => a.sort - b.sort)
- .map(({ value }) => value);
-}
-
-export function pickMany(array: Array, count: number): Array {
- const shuffled = shuffle(array);
-
- return shuffled.slice(0, count);
-}
diff --git a/src/store/sound/index.ts b/src/store/sound/index.ts
index e44b43f..b301dff 100644
--- a/src/store/sound/index.ts
+++ b/src/store/sound/index.ts
@@ -12,6 +12,7 @@ export const useSoundStore = create()(
}),
{
name: 'moodist-sounds',
+ partialize: state => ({ sounds: state.sounds }),
skipHydration: true,
storage: createJSONStorage(() => localStorage),
version: 0,
diff --git a/src/store/sound/sound.actions.ts b/src/store/sound/sound.actions.ts
index 2c18b96..1d4f9a2 100644
--- a/src/store/sound/sound.actions.ts
+++ b/src/store/sound/sound.actions.ts
@@ -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<
@@ -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: {
@@ -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: {
@@ -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 => {
diff --git a/src/store/sound/sound.state.ts b/src/store/sound/sound.state.ts
index 3019c6d..6857fa0 100644
--- a/src/store/sound/sound.state.ts
+++ b/src/store/sound/sound.state.ts
@@ -11,6 +11,12 @@ export interface SoundState {
volume: number;
};
};
+ history: {
+ [id: string]: {
+ isSelected: boolean;
+ volume: number;
+ };
+ } | null;
noSelected: () => boolean;
}
@@ -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: {},
};