XSOverlay: add settings for different notification types (#2055)

Co-authored-by: vee <vendicated@riseup.net>
This commit is contained in:
nyan 2024-05-11 12:05:22 -04:00 committed by GitHub
parent 395b0007bf
commit fbaa4ad5bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,6 +1,6 @@
/* /*
* Vencord, a Discord client mod * Vencord, a Discord client mod
* Copyright (c) 2023 Vendicated and contributors * Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@ -13,10 +13,7 @@ import { findByPropsLazy } from "@webpack";
import { ChannelStore, GuildStore, UserStore } from "@webpack/common"; import { ChannelStore, GuildStore, UserStore } from "@webpack/common";
import type { Channel, Embed, GuildMember, MessageAttachment, User } from "discord-types/general"; import type { Channel, Embed, GuildMember, MessageAttachment, User } from "discord-types/general";
const enum ChannelTypes { const { ChannelTypes } = findByPropsLazy("ChannelTypes");
DM = 1,
GROUP_DM = 3
}
interface Message { interface Message {
guild_id: string, guild_id: string,
@ -72,14 +69,35 @@ interface Call {
} }
const MuteStore = findByPropsLazy("isSuppressEveryoneEnabled"); const MuteStore = findByPropsLazy("isSuppressEveryoneEnabled");
const Notifs = findByPropsLazy("makeTextChatNotification");
const XSLog = new Logger("XSOverlay"); const XSLog = new Logger("XSOverlay");
const settings = definePluginSettings({ const settings = definePluginSettings({
ignoreBots: { botNotifications: {
type: OptionType.BOOLEAN, type: OptionType.BOOLEAN,
description: "Ignore messages from bots", description: "Allow bot notifications",
default: false default: false
}, },
serverNotifications: {
type: OptionType.BOOLEAN,
description: "Allow server notifications",
default: true
},
dmNotifications: {
type: OptionType.BOOLEAN,
description: "Allow Direct Message notifications",
default: true
},
groupDmNotifications: {
type: OptionType.BOOLEAN,
description: "Allow Group DM notifications",
default: true
},
callNotifications: {
type: OptionType.BOOLEAN,
description: "Allow call notifications",
default: true
},
pingColor: { pingColor: {
type: OptionType.STRING, type: OptionType.STRING,
description: "User mention color", description: "User mention color",
@ -100,6 +118,11 @@ const settings = definePluginSettings({
description: "Notif duration (secs)", description: "Notif duration (secs)",
default: 1.0, default: 1.0,
}, },
timeoutPerCharacter: {
type: OptionType.NUMBER,
description: "Duration multiplier per character",
default: 0.5
},
opacity: { opacity: {
type: OptionType.SLIDER, type: OptionType.SLIDER,
description: "Notif opacity", description: "Notif opacity",
@ -124,7 +147,7 @@ export default definePlugin({
settings, settings,
flux: { flux: {
CALL_UPDATE({ call }: { call: Call; }) { CALL_UPDATE({ call }: { call: Call; }) {
if (call?.ringing?.includes(UserStore.getCurrentUser().id)) { if (call?.ringing?.includes(UserStore.getCurrentUser().id) && settings.store.callNotifications) {
const channel = ChannelStore.getChannel(call.channel_id); const channel = ChannelStore.getChannel(call.channel_id);
sendOtherNotif("Incoming call", `${channel.name} is calling you...`); sendOtherNotif("Incoming call", `${channel.name} is calling you...`);
} }
@ -134,7 +157,7 @@ export default definePlugin({
try { try {
if (optimistic) return; if (optimistic) return;
const channel = ChannelStore.getChannel(message.channel_id); const channel = ChannelStore.getChannel(message.channel_id);
if (!shouldNotify(message, channel)) return; if (!shouldNotify(message, message.channel_id)) return;
const pingColor = settings.store.pingColor.replaceAll("#", "").trim(); const pingColor = settings.store.pingColor.replaceAll("#", "").trim();
const channelPingColor = settings.store.channelPingColor.replaceAll("#", "").trim(); const channelPingColor = settings.store.channelPingColor.replaceAll("#", "").trim();
@ -194,6 +217,7 @@ export default definePlugin({
finalMsg = finalMsg.replace(/<@!?(\d{17,20})>/g, (_, id) => `<color=#${pingColor}><b>@${UserStore.getUser(id)?.username || "unknown-user"}</color></b>`); finalMsg = finalMsg.replace(/<@!?(\d{17,20})>/g, (_, id) => `<color=#${pingColor}><b>@${UserStore.getUser(id)?.username || "unknown-user"}</color></b>`);
} }
// color role mentions (unity styling btw lol)
if (message.mention_roles.length > 0) { if (message.mention_roles.length > 0) {
for (const roleId of message.mention_roles) { for (const roleId of message.mention_roles) {
const role = GuildStore.getRole(channel.guild_id, roleId); const role = GuildStore.getRole(channel.guild_id, roleId);
@ -213,6 +237,7 @@ export default definePlugin({
} }
} }
// color channel mentions
if (channelMatches) { if (channelMatches) {
for (const cMatch of channelMatches) { for (const cMatch of channelMatches) {
let channelId = cMatch.split("<#")[1]; let channelId = cMatch.split("<#")[1];
@ -221,6 +246,7 @@ export default definePlugin({
} }
} }
if (shouldIgnoreForChannelType(channel)) return;
sendMsgNotif(titleString, finalMsg, message); sendMsgNotif(titleString, finalMsg, message);
} catch (err) { } catch (err) {
XSLog.error(`Failed to catch MESSAGE_CREATE: ${err}`); XSLog.error(`Failed to catch MESSAGE_CREATE: ${err}`);
@ -229,13 +255,20 @@ export default definePlugin({
} }
}); });
function shouldIgnoreForChannelType(channel: Channel) {
if (channel.type === ChannelTypes.DM && settings.store.dmNotifications) return false;
if (channel.type === ChannelTypes.GROUP_DM && settings.store.groupDmNotifications) return false;
else return !settings.store.serverNotifications;
}
function sendMsgNotif(titleString: string, content: string, message: Message) { function sendMsgNotif(titleString: string, content: string, message: Message) {
const timeout = Math.max(settings.store.timeout, content.length * settings.store.timeoutPerCharacter);
fetch(`https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png?size=128`).then(response => response.arrayBuffer()).then(result => { fetch(`https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png?size=128`).then(response => response.arrayBuffer()).then(result => {
const msgData = { const msgData = {
messageType: 1, messageType: 1,
index: 0, index: 0,
timeout: settings.store.timeout, timeout,
height: calculateHeight(cleanMessage(content)), height: calculateHeight(content),
opacity: settings.store.opacity, opacity: settings.store.opacity,
volume: settings.store.volume, volume: settings.store.volume,
audioPath: settings.store.soundPath, audioPath: settings.store.soundPath,
@ -254,7 +287,7 @@ function sendOtherNotif(content: string, titleString: string) {
messageType: 1, messageType: 1,
index: 0, index: 0,
timeout: settings.store.timeout, timeout: settings.store.timeout,
height: calculateHeight(cleanMessage(content)), height: calculateHeight(content),
opacity: settings.store.opacity, opacity: settings.store.opacity,
volume: settings.store.volume, volume: settings.store.volume,
audioPath: settings.store.soundPath, audioPath: settings.store.soundPath,
@ -267,13 +300,11 @@ function sendOtherNotif(content: string, titleString: string) {
Native.sendToOverlay(msgData); Native.sendToOverlay(msgData);
} }
function shouldNotify(message: Message, channel: Channel) { function shouldNotify(message: Message, channel: string) {
const currentUser = UserStore.getCurrentUser(); const currentUser = UserStore.getCurrentUser();
if (message.author.id === currentUser.id) return false; if (message.author.id === currentUser.id) return false;
if (message.author.bot && settings.store.ignoreBots) return false; if (message.author.bot && !settings.store.botNotifications) return false;
if (MuteStore.allowAllMessages(channel) || message.mention_everyone && !MuteStore.isSuppressEveryoneEnabled(message.guild_id)) return true; return Notifs.shouldNotify(message, channel);
return message.mentions.some(m => m.id === currentUser.id);
} }
function calculateHeight(content: string) { function calculateHeight(content: string) {
@ -282,7 +313,3 @@ function calculateHeight(content: string) {
if (content.length <= 300) return 200; if (content.length <= 300) return 200;
return 250; return 250;
} }
function cleanMessage(content: string) {
return content.replace(new RegExp("<[^>]*>", "g"), "");
}