diff --git a/crates/desktop/artcraft/src/core/commands/app_preferences/get_app_preferences_command.rs b/crates/desktop/artcraft/src/core/commands/app_preferences/get_app_preferences_command.rs index 3ea0245037..a42668a668 100644 --- a/crates/desktop/artcraft/src/core/commands/app_preferences/get_app_preferences_command.rs +++ b/crates/desktop/artcraft/src/core/commands/app_preferences/get_app_preferences_command.rs @@ -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, + /// Key pointing to file; defined in the frontend code. /// Defined for enqueue since image enqueue can be async pub enqueue_success_sound: Option, @@ -61,6 +64,7 @@ async fn get_prefs(app_prefs: &AppPreferencesManager) -> AnyhowResult { + 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)) diff --git a/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences.rs b/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences.rs index ccae1d67c6..8178bfca2e 100644 --- a/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences.rs +++ b/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences.rs @@ -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, + /// Key pointing to file; defined in the frontend code. /// Defined for enqueue since image enqueue can be async pub enqueue_success_sound: Option, @@ -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()), } } } diff --git a/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences_serializable.rs b/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences_serializable.rs index 530029d6af..e795d44cc2 100644 --- a/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences_serializable.rs +++ b/crates/desktop/artcraft/src/core/state/app_preferences/app_preferences_serializable.rs @@ -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, /// Play sounds on events. + #[serde(skip_serializing_if = "Option::is_none")] pub play_sounds: Option, - + /// Key pointing to file; defined in the frontend code. + #[serde(skip_serializing_if = "Option::is_none")] + pub delete_file_sound: Option, + + /// Key pointing to file; defined in the frontend code. + #[serde(skip_serializing_if = "Option::is_none")] pub generation_success_sound: Option, /// Key pointing to file; defined in the frontend code. + #[serde(skip_serializing_if = "Option::is_none")] pub generation_failure_sound: Option, /// Key pointing to file; defined in the frontend code. + #[serde(skip_serializing_if = "Option::is_none")] pub generation_enqueue_sound: Option, } @@ -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 } } diff --git a/frontend/apps/artcraft/app/public/resources/sound/oot_scrub_crumble.wav b/frontend/apps/artcraft/app/public/resources/sound/oot_scrub_crumble.wav new file mode 100644 index 0000000000..cacadcc22c Binary files /dev/null and b/frontend/apps/artcraft/app/public/resources/sound/oot_scrub_crumble.wav differ diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/InstallSounds.ts b/frontend/apps/artcraft/app/src/pages/PageEnigma/InstallSounds.ts index 0d3a795415..04e7f6efc2 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/InstallSounds.ts +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/InstallSounds.ts @@ -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 })); diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/PageEnigma.tsx b/frontend/apps/artcraft/app/src/pages/PageEnigma/PageEnigma.tsx index ba622c1f72..b6c7e6d6e4 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/PageEnigma.tsx +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/PageEnigma.tsx @@ -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."); }); diff --git a/frontend/libs/components/settings-modal/src/lib/panes/AudioSettingsPane.tsx b/frontend/libs/components/settings-modal/src/lib/panes/AudioSettingsPane.tsx index 4d1c1fbe12..35b8a62694 100644 --- a/frontend/libs/components/settings-modal/src/lib/panes/AudioSettingsPane.tsx +++ b/frontend/libs/components/settings-modal/src/lib/panes/AudioSettingsPane.tsx @@ -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) => { +
+ +
+