Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Plugin] Bypass DND #2239

Open
wants to merge 81 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
79b2030
Added encryptcord
Inbestigator Feb 29, 2024
622a13c
Added myself to devs
Inbestigator Feb 29, 2024
dbe9dda
1
Inbestigator Feb 29, 2024
11de96a
Update index.tsx
Inbestigator Feb 29, 2024
fb82a2f
Create index.tsx
Inbestigator Feb 29, 2024
a31e2d4
Delete src/plugins/Encryptcord directory
Inbestigator Feb 29, 2024
faf76d1
Made keys longer
Inbestigator Feb 29, 2024
352b6fc
Made keys longer
Inbestigator Feb 29, 2024
ec75223
Merge branch 'Encryptcord' of https://github.com/Inbestigator/Vencord…
Inbestigator Feb 29, 2024
3275c01
Removed axios
Inbestigator Mar 1, 2024
9228702
Removed node-forge, encryptcord is now fully self contained
Inbestigator Mar 2, 2024
a7b7008
Minor patches
Inbestigator Mar 2, 2024
f2c9f59
Merge branch 'Vendicated:main' into Encryptcord
Inbestigator Mar 2, 2024
0ed92fd
Raised key size and added creategroup button
Inbestigator Mar 2, 2024
fb039f9
Added data command
Inbestigator Mar 2, 2024
9d6d894
Joining overhaul
Inbestigator Mar 3, 2024
0ffe846
Fixed a couple things
Inbestigator Mar 3, 2024
1237687
Made join button unspammable
Inbestigator Mar 4, 2024
2a6745f
Added leave tooltip
Inbestigator Mar 4, 2024
b21f77f
Removing dependencies I forgot to
Inbestigator Mar 4, 2024
1297636
tip
Inbestigator Mar 4, 2024
eecb21f
Fixed privatechannel stuff
Inbestigator Mar 4, 2024
76d7ff0
Added bypassdnd
Inbestigator Mar 6, 2024
4fa67ca
Fixed notification
Inbestigator Mar 6, 2024
11f05ed
Added filtering so it only works in dnd
Inbestigator Mar 6, 2024
ba8a5aa
Lengthened description
Inbestigator Mar 6, 2024
0f042bc
Cleaned up the flux function a bit
Inbestigator Mar 6, 2024
245b274
Renaming folder
Inbestigator Mar 6, 2024
bc2eff8
Update and rename s to index.tsx
Inbestigator Mar 6, 2024
76b5b1e
Delete original bypassdnd directory
Inbestigator Mar 6, 2024
ee9e44d
Update pnpm-lock.yaml
Inbestigator Mar 6, 2024
c090b8b
Added types to bypasses object
Inbestigator Mar 6, 2024
58d64f7
Removed unnecessary bit
Inbestigator Mar 6, 2024
daee463
Let bypass users create notification outside of DM
Inbestigator Mar 6, 2024
21654c8
Made the allow in all channels option a toggle
Inbestigator Mar 6, 2024
9bb33f7
Fixed spelling mistake
Inbestigator Mar 6, 2024
4f218da
Added clarification
Inbestigator Mar 6, 2024
0e6f19f
Consistency 👏
Inbestigator Mar 6, 2024
733de54
Trycatch
Inbestigator Mar 6, 2024
68412b9
Fixed all Lint issues, formatted script
Inbestigator Mar 6, 2024
22d6921
Combined notification functions
Inbestigator Mar 7, 2024
90c460e
Added context icon
Inbestigator Mar 8, 2024
68c1f7a
Fixed mentioned checks
Inbestigator Mar 8, 2024
353173e
Merge branch 'main' into BypassDND
Inbestigator Mar 8, 2024
3e7032b
Merge branch 'main' into BypassDND
Inbestigator Mar 8, 2024
96b6ac6
Updated contextmenus
Inbestigator Mar 8, 2024
98ee690
Removed unused interface
Inbestigator Mar 9, 2024
ce99871
Removed excessive number of ifs
Inbestigator Mar 9, 2024
e1b75bd
Removed DataStore shenanigans, this change means that bypasses can be…
Inbestigator Mar 9, 2024
1e462cc
Shortbread
Inbestigator Mar 9, 2024
fd9f7aa
Welfare
Inbestigator Mar 9, 2024
e483584
Organz
Inbestigator Mar 9, 2024
e331cfe
Made it check focus/channel
Inbestigator Mar 11, 2024
a6a63d9
Merge branch 'main' into BypassDND
Inbestigator Mar 11, 2024
19fb542
Updated notification to look more like the normal notification
Inbestigator Mar 13, 2024
175088c
Added types
Inbestigator Mar 13, 2024
49777e4
Made icon PascalCase
Inbestigator Mar 13, 2024
4875cb0
Changed to Logger
Inbestigator Mar 13, 2024
46063b4
Moved self to bottom of devs
Inbestigator Mar 18, 2024
a331062
Merge branch 'main' into BypassDND
Inbestigator Mar 22, 2024
107140a
Fixed using globalname
Inbestigator Mar 22, 2024
3636de8
Enforced User type
Inbestigator Mar 22, 2024
1c38128
Merge branch 'Vendicated:main' into BypassDND
Inbestigator Mar 29, 2024
956104c
Merge branch 'main' into BypassDND
Inbestigator Apr 5, 2024
6e91865
Merge branch 'Vendicated:main' into BypassDND
Inbestigator Apr 9, 2024
172b754
Added notification sound (thanks to Drakz for the snippet)
Inbestigator Apr 13, 2024
02e18af
Merge branch 'main' into BypassDND
Inbestigator Apr 15, 2024
aa87b5a
Merge branch 'main' into BypassDND
Inbestigator Apr 18, 2024
8c93cc6
Merge branch 'main' into BypassDND
Inbestigator Apr 23, 2024
c92c7b7
Merge branch 'main' into BypassDND
Inbestigator Apr 29, 2024
8fdbf00
Merge branch 'main' into BypassDND
Inbestigator May 25, 2024
d9df420
Merge branch 'main' into BypassDND
Inbestigator May 31, 2024
1bd1bdb
Merge branch 'main' into BypassDND
Inbestigator Jun 14, 2024
41694a6
Merge branch 'main' into BypassDND
Inbestigator Jun 21, 2024
0952dce
Merge branch 'main' into BypassDND
Inbestigator Jun 25, 2024
efb5651
Merge branch 'main' into BypassDND
Inbestigator Jul 19, 2024
94b57d9
Merge branch 'main' into BypassDND
Inbestigator Aug 2, 2024
75ef0eb
Create README.md
Inbestigator Aug 8, 2024
fad1fbd
Merge branch 'main' into BypassDND
Inbestigator Aug 13, 2024
0de0f6d
Merge branch 'main' into BypassDND
Inbestigator Aug 16, 2024
e9f5365
Merge branch 'main' into BypassDND
Inbestigator Aug 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/plugins/bypassDND/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# BypassDND

Bypass DND allows you to set specific guilds/channels/users to still receive a notification from when in DND mode.
You will only get the notification if:

- The message is pinging you (for guild and channel bypasses, or users too if `allowOutsideOfDms` is enabled)
- All messages in DMs
158 changes: 158 additions & 0 deletions src/plugins/bypassDND/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

import { type NavContextMenuPatchCallback } from "@api/ContextMenu";
import { Notifications } from "@api/index";
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { ChannelStore, Menu, MessageStore, NavigationRouter, PresenceStore, PrivateChannelsStore, UserStore, WindowStore } from "@webpack/common";
import type { Message } from "discord-types/general";

interface IMessageCreate {
channelId: string;
guildId: string;
message: Message;
}

function Icon(enabled?: boolean): JSX.Element {
return <svg
width="18"
height="18"
>
<circle cx="9" cy="9" r="8" fill={!enabled ? "var(--status-danger)" : "currentColor"} />
<circle cx="9" cy="9" r="3.75" fill={!enabled ? "white" : "black"} />
</svg>;
}

function processIds(value: string): string {
return value.replace(/\s/g, "").split(",").filter(id => id.trim() !== "").join(", ");
}

async function showNotification(message: Message, guildId: string | undefined): Promise<void> {
try {
const channel = ChannelStore.getChannel(message.channel_id);
const channelRegex = /<#(\d{19})>/g;
const userRegex = /<@(\d{18})>/g;

message.content = message.content.replace(channelRegex, (match: any, channelId: string) => {
return `#${ChannelStore.getChannel(channelId)?.name}`;
});

message.content = message.content.replace(userRegex, (match: any, userId: string) => {
return `@${(UserStore.getUser(userId) as any).globalName}`;
});

await Notifications.showNotification({
title: `${(message.author as any).globalName} ${guildId ? `(#${channel?.name}, ${ChannelStore.getChannel(channel?.parent_id)?.name})` : ""}`,
body: message.content,
icon: UserStore.getUser(message.author.id).getAvatarURL(undefined, undefined, false),
onClick: function (): void {
NavigationRouter.transitionTo(`/channels/${guildId ?? "@me"}/${message.channel_id}/${message.id}`);
}
});

if (settings.store.notificationSound) {
new Audio("https://discord.com/assets/9422aef94aa931248105.mp3").play();
}
} catch (error) {
new Logger("BypassDND").error("Failed to notify user: ", error);
}
}

function ContextCallback(name: "guild" | "user" | "channel"): NavContextMenuPatchCallback {
return (children, props) => {
const type = props[name];
if (!type) return;
const enabled = settings.store[`${name}s`].split(", ").includes(type.id);
if (name === "user" && type.id === UserStore.getCurrentUser().id) return;
children.splice(-1, 0, (
<Menu.MenuGroup>
<Menu.MenuItem
id={`dnd-${name}-bypass`}
label={`${enabled ? "Remove" : "Add"} DND Bypass`}
icon={() => Icon(enabled)}
action={() => {
let bypasses: string[] = settings.store[`${name}s`].split(", ");
if (enabled) bypasses = bypasses.filter(id => id !== type.id);
else bypasses.push(type.id);
settings.store[`${name}s`] = bypasses.filter(id => id.trim() !== "").join(", ");
}}
/>
</Menu.MenuGroup>
));
};
}

const settings = definePluginSettings({
guilds: {
type: OptionType.STRING,
description: "Guilds to let bypass (notified when pinged anywhere in guild)",
default: "",
placeholder: "Separate with commas",
onChange: value => settings.store.guilds = processIds(value)
},
channels: {
type: OptionType.STRING,
description: "Channels to let bypass (notified when pinged in that channel)",
default: "",
placeholder: "Separate with commas",
onChange: value => settings.store.channels = processIds(value)
},
users: {
type: OptionType.STRING,
description: "Users to let bypass (notified for all messages sent in DMs)",
default: "",
placeholder: "Separate with commas",
onChange: value => settings.store.users = processIds(value)
},
allowOutsideOfDms: {
type: OptionType.BOOLEAN,
description: "Allow selected users to bypass DND outside of DMs too (acts like a channel/guild bypass, but it's for all messages sent by the selected users)"
},
notificationSound: {
type: OptionType.BOOLEAN,
description: "Whether the notification sound should be played",
default: true,
}
});

export default definePlugin({
name: "BypassDND",
description: "Still get notifications from specific sources when in do not disturb mode. Right-click on users/channels/guilds to set them to bypass do not disturb mode.",
authors: [Devs.Inbestigator],
flux: {
async MESSAGE_CREATE({ message, guildId, channelId }: IMessageCreate): Promise<void> {
try {
const currentUser = UserStore.getCurrentUser();
const userStatus = await PresenceStore.getStatus(currentUser.id);
const currentChannelId = getCurrentChannel()?.id ?? "0";
if (message.state === "SENDING" || message.content === "" || message.author.id === currentUser.id || (channelId === currentChannelId && WindowStore.isFocused()) || userStatus !== "dnd") {
return;
}
const mentioned = MessageStore.getMessage(channelId, message.id)?.mentioned;
if ((settings.store.guilds.split(", ").includes(guildId) || settings.store.channels.split(", ").includes(channelId)) && mentioned) {
await showNotification(message, guildId);
} else if (settings.store.users.split(", ").includes(message.author.id)) {
const userChannelId = await PrivateChannelsStore.getOrEnsurePrivateChannel(message.author.id);
if (channelId === userChannelId || (mentioned && settings.store.allowOutsideOfDms === true)) {
await showNotification(message, guildId);
}
}
} catch (error) {
new Logger("BypassDND").error("Failed to handle message: ", error);
}
}
},
settings,
contextMenus: {
"guild-context": ContextCallback("guild"),
"channel-context": ContextCallback("channel"),
"user-context": ContextCallback("user"),
}
});