summaryrefslogtreecommitdiff
path: root/src/store
diff options
context:
space:
mode:
Diffstat (limited to 'src/store')
-rw-r--r--src/store/audioStore.ts84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/store/audioStore.ts b/src/store/audioStore.ts
new file mode 100644
index 0000000..39cbf8b
--- /dev/null
+++ b/src/store/audioStore.ts
@@ -0,0 +1,84 @@
+import { invoke } from '@tauri-apps/api/core';
+import { create } from 'zustand';
+
+export type AmbientSound = 'none' | 'rain' | 'cafe' | 'white_noise';
+
+interface AudioStatus {
+ available: boolean;
+ playing: boolean;
+ sound: AmbientSound | null;
+ volume: number;
+}
+
+interface AudioStore {
+ available: boolean;
+ playing: boolean;
+ sound: AmbientSound;
+ volume: number;
+ fetchStatus: () => Promise<void>;
+ setSound: (sound: AmbientSound) => Promise<void>;
+ setVolume: (volume: number) => Promise<void>;
+}
+
+function normalizeSound(sound: AudioStatus['sound'], playing: boolean): AmbientSound {
+ if (!playing || sound === null) {
+ return 'none';
+ }
+
+ return sound;
+}
+
+export const useAudioStore = create<AudioStore>((set, get) => ({
+ available: true,
+ playing: false,
+ sound: 'none',
+ volume: 0.5,
+
+ fetchStatus: async () => {
+ try {
+ const status = await invoke<AudioStatus>('get_audio_status');
+ set({
+ available: status.available,
+ playing: status.playing,
+ sound: normalizeSound(status.sound, status.playing),
+ volume: status.volume,
+ });
+ } catch (error) {
+ console.error('get_audio_status error:', error);
+ set({ available: false, playing: false, sound: 'none' });
+ }
+ },
+
+ setSound: async (sound) => {
+ try {
+ if (sound === 'none') {
+ await invoke('stop_ambient');
+ set({ playing: false, sound: 'none' });
+ return;
+ }
+
+ await invoke('play_ambient', { sound });
+ set({ available: true, playing: true, sound });
+ } catch (error) {
+ console.error('play_ambient error:', error);
+ set({ available: false, playing: false, sound: 'none' });
+ }
+ },
+
+ setVolume: async (volume) => {
+ const nextVolume = Math.min(1, Math.max(0, volume));
+ set({ volume: nextVolume });
+
+ try {
+ await invoke('set_ambient_volume', { volume: nextVolume });
+ set({ available: true });
+ } catch (error) {
+ console.error('set_ambient_volume error:', error);
+ set({
+ available: false,
+ playing: false,
+ sound: get().sound,
+ });
+ }
+ },
+}));