Compare commits

...
Author SHA1 Message Date
Brandon Thomas 8f2f07511d sound for delete 2026-01-23 08:54:13 -05:00
10 changed files with 74 additions and 4 deletions
@@ -18,6 +18,9 @@ pub struct AppPreferencesPayload {
/// Play sounds on events.
pub play_sounds: bool,
/// Key pointing to file; defined in the frontend code.
pub delete_file_sound: Option<String>,
/// Key pointing to file; defined in the frontend code.
/// Defined for enqueue since image enqueue can be async
pub enqueue_success_sound: Option<String>,
@@ -61,6 +64,7 @@ async fn get_prefs(app_prefs: &AppPreferencesManager) -> AnyhowResult<AppPrefere
Ok(AppPreferencesPayload {
preferred_download_directory: prefs.preferred_download_directory,
play_sounds: prefs.play_sounds,
delete_file_sound: prefs.delete_file_sound,
enqueue_success_sound: prefs.enqueue_success_sound,
enqueue_failure_sound: prefs.enqueue_failure_sound,
generation_success_sound: prefs.generation_success_sound,
@@ -28,6 +28,7 @@ pub enum ValueType {
pub enum PreferenceName {
PreferredDownloadDirectory,
PlaySounds,
DeleteFileSound,
EnqueueSuccessSound,
EnqueueFailureSound,
GenerationSuccessSound,
@@ -85,6 +86,11 @@ async fn update_prefs(
return Err(anyhow!("Invalid value: {:?}", request.value)),
}
}
PreferenceName::DeleteFileSound => {
prefs.delete_file_sound = request.value
.map(|val| string_value(&val))
.transpose()?;
}
PreferenceName::EnqueueSuccessSound => {
prefs.enqueue_success_sound = request.value
.map(|val| string_value(&val))
@@ -10,6 +10,9 @@ pub struct AppPreferences {
/// Play sounds on events.
pub play_sounds: bool,
/// Key pointing to file; defined in the frontend code.
pub delete_file_sound: Option<String>,
/// Key pointing to file; defined in the frontend code.
/// Defined for enqueue since image enqueue can be async
pub enqueue_success_sound: Option<String>,
@@ -40,6 +43,7 @@ impl Default for AppPreferences {
generation_success_sound: Some("special_flower".to_string()),
generation_failure_sound: Some("crumble".to_string()),
generation_enqueue_sound: Some("done".to_string()),
delete_file_sound: Some("trash".to_string()),
}
}
}
@@ -5,7 +5,9 @@ use errors::AnyhowResult;
use serde_derive::{Deserialize, Serialize};
/// Vector clock versioning string rather than semver.
const CURRENT_VERSION: &str = "1";
/// - Version 1 - initial version.
/// - Version 2 - added "delete_file_sound", marked optionals "skip_serializing_if"
const CURRENT_VERSION: &str = "2";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppPreferencesSerializable {
@@ -16,15 +18,23 @@ pub struct AppPreferencesSerializable {
pub preferred_download_directory: Option<PreferredDownloadDirectory>,
/// Play sounds on events.
#[serde(skip_serializing_if = "Option::is_none")]
pub play_sounds: Option<bool>,
/// Key pointing to file; defined in the frontend code.
#[serde(skip_serializing_if = "Option::is_none")]
pub delete_file_sound: Option<String>,
/// Key pointing to file; defined in the frontend code.
#[serde(skip_serializing_if = "Option::is_none")]
pub generation_success_sound: Option<String>,
/// Key pointing to file; defined in the frontend code.
#[serde(skip_serializing_if = "Option::is_none")]
pub generation_failure_sound: Option<String>,
/// Key pointing to file; defined in the frontend code.
#[serde(skip_serializing_if = "Option::is_none")]
pub generation_enqueue_sound: Option<String>,
}
@@ -45,6 +55,7 @@ impl AppPreferencesSerializable {
version: CURRENT_VERSION.to_string(),
preferred_download_directory: Some(preferences.preferred_download_directory.clone()),
play_sounds: Some(preferences.play_sounds),
delete_file_sound: preferences.delete_file_sound.clone(),
generation_success_sound: preferences.generation_success_sound.clone(),
generation_failure_sound: preferences.generation_failure_sound.clone(),
generation_enqueue_sound: preferences.generation_enqueue_sound.clone(),
@@ -61,11 +72,12 @@ impl AppPreferencesSerializable {
if let Some(play_sounds) = self.play_sounds {
preferences.play_sounds = play_sounds;
}
preferences.delete_file_sound = self.delete_file_sound.clone();
preferences.generation_success_sound = self.generation_success_sound.clone();
preferences.generation_failure_sound = self.generation_failure_sound.clone();
preferences.generation_enqueue_sound = self.generation_enqueue_sound.clone();
preferences
}
}
@@ -43,6 +43,9 @@ export const InstallSounds = () => {
r.setSoundOnce("correct", new SoundEffect("resources/sound/smrpg_correct.wav", { defaultVolume: 0.1 }));
r.setSoundOnce("flower", new SoundEffect("resources/sound/smrpg_flower.wav", { defaultVolume: 0.1 }));
// File delete, trash, etc.
r.setSoundOnce("trash", new SoundEffect("resources/sound/oot_scrub_crumble.wav", { defaultVolume: 0.4 }));
// Misc / ungrouped
r.setSoundOnce("accept_chirp", new SoundEffect("resources/sound/goldensun_101.wav", { defaultVolume: 0.2 }));
r.setSoundOnce("accept_normal_level_1", new SoundEffect("resources/sound/goldensun_173.wav", { defaultVolume: 0.2 }));
@@ -39,6 +39,8 @@ import { useGenerationEnqueueSuccessEvent } from "@storyteller/tauri-events";
import { useGenerationFailedEvent } from "@storyteller/tauri-events";
import { useTextToImageGenerationCompleteEvent } from "@storyteller/tauri-events";
import { useTextToImageStore } from "~/pages/PageImage/TextToImageStore";
import { GetAppPreferences } from "@storyteller/tauri-api";
import { SoundRegistry } from "@storyteller/soundboard";
export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
useSignals();
@@ -117,6 +119,12 @@ export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
useMediaFileDeletedEvent(async (event) => {
console.log("Media file deleted event received:", event);
const prefs = await GetAppPreferences();
const soundName = prefs.preferences?.delete_file_sound;
if (soundName !== undefined) {
const registry = SoundRegistry.getInstance();
registry.playSound(soundName);
}
toast.error("File deleted.");
});
@@ -36,6 +36,7 @@ const SOUND_OPTIONS = [
{ label: "Special Alert", value: "special_alert" },
{ label: "Special Flower", value: "special_flower" },
{ label: "Spike Throw", value: "spike_throw" },
{ label: "Trash", value: "trash" },
{ label: "Wrong", value: "wrong" },
];
@@ -56,6 +57,7 @@ export const AudioSettingsPane = (args: AudioSettingsPaneProps) => {
const playSounds = preferences?.play_sounds || false;
const deleteFileSound = orNone(preferences?.delete_file_sound);
const enqueueSuccessSound = orNone(preferences?.enqueue_success_sound);
const enqueueFailureSound = orNone(preferences?.enqueue_failure_sound);
const generationSuccessSound = orNone(preferences?.generation_success_sound);
@@ -75,6 +77,16 @@ export const AudioSettingsPane = (args: AudioSettingsPaneProps) => {
await reloadPreferences();
};
const setDeleteFileSound = async (val: string) => {
let sendVal = val === "none" ? undefined : val;
await UpdateAppPreferences({
preference: PreferenceName.DeleteFileSound,
value: sendVal,
});
SoundRegistry.getInstance().playSound(val);
await reloadPreferences();
};
const setEnqueueSuccessSound = async (val: string) => {
let sendVal = val === "none" ? undefined : val;
await UpdateAppPreferences({
@@ -131,6 +143,25 @@ export const AudioSettingsPane = (args: AudioSettingsPaneProps) => {
<Switch enabled={playSounds} setEnabled={setPlaySounds} />
</div>
<div className="space-y-1">
<Label htmlFor="success-sound">Delete File Sound</Label>
<div className="flex items-center gap-2">
<Select
id="success-sound"
value={deleteFileSound}
onChange={(val: SelectValue) => setDeleteFileSound(val as string)}
options={SOUND_OPTIONS}
className="grow"
/>
<Button
variant="primary"
className="w-[40px] h-[40px]"
icon={faPlay}
onClick={() => playSound(deleteFileSound)}
/>
</div>
</div>
<div className="space-y-1">
<Label htmlFor="success-sound">Enqueue Success Sound</Label>
<div className="flex items-center gap-2">
@@ -13,6 +13,7 @@ export interface AppPreferencesPayload {
// Sound names to play.
// These are keys, not filenames, and are defined by the frontend.
delete_file_sound?: string,
enqueue_success_sound?: string,
enqueue_failure_sound?: string,
generation_success_sound?: string,
@@ -10,6 +10,7 @@ export interface UpdateAppPreferencesRequest {
export enum PreferenceName {
PreferredDownloadDirectory = "preferred_download_directory",
PlaySounds = "play_sounds",
DeleteFileSound = "delete_file_sound",
EnqueueSuccessSound = "enqueue_success_sound",
EnqueueFailureSound = "enqueue_failure_sound",
GenerationSuccessSound = "generation_success_sound",