aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/apiBadges.tsx19
-rw-r--r--src/plugins/apiMemberListDecorators.ts42
-rw-r--r--src/plugins/apiMessageDecorations.ts35
-rw-r--r--src/plugins/platformIndicators.tsx145
4 files changed, 174 insertions, 67 deletions
diff --git a/src/plugins/apiBadges.tsx b/src/plugins/apiBadges.tsx
index 77ea46e..72c19f3 100644
--- a/src/plugins/apiBadges.tsx
+++ b/src/plugins/apiBadges.tsx
@@ -66,11 +66,20 @@ export default definePlugin({
/* Patch the badge list component on user profiles */
{
find: "Messages.PROFILE_USER_BADGES,role:",
- replacement: {
- match: /src:(\w{1,3})\[(\w{1,3})\.key\],/,
- // <img src={badge.image ?? imageMap[badge.key]} {...badge.props} />
- replace: (_, imageMap, badge) => `src: ${badge}.image ?? ${imageMap}[${badge}.key], ...${badge}.props,`
- }
+ replacement: [
+ {
+ match: /src:(\w{1,3})\[(\w{1,3})\.key\],/,
+ // <img src={badge.image ?? imageMap[badge.key]} {...badge.props} />
+ replace: (_, imageMap, badge) => `src: ${badge}.image ?? ${imageMap}[${badge}.key], ...${badge}.props,`
+ },
+ {
+ match: /spacing:(\d{1,2}),children:(.{1,40}(.{1,2})\.jsx.+(.{1,2})\.onClick.+\)})},/,
+ // if the badge provides it's own component, render that instead of an image
+ // the badge also includes info about the user that has it (type BadgeUserArgs), which is why it's passed as props
+ replace: (_, s, origBadgeComponent, React, badge) =>
+ `spacing:${s},children:${badge}.component ? () => (0,${React}.jsx)(${badge}.component, { ...${badge} }) : ${origBadgeComponent}},`
+ }
+ ]
}
],
diff --git a/src/plugins/apiMemberListDecorators.ts b/src/plugins/apiMemberListDecorators.ts
new file mode 100644
index 0000000..6b8cffa
--- /dev/null
+++ b/src/plugins/apiMemberListDecorators.ts
@@ -0,0 +1,42 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { Devs } from "@utils/constants";
+import definePlugin from "@utils/types";
+
+export default definePlugin({
+ name: "MemberListDecoratorsAPI",
+ description: "API to add decorators to member list (both in servers and DMs)",
+ authors: [Devs.TheSun],
+ patches: [
+ {
+ find: "lostPermissionTooltipText,",
+ replacement: {
+ match: /Fragment,{children:\[(.{30,80})\]/,
+ replace: "Fragment,{children:Vencord.Api.MemberListDecorators.__addDecoratorsToList(this.props).concat($1)"
+ }
+ },
+ {
+ find: "PrivateChannel.renderAvatar",
+ replacement: {
+ match: /(subText:(.{1,2})\.renderSubtitle\(\).{1,50}decorators):(.{30,100}:null)/,
+ replace: "$1:Vencord.Api.MemberListDecorators.__addDecoratorsToList($2.props).concat($3)"
+ }
+ }
+ ],
+});
diff --git a/src/plugins/apiMessageDecorations.ts b/src/plugins/apiMessageDecorations.ts
new file mode 100644
index 0000000..47f03f3
--- /dev/null
+++ b/src/plugins/apiMessageDecorations.ts
@@ -0,0 +1,35 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { Devs } from "@utils/constants";
+import definePlugin from "@utils/types";
+
+export default definePlugin({
+ name: "MessageDecorationsAPI",
+ description: "API to add decorations to messages",
+ authors: [Devs.TheSun],
+ patches: [
+ {
+ find: ".withMentionPrefix",
+ replacement: {
+ match: /(\(\).roleDot.{10,50}{children:.{1,2})}\)/,
+ replace: "$1.concat(Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0]))})"
+ }
+ }
+ ],
+});
diff --git a/src/plugins/platformIndicators.tsx b/src/plugins/platformIndicators.tsx
index 5cae38f..8ca0677 100644
--- a/src/plugins/platformIndicators.tsx
+++ b/src/plugins/platformIndicators.tsx
@@ -16,6 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import { addBadge, BadgePosition, ProfileBadge, removeBadge } from "@api/Badges";
+import { addDecorator, removeDecorator } from "@api/MemberListDecorators";
+import { addDecoration, removeDecoration } from "@api/MessageDecorations";
import { Settings } from "@api/settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
@@ -59,10 +62,12 @@ const PlatformIcon = ({ platform, status }: { platform: Platform, status: string
return <Icon color={`var(--${getStatusColor(status)}`} tooltip={tooltip} />;
};
+const getStatus = (id: string): Record<Platform, string> => PresenceStore.getState()?.clientStatuses?.[id];
+
const PlatformIndicator = ({ user }: { user: User; }) => {
if (!user || user.bot) return null;
- const status = PresenceStore.getState()?.clientStatuses?.[user.id] as Record<Platform, string>;
+ const status = getStatus(user.id);
if (!status) return null;
const icons = Object.entries(status).map(([platform, status]) => (
@@ -75,79 +80,95 @@ const PlatformIndicator = ({ user }: { user: User; }) => {
if (!icons.length) return null;
- return (
- <div
+ const indicator =
+ <span
className="vc-platform-indicator"
- style={{
- display: "flex", alignItems: "center", marginLeft: "4px", gap: "4px"
- }}
+ style={{ marginLeft: "4px", gap: "4px" }}
>
{icons}
- </div>
- );
+ </span>;
+
+ return indicator;
+};
+
+const badge: ProfileBadge = {
+ component: PlatformIndicator,
+ position: BadgePosition.START,
+ shouldShow: userInfo => !!Object.keys(getStatus(userInfo.user.id) ?? {}).length,
+ key: "indicator"
+};
+
+const indicatorLocations = {
+ list: {
+ description: "In the member list",
+ onEnable: () => addDecorator("platform-indicator", props =>
+ <ErrorBoundary noop>
+ <PlatformIndicator user={props.user} />
+ </ErrorBoundary>
+ ),
+ onDisable: () => removeDecorator("platform-indicator")
+ },
+ badges: {
+ description: "In user profiles, as badges",
+ onEnable: () => addBadge(badge),
+ onDisable: () => removeBadge(badge)
+ },
+ messages: {
+ description: "Inside messages",
+ onEnable: () => addDecoration("platform-indicator", props =>
+ <ErrorBoundary noop>
+ <PlatformIndicator user={
+ props.decorations[1]?.find(i => i.key === "new-member")?.props.message?.author
+ } />
+ </ErrorBoundary>
+ ),
+ onDisable: () => removeDecoration("platform-indicator")
+ }
};
export default definePlugin({
name: "PlatformIndicators",
description: "Adds platform indicators (Desktop, Mobile, Web...) to users",
- authors: [Devs.kemo],
-
- patches: [
- {
- // Server member list decorators
- find: "this.renderPremium()",
- predicate: () => ["both", "list"].includes(Settings.plugins.PlatformIndicators.displayMode),
- replacement: {
- match: /this.renderPremium\(\)[^\]]*?\]/,
- replace: "$&.concat(Vencord.Plugins.plugins.PlatformIndicators.renderPlatformIndicators(this.props))"
- }
- },
- {
- // Dm list decorators
- find: "PrivateChannel.renderAvatar",
- predicate: () => ["both", "list"].includes(Settings.plugins.PlatformIndicators.displayMode),
- replacement: {
- match: /(subText:(.{1,3})\..+?decorators:)(.+?:null)/,
- replace: "$1[$3].concat(Vencord.Plugins.plugins.PlatformIndicators.renderPlatformIndicators($2.props))"
- }
- },
- {
- // User badges
- find: "Messages.PROFILE_USER_BADGES",
- predicate: () => ["both", "badges"].includes(Settings.plugins.PlatformIndicators.displayMode),
- replacement: {
- match: /(Messages\.PROFILE_USER_BADGES,role:"group",children:)(.+?\.key\)\}\)\))/,
- replace: "$1[Vencord.Plugins.plugins.PlatformIndicators.renderPlatformIndicators(e)].concat($2)"
+ authors: [Devs.kemo, Devs.TheSun],
+ dependencies: ["MessageDecorationsAPI", "MemberListDecoratorsAPI"],
+
+ start() {
+ const settings = Settings.plugins.PlatformIndicators;
+ const { displayMode } = settings;
+
+ // transfer settings from the old ones, which had a select menu instead of booleans
+ if (displayMode) {
+ if (displayMode !== "both") settings[displayMode] = true;
+ else {
+ settings.list = true;
+ settings.badges = true;
}
+ settings.messages = true;
+ delete settings.displayMode;
}
- ],
- renderPlatformIndicators: ({ user }: { user: User; }) => (
- <ErrorBoundary noop>
- <PlatformIndicator user={user} />
- </ErrorBoundary>
- ),
+ Object.entries(indicatorLocations).forEach(([key, value]) => {
+ if (settings[key]) value.onEnable();
+ });
+ },
+
+ stop() {
+ Object.entries(indicatorLocations).forEach(([_, value]) => {
+ value.onDisable();
+ });
+ },
options: {
- displayMode: {
- type: OptionType.SELECT,
- description: "Where to display the platform indicators",
- restartNeeded: true,
- options: [
- {
- label: "Member List & Badges",
- value: "both",
- default: true
- },
- {
- label: "Member List Only",
- value: "list"
- },
- {
- label: "Badges Only",
- value: "badges"
- }
- ]
- },
+ ...Object.fromEntries(
+ Object.entries(indicatorLocations).map(([key, value]) => {
+ return [key, {
+ type: OptionType.BOOLEAN,
+ description: `Show indicators ${value.description.toLowerCase()}`,
+ // onChange doesn't give any way to know which setting was changed, so restart required
+ restartNeeded: true,
+ default: false
+ }];
+ })
+ )
}
});