2020-10-20 23:25:34 +02:00
/ * *
* @ name NotificationSounds
2021-03-05 13:26:41 +01:00
* @ author DevilBro
2020-10-20 23:25:34 +02:00
* @ authorId 278543574059057154
2022-04-08 11:32:42 +02:00
* @ version 3.7 . 0
2022-03-21 22:38:32 +01:00
* @ description Allows you to replace the native Sounds with custom Sounds
2020-10-20 23:25:34 +02:00
* @ invite Jx3TjNS
* @ donate https : //www.paypal.me/MircoWittrien
* @ patreon https : //www.patreon.com/MircoWittrien
2021-03-09 15:10:55 +01:00
* @ website https : //mwittrien.github.io/
* @ source https : //github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/NotificationSounds/
2021-03-10 09:17:37 +01:00
* @ updateUrl https : //mwittrien.github.io/BetterDiscordAddons/Plugins/NotificationSounds/NotificationSounds.plugin.js
2020-10-20 23:25:34 +02:00
* /
2018-10-11 10:21:26 +02:00
2020-09-19 20:49:33 +02:00
module . exports = ( _ => {
2020-10-09 21:09:35 +02:00
const config = {
2020-09-19 20:49:33 +02:00
"info" : {
"name" : "NotificationSounds" ,
"author" : "DevilBro" ,
2022-04-08 11:32:42 +02:00
"version" : "3.7.0" ,
2021-03-04 12:26:17 +01:00
"description" : "Allows you to replace the native Sounds with custom Sounds"
2020-03-10 15:58:09 +01:00
}
2020-09-19 20:49:33 +02:00
} ;
2020-11-13 19:47:44 +01:00
2022-02-05 21:14:17 +01:00
return ! window . BDFDB _Global || ( ! window . BDFDB _Global . loaded && ! window . BDFDB _Global . started ) ? class {
2021-01-06 12:38:36 +01:00
getName ( ) { return config . info . name ; }
getAuthor ( ) { return config . info . author ; }
getVersion ( ) { return config . info . version ; }
2021-02-01 17:13:13 +01:00
getDescription ( ) { return ` The Library Plugin needed for ${ config . info . name } is missing. Open the Plugin Settings to download it. \n \n ${ config . info . description } ` ; }
downloadLibrary ( ) {
require ( "request" ) . get ( "https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js" , ( e , r , b ) => {
2021-03-05 13:14:18 +01:00
if ( ! e && b && r . statusCode == 200 ) require ( "fs" ) . writeFile ( require ( "path" ) . join ( BdApi . Plugins . folder , "0BDFDB.plugin.js" ) , b , _ => BdApi . showToast ( "Finished downloading BDFDB Library" , { type : "success" } ) ) ;
2021-03-06 14:59:48 +01:00
else BdApi . alert ( "Error" , "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library" ) ;
2021-02-01 17:13:13 +01:00
} ) ;
}
2020-07-07 21:03:57 +02:00
2021-01-06 12:38:36 +01:00
load ( ) {
2020-11-19 16:51:14 +01:00
if ( ! window . BDFDB _Global || ! Array . isArray ( window . BDFDB _Global . pluginQueue ) ) window . BDFDB _Global = Object . assign ( { } , window . BDFDB _Global , { pluginQueue : [ ] } ) ;
2020-09-19 20:49:33 +02:00
if ( ! window . BDFDB _Global . downloadModal ) {
window . BDFDB _Global . downloadModal = true ;
2021-01-14 16:14:44 +01:00
BdApi . showConfirmationModal ( "Library Missing" , ` The Library Plugin needed for ${ config . info . name } is missing. Please click "Download Now" to install it. ` , {
2020-09-19 20:49:33 +02:00
confirmText : "Download Now" ,
cancelText : "Cancel" ,
onCancel : _ => { delete window . BDFDB _Global . downloadModal ; } ,
2020-09-20 08:15:13 +02:00
onConfirm : _ => {
delete window . BDFDB _Global . downloadModal ;
2021-02-01 17:13:13 +01:00
this . downloadLibrary ( ) ;
2020-09-20 08:15:13 +02:00
}
2020-09-19 20:49:33 +02:00
} ) ;
2020-03-10 15:58:09 +01:00
}
2020-09-19 20:49:33 +02:00
if ( ! window . BDFDB _Global . pluginQueue . includes ( config . info . name ) ) window . BDFDB _Global . pluginQueue . push ( config . info . name ) ;
2020-10-09 21:09:35 +02:00
}
2021-01-06 12:38:36 +01:00
start ( ) { this . load ( ) ; }
stop ( ) { }
getSettingsPanel ( ) {
2020-11-28 23:12:09 +01:00
let template = document . createElement ( "template" ) ;
2021-01-14 16:14:44 +01:00
template . innerHTML = ` <div style="color: var(--header-primary); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${ config . info . name } is missing. \n Please click <a style="font-weight: 500;">Download Now</a> to install it.</div> ` ;
2021-02-01 17:13:13 +01:00
template . content . firstElementChild . querySelector ( "a" ) . addEventListener ( "click" , this . downloadLibrary ) ;
2020-11-28 23:12:09 +01:00
return template . content . firstElementChild ;
}
2020-10-09 21:09:35 +02:00
} : ( ( [ Plugin , BDFDB ] ) => {
2020-10-06 11:30:21 +02:00
var audios , choices , firedEvents ;
2020-11-11 00:36:02 +01:00
var volumes = { } ;
2020-10-06 11:30:21 +02:00
2020-09-19 20:49:33 +02:00
const removeAllKey = "REMOVE_ALL_BDFDB_DEVILBRO_DO_NOT_COPY" ;
2020-10-06 11:30:21 +02:00
const defaultDevice = "default" ;
var currentDevice = defaultDevice , createdAudios = { } , repatchIncoming ;
2020-09-19 20:49:33 +02:00
2021-07-02 23:29:38 +02:00
let types = { } ;
2021-06-09 17:52:32 +02:00
2021-07-02 23:29:38 +02:00
const message1Types = {
2021-08-27 13:07:03 +02:00
dm : { src : "./message3.mp3" , name : "Message (Direct Message)" , force : null , focus : true } ,
2022-02-12 20:49:00 +01:00
groupdm : { src : "./message3.mp3" , name : "Message (Group Message)" , force : null , focus : true } ,
2021-08-27 13:07:03 +02:00
mentioned : { src : "./message2.mp3" , name : "Message Mentioned" , force : false , focus : true } ,
reply : { src : "./message2.mp3" , name : "Message Mentioned (reply)" , force : false , focus : true } ,
role : { src : "./mention1.mp3" , name : "Message Mentioned (role)" , force : false , focus : true } ,
everyone : { src : "./mention2.mp3" , name : "Message Mentioned (@everyone)" , force : false , focus : true } ,
here : { src : "./mention3.mp3" , name : "Message Mentioned (@here)" , force : false , focus : true }
2020-09-19 20:49:33 +02:00
} ;
2021-07-02 23:29:38 +02:00
2020-09-19 20:49:33 +02:00
const defaultAudios = {
"---" : {
2021-07-02 23:29:38 +02:00
"---" : null
2020-09-19 20:49:33 +02:00
} ,
"Discord" : { }
} ;
2020-10-06 11:30:21 +02:00
const WebAudioSound = class WebAudioSound {
constructor ( type ) {
this . _name = type ;
2020-10-06 23:53:08 +02:00
this . _src = audios [ choices [ type ] . category ] [ choices [ type ] . sound ] || types [ type ] . src ;
2020-10-06 11:30:21 +02:00
this . _volume = choices [ type ] . volume ;
}
2021-01-06 12:38:36 +01:00
loop ( ) {
2020-10-06 11:30:21 +02:00
this . _ensureAudio ( ) . then ( audio => {
audio . loop = true ;
audio . play ( ) ;
} ) ;
}
2021-01-06 12:38:36 +01:00
play ( ) {
2020-10-06 11:30:21 +02:00
this . _ensureAudio ( ) . then ( audio => {
audio . loop = false ;
audio . play ( ) ;
} ) ;
}
2021-01-06 12:38:36 +01:00
pause ( ) {
2020-10-06 11:30:21 +02:00
this . _audio . then ( audio => {
audio . pause ( ) ;
} ) ;
}
2021-01-06 12:38:36 +01:00
stop ( ) {
2020-10-06 11:30:21 +02:00
this . _destroyAudio ( ) ;
}
setTime ( time ) {
this . _audio . then ( audio => {
audio . currentTime = time ;
} ) ;
}
setLoop ( loop ) {
this . _audio . then ( audio => {
audio . loop = loop ;
} ) ;
}
2021-01-06 12:38:36 +01:00
_destroyAudio ( ) {
2020-10-06 11:30:21 +02:00
if ( this . _audio ) {
this . _audio . then ( audio => {
audio . pause ( ) ;
audio . src = "" ;
} ) ;
this . _audio = null ;
}
}
2021-01-06 12:38:36 +01:00
_ensureAudio ( ) {
2020-10-06 11:30:21 +02:00
return this . _audio = this . _audio || new Promise ( ( callback , errorCallback ) => {
let audio = new Audio ;
2020-11-22 15:12:40 +01:00
audio . src = this . _src && this . _src . startsWith ( "data" ) ? this . _src . replace ( / /g , "" ) : this . _src ;
2020-10-06 11:30:21 +02:00
audio . onloadeddata = _ => {
2020-11-11 00:36:02 +01:00
audio . volume = Math . min ( ( BDFDB . LibraryModules . MediaDeviceUtils . getOutputVolume ( ) / 100 ) * ( this . _volume / 100 ) * ( volumes . globalVolume / 100 ) , 1 ) ;
2020-10-06 11:30:21 +02:00
BDFDB . LibraryModules . PlatformUtils . embedded && audio . setSinkId ( currentDevice || defaultDevice ) ;
callback ( audio ) ;
} ;
2021-08-27 13:07:03 +02:00
audio . onerror = _ => errorCallback ( new Error ( "could not play audio" ) ) ;
audio . onended = _ => this . _destroyAudio ( ) ;
2020-10-06 11:30:21 +02:00
audio . load ( ) ;
} ) , this . _audio ;
}
} ;
2020-09-19 20:49:33 +02:00
2020-10-09 21:09:35 +02:00
return class NotificationSounds extends Plugin {
2021-01-06 12:38:36 +01:00
onLoad ( ) {
2020-09-19 20:49:33 +02:00
audios = { } ;
choices = { } ;
firedEvents = { } ;
2020-03-10 15:58:09 +01:00
2020-11-11 00:36:02 +01:00
this . defaults = {
volumes : {
2020-11-19 16:51:14 +01:00
globalVolume : { value : 100 , description : "Global Notification Sounds Volume" }
2020-11-11 00:36:02 +01:00
}
} ;
2021-04-09 18:13:38 +02:00
this . patchPriority = 9 ;
2021-07-02 23:29:38 +02:00
const soundKeys = BDFDB . LibraryModules . SoundParser . keys ( ) ;
for ( let key of soundKeys ) {
const id = key . replace ( "./" , "" ) . replace ( ".mp3" , "" ) ;
const name = id == "reconnect" ? "Invited To Speak" : id . replace ( "ddr-" , "HotKeys_" ) . replace ( "ptt_" , "Push2Talk_" ) . split ( "_" ) . map ( BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ) . join ( " " ) . replace ( /1$/g , "" ) ;
const src = BDFDB . LibraryModules . SoundParser ( key ) ;
let soundPackName = id . split ( "_" ) [ 0 ] ;
if ( soundPackName != id && soundKeys . filter ( n => n . indexOf ( ` ./ ${ soundPackName } ` ) > - 1 ) . length > 10 ) {
soundPackName = BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( soundPackName ) ;
if ( ! defaultAudios [ soundPackName ] ) defaultAudios [ soundPackName ] = { } ;
defaultAudios [ soundPackName ] [ name . replace ( new RegExp ( ` ${ soundPackName } ` , "i" ) , "" ) . replace ( /bootup/i , "Discodo" ) ] = src ;
}
else {
defaultAudios . Discord [ name ] = src ;
if ( this . isSoundUsedAnywhere ( id ) ) types [ id ] = {
name : name ,
src : src ,
mute : id . startsWith ( "call_" ) ? null : false ,
2022-03-09 09:39:03 +01:00
force : id == "message1" ? false : null ,
2022-03-08 13:34:15 +01:00
focus : id == "message1" ? true : false
2021-07-02 23:29:38 +02:00
} ;
if ( id == "message1" ) {
types [ id ] . mute = true ;
for ( let subType in message1Types ) types [ subType ] = {
name : message1Types [ subType ] . name ,
src : BDFDB . LibraryModules . SoundParser ( message1Types [ subType ] . src ) ,
mute : true ,
2021-08-27 13:07:03 +02:00
force : message1Types [ subType ] . force ,
focus : message1Types [ subType ] . focus
2021-07-02 23:29:38 +02:00
}
}
}
types = BDFDB . ObjectUtils . sort ( types , "name" ) ;
}
for ( let pack in defaultAudios ) defaultAudios [ pack ] = BDFDB . ObjectUtils . sort ( defaultAudios [ pack ] ) ;
2020-09-19 20:49:33 +02:00
}
2021-01-06 12:38:36 +01:00
onStart ( ) {
2020-10-06 11:30:21 +02:00
if ( BDFDB . LibraryModules . PlatformUtils . embedded ) {
let change = _ => {
if ( window . navigator . mediaDevices && window . navigator . mediaDevices . enumerateDevices ) {
window . navigator . mediaDevices . enumerateDevices ( ) . then ( enumeratedDevices => {
let id = BDFDB . LibraryModules . MediaDeviceUtils . getOutputDeviceId ( ) ;
let allDevices = BDFDB . LibraryModules . MediaDeviceUtils . getOutputDevices ( ) ;
let filteredDevices = enumeratedDevices . filter ( d => d . kind == "audiooutput" && d . deviceId != "communications" ) ;
let deviceIndex = BDFDB . LibraryModules . ArrayUtils ( allDevices ) . sortBy ( d => d . index ) . findIndex ( d => d . id == id ) ;
let deviceViaId = allDevices [ id ] ;
let deviceViaIndex = filteredDevices [ deviceIndex ] ;
if ( deviceViaId && deviceViaIndex && deviceViaIndex . label != deviceViaId . name ) deviceViaIndex = filteredDevices . find ( d => d . label == deviceViaId . name ) ;
currentDevice = deviceViaIndex ? deviceViaIndex . deviceId : defaultDevice ;
} ) . catch ( _ => {
currentDevice = defaultDevice ;
} ) ;
}
} ;
BDFDB . StoreChangeUtils . add ( this , BDFDB . LibraryModules . MediaDeviceUtils , change ) ;
change ( ) ;
}
2020-09-11 19:31:36 +02:00
BDFDB . PatchUtils . patch ( this , BDFDB . LibraryModules . DispatchApiUtils , "dirtyDispatch" , { before : e => {
2020-03-10 15:58:09 +01:00
if ( BDFDB . ObjectUtils . is ( e . methodArguments [ 0 ] ) && e . methodArguments [ 0 ] . type == BDFDB . DiscordConstants . ActionTypes . MESSAGE _CREATE && e . methodArguments [ 0 ] . message ) {
2021-08-27 13:07:03 +02:00
const message = e . methodArguments [ 0 ] . message ;
const guildId = message . guild _id || null ;
if ( message . author . id != BDFDB . UserUtils . me . id && ! BDFDB . LibraryModules . RelationshipStore . isBlocked ( message . author . id ) ) {
2022-02-12 20:49:00 +01:00
const channel = BDFDB . LibraryModules . ChannelStore . getChannel ( message . channel _id ) ;
const isGroupDM = channel . isGroupDM ( ) ;
2022-04-08 11:32:42 +02:00
const muted = BDFDB . LibraryModules . MutedUtils . isGuildOrCategoryOrChannelMuted ( guildId , channel . id ) ;
const focused = document . hasFocus ( ) && BDFDB . LibraryModules . LastChannelStore . getChannelId ( ) == channel . id ;
2022-02-12 20:49:00 +01:00
if ( ! guildId && ! muted && ! ( choices [ isGroupDM ? "groupdm" : "dm" ] . focus && focused ) ) {
this . fireEvent ( isGroupDM ? "groupdm" : "dm" ) ;
this . playAudio ( isGroupDM ? "groupdm" : "dm" ) ;
2020-03-24 12:15:03 +01:00
return ;
2020-01-16 17:33:59 +01:00
}
2022-03-09 09:39:03 +01:00
else if ( guildId ) {
2022-04-10 09:07:00 +02:00
if ( BDFDB . LibraryModules . MentionUtils . isRawMessageMentioned ( { rawMessage : message , userId : BDFDB . UserUtils . me . id } ) ) {
2022-04-08 11:32:42 +02:00
if ( message . mentions . length && ! this . isSuppressMentionsEnabled ( guildId , channel . id ) ) for ( const mention of message . mentions ) if ( mention . id == BDFDB . UserUtils . me . id ) {
2022-03-15 22:31:19 +01:00
if ( message . message _reference && ! message . interaction && ( ! muted || choices . reply . force ) && ! ( choices . reply . focus && focused ) ) {
2022-03-09 09:39:03 +01:00
this . fireEvent ( "reply" ) ;
this . playAudio ( "reply" ) ;
return ;
}
if ( ! message . message _reference && ( ! muted || choices . mentioned . force ) && ! ( choices . mentioned . focus && focused ) ) {
this . fireEvent ( "mentioned" ) ;
this . playAudio ( "mentioned" ) ;
return ;
}
2021-08-27 13:07:03 +02:00
}
2022-04-08 11:32:42 +02:00
if ( message . mention _roles . length && ! BDFDB . LibraryModules . MutedUtils . isSuppressRolesEnabled ( guildId , channel . id ) && ( ! muted || choices . role . force ) && ! ( choices . role . focus && focused ) ) {
2022-03-09 09:39:03 +01:00
const member = BDFDB . LibraryModules . MemberStore . getMember ( guildId , BDFDB . UserUtils . me . id ) ;
if ( member && member . roles . length ) for ( const roleId of message . mention _roles ) if ( member . roles . includes ( roleId ) ) {
this . fireEvent ( "role" ) ;
this . playAudio ( "role" ) ;
return ;
}
2021-08-27 13:07:03 +02:00
}
2022-04-08 11:32:42 +02:00
if ( message . mention _everyone && ! BDFDB . LibraryModules . MutedUtils . isSuppressEveryoneEnabled ( guildId , channel . id ) ) {
2022-03-09 09:39:03 +01:00
if ( message . content . indexOf ( "@everyone" ) > - 1 && ( ! muted || choices . everyone . force ) && ! ( choices . everyone . focus && focused ) ) {
this . fireEvent ( "everyone" ) ;
this . playAudio ( "everyone" ) ;
return ;
}
if ( message . content . indexOf ( "@here" ) > - 1 && ( ! muted || choices . here . force ) && ! ( choices . here . focus && focused ) ) {
this . fireEvent ( "here" ) ;
this . playAudio ( "here" ) ;
return ;
}
2020-03-24 13:52:51 +01:00
}
2020-03-10 15:58:09 +01:00
}
2022-04-08 11:32:42 +02:00
if ( BDFDB . LibraryModules . MutedUtils . allowAllMessages ( channel ) && ( ! muted || choices . message1 . force ) && ! ( choices . message1 . focus && focused ) ) {
2022-03-09 09:39:03 +01:00
this . fireEvent ( "message1" ) ;
this . playAudio ( "message1" ) ;
return ;
2020-03-10 15:58:09 +01:00
}
2020-01-16 17:33:59 +01:00
}
2018-10-11 10:21:26 +02:00
}
}
2020-03-10 15:58:09 +01:00
} } ) ;
2022-02-12 20:49:00 +01:00
2022-02-12 23:28:36 +01:00
BDFDB . PatchUtils . patch ( this , BDFDB . LibraryModules . DesktopNotificationUtils , "showNotification" , { before : e => {
2022-03-17 16:00:06 +01:00
let soundObjIndex = Array . from ( e . methodArguments ) . findIndex ( n => n && n . sound ) ;
if ( soundObjIndex && e . methodArguments [ soundObjIndex ] . sound . includes ( "message" ) ) e . methodArguments [ soundObjIndex ] . sound = null ;
2022-02-12 23:28:36 +01:00
} } ) ;
2020-09-11 19:31:36 +02:00
BDFDB . PatchUtils . patch ( this , BDFDB . LibraryModules . SoundUtils , "playSound" , { instead : e => {
2020-03-10 15:58:09 +01:00
let type = e . methodArguments [ 0 ] ;
2022-03-08 13:34:15 +01:00
if ( type && choices [ type ] ) {
2020-11-13 20:48:55 +01:00
e . stopOriginalMethodCall ( ) ;
2020-11-14 02:10:14 +01:00
BDFDB . TimeUtils . timeout ( _ => {
if ( type == "message1" ) {
2021-06-09 17:52:32 +02:00
let called = false ;
2022-03-08 13:34:15 +01:00
for ( let subType of [ type ] . concat ( Object . keys ( message1Types ) ) ) if ( firedEvents [ subType ] ) {
2021-06-09 17:52:32 +02:00
delete firedEvents [ subType ] ;
called = true ;
break ;
}
if ( ! called ) this . playAudio ( type ) ;
2020-11-14 02:10:14 +01:00
}
2020-03-10 15:58:09 +01:00
else this . playAudio ( type ) ;
2020-11-14 02:10:14 +01:00
} ) ;
}
2020-11-13 20:48:55 +01:00
else e . callOriginalMethodAfterwards ( ) ;
2020-03-10 15:58:09 +01:00
} } ) ;
2020-09-11 19:31:36 +02:00
BDFDB . PatchUtils . patch ( this , BDFDB . LibraryModules . SoundUtils , "createSound" , { after : e => {
2022-03-08 13:34:15 +01:00
let type = e . methodArguments [ 0 ] ;
if ( type && choices [ type ] ) {
let audio = new WebAudioSound ( type ) ;
createdAudios [ type ] = audio ;
2020-10-15 12:54:49 +02:00
return audio ;
}
2022-03-08 13:34:15 +01:00
else BDFDB . LogUtils . warn ( ` Could not create Sound for " ${ type } ". ` , this ) ;
2020-03-10 15:58:09 +01:00
} } ) ;
this . loadAudios ( ) ;
this . loadChoices ( ) ;
2020-05-07 18:23:19 +02:00
let callListenerModule = BDFDB . ModuleUtils . findByProperties ( "handleRingUpdate" ) ;
if ( callListenerModule ) {
callListenerModule . terminate ( ) ;
2020-09-11 19:31:36 +02:00
BDFDB . PatchUtils . patch ( this , callListenerModule , "handleRingUpdate" , { instead : e => {
2020-10-06 11:30:21 +02:00
if ( BDFDB . LibraryModules . CallUtils . getCalls ( ) . filter ( call => call . ringing . length > 0 && BDFDB . LibraryModules . VoiceUtils . getCurrentClientVoiceChannelId ( ) === call . channelId ) . length > 0 && ! BDFDB . LibraryModules . SoundStateUtils . isSoundDisabled ( "call_calling" ) && ! BDFDB . LibraryModules . StreamerModeStore . disableSounds ) {
createdAudios [ "call_calling" ] . loop ( ) ;
}
else createdAudios [ "call_calling" ] . stop ( ) ;
2020-05-07 18:23:19 +02:00
} } ) ;
callListenerModule . initialize ( ) ;
}
2020-05-08 19:59:59 +02:00
this . forceUpdateAll ( ) ;
2020-03-10 15:58:09 +01:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStop ( ) {
2020-10-06 11:30:21 +02:00
for ( let type in createdAudios ) if ( createdAudios [ type ] ) createdAudios [ type ] . stop ( ) ;
2020-03-10 15:58:09 +01:00
}
2018-10-11 10:21:26 +02:00
2021-08-27 13:07:03 +02:00
getSettingsPanel ( collapseStates = { } ) {
2020-09-19 20:49:33 +02:00
let successSavedAudio = data => {
2020-11-19 16:51:14 +01:00
BDFDB . NotificationUtils . toast ( ` Sound ${ data . sound } was added to category ${ data . category } . ` , { type : "success" } ) ;
2020-09-19 20:49:33 +02:00
if ( ! audios [ data . category ] ) audios [ data . category ] = { } ;
2020-10-06 23:53:08 +02:00
audios [ data . category ] [ data . sound ] = data . source ;
2020-09-19 20:49:33 +02:00
BDFDB . DataUtils . save ( audios , this , "audios" ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
} ;
2020-05-08 19:59:59 +02:00
2020-11-23 20:56:13 +01:00
let settingsPanel ;
return settingsPanel = BDFDB . PluginUtils . createSettingsPanel ( this , {
2020-09-19 20:49:33 +02:00
collapseStates : collapseStates ,
2020-11-23 20:56:13 +01:00
children : _ => {
let settingsItems = [ ] ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Settings" ,
collapseStates : collapseStates ,
children : Object . keys ( volumes ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
type : "Slider" ,
plugin : this ,
keys : [ "volumes" , key ] ,
basis : "50%" ,
label : this . defaults . volumes [ key ] . description ,
value : volumes [ key ]
} ) )
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Add new Sound" ,
collapseStates : collapseStates ,
2020-09-19 20:49:33 +02:00
children : [
2020-11-23 20:56:13 +01:00
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . margintop4 ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Categoryname" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
className : "input-newsound input-category" ,
value : "" ,
placeholder : "Categoryname"
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Soundname" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
className : "input-newsound input-sound" ,
value : "" ,
placeholder : "Soundname"
} )
} )
2020-09-19 20:49:33 +02:00
} )
2020-11-23 20:56:13 +01:00
]
2020-09-19 20:49:33 +02:00
} ) ,
2020-11-23 20:56:13 +01:00
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . margintop4 ,
align : BDFDB . LibraryComponents . Flex . Align . END ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Source" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
className : "input-newsound input-source" ,
type : "file" ,
filter : [ "audio" , "video" ] ,
useFilePath : true ,
value : "" ,
placeholder : "Source"
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
style : { marginBottom : 1 } ,
onClick : _ => {
for ( let input of settingsPanel . props . _node . querySelectorAll ( ".input-newsound " + BDFDB . dotCN . input ) ) if ( ! input . value || input . value . length == 0 || input . value . trim ( ) . length == 0 ) return BDFDB . NotificationUtils . toast ( "Fill out all fields to add a new sound" , { type : "danger" } ) ;
let category = settingsPanel . props . _node . querySelector ( ".input-category " + BDFDB . dotCN . input ) . value . trim ( ) ;
let sound = settingsPanel . props . _node . querySelector ( ".input-sound " + BDFDB . dotCN . input ) . value . trim ( ) ;
let source = settingsPanel . props . _node . querySelector ( ".input-source " + BDFDB . dotCN . input ) . value . trim ( ) ;
if ( source . indexOf ( "http" ) == 0 ) BDFDB . LibraryRequires . request ( source , ( error , response , result ) => {
if ( response ) {
let type = response . headers [ "content-type" ] ;
if ( type && ( type . indexOf ( "octet-stream" ) > - 1 || type . indexOf ( "audio" ) > - 1 || type . indexOf ( "video" ) > - 1 ) ) return successSavedAudio ( { category , sound , source } ) ;
}
BDFDB . NotificationUtils . toast ( "Use a valid direct link to a video or audio source, they usually end on something like .mp3, .mp4 or .wav" , { type : "danger" } ) ;
} ) ;
else BDFDB . LibraryRequires . fs . readFile ( source , ( error , response ) => {
if ( error ) BDFDB . NotificationUtils . toast ( "Could not fetch file. Please make sure the file exists" , { type : "danger" } ) ;
else return successSavedAudio ( { category , sound , source : ` data:audio/mpeg;base64, ${ response . toString ( "base64" ) } ` } ) ;
} ) ;
} ,
children : BDFDB . LanguageUtils . LanguageStrings . SAVE
2020-09-19 20:49:33 +02:00
} )
2020-11-23 20:56:13 +01:00
]
2020-09-19 20:49:33 +02:00
} )
]
2020-11-23 20:56:13 +01:00
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2021-05-12 19:59:57 +02:00
title : "Sound Configuration" ,
2020-11-23 20:56:13 +01:00
collapseStates : collapseStates ,
2021-08-27 13:07:03 +02:00
children : Object . keys ( types ) . map ( type => [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
direction : BDFDB . LibraryComponents . Flex . Direction . HORIZONTAL ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsLabel , {
label : types [ type ] . name
} ) ,
types [ type ] . force != null ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Switch" ,
mini : true ,
grow : 0 ,
label : "Force Play" ,
labelChildren : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : "Plays the Sound even if the Channel, the Message was sent in, is muted" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
name : BDFDB . LibraryComponents . SvgIcon . Names . QUESTIONMARK ,
style : { marginLeft : 4 , marginRight : - 2 } ,
width : 14 ,
height : 14
} )
} ) ,
value : choices [ type ] . force ,
onChange : value => {
choices [ type ] . force = value ;
this . saveChoice ( type , false ) ;
}
} ) : null ,
types [ type ] . focus != null ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Switch" ,
mini : true ,
grow : 0 ,
label : "Focus Mute" ,
labelChildren : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : "Does not play the Sound when the Channel, the Message was sent in, is currently opened" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
name : BDFDB . LibraryComponents . SvgIcon . Names . QUESTIONMARK ,
style : { marginLeft : 4 , marginRight : - 2 } ,
width : 14 ,
height : 14
} )
} ) ,
value : choices [ type ] . focus ,
onChange : value => {
choices [ type ] . focus = value ;
this . saveChoice ( type , false ) ;
}
} ) : null ,
types [ type ] . mute !== null && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Switch" ,
mini : true ,
grow : 0 ,
label : "Mute in" ,
labelChildren : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Status , {
style : { marginLeft : 6 } ,
size : 12 ,
status : BDFDB . DiscordConstants . StatusTypes . DND
} ) ,
value : choices [ type ] . mute ,
onChange : value => {
choices [ type ] . mute = value ;
this . saveChoice ( type , false ) ;
}
} )
] . filter ( n => n )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 0 ,
shrink : 0 ,
basis : "31%" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Category" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Select , {
value : choices [ type ] . category ,
options : Object . keys ( audios ) . map ( name => ( { value : name , label : name } ) ) ,
searchable : true ,
onChange : value => {
const categorySounds = audios [ value ] || { } ;
choices [ type ] . category = value ;
choices [ type ] . sound = categorySounds [ types [ type ] . name ] ? types [ type ] . name : Object . keys ( categorySounds ) [ 0 ] ;
this . saveChoice ( type , true ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
}
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 0 ,
shrink : 0 ,
basis : "31%" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Sound" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Select , {
value : choices [ type ] . sound ,
options : Object . keys ( audios [ choices [ type ] . category ] || { } ) . map ( name => ( { value : name , label : name } ) ) ,
searchable : true ,
onChange : value => {
choices [ type ] . sound = value ;
this . saveChoice ( type , true ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
}
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 0 ,
shrink : 0 ,
basis : "31%" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Volume" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Slider , {
defaultValue : choices [ type ] . volume ,
digits : 1 ,
onValueRender : value => {
return value + "%" ;
} ,
onValueChange : value => {
choices [ type ] . volume = value ;
this . saveChoice ( type , true ) ;
}
} )
} )
} )
]
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormDivider , {
className : BDFDB . disCN . marginbottom8
} )
] ) . flat ( 10 ) . filter ( n => n )
2020-11-23 20:56:13 +01:00
} ) ) ;
let removeableCategories = [ { value : removeAllKey , label : BDFDB . LanguageUtils . LanguageStrings . FORM _LABEL _ALL } ] . concat ( Object . keys ( audios ) . filter ( category => ! ( defaultAudios [ category ] && ! Object . keys ( audios [ category ] || { } ) . filter ( sound => defaultAudios [ category ] [ sound ] === undefined ) . length ) ) . map ( name => ( { value : name , label : name } ) ) ) ;
let removeableSounds = { } ;
for ( let category of removeableCategories ) removeableSounds [ category . value ] = [ { value : removeAllKey , label : BDFDB . LanguageUtils . LanguageStrings . FORM _LABEL _ALL } ] . concat ( Object . keys ( audios [ category . value ] || { } ) . filter ( sound => ! ( defaultAudios [ category . value ] && defaultAudios [ category . value ] [ sound ] !== undefined ) ) . map ( name => ( { value : name , label : name } ) ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Remove Sounds" ,
collapseStates : collapseStates ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . margintop4 ,
align : BDFDB . LibraryComponents . Flex . Align . END ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 0 ,
shrink : 0 ,
basis : "35%" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Category" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Select , {
key : "REMOVE_CATEGORY" ,
value : removeAllKey ,
options : removeableCategories ,
searchable : true ,
onChange : ( category , instance ) => {
let soundSelectIns = BDFDB . ReactUtils . findOwner ( BDFDB . ReactUtils . findOwner ( instance , { name : [ "BDFDB_Modal" , "BDFDB_SettingsPanel" ] , up : true } ) , { key : "REMOVE_SOUND" } ) ;
if ( soundSelectIns && removeableSounds [ category . value ] ) {
soundSelectIns . props . options = removeableSounds [ category . value ] ;
soundSelectIns . props . value = removeAllKey ;
BDFDB . ReactUtils . forceUpdate ( soundSelectIns ) ;
}
}
} )
2020-09-19 20:49:33 +02:00
} )
2020-11-23 20:56:13 +01:00
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 0 ,
shrink : 0 ,
basis : "35%" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : "Sound" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Select , {
key : "REMOVE_SOUND" ,
value : removeAllKey ,
options : removeableSounds [ removeAllKey ] ,
searchable : true
} )
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 0 ,
shrink : 1 ,
basis : "25%" ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
style : { marginBottom : 1 } ,
color : BDFDB . LibraryComponents . Button . Colors . RED ,
onClick : ( event , instance ) => {
let wrapperIns = BDFDB . ReactUtils . findOwner ( instance , { name : [ "BDFDB_Modal" , "BDFDB_SettingsPanel" ] , up : true } ) ;
let categorySelectIns = BDFDB . ReactUtils . findOwner ( wrapperIns , { key : "REMOVE_CATEGORY" } ) ;
let soundSelectIns = BDFDB . ReactUtils . findOwner ( wrapperIns , { key : "REMOVE_SOUND" } ) ;
if ( categorySelectIns && soundSelectIns ) {
let soundAmount = 0 ;
let catAll = categorySelectIns . props . value == removeAllKey ;
let soundAll = soundSelectIns . props . value == removeAllKey ;
if ( catAll ) soundAmount = BDFDB . ArrayUtils . sum ( Object . keys ( audios ) . map ( category => Object . keys ( audios [ category ] || { } ) . filter ( sound => ! ( defaultAudios [ category ] && defaultAudios [ category ] [ sound ] !== undefined ) ) . length ) ) ;
else if ( soundAll ) soundAmount = Object . keys ( audios [ categorySelectIns . props . value ] || { } ) . filter ( sound => ! ( defaultAudios [ categorySelectIns . props . value ] && defaultAudios [ categorySelectIns . props . value ] [ sound ] !== undefined ) ) . length ;
else if ( audios [ categorySelectIns . props . value ] [ soundSelectIns . props . value ] ) soundAmount = 1 ;
2021-05-12 19:59:57 +02:00
if ( soundAmount ) BDFDB . ModalUtils . confirm ( this , ` Are you sure you want to delete ${ soundAmount } added Sound ${ soundAmount == 1 ? "" : "s" } ? ` , _ => {
2020-11-23 20:56:13 +01:00
if ( catAll ) BDFDB . DataUtils . remove ( this , "audios" ) ;
else if ( soundAll ) BDFDB . DataUtils . remove ( this , "audios" , categorySelectIns . props . value ) ;
else {
delete audios [ categorySelectIns . props . value ] [ soundSelectIns . props . value ] ;
if ( BDFDB . ObjectUtils . isEmpty ( audios [ categorySelectIns . props . value ] ) ) delete audios [ categorySelectIns . props . value ] ;
BDFDB . DataUtils . save ( audios , this , "audios" ) ;
}
this . loadAudios ( ) ;
this . loadChoices ( ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
} ) ;
2021-05-12 19:59:57 +02:00
else BDFDB . NotificationUtils . toast ( "No Sounds to delete" , { type : "danger" } ) ;
2020-09-19 20:49:33 +02:00
}
2020-11-23 20:56:13 +01:00
} ,
children : BDFDB . LanguageUtils . LanguageStrings . DELETE
} )
} )
]
2020-09-19 20:49:33 +02:00
} )
2020-11-23 20:56:13 +01:00
} ) ) ;
return settingsItems ;
}
} ) ;
2020-09-19 20:49:33 +02:00
}
2021-01-06 12:38:36 +01:00
onSettingsClosed ( ) {
2020-09-19 20:49:33 +02:00
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
2020-10-06 11:30:21 +02:00
for ( let type in createdAudios ) if ( createdAudios [ type ] ) createdAudios [ type ] . stop ( ) ;
createdAudios = { } ;
2020-09-19 20:49:33 +02:00
this . forceUpdateAll ( ) ;
}
2020-05-08 19:59:59 +02:00
}
2020-08-03 18:26:59 +02:00
2021-01-06 12:38:36 +01:00
forceUpdateAll ( ) {
2020-09-19 20:49:33 +02:00
repatchIncoming = true ;
2020-10-06 11:30:21 +02:00
createdAudios [ "call_calling" ] = BDFDB . LibraryModules . SoundUtils . createSound ( "call_calling" ) ;
2020-11-11 00:36:02 +01:00
volumes = BDFDB . DataUtils . get ( this , "volumes" ) ;
2020-09-19 20:49:33 +02:00
BDFDB . PatchUtils . forceAllUpdates ( this ) ;
2021-02-04 15:24:56 +01:00
BDFDB . DiscordUtils . rerenderAll ( ) ;
2020-03-10 15:58:09 +01:00
}
2020-05-30 20:03:50 +02:00
2021-01-06 12:38:36 +01:00
loadAudios ( ) {
2020-11-12 17:48:14 +01:00
audios = Object . assign ( { } , BDFDB . DataUtils . load ( this , "audios" ) , defaultAudios ) ;
BDFDB . DataUtils . save ( BDFDB . ObjectUtils . exclude ( audios , Object . keys ( defaultAudios ) ) , this , "audios" ) ;
2020-09-19 20:49:33 +02:00
}
2019-01-26 22:45:19 +01:00
2021-01-06 12:38:36 +01:00
loadChoices ( ) {
2020-09-19 20:49:33 +02:00
let loadedChoices = BDFDB . DataUtils . load ( this , "choices" ) ;
for ( let type in types ) {
2020-10-06 23:53:08 +02:00
let choice = loadedChoices [ type ] || { } , soundFound = false ;
for ( let category in audios ) if ( choice . category == category ) for ( let sound in audios [ category ] ) if ( choice . sound == sound ) {
soundFound = true ;
2020-09-19 20:49:33 +02:00
break ;
}
2020-10-06 23:53:08 +02:00
if ( ! soundFound ) choice = {
2020-09-19 20:49:33 +02:00
category : "---" ,
2020-10-06 23:53:08 +02:00
sound : "---" ,
2020-09-19 20:49:33 +02:00
volume : 100 ,
mute : types [ type ] . mute ,
focus : types [ type ] . focus
} ;
choices [ type ] = choice ;
this . saveChoice ( type , false ) ;
2020-03-10 15:58:09 +01:00
}
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
saveChoice ( type , play ) {
if ( ! choices [ type ] ) return ;
BDFDB . DataUtils . save ( choices [ type ] , this , "choices" , type ) ;
if ( play ) {
this . SettingsUpdated = true ;
2020-10-06 11:30:21 +02:00
this . playAudio ( type ) ;
2020-09-19 20:49:33 +02:00
}
2020-03-10 15:58:09 +01:00
}
2019-01-26 22:45:19 +01:00
2020-10-06 11:30:21 +02:00
playAudio ( type ) {
if ( this . dontPlayAudio ( type ) || BDFDB . LibraryModules . StreamerModeStore . disableSounds ) return ;
if ( createdAudios [ type ] ) createdAudios [ type ] . stop ( ) ;
createdAudios [ type ] = new WebAudioSound ( type ) ;
createdAudios [ type ] . play ( ) ;
2020-03-10 15:58:09 +01:00
}
2022-04-08 11:32:42 +02:00
2022-03-09 09:39:03 +01:00
isSuppressMentionsEnabled ( guildId , channelId ) {
2020-09-19 20:49:33 +02:00
let channelSettings = BDFDB . LibraryModules . MutedUtils . getChannelMessageNotifications ( guildId , channelId ) ;
return channelSettings && ( channelSettings == BDFDB . DiscordConstants . UserNotificationSettings . NO _MESSAGES || channelSettings == BDFDB . DiscordConstants . UserNotificationSettings . NULL && BDFDB . LibraryModules . MutedUtils . getMessageNotifications ( guildId ) == BDFDB . DiscordConstants . UserNotificationSettings . NO _MESSAGES ) ;
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
dontPlayAudio ( type ) {
let status = BDFDB . UserUtils . getStatus ( ) ;
return choices [ type ] . mute && ( status == "dnd" || status == "streaming" ) ;
}
2020-07-26 17:02:25 +02:00
2020-09-19 20:49:33 +02:00
fireEvent ( type ) {
firedEvents [ type ] = true ;
2021-06-09 17:52:32 +02:00
BDFDB . TimeUtils . timeout ( _ => delete firedEvents [ type ] , 3000 ) ;
2020-09-19 20:49:33 +02:00
}
2021-07-02 23:29:38 +02:00
isSoundUsedAnywhere ( type ) {
return type != "human_man" && type != "robot_man" && type != "discodo" && type != "overlayunlock" && type != "call_ringing_beat" && ! ( type != "message1" && /\d$/ . test ( type ) ) ;
}
2020-09-19 20:49:33 +02:00
} ;
2020-10-09 21:09:35 +02:00
} ) ( window . BDFDB _Global . PluginUtils . buildPlugin ( config ) ) ;
2020-11-14 02:10:14 +01:00
} ) ( ) ;