1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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,
});
}
},
}));
|