added UI effects

This commit is contained in:
SrGooglo 2023-04-03 16:21:29 +00:00
parent 16becabc23
commit 4434e8c1d0
9 changed files with 137 additions and 34 deletions

View File

@ -1,6 +1,7 @@
{ {
"themeVariant": "dark",
"forceMobileMode": false, "forceMobileMode": false,
"ui.effects": true,
"ui.general_volume": 50,
"notifications_sound": true, "notifications_sound": true,
"notifications_vibrate": true, "notifications_vibrate": true,
"notifications_sound_volume": 50, "notifications_sound_volume": 50,
@ -10,11 +11,8 @@
"haptic_feedback": false, "haptic_feedback": false,
"collapseOnLooseFocus": true, "collapseOnLooseFocus": true,
"style.auto_darkMode": true, "style.auto_darkMode": true,
"compactWidth": false,
"postCard_carrusel_auto": true,
"postCard_expansible_actions": true,
"feed_max_fetch": 20, "feed_max_fetch": 20,
"style.compactMode": false, "style.compactMode": false,
"sidebar.floating": true, "sidebar.floating": false,
"language": "en" "language": "en"
} }

View File

@ -1,5 +1,11 @@
{ {
"crash": "/sounds/crash.wav", "id": "default",
"error": "/sounds/error.wav", "name": "Default Soundpack",
"notification": "/sounds/notification.wav" "author": "RageStudio",
"version": "1.0.0",
"sounds": {
"crash": "/sounds/crash.wav",
"error": "/sounds/error.wav",
"notification": "/sounds/notification.wav"
}
} }

View File

@ -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.", "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" "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", "id": "notifications_sound",
"storaged": true, "storaged": true,

View File

@ -202,6 +202,8 @@ class ComtyApp extends React.Component {
}) })
}, },
openSearcher: (options) => { openSearcher: (options) => {
app.cores.sound.useUIAudio("navigation.search")
window.app.ModalController.open((props) => <Searcher {...props} />) window.app.ModalController.open((props) => <Searcher {...props} />)
}, },
openNavigationMenu: () => window.app.DrawerController.open("navigation", Navigation), openNavigationMenu: () => window.app.DrawerController.open("navigation", Navigation),
@ -252,6 +254,8 @@ class ComtyApp extends React.Component {
return app.setLocation(config.app.mainPath ?? "/home") return app.setLocation(config.app.mainPath ?? "/home")
}, },
goToSettings: (setting_id) => { goToSettings: (setting_id) => {
app.cores.sound.useUIAudio("navigation.settings")
return app.setLocation(`/settings`, { return app.setLocation(`/settings`, {
query: { query: {
setting: setting_id setting: setting_id
@ -484,6 +488,8 @@ class ComtyApp extends React.Component {
}) })
} }
//app.cores.sound.useUIAudio("splash_out")
app.eventBus.emit("app.initialization.start") app.eventBus.emit("app.initialization.start")
await this.initialization() await this.initialization()

View File

@ -274,6 +274,8 @@ export default class Sidebar extends React.Component {
return onClickHandlers[e.key](e) return onClickHandlers[e.key](e)
} }
window.app.cores.sound.useUIAudio("sidebar.switch_tab")
if (typeof this.state.pathResolvers === "object") { if (typeof this.state.pathResolvers === "object") {
if (typeof this.state.pathResolvers[e.key] !== "undefined") { if (typeof this.state.pathResolvers[e.key] !== "undefined") {
return window.app.setLocation(`/${this.state.pathResolvers[e.key]}`, 150) return window.app.setLocation(`/${this.state.pathResolvers[e.key]}`, 150)

View File

@ -153,8 +153,12 @@ export default class SidedrawerController extends React.Component {
const drawerClasses = drawer.classList const drawerClasses = drawer.classList
if (to) { if (to) {
app.cores.sound.useUIAudio("sidebar.expand")
drawerClasses.remove("hided") drawerClasses.remove("hided")
} else { } else {
app.cores.sound.useUIAudio("sidebar.collapse")
drawerClasses.add("hided") drawerClasses.add("hided")
} }
} }
@ -226,10 +230,10 @@ export default class SidedrawerController extends React.Component {
return <div return <div
className={classnames( className={classnames(
"sidedrawers-wrapper", "sidedrawers-wrapper",
{ {
["floating-sidebar"]: window.app?.cores.settings.get("sidebar.floating") ["floating-sidebar"]: window.app?.cores.settings.get("sidebar.floating")
} }
)} )}
> >
{this.state.drawers} {this.state.drawers}
</div> </div>

View File

@ -7,7 +7,7 @@ import { Haptics } from "@capacitor/haptics"
export default class NotificationCore extends Core { export default class NotificationCore extends Core {
static refName = "notifications" static refName = "notifications"
onEvents = { onEvents = {
"changeNotificationsSoundVolume": (value) => { "changeNotificationsSoundVolume": (value) => {
this.playAudio({ soundVolume: value }) this.playAudio({ soundVolume: value })
@ -117,8 +117,8 @@ export default class NotificationCore extends Core {
const soundVolume = options.soundVolume ? options.soundVolume / 100 : this.getSoundVolume() const soundVolume = options.soundVolume ? options.soundVolume / 100 : this.getSoundVolume()
if (soundEnabled) { if (soundEnabled) {
if (typeof window.app.sound?.play === "function") { if (typeof window.app.cores.sound?.play === "function") {
window.app.sound.play("notification", { window.app.cores.sound.play("notification", {
volume: soundVolume, volume: soundVolume,
}) })
} }

View File

@ -12,22 +12,40 @@ export default class SoundCore extends Core {
soundsPool = {} soundsPool = {}
public = { public = {
play: this.play, play: this.play.bind(this),
getSounds: this.getSounds, 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 ?? {} let soundpack = config.defaultSoundPack ?? {}
const storedCustomSoundpack = store.get("soundpack_manifest") const storedCustomSoundpack = manifest ?? store.get("soundpack_manifest")
if (storedCustomSoundpack) { if (storedCustomSoundpack) {
// check if is valid url with regex // check if is valid url with regex
const urlRegex = /^(ftp|http|https):\/\/[^ "]+$/; const urlRegex = /^(ftp|http|https):\/\/[^ "]+$/;
if (urlRegex.test(storedCustomSoundpack)) { if (urlRegex.test(storedCustomSoundpack)) {
// load with axios // load with axios
const { data } = await axios.get(storedCustomSoundpack) const { data } = await axios.get(storedCustomSoundpack)
soundpack = data soundpack = data
} else { } 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({ this.soundsPool[name] = new Howl({
volume: window.app.cores.settings.get("generalAudioVolume") ?? 0.5, volume: 0.5,
src: [path], src: [path],
}) })
} }
console.log(this.soundsPool)
} }
async play(name, options) { async injectUseUIAudio() {
if (this.soundsPool[name]) { const injectOnButtons = (event) => {
return new Howl({ // search for closest button
volume: window.app.cores.settings.get("generalAudioVolume") ?? 0.5, const button = event.target.closest("button")
...options,
src: [soundPack[name]], // if button exist and has aria-checked attribute then play switch_on or switch_off
}).play() if (button) {
} else { 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.`) console.error(`Sound [${name}] not found or is not available.`)
return false 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()
} }
} }

View File

@ -551,6 +551,8 @@ export default () => {
return menuEvents[event.key]() return menuEvents[event.key]()
} }
app.cores.sound.useUIAudio("navigation")
setActiveKey(event.key) setActiveKey(event.key)
} }