diff --git a/packages/app/constants/defaultSettings.json b/packages/app/constants/defaultSettings.json
index f1cde562..3b2c9387 100755
--- a/packages/app/constants/defaultSettings.json
+++ b/packages/app/constants/defaultSettings.json
@@ -1,6 +1,7 @@
{
- "themeVariant": "dark",
"forceMobileMode": false,
+ "ui.effects": true,
+ "ui.general_volume": 50,
"notifications_sound": true,
"notifications_vibrate": true,
"notifications_sound_volume": 50,
@@ -10,11 +11,8 @@
"haptic_feedback": false,
"collapseOnLooseFocus": true,
"style.auto_darkMode": true,
- "compactWidth": false,
- "postCard_carrusel_auto": true,
- "postCard_expansible_actions": true,
"feed_max_fetch": 20,
"style.compactMode": false,
- "sidebar.floating": true,
+ "sidebar.floating": false,
"language": "en"
}
\ No newline at end of file
diff --git a/packages/app/constants/defaultSoundPack.json b/packages/app/constants/defaultSoundPack.json
index 467a491d..c7fb1e78 100755
--- a/packages/app/constants/defaultSoundPack.json
+++ b/packages/app/constants/defaultSoundPack.json
@@ -1,5 +1,11 @@
{
- "crash": "/sounds/crash.wav",
- "error": "/sounds/error.wav",
- "notification": "/sounds/notification.wav"
+ "id": "default",
+ "name": "Default Soundpack",
+ "author": "RageStudio",
+ "version": "1.0.0",
+ "sounds": {
+ "crash": "/sounds/crash.wav",
+ "error": "/sounds/error.wav",
+ "notification": "/sounds/notification.wav"
+ }
}
\ No newline at end of file
diff --git a/packages/app/constants/settings/general/index.jsx b/packages/app/constants/settings/general/index.jsx
index 8af7f8d7..de930446 100755
--- a/packages/app/constants/settings/general/index.jsx
+++ b/packages/app/constants/settings/general/index.jsx
@@ -74,6 +74,33 @@ export default {
"description": "Enable low performance mode to reduce the memory usage and improve the performance in low-end devices. This will disable some animations and other decorative features.",
"emitEvent": "app.lowPerformanceMode"
},
+ {
+ id: "ui.effects",
+ storaged: true,
+ group: "ui_sounds",
+ component: "Switch",
+ icon: "MdVolumeUp",
+ title: "UI effects",
+ description: "Enable the UI effects.",
+ },
+ {
+ id: "ui.general_volume",
+ storaged: true,
+ group: "ui_sounds",
+ component: "Slider",
+ icon: "MdVolumeUp",
+ title: "UI volume",
+ description: "Set the volume of the app sounds.",
+ props: {
+ tipFormatter: (value) => {
+ return `${value}%`
+ },
+ min: 0,
+ max: 100,
+ step: 10,
+ },
+ emitEvent: "change:app.general_ui_volume"
+ },
{
"id": "notifications_sound",
"storaged": true,
diff --git a/packages/app/src/App.jsx b/packages/app/src/App.jsx
index 247cb8b8..0aadc223 100755
--- a/packages/app/src/App.jsx
+++ b/packages/app/src/App.jsx
@@ -202,6 +202,8 @@ class ComtyApp extends React.Component {
})
},
openSearcher: (options) => {
+ app.cores.sound.useUIAudio("navigation.search")
+
window.app.ModalController.open((props) => )
},
openNavigationMenu: () => window.app.DrawerController.open("navigation", Navigation),
@@ -252,6 +254,8 @@ class ComtyApp extends React.Component {
return app.setLocation(config.app.mainPath ?? "/home")
},
goToSettings: (setting_id) => {
+ app.cores.sound.useUIAudio("navigation.settings")
+
return app.setLocation(`/settings`, {
query: {
setting: setting_id
@@ -484,6 +488,8 @@ class ComtyApp extends React.Component {
})
}
+ //app.cores.sound.useUIAudio("splash_out")
+
app.eventBus.emit("app.initialization.start")
await this.initialization()
diff --git a/packages/app/src/components/Layout/sidebar/index.jsx b/packages/app/src/components/Layout/sidebar/index.jsx
index fff64309..43993c8e 100755
--- a/packages/app/src/components/Layout/sidebar/index.jsx
+++ b/packages/app/src/components/Layout/sidebar/index.jsx
@@ -274,6 +274,8 @@ export default class Sidebar extends React.Component {
return onClickHandlers[e.key](e)
}
+ window.app.cores.sound.useUIAudio("sidebar.switch_tab")
+
if (typeof this.state.pathResolvers === "object") {
if (typeof this.state.pathResolvers[e.key] !== "undefined") {
return window.app.setLocation(`/${this.state.pathResolvers[e.key]}`, 150)
diff --git a/packages/app/src/components/Layout/sidedrawer/index.jsx b/packages/app/src/components/Layout/sidedrawer/index.jsx
index 090cf0cc..e10c85b4 100755
--- a/packages/app/src/components/Layout/sidedrawer/index.jsx
+++ b/packages/app/src/components/Layout/sidedrawer/index.jsx
@@ -153,8 +153,12 @@ export default class SidedrawerController extends React.Component {
const drawerClasses = drawer.classList
if (to) {
+ app.cores.sound.useUIAudio("sidebar.expand")
+
drawerClasses.remove("hided")
} else {
+ app.cores.sound.useUIAudio("sidebar.collapse")
+
drawerClasses.add("hided")
}
}
@@ -226,10 +230,10 @@ export default class SidedrawerController extends React.Component {
return
{this.state.drawers}
diff --git a/packages/app/src/cores/notifications/index.jsx b/packages/app/src/cores/notifications/index.jsx
index 2cfb2213..096f8e8a 100755
--- a/packages/app/src/cores/notifications/index.jsx
+++ b/packages/app/src/cores/notifications/index.jsx
@@ -7,7 +7,7 @@ import { Haptics } from "@capacitor/haptics"
export default class NotificationCore extends Core {
static refName = "notifications"
-
+
onEvents = {
"changeNotificationsSoundVolume": (value) => {
this.playAudio({ soundVolume: value })
@@ -117,8 +117,8 @@ export default class NotificationCore extends Core {
const soundVolume = options.soundVolume ? options.soundVolume / 100 : this.getSoundVolume()
if (soundEnabled) {
- if (typeof window.app.sound?.play === "function") {
- window.app.sound.play("notification", {
+ if (typeof window.app.cores.sound?.play === "function") {
+ window.app.cores.sound.play("notification", {
volume: soundVolume,
})
}
diff --git a/packages/app/src/cores/sound/index.js b/packages/app/src/cores/sound/index.js
index 5a22e91a..d0798911 100755
--- a/packages/app/src/cores/sound/index.js
+++ b/packages/app/src/cores/sound/index.js
@@ -12,22 +12,40 @@ export default class SoundCore extends Core {
soundsPool = {}
public = {
- play: this.play,
- getSounds: this.getSounds,
+ play: this.play.bind(this),
+ loadSoundpack: this.loadSoundpack.bind(this),
+ useUIAudio: function (audio_id) {
+ try {
+ if (window.app.cores.settings.is("ui.effects", true)) {
+ this.play(audio_id)
+ }
+ } catch (error) {
+ console.error(error)
+ }
+ }.bind(this)
}
- async initialize() {
+ listenEvents = {
+ "change:app.general_ui_volume": (volume) => {
+ // play a sound to test volume
+ this.play("test", {
+ volume: volume / 100,
+ })
+ }
+ }
+
+ async loadSoundpack(manifest) {
let soundpack = config.defaultSoundPack ?? {}
- const storedCustomSoundpack = store.get("soundpack_manifest")
+ const storedCustomSoundpack = manifest ?? store.get("soundpack_manifest")
if (storedCustomSoundpack) {
// check if is valid url with regex
const urlRegex = /^(ftp|http|https):\/\/[^ "]+$/;
-
+
if (urlRegex.test(storedCustomSoundpack)) {
- // load with axios
- const { data } = await axios.get(storedCustomSoundpack)
+ // load with axios
+ const { data } = await axios.get(storedCustomSoundpack)
soundpack = data
} else {
@@ -36,26 +54,66 @@ export default class SoundCore extends Core {
}
}
- for (const [name, path] of Object.entries(soundpack)) {
+ if (typeof soundpack.sounds !== "object") {
+ console.error(`Soundpack [${soundpack.id}] is not a valid soundpack.`)
+ return false
+ }
+
+ console.log(`Loading soundpack [${soundpack.id} | ${soundpack.name}] by ${soundpack.author} (${soundpack.version})`)
+
+ for (const [name, path] of Object.entries(soundpack.sounds)) {
this.soundsPool[name] = new Howl({
- volume: window.app.cores.settings.get("generalAudioVolume") ?? 0.5,
+ volume: 0.5,
src: [path],
})
}
-
- console.log(this.soundsPool)
}
- async play(name, options) {
- if (this.soundsPool[name]) {
- return new Howl({
- volume: window.app.cores.settings.get("generalAudioVolume") ?? 0.5,
- ...options,
- src: [soundPack[name]],
- }).play()
- } else {
+ async injectUseUIAudio() {
+ const injectOnButtons = (event) => {
+ // search for closest button
+ const button = event.target.closest("button")
+
+ // if button exist and has aria-checked attribute then play switch_on or switch_off
+ if (button) {
+ if (button.hasAttribute("aria-checked")) {
+ return this.public.useUIAudio(button.getAttribute("aria-checked") === "true" ? "component.slider_down" : "component.slider_up")
+ }
+
+ return this.public.useUIAudio("generic_click")
+ }
+ }
+
+ document.addEventListener("click", (event) => {
+ injectOnButtons(event)
+ }, true)
+ }
+
+ async play(name, options = {}) {
+ const audioInstance = this.soundsPool[name]
+
+ if (!audioInstance) {
console.error(`Sound [${name}] not found or is not available.`)
return false
}
+
+ if (typeof options.volume !== "undefined") {
+ audioInstance.volume(options.volume)
+ } else {
+ audioInstance.volume((window.app.cores.settings.get("ui.general_volume") ?? 0) / 100)
+ }
+
+ audioInstance.play()
+ }
+
+ async onInitialize() {
+ await this.loadSoundpack()
+
+ // listen eventBus
+ for (const [eventName, callback] of Object.entries(this.listenEvents)) {
+ window.app.eventBus.on(eventName, callback)
+ }
+
+ this.injectUseUIAudio()
}
}
\ No newline at end of file
diff --git a/packages/app/src/pages/settings/index.jsx b/packages/app/src/pages/settings/index.jsx
index 5f441613..acd2086e 100755
--- a/packages/app/src/pages/settings/index.jsx
+++ b/packages/app/src/pages/settings/index.jsx
@@ -551,6 +551,8 @@ export default () => {
return menuEvents[event.key]()
}
+ app.cores.sound.useUIAudio("navigation")
+
setActiveKey(event.key)
}