This commit is contained in:
poslop
2024-04-30 15:32:45 -05:00
parent a21e33aeb6
commit 7d153f28e0
23 changed files with 1781 additions and 1490 deletions

View File

@@ -2,7 +2,7 @@
* @name NotificationSounds
* @author DevilBro
* @authorId 278543574059057154
* @version 3.7.8
* @version 3.9.2
* @description Allows you to replace the native Sounds with custom Sounds
* @invite Jx3TjNS
* @donate https://www.paypal.me/MircoWittrien
@@ -14,7 +14,12 @@
module.exports = (_ => {
const changeLog = {
"added": {
"Current Channel": "Added Option to change the sound for the current channel notification, (note: Discord added an option in the THEIR notification settings to play a different sound when a message is sent in the current channel, you need to have this enabled in order to be able to change the sound in the plugin settings"
},
"fixed": {
"Current Channel": "No longer plays notification sounds for current channels, if the option is disabled"
}
};
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
@@ -25,9 +30,14 @@ module.exports = (_ => {
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
downloadLibrary () {
require("request").get("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js", (e, r, b) => {
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"}));
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");
BdApi.Net.fetch("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js").then(r => {
if (!r || r.status != 200) throw new Error();
else return r.text();
}).then(b => {
if (!b) throw new Error();
else return require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.showToast("Finished downloading BDFDB Library", {type: "success"}));
}).catch(error => {
BdApi.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
});
}
@@ -67,13 +77,24 @@ module.exports = (_ => {
let types = {};
const message1Types = {
dm: {src: "./message3.mp3", name: "Message (Direct Message)", force: null, focus: true},
groupdm: {src: "./message3.mp3", name: "Message (Group Message)", force: null, focus: true},
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}
dm: {src: "./message3.mp3", name: "Message (Direct Message)"},
groupdm: {src: "./message3.mp3", name: "Message (Group Message)"},
mentioned: {src: "./message2.mp3", name: "Message Mentioned"},
reply: {src: "./message2.mp3", name: "Message Mentioned (reply)"},
role: {src: "./mention1.mp3", name: "Message Mentioned (role)"},
everyone: {src: "./mention2.mp3", name: "Message Mentioned (@everyone)"},
here: {src: "./mention3.mp3", name: "Message Mentioned (@here)"}
};
const namePrefixes = {
"user_join": "Voice Channel",
"user_leave": "Voice Channel",
"user_moved": "Voice Channel"
};
const nameSynonymes = {
"message3": "Message (Current Channel)",
"reconnect": "Invited To Speak"
};
const defaultAudios = {
@@ -101,6 +122,16 @@ module.exports = (_ => {
audio.play();
});
}
playWithListener (duration) {
return new Promise((callback, errorCallback) => {
this._ensureAudio().then(audio => {
if (!duration && duration !== 0) errorCallback(new Error("sound has no duration"));
audio.loop = false;
audio.play();
setTimeout(_ => callback(true), duration);
});
});
}
pause () {
this._audio.then(audio => {
audio.pause();
@@ -152,7 +183,7 @@ module.exports = (_ => {
this.defaults = {
volumes: {
globalVolume: {value: 100, description: "Global Notification Sounds Volume"}
globalVolume: {value: 100, description: "Global Notification Sounds Volume"}
}
};
@@ -163,7 +194,7 @@ module.exports = (_ => {
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.StringUtils.upperCaseFirstChar).join(" ").replace(/1$/g, "");
const name = [namePrefixes[id], (nameSynonymes[id] || id).replace("ddr-", "HotKeys_").replace("ptt_", "Push2Talk_").split(/[_-]/)].flat(10).filter(n => n).map(BDFDB.StringUtils.upperCaseFirstChar).join(" ").replace(/1$/g, "");
const src = BDFDB.LibraryModules.SoundParser(key);
let soundPackName = id.split("_")[0];
@@ -179,19 +210,18 @@ module.exports = (_ => {
src: src,
mute: id.startsWith("call_") ? null : false,
streamMute: false,
force: id == "message1" ? false : null,
focus: id == "message1" ? true : false
invisibleMute: false
};
if (id == "message1") {
types[id].mute = true;
types[id].streamMute = false;
types[id].invisibleMute = false;
for (let subType in message1Types) types[subType] = {
name: message1Types[subType].name,
src: BDFDB.LibraryModules.SoundParser(message1Types[subType].src),
mute: true,
streamMute: false,
force: message1Types[subType].force,
focus: message1Types[subType].focus
invisibleMute: false
}
}
}
@@ -225,53 +255,54 @@ module.exports = (_ => {
const message = e.methodArguments[0].message;
const guildId = message.guild_id || null;
if (message.author.id != BDFDB.UserUtils.me.id && !BDFDB.LibraryStores.RelationshipStore.isBlocked(message.author.id)) {
const isCurrent = BDFDB.LibraryStores.SelectedChannelStore.getChannelId() == message.channel_id;
const channel = BDFDB.LibraryStores.ChannelStore.getChannel(message.channel_id);
const isGroupDM = channel.isGroupDM();
const muted = BDFDB.ChannelUtils.isThread(channel) ? BDFDB.LibraryStores.JoinedThreadsStore.isMuted(channel.id) : BDFDB.LibraryStores.UserGuildSettingsStore.isGuildOrCategoryOrChannelMuted(guildId, channel.id);
const focused = document.hasFocus() && BDFDB.LibraryStores.SelectedChannelStore.getChannelId() == channel.id;
if (!guildId && !muted && !(choices[isGroupDM ? "groupdm" : "dm"].focus && focused)) {
const isThread = BDFDB.ChannelUtils.isThread(channel);
if (isThread && BDFDB.LibraryStores.JoinedThreadsStore.isMuted(channel.id) || !isThread && BDFDB.LibraryStores.UserGuildSettingsStore.isGuildOrCategoryOrChannelMuted(guildId, channel.id)) return;
if (!guildId) {
this.fireEvent(isGroupDM ? "groupdm" : "dm");
this.playAudio(isGroupDM ? "groupdm" : "dm");
!BDFDB.LibraryStores.NotificationSettingsStore.getNotifyMessagesInSelectedChannel() && !document.hasFocus() && this.playAudio(isGroupDM ? "groupdm" : "dm");
return;
}
else if (guildId) {
if (BDFDB.LibraryModules.MentionUtils.isRawMessageMentioned({rawMessage: message, userId: BDFDB.UserUtils.me.id})) {
if (message.mentions.length && !this.isSuppressMentionsEnabled(guildId, channel.id)) for (const mention of message.mentions) if (mention.id == BDFDB.UserUtils.me.id) {
if (message.message_reference && !message.interaction && (!muted || choices.reply.force) && !(choices.reply.focus && focused)) {
if (message.message_reference && !message.interaction) {
this.fireEvent("reply");
this.playAudio("reply");
!isCurrent && this.playAudio("reply");
return;
}
if (!message.message_reference && (!muted || choices.mentioned.force) && !(choices.mentioned.focus && focused)) {
if (!message.message_reference) {
this.fireEvent("mentioned");
this.playAudio("mentioned");
!isCurrent && this.playAudio("mentioned");
return;
}
}
if (message.mention_roles.length && !BDFDB.LibraryStores.UserGuildSettingsStore.isSuppressRolesEnabled(guildId, channel.id) && (!muted || choices.role.force) && !(choices.role.focus && focused)) {
if (message.mention_roles.length && !BDFDB.LibraryStores.UserGuildSettingsStore.isSuppressRolesEnabled(guildId, channel.id)) {
const member = BDFDB.LibraryStores.GuildMemberStore.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");
!isCurrent && this.playAudio("role");
return;
}
}
if (message.mention_everyone && !BDFDB.LibraryStores.UserGuildSettingsStore.isSuppressEveryoneEnabled(guildId, channel.id)) {
if (message.content.indexOf("@everyone") > -1 && (!muted || choices.everyone.force) && !(choices.everyone.focus && focused)) {
if (message.content.indexOf("@everyone") > -1) {
this.fireEvent("everyone");
this.playAudio("everyone");
!isCurrent && this.playAudio("everyone");
return;
}
if (message.content.indexOf("@here") > -1 && (!muted || choices.here.force) && !(choices.here.focus && focused)) {
if (message.content.indexOf("@here") > -1) {
this.fireEvent("here");
this.playAudio("here");
!isCurrent && this.playAudio("here");
return;
}
}
}
if (BDFDB.LibraryStores.UserGuildSettingsStore.allowAllMessages(channel) && (!muted || choices.message1.force) && !(choices.message1.focus && focused)) {
if (BDFDB.LibraryStores.UserGuildSettingsStore.allowAllMessages(channel) && !(isThread && !BDFDB.LibraryStores.JoinedThreadsStore.hasJoined(channel.id))) {
this.fireEvent("message1");
this.playAudio("message1");
!isCurrent && this.playAudio("message1");
return;
}
}
@@ -287,25 +318,22 @@ module.exports = (_ => {
let cancel = BDFDB.PatchUtils.patch(this, BDFDB.LibraryModules.SoundUtils, "createSound", {after: e => {
if (e.returnValue && e.returnValue.constructor && e.returnValue.constructor.prototype && typeof e.returnValue.constructor.prototype.play == "function") {
cancel();
BDFDB.PatchUtils.patch(this, e.returnValue.constructor.prototype, ["play", "loop"], {instead: e2 => {
BDFDB.PatchUtils.patch(this, e.returnValue.constructor.prototype, ["play", "loop", "playWithListener"], {instead: e2 => {
let type = e2.instance && e2.instance.name;
let loop = e2.originalMethodName == "loop";
if (type && choices[type]) {
e2.stopOriginalMethodCall();
BDFDB.TimeUtils.timeout(_ => {
if (type == "message1") {
let called = false;
for (let subType of [type].concat(Object.keys(message1Types))) if (firedEvents[subType]) {
delete firedEvents[subType];
called = true;
break;
}
if (!called) this.playAudio(type, loop);
if (type == "message1") BDFDB.TimeUtils.timeout(_ => {
let called = false;
for (let subType of [type].concat(Object.keys(message1Types))) if (firedEvents[subType]) {
delete firedEvents[subType];
called = true;
break;
}
else this.playAudio(type, loop);
if (!called) return this.playAudio(type, e2.originalMethodName, e2.instance.duration);
});
else return this.playAudio(type, e2.originalMethodName, e2.instance.duration);
}
else this.playAudio(type, loop);
else return this.playAudio(type, e2.originalMethodName, e2.instance.duration);
}});
BDFDB.PatchUtils.patch(this, e.returnValue.constructor.prototype, "stop", {after: e2 => {
let type = e2.instance && e2.instance.name;
@@ -404,7 +432,7 @@ module.exports = (_ => {
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"});
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();
@@ -415,9 +443,9 @@ module.exports = (_ => {
}
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, buffer) => {
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,${Buffer.from(buffer).toString("base64")}`});
else BDFDB.LibraryRequires.fs.readFile(source, "base64", (error, body) => {
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,${body}`});
});
},
children: BDFDB.LanguageUtils.LanguageStrings.SAVE
@@ -430,7 +458,7 @@ module.exports = (_ => {
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
title: "Sound Configuration",
collapseStates: collapseStates,
children: Object.keys(types).map(type => [
children: Object.keys(types).map(type => type == "message3" && !BDFDB.LibraryStores.NotificationSettingsStore.getNotifyMessagesInSelectedChannel() ? null : [
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
className: BDFDB.disCN.marginbottom8,
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
@@ -439,34 +467,20 @@ module.exports = (_ => {
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsLabel, {
label: types[type].name
}),
["force", "focus", "mute", "streamMute"].some(n => types[type][n] !== null) && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
["mute", "streamMute", "invisibleMute"].some(n => types[type][n] !== null) && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
onClick: event => BDFDB.ContextMenuUtils.open(this, event, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
children: [
{key: "force", label: "Force Play", hint: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
text: "Plays the Message Sound even if the Channel of the Message is muted",
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
name: BDFDB.LibraryComponents.SvgIcon.Names.QUESTIONMARK,
width: 18,
height: 18
})
})},
{key: "focus", label: "Focus Mute", hint: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
text: "Does not play the Message Sound when the Channel of the Message is currently opened",
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
name: BDFDB.LibraryComponents.SvgIcon.Names.QUESTIONMARK,
width: 18,
height: 18
})
})},
{key: "mute", label: ["Mute in", BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.StatusComponents.Status, {style: {marginLeft: 6}, size: 12, status: BDFDB.LibraryComponents.StatusComponents.Types.DND})]},
{key: "streamMute", label: ["Mute while", BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.StatusComponents.Status, {style: {marginLeft: 6}, size: 12, status: BDFDB.LibraryComponents.StatusComponents.Types.STREAMING})]},
{key: "invisibleMute", label: ["Mute in", BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.StatusComponents.Status, {style: {marginLeft: 6}, size: 12, status: BDFDB.LibraryComponents.StatusComponents.Types.INVISIBLE})]},
{key: "streamMute", label: ["Mute while", BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.StatusComponents.Status, {style: {marginLeft: 6}, size: 12, status: BDFDB.LibraryComponents.StatusComponents.Types.STREAMING})]}
].map(n => types[type][n.key] !== null && BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuCheckboxItem, {
label: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
children: n.label
}),
hint: n.hint,
id: BDFDB.ContextMenuUtils.createItemId(this.name, type, n.key),
checked: types[type][n.key],
checked: choices[type][n.key],
action: state => {
choices[type][n.key] = state;
this.saveChoice(type, false);
@@ -676,7 +690,7 @@ module.exports = (_ => {
volume: 100,
mute: types[type].mute,
streamMute: types[type].streamMute,
focus: types[type].focus
invisibleMute: types[type].invisibleMute
};
choices[type] = choice;
this.saveChoice(type, false);
@@ -692,11 +706,11 @@ module.exports = (_ => {
}
}
playAudio (type, loop = false) {
playAudio (type, functionCall = "play", duration = 0) {
if (this.dontPlayAudio(type) || BDFDB.LibraryStores.StreamerModeStore.disableSounds) return;
if (createdAudios[type]) createdAudios[type].stop();
createdAudios[type] = new WebAudioSound(type);
createdAudios[type][loop ? "loop" : "play"]();
return createdAudios[type][typeof createdAudios[type][functionCall] == "function" ? functionCall : "play"](duration);
}
isSuppressMentionsEnabled (guildId, channelId) {
@@ -706,7 +720,7 @@ module.exports = (_ => {
dontPlayAudio (type) {
let status = BDFDB.UserUtils.getStatus();
return choices[type] && (choices[type].mute && status == "dnd" || choices[type].streamMute && status == "streaming");
return choices[type] && (choices[type].mute && status == "dnd" || choices[type].streamMute && status == "streaming" || choices[type].invisibleMute && (status == "offline" || status == "invisible"));
}
fireEvent (type) {
@@ -715,7 +729,7 @@ module.exports = (_ => {
}
isSoundUsedAnywhere (type) {
return type && type.indexOf("poggermode_") != 0 && type != "human_man" && type != "robot_man" && type != "discodo" && type != "overlayunlock" && type != "call_ringing_beat" && !(type != "message1" && /\d$/.test(type));
return type && type.indexOf("poggermode_") != 0 && type != "human_man" && type != "robot_man" && type != "discodo" && type != "overlayunlock" && type != "call_ringing_beat" && !(type != "message1" && type != "message3" && /\d$/.test(type));
}
};
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));