From bf55ea0763d0f75bcdbc7d912f28d654f2bc4d29 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 12:56:03 +0100 Subject: [PATCH 01/59] feat(memberListActivities): add new plugin --- src/plugins/memberListActivities/README.md | 5 + .../components/SpotifyIcon.tsx | 11 ++ src/plugins/memberListActivities/index.tsx | 123 ++++++++++++++++++ .../memberListActivities/screenshot.png | Bin 0 -> 114471 bytes src/plugins/memberListActivities/styles.css | 20 +++ 5 files changed, 159 insertions(+) create mode 100644 src/plugins/memberListActivities/README.md create mode 100644 src/plugins/memberListActivities/components/SpotifyIcon.tsx create mode 100644 src/plugins/memberListActivities/index.tsx create mode 100644 src/plugins/memberListActivities/screenshot.png create mode 100644 src/plugins/memberListActivities/styles.css diff --git a/src/plugins/memberListActivities/README.md b/src/plugins/memberListActivities/README.md new file mode 100644 index 000000000..fe67bad79 --- /dev/null +++ b/src/plugins/memberListActivities/README.md @@ -0,0 +1,5 @@ +# MemberListActivities + +Shows activity icons in the member list + +![Screenshot](screenshot.png) diff --git a/src/plugins/memberListActivities/components/SpotifyIcon.tsx b/src/plugins/memberListActivities/components/SpotifyIcon.tsx new file mode 100644 index 000000000..9210169e2 --- /dev/null +++ b/src/plugins/memberListActivities/components/SpotifyIcon.tsx @@ -0,0 +1,11 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import type { SVGProps } from "react"; + +export function SpotifyIcon(props: SVGProps) { + return (); +} diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx new file mode 100644 index 000000000..f4cdd0f95 --- /dev/null +++ b/src/plugins/memberListActivities/index.tsx @@ -0,0 +1,123 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2023 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 . +*/ + +import "./styles.css"; + +import { definePluginSettings } from "@api/Settings"; +import { classNameFactory } from "@api/Styles"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; + +import { SpotifyIcon } from "./components/SpotifyIcon"; + +export const settings = definePluginSettings({ +}); + +interface Activity { + created_at: number; + id: string; + name: string; + state: string; + type: number; + flags?: number; + sync_id?: string; + details?: string; + application_id?: string; + assets?: { + large_text?: string; + large_image?: string; + small_text?: string; + small_image?: string; + }; +} + +const cl = classNameFactory("vc-mla-"); + +export default definePlugin({ + name: "MemberListActivities", + description: "Shows activity icons in the member list", + authors: [Devs.D3SOX], + tags: ["activity"], + settings, + + patchActivityList: (activities: Activity[]) => { + const icons: JSX.Element[] = []; + + if (activities.some(activity => activity.name === "Spotify")) { + icons.push(); + } + + const applications = activities.filter(activity => activity.application_id); + applications.forEach(activity => { + const { assets } = activity; + if (assets) { + + const addImage = (image: string, alt: string) => { + if (image.startsWith("mp:external/")) { + const externalLink = image.replace(/mp:external\/.{0,43}\//, "").replaceAll("https/", "https://"); + console.log("patch activity list external link", image, externalLink); + if (externalLink) { + icons.push({alt}/); + } + } else { + const src = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${image}.png`; + icons.push({alt}/); + } + }; + + // Prefer small image + const smallImage = assets.small_image; + if (smallImage) { + addImage(smallImage, assets.small_text ?? "Small Text"); + } else { + const largeImage = assets.large_image; + if (largeImage) { + addImage(largeImage, assets.large_text ?? "Large Text"); + } + } + + } + }); + + if (icons.length) { + return +
+ {icons.map((icon, i) => ( +
+ {icon} +
+ ))} +
+
; + } + + return false; + }, + + patches: [ + { + // Patch activity icons + find: "default.getHangStatusActivity():null!", + replacement: { + match: /(\i).some\((\i).default\)\?/, + replace: "$&$self.patchActivityList(l,d,_)?$self.patchActivityList(l,d,_):" + } + }, + ], +}); diff --git a/src/plugins/memberListActivities/screenshot.png b/src/plugins/memberListActivities/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..645f8d612218618e8e5bdb9eb55e227797bea562 GIT binary patch literal 114471 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

9;2+oldr(^Tkt2Pu#9J&)v2#qQx| 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㼉_Ln!u1;4S%2JI&Hn~_(} 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%0AE+Hz8_9r=J56I%st(7Ro6Eb;7Wb(jp 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 Date: Thu, 15 Feb 2024 13:01:23 +0100 Subject: [PATCH 02/59] chore(memberListActivities): remove obsolete settings --- src/plugins/memberListActivities/index.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index f4cdd0f95..46b4ff1a5 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -18,7 +18,6 @@ import "./styles.css"; -import { definePluginSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; @@ -26,9 +25,6 @@ import definePlugin from "@utils/types"; import { SpotifyIcon } from "./components/SpotifyIcon"; -export const settings = definePluginSettings({ -}); - interface Activity { created_at: number; id: string; @@ -54,7 +50,6 @@ export default definePlugin({ description: "Shows activity icons in the member list", authors: [Devs.D3SOX], tags: ["activity"], - settings, patchActivityList: (activities: Activity[]) => { const icons: JSX.Element[] = []; From c13bb6e47ed59f7322fb0f35b683b29252c8e287 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 13:05:09 +0100 Subject: [PATCH 03/59] fix(memberListActivities): use discord proxy for external media --- src/plugins/memberListActivities/index.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 46b4ff1a5..02c47043e 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -65,10 +65,11 @@ export default definePlugin({ const addImage = (image: string, alt: string) => { if (image.startsWith("mp:external/")) { - const externalLink = image.replace(/mp:external\/.{0,43}\//, "").replaceAll("https/", "https://"); - console.log("patch activity list external link", image, externalLink); + const externalLink = image.replace(/mp:/, ""); + const externalDiscordLink = `https://media.discordapp.net/${externalLink}`; + if (externalLink) { - icons.push({alt}/); + icons.push({alt}/); } } else { const src = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${image}.png`; From 94c5e6fdb71b5b929a9493ae50786e9217205440 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 13:13:35 +0100 Subject: [PATCH 04/59] fix(memberListActivities): support twitch and attachment images --- .../memberListActivities/components/TwitchIcon.tsx | 11 +++++++++++ src/plugins/memberListActivities/index.tsx | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/plugins/memberListActivities/components/TwitchIcon.tsx diff --git a/src/plugins/memberListActivities/components/TwitchIcon.tsx b/src/plugins/memberListActivities/components/TwitchIcon.tsx new file mode 100644 index 000000000..f0246c161 --- /dev/null +++ b/src/plugins/memberListActivities/components/TwitchIcon.tsx @@ -0,0 +1,11 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import type { SVGProps } from "react"; + +export function TwitchIcon(props: SVGProps) { + return (); +} diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 02c47043e..807afeead 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -24,6 +24,7 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { SpotifyIcon } from "./components/SpotifyIcon"; +import { TwitchIcon } from "./components/TwitchIcon"; interface Activity { created_at: number; @@ -58,6 +59,10 @@ export default definePlugin({ icons.push(); } + if (activities.some(activity => activity.name === "Twitch")) { + icons.push(); + } + const applications = activities.filter(activity => activity.application_id); applications.forEach(activity => { const { assets } = activity; @@ -71,6 +76,12 @@ export default definePlugin({ if (externalLink) { icons.push({alt}/); } + } else if (image.startsWith("mp:attachments/")) { + const attachmentId = image.replace(/mp:attachments\//, ""); + const attachmentLink = `https://media.discordapp.net/attachments/${attachmentId}`; + if (attachmentId) { + icons.push({alt}/); + } } else { const src = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${image}.png`; icons.push({alt}/); From 1867427de42bff51d231a09c0055c70a84c97628 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 13:16:10 +0100 Subject: [PATCH 05/59] refactor(memberListActivities): simplify media link transformation --- src/plugins/memberListActivities/index.tsx | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 807afeead..66edd776a 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -69,19 +69,9 @@ export default definePlugin({ if (assets) { const addImage = (image: string, alt: string) => { - if (image.startsWith("mp:external/")) { - const externalLink = image.replace(/mp:/, ""); - const externalDiscordLink = `https://media.discordapp.net/${externalLink}`; - - if (externalLink) { - icons.push({alt}/); - } - } else if (image.startsWith("mp:attachments/")) { - const attachmentId = image.replace(/mp:attachments\//, ""); - const attachmentLink = `https://media.discordapp.net/attachments/${attachmentId}`; - if (attachmentId) { - icons.push({alt}/); - } + if (image.startsWith("mp:")) { + const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; + icons.push({alt}/); } else { const src = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${image}.png`; icons.push({alt}/); From 2254da2474f5fa5fd7ab051c37f35cd3d97304ac Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 13:59:50 +0100 Subject: [PATCH 06/59] feat(memberListActivities): support application icons --- src/plugins/memberListActivities/index.tsx | 59 +++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 66edd776a..bcc70efbf 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -22,6 +22,7 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; +import { findStoreLazy } from "@webpack"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; @@ -46,6 +47,40 @@ interface Activity { const cl = classNameFactory("vc-mla-"); +interface Application { + id: string; + name: string; + icon: string; + description: string; + summary: string; + type: number; + hook: boolean; + guild_id: string; + executables: Executable[]; + verify_key: string; + publishers: Developer[]; + developers: Developer[]; + flags: number; +} + +interface Developer { + id: string; + name: string; +} + +interface Executable { + os: string; + name: string; + is_launcher: boolean; +} + +const ApplicationStore: { + getApplication: (id: string) => Application | null; + fetchApplication: (id: string) => Promise; +} = findStoreLazy("ApplicationStore"); + +const fetchedApplications = new Map(); + export default definePlugin({ name: "MemberListActivities", description: "Shows activity icons in the member list", @@ -65,7 +100,10 @@ export default definePlugin({ const applications = activities.filter(activity => activity.application_id); applications.forEach(activity => { - const { assets } = activity; + const { assets, application_id } = activity; + if (!application_id) { + return; + } if (assets) { const addImage = (image: string, alt: string) => { @@ -73,7 +111,7 @@ export default definePlugin({ const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; icons.push({alt}/); } else { - const src = `https://cdn.discordapp.com/app-assets/${activity.application_id}/${image}.png`; + const src = `https://cdn.discordapp.com/app-assets/${application_id}/${image}.png`; icons.push({alt}/); } }; @@ -89,6 +127,23 @@ export default definePlugin({ } } + } else { + let application = ApplicationStore.getApplication(application_id); + if (!application) { + if (fetchedApplications.has(application_id)) { + application = fetchedApplications.get(application_id) as Application | null; + } else { + fetchedApplications.set(application_id, null); + ApplicationStore.fetchApplication(application_id).then(app => { + fetchedApplications.set(application_id, app); + }); + } + } + + if (application) { + const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; + icons.push({application.name}/); + } } }); From da764f51446741e5a9272d0bb18bbc2433a00bab Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 14:05:23 +0100 Subject: [PATCH 07/59] feat(memberListActivities): improve patch --- src/plugins/memberListActivities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index bcc70efbf..ef1e1e88f 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -168,7 +168,7 @@ export default definePlugin({ find: "default.getHangStatusActivity():null!", replacement: { match: /(\i).some\((\i).default\)\?/, - replace: "$&$self.patchActivityList(l,d,_)?$self.patchActivityList(l,d,_):" + replace: "$&$self.patchActivityList($1)||" } }, ], From 682f7e65c8e89bf015a85919fea628ccb1471811 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 14:08:48 +0100 Subject: [PATCH 08/59] fix(memberListActivities): make icons round --- src/plugins/memberListActivities/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css index 4a66255b1..ce87e633c 100644 --- a/src/plugins/memberListActivities/styles.css +++ b/src/plugins/memberListActivities/styles.css @@ -10,11 +10,11 @@ .vc-mla-icon { height: 20px; width: 20px; - border-radius: 50%; } .vc-mla-icon img { width: 100%; height: 100%; object-fit: cover; + border-radius: 50%; } From 5c4f743b210cdcddf6dbce224c5de5bbe49dfcf9 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 14:12:57 +0100 Subject: [PATCH 09/59] docs(memberListActivities): update screenshot --- .../memberListActivities/screenshot.png | Bin 114471 -> 7143 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/plugins/memberListActivities/screenshot.png b/src/plugins/memberListActivities/screenshot.png index 645f8d612218618e8e5bdb9eb55e227797bea562..16451da272e21e944206ce72e507ce29099c3267 100644 GIT binary patch literal 7143 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 literal 114471 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

9;2+oldr(^Tkt2Pu#9J&)v2#qQx| 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㼉_Ln!u1;4S%2JI&Hn~_(} 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%0AE+Hz8_9r=J56I%st(7Ro6Eb;7Wb(jp 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 Date: Thu, 15 Feb 2024 14:30:42 +0100 Subject: [PATCH 10/59] fix(memberListActivities): always replace icon Update patch to support single app icons (like simple Minecraft RPC) --- src/plugins/memberListActivities/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index ef1e1e88f..a23464b14 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -167,8 +167,8 @@ export default definePlugin({ // Patch activity icons find: "default.getHangStatusActivity():null!", replacement: { - match: /(\i).some\((\i).default\)\?/, - replace: "$&$self.patchActivityList($1)||" + match: /null!=(\i)&&(\i).some\((\i).default\)\?/, + replace: "$self.patchActivityList($1),false?" } }, ], From d7404417be1bccf22ab322b42039d20a08b0d8da Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 14:44:02 +0100 Subject: [PATCH 11/59] fix(memberListActivities): use correct fetchApplication method --- src/plugins/memberListActivities/index.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index a23464b14..d967af5a2 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -22,7 +22,7 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; -import { findStoreLazy } from "@webpack"; +import { findByPropsLazy, findStoreLazy } from "@webpack"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; @@ -76,9 +76,12 @@ interface Executable { const ApplicationStore: { getApplication: (id: string) => Application | null; - fetchApplication: (id: string) => Promise; } = findStoreLazy("ApplicationStore"); +const { fetchApplication }: { + fetchApplication: (id: string) => Promise; +} = findByPropsLazy("fetchApplication"); + const fetchedApplications = new Map(); export default definePlugin({ @@ -134,7 +137,7 @@ export default definePlugin({ application = fetchedApplications.get(application_id) as Application | null; } else { fetchedApplications.set(application_id, null); - ApplicationStore.fetchApplication(application_id).then(app => { + fetchApplication(application_id).then(app => { fetchedApplications.set(application_id, app); }); } From 358fa1d1b4a7762b676e677af282c4e48b804616 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 15 Feb 2024 16:09:52 +0100 Subject: [PATCH 12/59] feat(memberListActivities): configurable icon size --- src/plugins/memberListActivities/index.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index d967af5a2..69d45cde5 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -18,15 +18,26 @@ import "./styles.css"; +import { definePluginSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; -import definePlugin from "@utils/types"; +import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy, findStoreLazy } from "@webpack"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; +const settings = definePluginSettings({ + iconSize: { + type: OptionType.SLIDER, + description: "Size of the activity icons", + markers: [10, 15, 20], + default: 20, + stickToMarkers: false, + }, +}); + interface Activity { created_at: number; id: string; @@ -90,6 +101,8 @@ export default definePlugin({ authors: [Devs.D3SOX], tags: ["activity"], + settings, + patchActivityList: (activities: Activity[]) => { const icons: JSX.Element[] = []; @@ -154,7 +167,7 @@ export default definePlugin({ return

{icons.map((icon, i) => ( -
+
{icon}
))} From 96c1d9cb4bb8f196ee1cd77d301a829d4dec8fc1 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 16 Feb 2024 09:15:13 +0100 Subject: [PATCH 13/59] feat(memberListActivities): option to disable rendering GIFs --- src/plugins/memberListActivities/index.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 69d45cde5..a87dd8931 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -36,6 +36,12 @@ const settings = definePluginSettings({ default: 20, stickToMarkers: false, }, + renderGifs: { + type: OptionType.BOOLEAN, + description: "Allow rendering GIFs", + default: true, + restartNeeded: false, + }, }); interface Activity { @@ -125,7 +131,9 @@ export default definePlugin({ const addImage = (image: string, alt: string) => { if (image.startsWith("mp:")) { const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; - icons.push({alt}/); + if (settings.store.renderGifs || !discordMediaLink.endsWith(".gif")) { + icons.push({alt}/); + } } else { const src = `https://cdn.discordapp.com/app-assets/${application_id}/${image}.png`; icons.push({alt}/); From 004517ce9bbe060ca2195f7eb9edafb4066248f5 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 16 Feb 2024 09:31:33 +0100 Subject: [PATCH 14/59] fix(memberListActivities): prefer large image I found the large image to be more applicable most of the time as the small image is often only used as an indicator. Maybe make this a setting? I also thought about maintaining a list of applications where to use which image but gave up on that idea. --- src/plugins/memberListActivities/index.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index a87dd8931..2c7092838 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -140,17 +140,16 @@ export default definePlugin({ } }; - // Prefer small image - const smallImage = assets.small_image; - if (smallImage) { - addImage(smallImage, assets.small_text ?? "Small Text"); + // Prefer large image + const largeImage = assets.large_image; + if (largeImage) { + addImage(largeImage, assets.large_text ?? "Large Text"); } else { - const largeImage = assets.large_image; - if (largeImage) { - addImage(largeImage, assets.large_text ?? "Large Text"); + const smallImage = assets.small_image; + if (smallImage) { + addImage(smallImage, assets.small_text ?? "Small Text"); } } - } else { let application = ApplicationStore.getApplication(application_id); if (!application) { From ab1ecd2b7fad55f94eb81a11763ec4bbad002669 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 19 Feb 2024 18:17:10 +0100 Subject: [PATCH 15/59] feat(memberListActivities): better console icons support --- src/plugins/memberListActivities/index.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 2c7092838..88bdb2dc5 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -60,6 +60,7 @@ interface Activity { small_text?: string; small_image?: string; }; + platform?: string; } const cl = classNameFactory("vc-mla-"); @@ -101,6 +102,8 @@ const { fetchApplication }: { const fetchedApplications = new Map(); +const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; + export default definePlugin({ name: "MemberListActivities", description: "Shows activity icons in the member list", @@ -120,10 +123,10 @@ export default definePlugin({ icons.push(); } - const applications = activities.filter(activity => activity.application_id); + const applications = activities.filter(activity => activity.application_id || activity.platform); applications.forEach(activity => { - const { assets, application_id } = activity; - if (!application_id) { + const { assets, application_id, platform } = activity; + if (!application_id && !platform) { return; } if (assets) { @@ -150,7 +153,7 @@ export default definePlugin({ addImage(smallImage, assets.small_text ?? "Small Text"); } } - } else { + } else if (application_id) { let application = ApplicationStore.getApplication(application_id); if (!application) { if (fetchedApplications.has(application_id)) { @@ -164,9 +167,13 @@ export default definePlugin({ } if (application) { - const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; + const src = platform === "xbox" && application.icon === null ? xboxUrl : `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; icons.push({application.name}/); } + } else { + if (platform === "xbox") { + icons.push(Xbox); + } } }); From 12ae29c3892b13e855ed83b066a557f65b081817 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Wed, 21 Feb 2024 17:57:03 +0100 Subject: [PATCH 16/59] fix(memberListActivities): get rid of duplicate icons --- src/plugins/memberListActivities/index.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 88bdb2dc5..ef6facfe2 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -178,9 +178,15 @@ export default definePlugin({ }); if (icons.length) { + const compareJSXElementsSource = (a: JSX.Element, b: JSX.Element) => { + return a.props?.src === b.props?.src; + }; + const uniqueIcons = icons.filter((element, index, array) => { + return array.findIndex(el => compareJSXElementsSource(el, element)) === index; + }); return
- {icons.map((icon, i) => ( + {uniqueIcons.map((icon, i) => (
{icon}
From d656aa7119d1d4f058218b5aeb8bed1aaf6c467f Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 22 Feb 2024 10:57:20 +0100 Subject: [PATCH 17/59] fix(memberListActivities): prefer application icons --- src/plugins/memberListActivities/index.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index ef6facfe2..fd5a90c9c 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -167,8 +167,12 @@ export default definePlugin({ } if (application) { - const src = platform === "xbox" && application.icon === null ? xboxUrl : `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; - icons.push({application.name}/); + if (application.icon) { + const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; + icons.push({application.name}); + } else if (platform === "xbox") { + icons.push(Xbox); + } } } else { if (platform === "xbox") { From f2b6e6570d3e7a297cf8e0d03a5a31328aa737a2 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Wed, 6 Mar 2024 14:08:30 +0100 Subject: [PATCH 18/59] fix(memberListActivities): update patch --- src/plugins/memberListActivities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index fd5a90c9c..3929f23a7 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -207,7 +207,7 @@ export default definePlugin({ // Patch activity icons find: "default.getHangStatusActivity():null!", replacement: { - match: /null!=(\i)&&(\i).some\((\i).default\)\?/, + match: /null!=(\i)&&\i.some\(\i=>\(0,\i.default\)\(\i,\i\)\)\?/, replace: "$self.patchActivityList($1),false?" } }, From 77a3b6c96c7959e4d16c4f276ccde9b880c58463 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 18 Mar 2024 18:03:36 +0100 Subject: [PATCH 19/59] feat(memberListActivities): show default icon when no icons where found --- src/plugins/memberListActivities/index.tsx | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 3929f23a7..f24c131f1 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -23,7 +23,7 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy, findStoreLazy } from "@webpack"; +import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; @@ -48,8 +48,13 @@ interface Activity { created_at: number; id: string; name: string; - state: string; type: number; + emoji?: { + animated: boolean; + id: string; + name: string; + } + state?: string; flags?: number; sync_id?: string; details?: string; @@ -100,6 +105,9 @@ const { fetchApplication }: { fetchApplication: (id: string) => Promise; } = findByPropsLazy("fetchApplication"); +// if discord one day decides changes their icon this needs to be updated +const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); + const fetchedApplications = new Map(); const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; @@ -112,7 +120,7 @@ export default definePlugin({ settings, - patchActivityList: (activities: Activity[]) => { + patchActivityList: (activities: Activity[]): JSX.Element | null => { const icons: JSX.Element[] = []; if (activities.some(activity => activity.name === "Spotify")) { @@ -197,9 +205,16 @@ export default definePlugin({ ))}
; + } else { + // Show default icon when there are no custom icons + // We need to filter out custom statuses + const shouldShow = activities.filter(a => a.type !== 4).length !== icons.length; + if (shouldShow) { + return ; + } } - return false; + return null; }, patches: [ From 99420e2cbe1e32474d70f4a032eb6b4f249398d4 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 2 Apr 2024 19:46:33 +0200 Subject: [PATCH 20/59] feat(memberListActivities): add tooltips --- src/plugins/memberListActivities/index.tsx | 189 +++++++++++++-------- 1 file changed, 116 insertions(+), 73 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index f24c131f1..0cf49a24c 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -24,6 +24,8 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; +import { Tooltip } from "@webpack/common"; +import type { ImgHTMLAttributes } from "react"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; @@ -97,6 +99,17 @@ interface Executable { is_launcher: boolean; } +type ImageAttributes = ImgHTMLAttributes & { + src: string; + alt: string; + activity: Activity; +}; + +interface ActivityListIcon { + iconElement: JSX.Element; + tooltip?: JSX.Element | string; +} + const ApplicationStore: { getApplication: (id: string) => Application | null; } = findStoreLazy("ApplicationStore"); @@ -112,6 +125,70 @@ const fetchedApplications = new Map(); const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; +function getApplicationIcons(activities: Activity[]) { + const applicationIcons: ImageAttributes[] = []; + const applications = activities.filter(activity => activity.application_id || activity.platform); + + for (const activity of applications) { + const { assets, application_id, platform } = activity; + if (!application_id && !platform) { + continue; + } + if (assets) { + + const addImage = (image: string, alt: string) => { + if (image.startsWith("mp:")) { + const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; + if (settings.store.renderGifs || !discordMediaLink.endsWith(".gif")) { + applicationIcons.push({ src: discordMediaLink, alt, activity }); + } + } else { + const src = `https://cdn.discordapp.com/app-assets/${application_id}/${image}.png`; + applicationIcons.push({ src, alt, activity }); + } + }; + + // Prefer large image + const largeImage = assets.large_image; + if (largeImage) { + addImage(largeImage, assets.large_text ?? "Large Text"); + } else { + const smallImage = assets.small_image; + if (smallImage) { + addImage(smallImage, assets.small_text ?? "Small Text"); + } + } + } else if (application_id) { + let application = ApplicationStore.getApplication(application_id); + if (!application) { + if (fetchedApplications.has(application_id)) { + application = fetchedApplications.get(application_id) as Application | null; + } else { + fetchedApplications.set(application_id, null); + fetchApplication(application_id).then(app => { + fetchedApplications.set(application_id, app); + }); + } + } + + if (application) { + if (application.icon) { + const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; + applicationIcons.push({ src, alt: application.name, activity }); + } else if (platform === "xbox") { + applicationIcons.push({ src: xboxUrl, alt: "Xbox", activity }); + } + } + } else { + if (platform === "xbox") { + applicationIcons.push({ src: xboxUrl, alt: "Xbox", activity }); + } + } + } + + return applicationIcons; +} + export default definePlugin({ name: "MemberListActivities", description: "Shows activity icons in the member list", @@ -121,88 +198,54 @@ export default definePlugin({ settings, patchActivityList: (activities: Activity[]): JSX.Element | null => { - const icons: JSX.Element[] = []; + const icons: ActivityListIcon[] = []; - if (activities.some(activity => activity.name === "Spotify")) { - icons.push(); + const spotifyActivity = activities.find(({ name }) => name === "Spotify"); + if (spotifyActivity) { + icons.push({ iconElement: , tooltip: spotifyActivity.details ?? spotifyActivity.name }); } - if (activities.some(activity => activity.name === "Twitch")) { - icons.push(); + const twitchActivity = activities.find(({ name }) => name === "Twitch"); + if (twitchActivity) { + icons.push({ iconElement: , tooltip: twitchActivity.details ?? twitchActivity.name }); } - - const applications = activities.filter(activity => activity.application_id || activity.platform); - applications.forEach(activity => { - const { assets, application_id, platform } = activity; - if (!application_id && !platform) { - return; + const applicationIcons = getApplicationIcons(activities); + if (applicationIcons.length) { + const compareImageSource = (a: ImageAttributes, b: ImageAttributes) => { + return a.src === b.src; + }; + const uniqueIcons = applicationIcons.filter((element, index, array) => { + return array.findIndex(el => compareImageSource(el, element)) === index; + }); + for (const iconAttrs of uniqueIcons) { + icons.push({ + iconElement: , + tooltip: iconAttrs.activity.details ?? iconAttrs.activity.name + }); } - if (assets) { - - const addImage = (image: string, alt: string) => { - if (image.startsWith("mp:")) { - const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; - if (settings.store.renderGifs || !discordMediaLink.endsWith(".gif")) { - icons.push({alt}/); - } - } else { - const src = `https://cdn.discordapp.com/app-assets/${application_id}/${image}.png`; - icons.push({alt}/); - } - }; - - // Prefer large image - const largeImage = assets.large_image; - if (largeImage) { - addImage(largeImage, assets.large_text ?? "Large Text"); - } else { - const smallImage = assets.small_image; - if (smallImage) { - addImage(smallImage, assets.small_text ?? "Small Text"); - } - } - } else if (application_id) { - let application = ApplicationStore.getApplication(application_id); - if (!application) { - if (fetchedApplications.has(application_id)) { - application = fetchedApplications.get(application_id) as Application | null; - } else { - fetchedApplications.set(application_id, null); - fetchApplication(application_id).then(app => { - fetchedApplications.set(application_id, app); - }); - } - } - - if (application) { - if (application.icon) { - const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; - icons.push({application.name}); - } else if (platform === "xbox") { - icons.push(Xbox); - } - } - } else { - if (platform === "xbox") { - icons.push(Xbox); - } - } - }); + } if (icons.length) { - const compareJSXElementsSource = (a: JSX.Element, b: JSX.Element) => { - return a.props?.src === b.props?.src; - }; - const uniqueIcons = icons.filter((element, index, array) => { - return array.findIndex(el => compareJSXElementsSource(el, element)) === index; - }); return
- {uniqueIcons.map((icon, i) => ( -
- {icon} -
- ))} + {icons.map(({ iconElement, tooltip }, i) => { + return ( +
+ {tooltip ? + {({ onMouseEnter, onMouseLeave }) => ( +
+ {iconElement} +
+ )} +
: iconElement} +
+ ); + })}
; } else { From 96175671b1188f3e7f056d86f3a96118a58aa439 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 2 Apr 2024 19:56:33 +0200 Subject: [PATCH 21/59] refactor(memberListActivities): don't spread activity into img element --- src/plugins/memberListActivities/index.tsx | 48 ++++++++++++++-------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 0cf49a24c..182108f85 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -98,12 +98,13 @@ interface Executable { name: string; is_launcher: boolean; } - -type ImageAttributes = ImgHTMLAttributes & { - src: string; - alt: string; +interface ApplicationIcon { + image: ImgHTMLAttributes & { + src: string; + alt: string; + }; activity: Activity; -}; +} interface ActivityListIcon { iconElement: JSX.Element; @@ -126,7 +127,7 @@ const fetchedApplications = new Map(); const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; function getApplicationIcons(activities: Activity[]) { - const applicationIcons: ImageAttributes[] = []; + const applicationIcons: ApplicationIcon[] = []; const applications = activities.filter(activity => activity.application_id || activity.platform); for (const activity of applications) { @@ -140,11 +141,17 @@ function getApplicationIcons(activities: Activity[]) { if (image.startsWith("mp:")) { const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; if (settings.store.renderGifs || !discordMediaLink.endsWith(".gif")) { - applicationIcons.push({ src: discordMediaLink, alt, activity }); + applicationIcons.push({ + image: { src: discordMediaLink, alt }, + activity + }); } } else { const src = `https://cdn.discordapp.com/app-assets/${application_id}/${image}.png`; - applicationIcons.push({ src, alt, activity }); + applicationIcons.push({ + image: { src, alt }, + activity + }); } }; @@ -174,14 +181,23 @@ function getApplicationIcons(activities: Activity[]) { if (application) { if (application.icon) { const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; - applicationIcons.push({ src, alt: application.name, activity }); + applicationIcons.push({ + image: { src, alt: application.name }, + activity + }); } else if (platform === "xbox") { - applicationIcons.push({ src: xboxUrl, alt: "Xbox", activity }); + applicationIcons.push({ + image: { src: xboxUrl, alt: "Xbox" }, + activity + }); } } } else { if (platform === "xbox") { - applicationIcons.push({ src: xboxUrl, alt: "Xbox", activity }); + applicationIcons.push({ + image: { src: xboxUrl, alt: "Xbox" }, + activity + }); } } } @@ -211,16 +227,16 @@ export default definePlugin({ } const applicationIcons = getApplicationIcons(activities); if (applicationIcons.length) { - const compareImageSource = (a: ImageAttributes, b: ImageAttributes) => { - return a.src === b.src; + const compareImageSource = (a: ApplicationIcon, b: ApplicationIcon) => { + return a.image.src === b.image.src; }; const uniqueIcons = applicationIcons.filter((element, index, array) => { return array.findIndex(el => compareImageSource(el, element)) === index; }); - for (const iconAttrs of uniqueIcons) { + for (const appIcon of uniqueIcons) { icons.push({ - iconElement: , - tooltip: iconAttrs.activity.details ?? iconAttrs.activity.name + iconElement: , + tooltip: appIcon.activity.details ?? appIcon.activity.name }); } } From e87ced9f9dfbe9012ce25a85ec6c91cc94061f8a Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 15 Apr 2024 00:19:52 +0200 Subject: [PATCH 22/59] feat(memberListActivities): better tooltips --- src/plugins/memberListActivities/index.tsx | 102 ++++++++++++++------ src/plugins/memberListActivities/styles.css | 34 +++++++ 2 files changed, 109 insertions(+), 27 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 182108f85..1ca32f26f 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -24,7 +24,8 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; -import { Tooltip } from "@webpack/common"; +import { Tooltip, useMemo } from "@webpack/common"; +import { User } from "discord-types/general"; import type { ImgHTMLAttributes } from "react"; import { SpotifyIcon } from "./components/SpotifyIcon"; @@ -104,6 +105,7 @@ interface ApplicationIcon { alt: string; }; activity: Activity; + application?: Application; } interface ActivityListIcon { @@ -124,7 +126,47 @@ const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z const fetchedApplications = new Map(); -const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; +const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; // TODO: replace with "renderXboxImage"? + +function getActivityImage(activity: Activity): string | undefined { + if (activity.type === 2 && activity.name === "Spotify") { + // get either from large or small image + const image = activity.assets?.large_image ?? activity.assets?.small_image; + // image needs to replace 'spotify: + if (image?.startsWith("spotify:")) { + // spotify cover art is always https://i.scdn.co/image/ID + return image.replace("spotify:", "https://i.scdn.co/image/"); + } + } + // TODO: we could support other assets here, like showing the small/large image counterpart in comparison to that was shown in the activity list +} + +const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { + const image = useMemo(() => { + const activityImage = getActivityImage(activity); + if (activityImage) { + return activityImage; + } + const icon = getApplicationIcons([activity])[0]; + return icon?.image.src; + }, [activity]); + + const hasDetails = activity.details ?? activity.state; + return ( + +
+ {image && Activity logo} +
{activity.name}
+ {hasDetails &&
} +
+
{activity.details}
+
{activity.state}
+
+
+ + ); +}; + function getApplicationIcons(activities: Activity[]) { const applicationIcons: ApplicationIcon[] = []; @@ -183,12 +225,14 @@ function getApplicationIcons(activities: Activity[]) { const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; applicationIcons.push({ image: { src, alt: application.name }, - activity + activity, + application }); } else if (platform === "xbox") { applicationIcons.push({ image: { src: xboxUrl, alt: "Xbox" }, - activity + activity, + application }); } } @@ -213,17 +257,23 @@ export default definePlugin({ settings, - patchActivityList: (activities: Activity[]): JSX.Element | null => { + patchActivityList: ({ activities, user }: { activities: Activity[], user: User }): JSX.Element | null => { const icons: ActivityListIcon[] = []; const spotifyActivity = activities.find(({ name }) => name === "Spotify"); if (spotifyActivity) { - icons.push({ iconElement: , tooltip: spotifyActivity.details ?? spotifyActivity.name }); + icons.push({ + iconElement: , + tooltip: + }); } const twitchActivity = activities.find(({ name }) => name === "Twitch"); if (twitchActivity) { - icons.push({ iconElement: , tooltip: twitchActivity.details ?? twitchActivity.name }); + icons.push({ + iconElement: , + tooltip: + }); } const applicationIcons = getApplicationIcons(activities); if (applicationIcons.length) { @@ -236,7 +286,7 @@ export default definePlugin({ for (const appIcon of uniqueIcons) { icons.push({ iconElement: , - tooltip: appIcon.activity.details ?? appIcon.activity.name + tooltip: }); } } @@ -244,24 +294,22 @@ export default definePlugin({ if (icons.length) { return
- {icons.map(({ iconElement, tooltip }, i) => { - return ( -
- {tooltip ? - {({ onMouseEnter, onMouseLeave }) => ( -
- {iconElement} -
- )} -
: iconElement} -
- ); - })} + {icons.map(({ iconElement, tooltip }, i) => ( +
+ {tooltip ? + {({ onMouseEnter, onMouseLeave }) => ( +
+ {iconElement} +
+ )} +
: iconElement} +
+ ))}
; } else { @@ -282,7 +330,7 @@ export default definePlugin({ find: "default.getHangStatusActivity():null!", replacement: { match: /null!=(\i)&&\i.some\(\i=>\(0,\i.default\)\(\i,\i\)\)\?/, - replace: "$self.patchActivityList($1),false?" + replace: "$self.patchActivityList(e),false?" } }, ], diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css index ce87e633c..22b2af21a 100644 --- a/src/plugins/memberListActivities/styles.css +++ b/src/plugins/memberListActivities/styles.css @@ -18,3 +18,37 @@ object-fit: cover; border-radius: 50%; } + +.vc-mla-activity { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + gap: 5px; +} + +.vc-mla-activity-title { + font-weight: bold; + text-align: center; +} + +.vc-mla-activity-image { + height: 20px; + width: 20px; + border-radius: 50%; + object-fit: cover; +} + +.vc-mla-activity-divider { + width: 100%; + border-top: 1px dotted rgba(255, 255, 255, 0.2); + margin-top: 3px; + margin-bottom: 3px; +} + +.vc-mla-activity-details { + display: flex; + flex-direction: column; + /* discord gray */ + color: var(--text-muted); +} From 57f548cb6912f2f2a3a94a59bb962095bdb46f7a Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 15 Apr 2024 00:27:26 +0200 Subject: [PATCH 23/59] chore(memberListActivities): linter be happy pls --- src/plugins/memberListActivities/styles.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css index 22b2af21a..ab653e911 100644 --- a/src/plugins/memberListActivities/styles.css +++ b/src/plugins/memberListActivities/styles.css @@ -41,7 +41,7 @@ .vc-mla-activity-divider { width: 100%; - border-top: 1px dotted rgba(255, 255, 255, 0.2); + border-top: 1px dotted rgba(255, 255, 255, 20%); margin-top: 3px; margin-bottom: 3px; } @@ -49,6 +49,5 @@ .vc-mla-activity-details { display: flex; flex-direction: column; - /* discord gray */ color: var(--text-muted); } From f6b3df7b5da4565ca86d350267c7d19809a68254 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 15 Apr 2024 00:37:01 +0200 Subject: [PATCH 24/59] chore(memberListActivities): omg linter yes like who cares --- src/plugins/memberListActivities/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css index ab653e911..c4b302cf2 100644 --- a/src/plugins/memberListActivities/styles.css +++ b/src/plugins/memberListActivities/styles.css @@ -41,7 +41,7 @@ .vc-mla-activity-divider { width: 100%; - border-top: 1px dotted rgba(255, 255, 255, 20%); + border-top: 1px dotted rgb(255 255 255 / 20%); margin-top: 3px; margin-bottom: 3px; } From b5b43a7900dc52a35872606cbfa2ee6d05568e9f Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 15 Apr 2024 00:57:07 +0200 Subject: [PATCH 25/59] feat(memberListActivities): show different asset in tooltip --- src/plugins/memberListActivities/index.tsx | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 1ca32f26f..ce61f637b 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -138,7 +138,7 @@ function getActivityImage(activity: Activity): string | undefined { return image.replace("spotify:", "https://i.scdn.co/image/"); } } - // TODO: we could support other assets here, like showing the small/large image counterpart in comparison to that was shown in the activity list + // TODO: we could support other assets here } const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { @@ -147,7 +147,7 @@ const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { if (activityImage) { return activityImage; } - const icon = getApplicationIcons([activity])[0]; + const icon = getApplicationIcons([activity], true)[0]; return icon?.image.src; }, [activity]); @@ -168,7 +168,7 @@ const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { }; -function getApplicationIcons(activities: Activity[]) { +function getApplicationIcons(activities: Activity[], preferSmall = false) { const applicationIcons: ApplicationIcon[] = []; const applications = activities.filter(activity => activity.application_id || activity.platform); @@ -197,14 +197,21 @@ function getApplicationIcons(activities: Activity[]) { } }; - // Prefer large image + const smallImage = assets.small_image; + const smallText = assets.small_text ?? "Small Text"; const largeImage = assets.large_image; - if (largeImage) { - addImage(largeImage, assets.large_text ?? "Large Text"); - } else { - const smallImage = assets.small_image; + const largeText = assets.large_text ?? "Large Text"; + if (preferSmall) { if (smallImage) { - addImage(smallImage, assets.small_text ?? "Small Text"); + addImage(smallImage, smallText); + } else if (largeImage) { + addImage(largeImage, largeText); + } + } else { + if (largeImage) { + addImage(largeImage, largeText); + } else if (smallImage) { + addImage(smallImage, smallText); } } } else if (application_id) { From 14f1569bc2248fdc7a6f91e34f6a81373ff40aa0 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 16 Apr 2024 17:03:34 +0200 Subject: [PATCH 26/59] feat(memberListActivities): show time bar in tooltip --- src/plugins/memberListActivities/index.tsx | 22 +++++++++++++++++++++ src/plugins/memberListActivities/styles.css | 6 ++++++ 2 files changed, 28 insertions(+) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index ce61f637b..5cfb8d302 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -47,6 +47,11 @@ const settings = definePluginSettings({ }, }); +interface Timestamp { + start?: number; + end?: number; +} + interface Activity { created_at: number; id: string; @@ -68,6 +73,7 @@ interface Activity { small_text?: string; small_image?: string; }; + timestamps?: Timestamp; platform?: string; } @@ -121,6 +127,13 @@ const { fetchApplication }: { fetchApplication: (id: string) => Promise; } = findByPropsLazy("fetchApplication"); +const TimeBar: React.ComponentType> = findComponentByCodeLazy("isSingleLine"); + // if discord one day decides changes their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); @@ -141,6 +154,13 @@ function getActivityImage(activity: Activity): string | undefined { // TODO: we could support other assets here } +function getValidTimestamps(activity: Activity): Required | null { + if (activity.timestamps?.start !== undefined && activity.timestamps?.end !== undefined) { + return activity.timestamps as Required; + } + return null; +} + const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { const image = useMemo(() => { const activityImage = getActivityImage(activity); @@ -150,6 +170,7 @@ const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { const icon = getApplicationIcons([activity], true)[0]; return icon?.image.src; }, [activity]); + const timestamps = useMemo(() => getValidTimestamps(activity), [activity]); const hasDetails = activity.details ?? activity.state; return ( @@ -162,6 +183,7 @@ const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => {
{activity.details}
{activity.state}
+ {timestamps && }
); diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css index c4b302cf2..f6a436af0 100644 --- a/src/plugins/memberListActivities/styles.css +++ b/src/plugins/memberListActivities/styles.css @@ -51,3 +51,9 @@ flex-direction: column; color: var(--text-muted); } + +.vc-mla-activity-time-bar { + width: 100%; + margin-top: 3px; + margin-bottom: 3px; +} From 17b9e782720dec282ea58d62bb1c1345631f6c84 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 16 Apr 2024 18:22:23 +0200 Subject: [PATCH 27/59] fix(memberListActivities): add word-break to fix cut off text --- src/plugins/memberListActivities/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css index f6a436af0..9caeb4319 100644 --- a/src/plugins/memberListActivities/styles.css +++ b/src/plugins/memberListActivities/styles.css @@ -50,6 +50,7 @@ display: flex; flex-direction: column; color: var(--text-muted); + word-break: break-word; } .vc-mla-activity-time-bar { From c0f97446b8e0c0a4b635e865e111d616f3ba6870 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 18 Apr 2024 08:03:08 +0200 Subject: [PATCH 28/59] refactor(memberListActivities): move types to their own file --- src/plugins/memberListActivities/index.tsx | 76 +-------------------- src/plugins/memberListActivities/types.ts | 78 ++++++++++++++++++++++ 2 files changed, 81 insertions(+), 73 deletions(-) create mode 100644 src/plugins/memberListActivities/types.ts diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 5cfb8d302..1c71be6ff 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -24,12 +24,12 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; -import { Tooltip, useMemo } from "@webpack/common"; +import { React, Tooltip, useMemo } from "@webpack/common"; import { User } from "discord-types/general"; -import type { ImgHTMLAttributes } from "react"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; +import { Activity, ActivityListIcon, Application, ApplicationIcon, Timestamp } from "./types"; const settings = definePluginSettings({ iconSize: { @@ -47,78 +47,8 @@ const settings = definePluginSettings({ }, }); -interface Timestamp { - start?: number; - end?: number; -} - -interface Activity { - created_at: number; - id: string; - name: string; - type: number; - emoji?: { - animated: boolean; - id: string; - name: string; - } - state?: string; - flags?: number; - sync_id?: string; - details?: string; - application_id?: string; - assets?: { - large_text?: string; - large_image?: string; - small_text?: string; - small_image?: string; - }; - timestamps?: Timestamp; - platform?: string; -} - const cl = classNameFactory("vc-mla-"); -interface Application { - id: string; - name: string; - icon: string; - description: string; - summary: string; - type: number; - hook: boolean; - guild_id: string; - executables: Executable[]; - verify_key: string; - publishers: Developer[]; - developers: Developer[]; - flags: number; -} - -interface Developer { - id: string; - name: string; -} - -interface Executable { - os: string; - name: string; - is_launcher: boolean; -} -interface ApplicationIcon { - image: ImgHTMLAttributes & { - src: string; - alt: string; - }; - activity: Activity; - application?: Application; -} - -interface ActivityListIcon { - iconElement: JSX.Element; - tooltip?: JSX.Element | string; -} - const ApplicationStore: { getApplication: (id: string) => Application | null; } = findStoreLazy("ApplicationStore"); @@ -296,7 +226,6 @@ export default definePlugin({ tooltip: }); } - const twitchActivity = activities.find(({ name }) => name === "Twitch"); if (twitchActivity) { icons.push({ @@ -304,6 +233,7 @@ export default definePlugin({ tooltip: }); } + const applicationIcons = getApplicationIcons(activities); if (applicationIcons.length) { const compareImageSource = (a: ApplicationIcon, b: ApplicationIcon) => { diff --git a/src/plugins/memberListActivities/types.ts b/src/plugins/memberListActivities/types.ts new file mode 100644 index 000000000..7f3f2b509 --- /dev/null +++ b/src/plugins/memberListActivities/types.ts @@ -0,0 +1,78 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import type { ImgHTMLAttributes } from "react"; + +export interface Timestamp { + start?: number; + end?: number; +} + +export interface Activity { + created_at: number; + id: string; + name: string; + type: number; + emoji?: { + animated: boolean; + id: string; + name: string; + } + state?: string; + flags?: number; + sync_id?: string; + details?: string; + application_id?: string; + assets?: { + large_text?: string; + large_image?: string; + small_text?: string; + small_image?: string; + }; + timestamps?: Timestamp; + platform?: string; +} + +export interface Application { + id: string; + name: string; + icon: string; + description: string; + summary: string; + type: number; + hook: boolean; + guild_id: string; + executables: Executable[]; + verify_key: string; + publishers: Developer[]; + developers: Developer[]; + flags: number; +} + +export interface Developer { + id: string; + name: string; +} + +export interface Executable { + os: string; + name: string; + is_launcher: boolean; +} + +export interface ApplicationIcon { + image: ImgHTMLAttributes & { + src: string; + alt: string; + }; + activity: Activity; + application?: Application; +} + +export interface ActivityListIcon { + iconElement: JSX.Element; + tooltip?: JSX.Element | string; +} From 7fee537ea1e9150832ef9a274bfb60650cb90a5b Mon Sep 17 00:00:00 2001 From: Nico Date: Thu, 18 Apr 2024 08:21:47 +0200 Subject: [PATCH 29/59] chore(memberListActivities): fix typo in comment --- src/plugins/memberListActivities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index 1c71be6ff..d2cc00422 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -64,7 +64,7 @@ const TimeBar: React.ComponentType> = findComponentByCodeLazy("isSingleLine"); -// if discord one day decides changes their icon this needs to be updated +// if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); const fetchedApplications = new Map(); From 957639be6cec6e13880cb2aee8d79e7fe692c3be Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 18 Apr 2024 23:32:21 +0200 Subject: [PATCH 30/59] feat(memberListActivities): show elapsed time in tooltip and support twitch images --- src/plugins/memberListActivities/index.tsx | 47 ++++++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/memberListActivities/index.tsx index d2cc00422..ec45fa2e0 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/memberListActivities/index.tsx @@ -24,7 +24,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; -import { React, Tooltip, useMemo } from "@webpack/common"; +import { moment, React, Tooltip, useMemo } from "@webpack/common"; import { User } from "discord-types/general"; import { SpotifyIcon } from "./components/SpotifyIcon"; @@ -71,16 +71,24 @@ const fetchedApplications = new Map(); const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; // TODO: replace with "renderXboxImage"? -function getActivityImage(activity: Activity): string | undefined { +function getActivityImage(activity: Activity, application?: Application): string | undefined { if (activity.type === 2 && activity.name === "Spotify") { // get either from large or small image const image = activity.assets?.large_image ?? activity.assets?.small_image; - // image needs to replace 'spotify: + // image needs to replace 'spotify:' if (image?.startsWith("spotify:")) { // spotify cover art is always https://i.scdn.co/image/ID return image.replace("spotify:", "https://i.scdn.co/image/"); } } + if (activity.type === 1 && activity.name === "Twitch") { + const image = activity.assets?.large_image; + // image needs to replace 'twitch:' + if (image?.startsWith("twitch:")) { + // twitch images are always https://static-cdn.jtvnw.net/previews-ttv/live_user_USERNAME-RESOLTUON.jpg + return `${image.replace("twitch:", "https://static-cdn.jtvnw.net/previews-ttv/live_user_")}-108x60.jpg`; + } + } // TODO: we could support other assets here } @@ -91,9 +99,27 @@ function getValidTimestamps(activity: Activity): Required | null { return null; } -const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { +function getValidStartTimeStamp(activity: Activity): number | null { + if (activity.timestamps?.start !== undefined) { + return activity.timestamps.start; + } + return null; +} + +const customFormat = (momentObj: moment.Moment): string => { + const hours = momentObj.hours(); + const formattedTime = momentObj.format("mm:ss"); + return hours > 0 ? `${momentObj.format("HH:")}${formattedTime}` : formattedTime; +}; + +function formatElapsedTime(startTime: moment.Moment, endTime: moment.Moment): string { + const duration = moment.duration(endTime.diff(startTime)); + return `${customFormat(moment.utc(duration.asMilliseconds()))} elapsed`; +} + +const ActivityTooltip = ({ activity, application }: Readonly<{ activity: Activity, application?: Application }>) => { const image = useMemo(() => { - const activityImage = getActivityImage(activity); + const activityImage = getActivityImage(activity, application); if (activityImage) { return activityImage; } @@ -101,6 +127,7 @@ const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => { return icon?.image.src; }, [activity]); const timestamps = useMemo(() => getValidTimestamps(activity), [activity]); + const startTime = useMemo(() => getValidStartTimeStamp(activity), [activity]); const hasDetails = activity.details ?? activity.state; return ( @@ -112,14 +139,18 @@ const ActivityTooltip = ({ activity }: Readonly<{ activity: Activity }>) => {
{activity.details}
{activity.state}
+ {!timestamps && startTime && +
+ {formatElapsedTime(moment(startTime), moment())} +
+ }
- {timestamps && } + {timestamps && }
); }; - function getApplicationIcons(activities: Activity[], preferSmall = false) { const applicationIcons: ApplicationIcon[] = []; const applications = activities.filter(activity => activity.application_id || activity.platform); @@ -245,7 +276,7 @@ export default definePlugin({ for (const appIcon of uniqueIcons) { icons.push({ iconElement: , - tooltip: + tooltip: }); } } From 4e430c42527556c8ddebd5bc327cee99c88828bc Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 6 May 2024 19:04:17 +0200 Subject: [PATCH 31/59] feat(betterActivities): rename and add show all activities functionality --- src/plugins/betterActivities/README.md | 6 + .../betterActivities/components/Caret.tsx | 13 ++ .../components/SpotifyIcon.tsx | 0 .../components/TwitchIcon.tsx | 0 .../index.tsx | 170 +++++++++++++++--- src/plugins/betterActivities/popout.png | Bin 0 -> 11607 bytes .../screenshot.png | Bin src/plugins/betterActivities/styles.css | 131 ++++++++++++++ .../types.ts | 6 +- src/plugins/memberListActivities/README.md | 5 - src/plugins/memberListActivities/styles.css | 60 ------- 11 files changed, 304 insertions(+), 87 deletions(-) create mode 100644 src/plugins/betterActivities/README.md create mode 100644 src/plugins/betterActivities/components/Caret.tsx rename src/plugins/{memberListActivities => betterActivities}/components/SpotifyIcon.tsx (100%) rename src/plugins/{memberListActivities => betterActivities}/components/TwitchIcon.tsx (100%) rename src/plugins/{memberListActivities => betterActivities}/index.tsx (66%) create mode 100644 src/plugins/betterActivities/popout.png rename src/plugins/{memberListActivities => betterActivities}/screenshot.png (100%) create mode 100644 src/plugins/betterActivities/styles.css rename src/plugins/{memberListActivities => betterActivities}/types.ts (90%) delete mode 100644 src/plugins/memberListActivities/README.md delete mode 100644 src/plugins/memberListActivities/styles.css diff --git a/src/plugins/betterActivities/README.md b/src/plugins/betterActivities/README.md new file mode 100644 index 000000000..b40385675 --- /dev/null +++ b/src/plugins/betterActivities/README.md @@ -0,0 +1,6 @@ +# BetterActivities + +Shows activity icons in the member list and allows showing all activities + +![Screenshot](screenshot.png) +![Popout](popout.png) diff --git a/src/plugins/betterActivities/components/Caret.tsx b/src/plugins/betterActivities/components/Caret.tsx new file mode 100644 index 000000000..b948d4358 --- /dev/null +++ b/src/plugins/betterActivities/components/Caret.tsx @@ -0,0 +1,13 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export function Caret({ disabled, direction }: { disabled: boolean; direction: "left" | "right"; }) { + return ( + + + + ); +} diff --git a/src/plugins/memberListActivities/components/SpotifyIcon.tsx b/src/plugins/betterActivities/components/SpotifyIcon.tsx similarity index 100% rename from src/plugins/memberListActivities/components/SpotifyIcon.tsx rename to src/plugins/betterActivities/components/SpotifyIcon.tsx diff --git a/src/plugins/memberListActivities/components/TwitchIcon.tsx b/src/plugins/betterActivities/components/TwitchIcon.tsx similarity index 100% rename from src/plugins/memberListActivities/components/TwitchIcon.tsx rename to src/plugins/betterActivities/components/TwitchIcon.tsx diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/betterActivities/index.tsx similarity index 66% rename from src/plugins/memberListActivities/index.tsx rename to src/plugins/betterActivities/index.tsx index ec45fa2e0..23ae64daa 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -23,15 +23,34 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; -import { moment, React, Tooltip, useMemo } from "@webpack/common"; -import { User } from "discord-types/general"; +import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; +import { moment, PresenceStore, React, Tooltip, useMemo, useStateFromStores } from "@webpack/common"; +import { Guild, User } from "discord-types/general"; +import { Caret } from "./components/Caret"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; -import { Activity, ActivityListIcon, Application, ApplicationIcon, Timestamp } from "./types"; +import { Activity, ActivityListIcon, Application, ApplicationIcon, IconCSSProperties, Timestamp } from "./types"; const settings = definePluginSettings({ + memberList: { + type: OptionType.BOOLEAN, + description: "Show activity icons in the member list", + default: true, + restartNeeded: true, + }, + profileSidebar: { + type: OptionType.BOOLEAN, + description: "Show all activities in the profile sidebar", + default: true, + restartNeeded: true, + }, + userPopout: { + type: OptionType.BOOLEAN, + description: "Show all activities in the user popout", + default: true, + restartNeeded: true, + }, iconSize: { type: OptionType.SLIDER, description: "Size of the activity icons", @@ -47,7 +66,7 @@ const settings = definePluginSettings({ }, }); -const cl = classNameFactory("vc-mla-"); +const cl = classNameFactory("vc-bactivities-"); const ApplicationStore: { getApplication: (id: string) => Application | null; @@ -57,12 +76,14 @@ const { fetchApplication }: { fetchApplication: (id: string) => Promise; } = findByPropsLazy("fetchApplication"); -const TimeBar: React.ComponentType> = findComponentByCodeLazy("isSingleLine"); +}>("isSingleLine"); + +const ActivityView = findByCodeLazy("onOpenGameProfile:"); // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); @@ -117,7 +138,7 @@ function formatElapsedTime(startTime: moment.Moment, endTime: moment.Moment): st return `${customFormat(moment.utc(duration.asMilliseconds()))} elapsed`; } -const ActivityTooltip = ({ activity, application }: Readonly<{ activity: Activity, application?: Application }>) => { +const ActivityTooltip = ({ activity, application, user }: Readonly<{ activity: Activity, application?: Application, user: User; }>) => { const image = useMemo(() => { const activityImage = getActivityImage(activity, application); if (activityImage) { @@ -145,7 +166,7 @@ const ActivityTooltip = ({ activity, application }: Readonly<{ activity: Activit } - {timestamps && } + {timestamps && } ); @@ -240,28 +261,28 @@ function getApplicationIcons(activities: Activity[], preferSmall = false) { } export default definePlugin({ - name: "MemberListActivities", - description: "Shows activity icons in the member list", - authors: [Devs.D3SOX], + name: "BetterActivities", + description: "Shows activity icons in the member list and allows showing all activities", + authors: [Devs.D3SOX, Devs.Arjix, Devs.AutumnVN], tags: ["activity"], settings, - patchActivityList: ({ activities, user }: { activities: Activity[], user: User }): JSX.Element | null => { + patchActivityList: ({ activities, user }: { activities: Activity[], user: User; }): JSX.Element | null => { const icons: ActivityListIcon[] = []; const spotifyActivity = activities.find(({ name }) => name === "Spotify"); if (spotifyActivity) { icons.push({ iconElement: , - tooltip: + tooltip: }); } const twitchActivity = activities.find(({ name }) => name === "Twitch"); if (twitchActivity) { icons.push({ iconElement: , - tooltip: + tooltip: }); } @@ -276,19 +297,20 @@ export default definePlugin({ for (const appIcon of uniqueIcons) { icons.push({ iconElement: , - tooltip: + tooltip: }); } } if (icons.length) { + const iconStyle: IconCSSProperties = { + "--icon-size": `${settings.store.iconSize}px`, + }; + return
{icons.map(({ iconElement, tooltip }, i) => ( -
+
{tooltip ? {({ onMouseEnter, onMouseLeave }) => (
void; }) { + const [currentActivity, setCurrentActivity] = React.useState( + activity?.type !== 4 ? activity! : null + ); + + const activities = useStateFromStores( + [PresenceStore], () => PresenceStore.getActivities(user.id).filter((activity: Activity) => activity.type !== 4) + ) ?? []; + + React.useEffect(() => { + if (!activities.length) { + setCurrentActivity(null); + return; + } + + if (!currentActivity || !activities.includes(currentActivity)) + setCurrentActivity(activities[0]); + + }, [activities]); + + if (!activities.length) return null; + + return ( +
+ +
+ {({ onMouseEnter, onMouseLeave }) => { + return { + const index = activities.indexOf(currentActivity!); + if (index - 1 >= 0) + setCurrentActivity(activities[index - 1]); + }} + > + + ; + }} + +
+ {activities.map((activity, index) => ( +
setCurrentActivity(activity)} + className={`dot ${currentActivity === activity ? "selected" : ""}`} + /> + ))} +
+ + {({ onMouseEnter, onMouseLeave }) => { + return { + const index = activities.indexOf(currentActivity!); + if (index + 1 < activities.length) + setCurrentActivity(activities[index + 1]); + }} + > + = activities.length - 1} + direction="right" + /> + ; + }} +
+
+ ); + }, + patches: [ { // Patch activity icons @@ -321,7 +430,26 @@ export default definePlugin({ replacement: { match: /null!=(\i)&&\i.some\(\i=>\(0,\i.default\)\(\i,\i\)\)\?/, replace: "$self.patchActivityList(e),false?" - } + }, + predicate: () => settings.store.memberList, }, + { + // Show all activities in the profile panel + find: "Profile Panel: user cannot be undefined", + replacement: { + match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{activity:.+?,user:\i,channelId:\i.id,)/, + replace: "$self.showAllActivitiesComponent" + }, + predicate: () => settings.store.profileSidebar, + }, + { + // Show all activities in the user popout + find: "customStatusSection,", + replacement: { + match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{activity:\i,user:\i,guild:\i,channelId:\i,onClose:\i,)/, + replace: "$self.showAllActivitiesComponent" + }, + predicate: () => settings.store.userPopout + } ], }); diff --git a/src/plugins/betterActivities/popout.png b/src/plugins/betterActivities/popout.png new file mode 100644 index 0000000000000000000000000000000000000000..c7e572188923de917aa7290741f35a3248800ce8 GIT binary patch literal 11607 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 literal 0 HcmV?d00001 diff --git a/src/plugins/memberListActivities/screenshot.png b/src/plugins/betterActivities/screenshot.png similarity index 100% rename from src/plugins/memberListActivities/screenshot.png rename to src/plugins/betterActivities/screenshot.png diff --git a/src/plugins/betterActivities/styles.css b/src/plugins/betterActivities/styles.css new file mode 100644 index 000000000..743f5d213 --- /dev/null +++ b/src/plugins/betterActivities/styles.css @@ -0,0 +1,131 @@ +.vc-bactivities-row { + display: flex; + flex-wrap: nowrap; + align-items: center; + margin-left: 5px; + text-align: center; + gap: 3px; +} + +.vc-bactivities-icon { + height: var(--icon-size); + width: var(--icon-size); +} + +.vc-bactivities-icon img { + width: var(--icon-size); + height: var(--icon-size); + object-fit: cover; + border-radius: 50%; +} + +.vc-bactivities-activity { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + gap: 5px; +} + +.vc-bactivities-activity-title { + font-weight: bold; + text-align: center; +} + +.vc-bactivities-activity-image { + height: 20px; + width: 20px; + border-radius: 50%; + object-fit: cover; +} + +.vc-bactivities-activity-divider { + width: 100%; + border-top: 1px dotted rgb(255 255 255 / 20%); + margin-top: 3px; + margin-bottom: 3px; +} + +.vc-bactivities-activity-details { + display: flex; + flex-direction: column; + color: var(--text-muted); + word-break: break-word; +} + +.vc-bactivities-activity-time-bar { + width: 100%; + margin-top: 3px; + margin-bottom: 3px; +} + +.vc-bactivities-caret-left, +.vc-bactivities-caret-right { + color: #ddd; +} + +.vc-bactivities-caret-left { + transform: rotate(90deg); +} + +.vc-bactivities-caret-right { + transform: rotate(-90deg); +} + +.vc-bactivities-controls { + display: flex; + align-items: center; + justify-content: space-between; + padding: 5px; + background: var(--background-secondary-alt); + border-radius: 3px; + flex: 1 0; + margin-top: 10px; +} + +.vc-bactivities-controls [class^="vc-activities-caret-"] { + display: inline-flex; + align-items: center; + justify-content: center; + cursor: pointer; + border-radius: 3px; + background-color: #ffffff4d; +} + +.vc-bactivities-controls [class^="vc-activities-caret-"].disabled { + cursor: not-allowed; + opacity: 0.3; +} + +.vc-bactivities-controls [class^="vc-activities-caret-"]:hover:not(.disabled) { + background: var(--background-modifier-accent); +} + +.vc-bactivities-controls .carousell { + display: flex; + align-items: center; +} + +.vc-bactivities-controls .carousell .dot { + margin: 0 4px; + width: 10px; + cursor: pointer; + height: 10px; + border-radius: 100px; + background: var(--interactive-muted); + transition: background 0.3s; + opacity: 0.6; +} + +.vc-bactivities-controls .carousell .dot:hover:not(.selected) { + opacity: 1; +} + +.vc-bactivities-controls .carousell .dot.selected { + opacity: 1; + background: var(--dot-color, var(--brand-experiment)); +} + +.vc-bactivities-controls-tooltip { + --background-floating: var(--background-secondary); +} diff --git a/src/plugins/memberListActivities/types.ts b/src/plugins/betterActivities/types.ts similarity index 90% rename from src/plugins/memberListActivities/types.ts rename to src/plugins/betterActivities/types.ts index 7f3f2b509..7e7421cb7 100644 --- a/src/plugins/memberListActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import type { ImgHTMLAttributes } from "react"; +import { CSSProperties, ImgHTMLAttributes } from "react"; export interface Timestamp { start?: number; @@ -76,3 +76,7 @@ export interface ActivityListIcon { iconElement: JSX.Element; tooltip?: JSX.Element | string; } + +export interface IconCSSProperties extends CSSProperties { + "--icon-size": string; +} diff --git a/src/plugins/memberListActivities/README.md b/src/plugins/memberListActivities/README.md deleted file mode 100644 index fe67bad79..000000000 --- a/src/plugins/memberListActivities/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# MemberListActivities - -Shows activity icons in the member list - -![Screenshot](screenshot.png) diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css deleted file mode 100644 index 9caeb4319..000000000 --- a/src/plugins/memberListActivities/styles.css +++ /dev/null @@ -1,60 +0,0 @@ -.vc-mla-row { - display: flex; - flex-wrap: nowrap; - align-items: center; - margin-left: 5px; - text-align: center; - gap: 3px; -} - -.vc-mla-icon { - height: 20px; - width: 20px; -} - -.vc-mla-icon img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 50%; -} - -.vc-mla-activity { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - gap: 5px; -} - -.vc-mla-activity-title { - font-weight: bold; - text-align: center; -} - -.vc-mla-activity-image { - height: 20px; - width: 20px; - border-radius: 50%; - object-fit: cover; -} - -.vc-mla-activity-divider { - width: 100%; - border-top: 1px dotted rgb(255 255 255 / 20%); - margin-top: 3px; - margin-bottom: 3px; -} - -.vc-mla-activity-details { - display: flex; - flex-direction: column; - color: var(--text-muted); - word-break: break-word; -} - -.vc-mla-activity-time-bar { - width: 100%; - margin-top: 3px; - margin-bottom: 3px; -} From 58eb7943dbb629f5b8e697e35e87ca3cf3b79f94 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 6 May 2024 20:27:16 +0200 Subject: [PATCH 32/59] refactor(betterActivities): add type for ActivityView component --- src/plugins/betterActivities/index.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 23ae64daa..f6b35ebff 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -23,7 +23,7 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; +import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; import { moment, PresenceStore, React, Tooltip, useMemo, useStateFromStores } from "@webpack/common"; import { Guild, User } from "discord-types/general"; @@ -83,7 +83,13 @@ const TimeBar = findComponentByCodeLazy<{ className: string; }>("isSingleLine"); -const ActivityView = findByCodeLazy("onOpenGameProfile:"); +const ActivityView = findComponentByCodeLazy<{ + activity: Activity | null; + user: User; + guild: Guild; + channelId: string; + onClose: () => void; + }>("onOpenGameProfile:"); // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); From 4f0e9312ec671a5bc20d80b0b8f34c60cab27ff5 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 7 May 2024 10:04:53 +0200 Subject: [PATCH 33/59] feat(betterActivities): allow showing all activities below each other --- src/plugins/betterActivities/index.tsx | 154 ++++++++++++++++--------- 1 file changed, 97 insertions(+), 57 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index f6b35ebff..1c7699813 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -64,6 +64,21 @@ const settings = definePluginSettings({ default: true, restartNeeded: false, }, + allActivitiesStyle: { + type: OptionType.SELECT, + description: "Style for showing all activities", + options: [ + { + default: true, + label: "Carousel", + value: "carousel", + }, + { + label: "List", + value: "list", + }, + ] + } }); const cl = classNameFactory("vc-bactivities-"); @@ -364,69 +379,94 @@ export default definePlugin({ if (!activities.length) return null; - return ( -
- + if (settings.store.allActivitiesStyle === "carousel") { + return ( +
+ +
+ {({ + onMouseEnter, + onMouseLeave + }) => { + return { + const index = activities.indexOf(currentActivity!); + if (index - 1 >= 0) + setCurrentActivity(activities[index - 1]); + }} + > + + ; + }} + +
+ {activities.map((activity, index) => ( +
setCurrentActivity(activity)} + className={`dot ${currentActivity === activity ? "selected" : ""}`}/> + ))} +
+ + {({ + onMouseEnter, + onMouseLeave + }) => { + return { + const index = activities.indexOf(currentActivity!); + if (index + 1 < activities.length) + setCurrentActivity(activities[index + 1]); + }} + > + = activities.length - 1} + direction="right"/> + ; + }} +
+
+ ); + } else { + return (
- {({ onMouseEnter, onMouseLeave }) => { - return { - const index = activities.indexOf(currentActivity!); - if (index - 1 >= 0) - setCurrentActivity(activities[index - 1]); - }} - > - - ; - }} - -
- {activities.map((activity, index) => ( -
setCurrentActivity(activity)} - className={`dot ${currentActivity === activity ? "selected" : ""}`} - /> - ))} -
- - {({ onMouseEnter, onMouseLeave }) => { - return { - const index = activities.indexOf(currentActivity!); - if (index + 1 < activities.length) - setCurrentActivity(activities[index + 1]); - }} - > - = activities.length - 1} - direction="right" - /> - ; - }} + {activities.map((activity, index) => ( + + ))}
-
- ); + ); + } }, patches: [ From d7d64f420c656eb8cc90914ffb9c4646807c4c40 Mon Sep 17 00:00:00 2001 From: Nico Date: Thu, 9 May 2024 17:57:11 +0200 Subject: [PATCH 34/59] fix(betterActivities): set default icon size to 15 idk why I've set this to 20 --- src/plugins/betterActivities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 1c7699813..1bba5426f 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -55,7 +55,7 @@ const settings = definePluginSettings({ type: OptionType.SLIDER, description: "Size of the activity icons", markers: [10, 15, 20], - default: 20, + default: 15, stickToMarkers: false, }, renderGifs: { From 8602141fea22b788d91b64120e548b6af7026aac Mon Sep 17 00:00:00 2001 From: D3SOX Date: Sat, 11 May 2024 00:02:46 +0200 Subject: [PATCH 35/59] feat(betterActivities): setting to not show special ones first and reorganize/group the settings --- src/plugins/betterActivities/index.tsx | 79 +++++++++++++++++--------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 1bba5426f..2cf06a44a 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -39,6 +39,38 @@ const settings = definePluginSettings({ default: true, restartNeeded: true, }, + iconSize: { + type: OptionType.SLIDER, + description: "Size of the activity icons", + markers: [10, 15, 20], + default: 15, + stickToMarkers: false, + }, + specialFirst: { + type: OptionType.BOOLEAN, + description: "Show special activities first (Currently Spotify and Twitch)", + default: true, + restartNeeded: false, + }, + renderGifs: { + type: OptionType.BOOLEAN, + description: "Allow rendering GIFs", + default: true, + restartNeeded: false, + }, + divider: { + type: OptionType.COMPONENT, + description: "", + component: () => ( +
+ ), + }, profileSidebar: { type: OptionType.BOOLEAN, description: "Show all activities in the profile sidebar", @@ -51,19 +83,6 @@ const settings = definePluginSettings({ default: true, restartNeeded: true, }, - iconSize: { - type: OptionType.SLIDER, - description: "Size of the activity icons", - markers: [10, 15, 20], - default: 15, - stickToMarkers: false, - }, - renderGifs: { - type: OptionType.BOOLEAN, - description: "Allow rendering GIFs", - default: true, - restartNeeded: false, - }, allActivitiesStyle: { type: OptionType.SELECT, description: "Style for showing all activities", @@ -292,21 +311,6 @@ export default definePlugin({ patchActivityList: ({ activities, user }: { activities: Activity[], user: User; }): JSX.Element | null => { const icons: ActivityListIcon[] = []; - const spotifyActivity = activities.find(({ name }) => name === "Spotify"); - if (spotifyActivity) { - icons.push({ - iconElement: , - tooltip: - }); - } - const twitchActivity = activities.find(({ name }) => name === "Twitch"); - if (twitchActivity) { - icons.push({ - iconElement: , - tooltip: - }); - } - const applicationIcons = getApplicationIcons(activities); if (applicationIcons.length) { const compareImageSource = (a: ApplicationIcon, b: ApplicationIcon) => { @@ -323,6 +327,25 @@ export default definePlugin({ } } + const addActivityIcon = (activityName: string, IconComponent: React.ComponentType) => { + const activityIndex = activities.findIndex(({ name }) => name === activityName); + if (activityIndex !== -1) { + const activity = activities[activityIndex]; + const iconObject = { + iconElement: , + tooltip: + }; + + if (settings.store.specialFirst) { + icons.unshift(iconObject); + } else { + icons.splice(activityIndex, 0, iconObject); + } + } + }; + addActivityIcon("Twitch", TwitchIcon); + addActivityIcon("Spotify", SpotifyIcon); + if (icons.length) { const iconStyle: IconCSSProperties = { "--icon-size": `${settings.store.iconSize}px`, From d31d1b74e0c10a33bb79871a0027c4830ea31600 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Sat, 11 May 2024 00:04:40 +0200 Subject: [PATCH 36/59] chore(betterActivities): add type for icon --- src/plugins/betterActivities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 2cf06a44a..ba6ce3d5e 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -331,7 +331,7 @@ export default definePlugin({ const activityIndex = activities.findIndex(({ name }) => name === activityName); if (activityIndex !== -1) { const activity = activities[activityIndex]; - const iconObject = { + const iconObject: ActivityListIcon = { iconElement: , tooltip: }; From 3ed2edf9672c369fcf681c750acc83f606fc2ff6 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Wed, 15 May 2024 09:04:25 +0200 Subject: [PATCH 37/59] docs(betterActivities): don't include screenshots in git --- src/plugins/betterActivities/README.md | 4 ++-- src/plugins/betterActivities/popout.png | Bin 11607 -> 0 bytes src/plugins/betterActivities/screenshot.png | Bin 7143 -> 0 bytes 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 src/plugins/betterActivities/popout.png delete mode 100644 src/plugins/betterActivities/screenshot.png diff --git a/src/plugins/betterActivities/README.md b/src/plugins/betterActivities/README.md index b40385675..5f3e51ecf 100644 --- a/src/plugins/betterActivities/README.md +++ b/src/plugins/betterActivities/README.md @@ -2,5 +2,5 @@ Shows activity icons in the member list and allows showing all activities -![Screenshot](screenshot.png) -![Popout](popout.png) +![Member List](https://github.com/Vendicated/Vencord/assets/24937357/4c034963-4448-483a-ba1d-c04f74e4aa51) +![Multiple Activities](https://github.com/Vendicated/Vencord/assets/24937357/11a2f15e-59b0-4072-847a-33444d964674) diff --git a/src/plugins/betterActivities/popout.png b/src/plugins/betterActivities/popout.png deleted file mode 100644 index c7e572188923de917aa7290741f35a3248800ce8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11607 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 diff --git a/src/plugins/betterActivities/screenshot.png b/src/plugins/betterActivities/screenshot.png deleted file mode 100644 index 16451da272e21e944206ce72e507ce29099c3267..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7143 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 From dd5dab5efb406ccadd1323f923ecac34b60b008f Mon Sep 17 00:00:00 2001 From: D3SOX Date: Thu, 16 May 2024 22:04:23 +0200 Subject: [PATCH 38/59] docs(betterActivities): add listview screenshot --- src/plugins/betterActivities/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/betterActivities/README.md b/src/plugins/betterActivities/README.md index 5f3e51ecf..6884fa216 100644 --- a/src/plugins/betterActivities/README.md +++ b/src/plugins/betterActivities/README.md @@ -4,3 +4,4 @@ Shows activity icons in the member list and allows showing all activities ![Member List](https://github.com/Vendicated/Vencord/assets/24937357/4c034963-4448-483a-ba1d-c04f74e4aa51) ![Multiple Activities](https://github.com/Vendicated/Vencord/assets/24937357/11a2f15e-59b0-4072-847a-33444d964674) +![List view](https://github.com/Vendicated/Vencord/assets/24937357/277f425f-65e7-4e25-ad98-ff61b4370f08) From 8278641c9b3756d716a5c4e0e964f2d3aa32d674 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 17 May 2024 18:05:00 +0200 Subject: [PATCH 39/59] refactor(betterSettings): split index into multiple files --- .../components/ActivityTooltip.tsx | 69 +++++ src/plugins/betterActivities/index.tsx | 280 ++---------------- src/plugins/betterActivities/settings.tsx | 79 +++++ src/plugins/betterActivities/types.ts | 9 + src/plugins/betterActivities/utils.ts | 158 ++++++++++ 5 files changed, 332 insertions(+), 263 deletions(-) create mode 100644 src/plugins/betterActivities/components/ActivityTooltip.tsx create mode 100644 src/plugins/betterActivities/settings.tsx create mode 100644 src/plugins/betterActivities/utils.ts diff --git a/src/plugins/betterActivities/components/ActivityTooltip.tsx b/src/plugins/betterActivities/components/ActivityTooltip.tsx new file mode 100644 index 000000000..64839d4a2 --- /dev/null +++ b/src/plugins/betterActivities/components/ActivityTooltip.tsx @@ -0,0 +1,69 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { classNameFactory } from "@api/Styles"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { findComponentByCodeLazy } from "@webpack"; +import { moment, React, useMemo } from "@webpack/common"; +import { User } from "discord-types/general"; + +import { Activity, Application } from "../types"; +import { + formatElapsedTime, + getActivityImage, + getApplicationIcons, + getValidStartTimeStamp, + getValidTimestamps +} from "../utils"; + +const TimeBar = findComponentByCodeLazy<{ + start: number; + end: number; + themed: boolean; + className: string; +}>("isSingleLine"); + +const ActivityTooltip = ({ activity, application, user, cl }: Readonly<{ activity: Activity, application?: Application, user: User; cl: ReturnType }>) => { + const image = useMemo(() => { + const activityImage = getActivityImage(activity, application); + if (activityImage) { + return activityImage; + } + const icon = getApplicationIcons([activity], true)[0]; + return icon?.image.src; + }, [activity]); + const timestamps = useMemo(() => getValidTimestamps(activity), [activity]); + const startTime = useMemo(() => getValidStartTimeStamp(activity), [activity]); + + const hasDetails = activity.details ?? activity.state; + return ( + +
+ {image && Activity logo} +
{activity.name}
+ {hasDetails &&
} +
+
{activity.details}
+
{activity.state}
+ {!timestamps && startTime && +
+ {formatElapsedTime(moment(startTime), moment())} +
+ } +
+ {timestamps && ( + + )} +
+ + ); +}; + +export default ActivityTooltip; diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index ba6ce3d5e..d51778de1 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -18,105 +18,26 @@ import "./styles.css"; -import { definePluginSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; -import { moment, PresenceStore, React, Tooltip, useMemo, useStateFromStores } from "@webpack/common"; +import definePlugin from "@utils/types"; +import { findComponentByCodeLazy } from "@webpack"; +import { PresenceStore, React, Tooltip, useStateFromStores } from "@webpack/common"; import { Guild, User } from "discord-types/general"; +import ActivityTooltip from "./components/ActivityTooltip"; import { Caret } from "./components/Caret"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; -import { Activity, ActivityListIcon, Application, ApplicationIcon, IconCSSProperties, Timestamp } from "./types"; - -const settings = definePluginSettings({ - memberList: { - type: OptionType.BOOLEAN, - description: "Show activity icons in the member list", - default: true, - restartNeeded: true, - }, - iconSize: { - type: OptionType.SLIDER, - description: "Size of the activity icons", - markers: [10, 15, 20], - default: 15, - stickToMarkers: false, - }, - specialFirst: { - type: OptionType.BOOLEAN, - description: "Show special activities first (Currently Spotify and Twitch)", - default: true, - restartNeeded: false, - }, - renderGifs: { - type: OptionType.BOOLEAN, - description: "Allow rendering GIFs", - default: true, - restartNeeded: false, - }, - divider: { - type: OptionType.COMPONENT, - description: "", - component: () => ( -
- ), - }, - profileSidebar: { - type: OptionType.BOOLEAN, - description: "Show all activities in the profile sidebar", - default: true, - restartNeeded: true, - }, - userPopout: { - type: OptionType.BOOLEAN, - description: "Show all activities in the user popout", - default: true, - restartNeeded: true, - }, - allActivitiesStyle: { - type: OptionType.SELECT, - description: "Style for showing all activities", - options: [ - { - default: true, - label: "Carousel", - value: "carousel", - }, - { - label: "List", - value: "list", - }, - ] - } -}); +import settings from "./settings"; +import { Activity, ActivityListIcon, ActivityViewProps, ApplicationIcon, IconCSSProperties } from "./types"; +import { + getApplicationIcons +} from "./utils"; const cl = classNameFactory("vc-bactivities-"); -const ApplicationStore: { - getApplication: (id: string) => Application | null; -} = findStoreLazy("ApplicationStore"); - -const { fetchApplication }: { - fetchApplication: (id: string) => Promise; -} = findByPropsLazy("fetchApplication"); - -const TimeBar = findComponentByCodeLazy<{ - start: number; - end: number; - themed: boolean; - className: string; -}>("isSingleLine"); - const ActivityView = findComponentByCodeLazy<{ activity: Activity | null; user: User; @@ -128,178 +49,6 @@ const ActivityView = findComponentByCodeLazy<{ // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); -const fetchedApplications = new Map(); - -const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; // TODO: replace with "renderXboxImage"? - -function getActivityImage(activity: Activity, application?: Application): string | undefined { - if (activity.type === 2 && activity.name === "Spotify") { - // get either from large or small image - const image = activity.assets?.large_image ?? activity.assets?.small_image; - // image needs to replace 'spotify:' - if (image?.startsWith("spotify:")) { - // spotify cover art is always https://i.scdn.co/image/ID - return image.replace("spotify:", "https://i.scdn.co/image/"); - } - } - if (activity.type === 1 && activity.name === "Twitch") { - const image = activity.assets?.large_image; - // image needs to replace 'twitch:' - if (image?.startsWith("twitch:")) { - // twitch images are always https://static-cdn.jtvnw.net/previews-ttv/live_user_USERNAME-RESOLTUON.jpg - return `${image.replace("twitch:", "https://static-cdn.jtvnw.net/previews-ttv/live_user_")}-108x60.jpg`; - } - } - // TODO: we could support other assets here -} - -function getValidTimestamps(activity: Activity): Required | null { - if (activity.timestamps?.start !== undefined && activity.timestamps?.end !== undefined) { - return activity.timestamps as Required; - } - return null; -} - -function getValidStartTimeStamp(activity: Activity): number | null { - if (activity.timestamps?.start !== undefined) { - return activity.timestamps.start; - } - return null; -} - -const customFormat = (momentObj: moment.Moment): string => { - const hours = momentObj.hours(); - const formattedTime = momentObj.format("mm:ss"); - return hours > 0 ? `${momentObj.format("HH:")}${formattedTime}` : formattedTime; -}; - -function formatElapsedTime(startTime: moment.Moment, endTime: moment.Moment): string { - const duration = moment.duration(endTime.diff(startTime)); - return `${customFormat(moment.utc(duration.asMilliseconds()))} elapsed`; -} - -const ActivityTooltip = ({ activity, application, user }: Readonly<{ activity: Activity, application?: Application, user: User; }>) => { - const image = useMemo(() => { - const activityImage = getActivityImage(activity, application); - if (activityImage) { - return activityImage; - } - const icon = getApplicationIcons([activity], true)[0]; - return icon?.image.src; - }, [activity]); - const timestamps = useMemo(() => getValidTimestamps(activity), [activity]); - const startTime = useMemo(() => getValidStartTimeStamp(activity), [activity]); - - const hasDetails = activity.details ?? activity.state; - return ( - -
- {image && Activity logo} -
{activity.name}
- {hasDetails &&
} -
-
{activity.details}
-
{activity.state}
- {!timestamps && startTime && -
- {formatElapsedTime(moment(startTime), moment())} -
- } -
- {timestamps && } -
- - ); -}; - -function getApplicationIcons(activities: Activity[], preferSmall = false) { - const applicationIcons: ApplicationIcon[] = []; - const applications = activities.filter(activity => activity.application_id || activity.platform); - - for (const activity of applications) { - const { assets, application_id, platform } = activity; - if (!application_id && !platform) { - continue; - } - if (assets) { - - const addImage = (image: string, alt: string) => { - if (image.startsWith("mp:")) { - const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; - if (settings.store.renderGifs || !discordMediaLink.endsWith(".gif")) { - applicationIcons.push({ - image: { src: discordMediaLink, alt }, - activity - }); - } - } else { - const src = `https://cdn.discordapp.com/app-assets/${application_id}/${image}.png`; - applicationIcons.push({ - image: { src, alt }, - activity - }); - } - }; - - const smallImage = assets.small_image; - const smallText = assets.small_text ?? "Small Text"; - const largeImage = assets.large_image; - const largeText = assets.large_text ?? "Large Text"; - if (preferSmall) { - if (smallImage) { - addImage(smallImage, smallText); - } else if (largeImage) { - addImage(largeImage, largeText); - } - } else { - if (largeImage) { - addImage(largeImage, largeText); - } else if (smallImage) { - addImage(smallImage, smallText); - } - } - } else if (application_id) { - let application = ApplicationStore.getApplication(application_id); - if (!application) { - if (fetchedApplications.has(application_id)) { - application = fetchedApplications.get(application_id) as Application | null; - } else { - fetchedApplications.set(application_id, null); - fetchApplication(application_id).then(app => { - fetchedApplications.set(application_id, app); - }); - } - } - - if (application) { - if (application.icon) { - const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; - applicationIcons.push({ - image: { src, alt: application.name }, - activity, - application - }); - } else if (platform === "xbox") { - applicationIcons.push({ - image: { src: xboxUrl, alt: "Xbox" }, - activity, - application - }); - } - } - } else { - if (platform === "xbox") { - applicationIcons.push({ - image: { src: xboxUrl, alt: "Xbox" }, - activity - }); - } - } - } - - return applicationIcons; -} - export default definePlugin({ name: "BetterActivities", description: "Shows activity icons in the member list and allows showing all activities", @@ -322,7 +71,12 @@ export default definePlugin({ for (const appIcon of uniqueIcons) { icons.push({ iconElement: , - tooltip: + tooltip: }); } } @@ -333,7 +87,7 @@ export default definePlugin({ const activity = activities[activityIndex]; const iconObject: ActivityListIcon = { iconElement: , - tooltip: + tooltip: }; if (settings.store.specialFirst) { @@ -380,7 +134,7 @@ export default definePlugin({ return null; }, - showAllActivitiesComponent({ activity, user, guild, channelId, onClose }: { activity: Activity; user: User, guild: Guild, channelId: string, onClose: () => void; }) { + showAllActivitiesComponent({ activity, user, guild, channelId, onClose }: ActivityViewProps) { const [currentActivity, setCurrentActivity] = React.useState( activity?.type !== 4 ? activity! : null ); diff --git a/src/plugins/betterActivities/settings.tsx b/src/plugins/betterActivities/settings.tsx new file mode 100644 index 000000000..415976bb8 --- /dev/null +++ b/src/plugins/betterActivities/settings.tsx @@ -0,0 +1,79 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { definePluginSettings } from "@api/Settings"; +import { OptionType } from "@utils/types"; +import { React } from "@webpack/common"; + +const settings = definePluginSettings({ + memberList: { + type: OptionType.BOOLEAN, + description: "Show activity icons in the member list", + default: true, + restartNeeded: true, + }, + iconSize: { + type: OptionType.SLIDER, + description: "Size of the activity icons", + markers: [10, 15, 20], + default: 15, + stickToMarkers: false, + }, + specialFirst: { + type: OptionType.BOOLEAN, + description: "Show special activities first (Currently Spotify and Twitch)", + default: true, + restartNeeded: false, + }, + renderGifs: { + type: OptionType.BOOLEAN, + description: "Allow rendering GIFs", + default: true, + restartNeeded: false, + }, + divider: { + type: OptionType.COMPONENT, + description: "", + component: () => ( +
+ ), + }, + profileSidebar: { + type: OptionType.BOOLEAN, + description: "Show all activities in the profile sidebar", + default: true, + restartNeeded: true, + }, + userPopout: { + type: OptionType.BOOLEAN, + description: "Show all activities in the user popout", + default: true, + restartNeeded: true, + }, + allActivitiesStyle: { + type: OptionType.SELECT, + description: "Style for showing all activities", + options: [ + { + default: true, + label: "Carousel", + value: "carousel", + }, + { + label: "List", + value: "list", + }, + ] + } +}); + +export default settings; diff --git a/src/plugins/betterActivities/types.ts b/src/plugins/betterActivities/types.ts index 7e7421cb7..909435fe2 100644 --- a/src/plugins/betterActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +import { Guild, User } from "discord-types/general"; import { CSSProperties, ImgHTMLAttributes } from "react"; export interface Timestamp { @@ -80,3 +81,11 @@ export interface ActivityListIcon { export interface IconCSSProperties extends CSSProperties { "--icon-size": string; } + +export interface ActivityViewProps { + activity: Activity; + user: User; + guild: Guild; + channelId: string; + onClose: () => void; +} diff --git a/src/plugins/betterActivities/utils.ts b/src/plugins/betterActivities/utils.ts new file mode 100644 index 000000000..d1511acc0 --- /dev/null +++ b/src/plugins/betterActivities/utils.ts @@ -0,0 +1,158 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { findByPropsLazy, findStoreLazy } from "@webpack"; +import { moment } from "@webpack/common"; + +import settings from "./settings"; +import { Activity, Application, ApplicationIcon, Timestamp } from "./types"; + +const ApplicationStore: { + getApplication: (id: string) => Application | null; +} = findStoreLazy("ApplicationStore"); + +const { fetchApplication }: { + fetchApplication: (id: string) => Promise; +} = findByPropsLazy("fetchApplication"); + +export function getActivityImage(activity: Activity, application?: Application): string | undefined { + if (activity.type === 2 && activity.name === "Spotify") { + // get either from large or small image + const image = activity.assets?.large_image ?? activity.assets?.small_image; + // image needs to replace 'spotify:' + if (image?.startsWith("spotify:")) { + // spotify cover art is always https://i.scdn.co/image/ID + return image.replace("spotify:", "https://i.scdn.co/image/"); + } + } + if (activity.type === 1 && activity.name === "Twitch") { + const image = activity.assets?.large_image; + // image needs to replace 'twitch:' + if (image?.startsWith("twitch:")) { + // twitch images are always https://static-cdn.jtvnw.net/previews-ttv/live_user_USERNAME-RESOLTUON.jpg + return `${image.replace("twitch:", "https://static-cdn.jtvnw.net/previews-ttv/live_user_")}-108x60.jpg`; + } + } + // TODO: we could support other assets here +} + +const fetchedApplications = new Map(); + +// TODO: replace with "renderXboxImage"? +const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; + +export function getApplicationIcons(activities: Activity[], preferSmall = false) { + const applicationIcons: ApplicationIcon[] = []; + const applications = activities.filter(activity => activity.application_id || activity.platform); + + for (const activity of applications) { + const { assets, application_id, platform } = activity; + if (!application_id && !platform) { + continue; + } + if (assets) { + + const addImage = (image: string, alt: string) => { + if (image.startsWith("mp:")) { + const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; + if (settings.store.renderGifs || !discordMediaLink.endsWith(".gif")) { + applicationIcons.push({ + image: { src: discordMediaLink, alt }, + activity + }); + } + } else { + const src = `https://cdn.discordapp.com/app-assets/${application_id}/${image}.png`; + applicationIcons.push({ + image: { src, alt }, + activity + }); + } + }; + + const smallImage = assets.small_image; + const smallText = assets.small_text ?? "Small Text"; + const largeImage = assets.large_image; + const largeText = assets.large_text ?? "Large Text"; + if (preferSmall) { + if (smallImage) { + addImage(smallImage, smallText); + } else if (largeImage) { + addImage(largeImage, largeText); + } + } else { + if (largeImage) { + addImage(largeImage, largeText); + } else if (smallImage) { + addImage(smallImage, smallText); + } + } + } else if (application_id) { + let application = ApplicationStore.getApplication(application_id); + if (!application) { + if (fetchedApplications.has(application_id)) { + application = fetchedApplications.get(application_id) as Application | null; + } else { + fetchedApplications.set(application_id, null); + fetchApplication(application_id).then(app => { + fetchedApplications.set(application_id, app); + }); + } + } + + if (application) { + if (application.icon) { + const src = `https://cdn.discordapp.com/app-icons/${application.id}/${application.icon}.png`; + applicationIcons.push({ + image: { src, alt: application.name }, + activity, + application + }); + } else if (platform === "xbox") { + applicationIcons.push({ + image: { src: xboxUrl, alt: "Xbox" }, + activity, + application + }); + } + } + } else { + if (platform === "xbox") { + applicationIcons.push({ + image: { src: xboxUrl, alt: "Xbox" }, + activity + }); + } + } + } + + return applicationIcons; +} + +export function getValidTimestamps(activity: Activity): Required | null { + if (activity.timestamps?.start !== undefined && activity.timestamps?.end !== undefined) { + return activity.timestamps as Required; + } + return null; +} + +export function getValidStartTimeStamp(activity: Activity): number | null { + if (activity.timestamps?.start !== undefined) { + return activity.timestamps.start; + } + return null; +} + +const customFormat = (momentObj: moment.Moment): string => { + const hours = momentObj.hours(); + const formattedTime = momentObj.format("mm:ss"); + return hours > 0 ? `${momentObj.format("HH:")}${formattedTime}` : formattedTime; +}; + +export function formatElapsedTime(startTime: moment.Moment, endTime: moment.Moment): string { + const duration = moment.duration(endTime.diff(startTime)); + return `${customFormat(moment.utc(duration.asMilliseconds()))} elapsed`; +} From 3be954f7137ceb76d3de5f2a19aea2ad1cbf6165 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 17 May 2024 18:06:42 +0200 Subject: [PATCH 40/59] docs(betterSettings): improve alt text --- src/plugins/betterActivities/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/betterActivities/README.md b/src/plugins/betterActivities/README.md index 6884fa216..cebfddbeb 100644 --- a/src/plugins/betterActivities/README.md +++ b/src/plugins/betterActivities/README.md @@ -2,6 +2,6 @@ Shows activity icons in the member list and allows showing all activities -![Member List](https://github.com/Vendicated/Vencord/assets/24937357/4c034963-4448-483a-ba1d-c04f74e4aa51) -![Multiple Activities](https://github.com/Vendicated/Vencord/assets/24937357/11a2f15e-59b0-4072-847a-33444d964674) -![List view](https://github.com/Vendicated/Vencord/assets/24937357/277f425f-65e7-4e25-ad98-ff61b4370f08) +![Shows activity icons next to the status line in the member list](https://github.com/Vendicated/Vencord/assets/24937357/4c034963-4448-483a-ba1d-c04f74e4aa51) +![Shows all activities in the profile via a carousel](https://github.com/Vendicated/Vencord/assets/24937357/11a2f15e-59b0-4072-847a-33444d964674) +![Optionally show all activities as list](https://github.com/Vendicated/Vencord/assets/24937357/277f425f-65e7-4e25-ad98-ff61b4370f08) From f78c9ce6084e68e16f64231616ca20c9d9b51795 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 17 May 2024 18:09:03 +0200 Subject: [PATCH 41/59] refactor(betterSettings): re-use ActivityViewProps type --- src/plugins/betterActivities/index.tsx | 10 ++-------- src/plugins/betterActivities/types.ts | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index d51778de1..47074e0af 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -24,7 +24,7 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { findComponentByCodeLazy } from "@webpack"; import { PresenceStore, React, Tooltip, useStateFromStores } from "@webpack/common"; -import { Guild, User } from "discord-types/general"; +import { User } from "discord-types/general"; import ActivityTooltip from "./components/ActivityTooltip"; import { Caret } from "./components/Caret"; @@ -38,13 +38,7 @@ import { const cl = classNameFactory("vc-bactivities-"); -const ActivityView = findComponentByCodeLazy<{ - activity: Activity | null; - user: User; - guild: Guild; - channelId: string; - onClose: () => void; - }>("onOpenGameProfile:"); +const ActivityView = findComponentByCodeLazy("onOpenGameProfile:"); // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); diff --git a/src/plugins/betterActivities/types.ts b/src/plugins/betterActivities/types.ts index 909435fe2..843df5455 100644 --- a/src/plugins/betterActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -83,7 +83,7 @@ export interface IconCSSProperties extends CSSProperties { } export interface ActivityViewProps { - activity: Activity; + activity: Activity | null; user: User; guild: Guild; channelId: string; From 46facce4b72395c36c56c378f3c8c2f316303fad Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 17 May 2024 19:16:47 +0200 Subject: [PATCH 42/59] refactor(betterActivities): ActivityTooltip as function component --- .../betterActivities/components/ActivityTooltip.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/betterActivities/components/ActivityTooltip.tsx b/src/plugins/betterActivities/components/ActivityTooltip.tsx index 64839d4a2..7776aa304 100644 --- a/src/plugins/betterActivities/components/ActivityTooltip.tsx +++ b/src/plugins/betterActivities/components/ActivityTooltip.tsx @@ -26,7 +26,14 @@ const TimeBar = findComponentByCodeLazy<{ className: string; }>("isSingleLine"); -const ActivityTooltip = ({ activity, application, user, cl }: Readonly<{ activity: Activity, application?: Application, user: User; cl: ReturnType }>) => { +interface ActivityTooltipProps { + activity: Activity; + application?: Application; + user: User; + cl: ReturnType; +} + +export default function ActivityTooltip({ activity, application, user, cl }: Readonly) { const image = useMemo(() => { const activityImage = getActivityImage(activity, application); if (activityImage) { @@ -64,6 +71,4 @@ const ActivityTooltip = ({ activity, application, user, cl }: Readonly<{ activit
); -}; - -export default ActivityTooltip; +} From b780ae4a2a99e4977f04e62ead31601b4c2cdd77 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 17 May 2024 19:20:49 +0200 Subject: [PATCH 43/59] refactor(betterActivities): remove obsolete restartNeeded props --- src/plugins/betterActivities/settings.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/betterActivities/settings.tsx b/src/plugins/betterActivities/settings.tsx index 415976bb8..e6231f41d 100644 --- a/src/plugins/betterActivities/settings.tsx +++ b/src/plugins/betterActivities/settings.tsx @@ -26,13 +26,11 @@ const settings = definePluginSettings({ type: OptionType.BOOLEAN, description: "Show special activities first (Currently Spotify and Twitch)", default: true, - restartNeeded: false, }, renderGifs: { type: OptionType.BOOLEAN, description: "Allow rendering GIFs", default: true, - restartNeeded: false, }, divider: { type: OptionType.COMPONENT, From c42e4906930d5c97651664c1e72d1bf2e8eb5865 Mon Sep 17 00:00:00 2001 From: Nico Date: Sat, 1 Jun 2024 19:43:40 +0200 Subject: [PATCH 44/59] fix(betterActivities): brand-experiment is now brand-500 --- src/plugins/betterActivities/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/betterActivities/styles.css b/src/plugins/betterActivities/styles.css index 743f5d213..1990c1730 100644 --- a/src/plugins/betterActivities/styles.css +++ b/src/plugins/betterActivities/styles.css @@ -123,7 +123,7 @@ .vc-bactivities-controls .carousell .dot.selected { opacity: 1; - background: var(--dot-color, var(--brand-experiment)); + background: var(--dot-color, var(--brand-500)); } .vc-bactivities-controls-tooltip { From fb3cdbbf62120aece1dd1664fdc5035ad2fbe4db Mon Sep 17 00:00:00 2001 From: Nico Date: Wed, 19 Jun 2024 06:35:14 +0200 Subject: [PATCH 45/59] fix(betterActivities): update icons patch --- src/plugins/betterActivities/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 47074e0af..34c5004fc 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -243,9 +243,9 @@ export default definePlugin({ patches: [ { // Patch activity icons - find: "default.getHangStatusActivity():null!", + find: ".getHangStatusActivity():null!", replacement: { - match: /null!=(\i)&&\i.some\(\i=>\(0,\i.default\)\(\i,\i\)\)\?/, + match: /null!=(\i)&&\i.some\(\i=>\(0,\i.\i\)\(\i,\i\)\)\?/, replace: "$self.patchActivityList(e),false?" }, predicate: () => settings.store.memberList, From e1dbd5f7531188c78103265a08c6be340c05cd95 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 2 Jul 2024 00:24:21 +0200 Subject: [PATCH 46/59] fix(betterActivities): show all activities for profiles v2 --- src/plugins/betterActivities/index.tsx | 19 +++++-------------- src/plugins/betterActivities/settings.tsx | 10 ++-------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 34c5004fc..f7949ded0 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -38,7 +38,7 @@ import { const cl = classNameFactory("vc-bactivities-"); -const ActivityView = findComponentByCodeLazy("onOpenGameProfile:"); +const ActivityView = findComponentByCodeLazy("onOpenGameProfile:", "USER_POPOUT_V2"); // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); @@ -251,22 +251,13 @@ export default definePlugin({ predicate: () => settings.store.memberList, }, { - // Show all activities in the profile panel - find: "Profile Panel: user cannot be undefined", + // Show all activities in the user popout/sidebar + find: "\"BiteSizeProfileActivitySection\"", replacement: { - match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{activity:.+?,user:\i,channelId:\i.id,)/, + match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{type:\i.\i.USER_POPOUT_V2,activity:\i,className:\i\.activity,user:\in)/, replace: "$self.showAllActivitiesComponent" }, - predicate: () => settings.store.profileSidebar, + predicate: () => settings.store.profiles }, - { - // Show all activities in the user popout - find: "customStatusSection,", - replacement: { - match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{activity:\i,user:\i,guild:\i,channelId:\i,onClose:\i,)/, - replace: "$self.showAllActivitiesComponent" - }, - predicate: () => settings.store.userPopout - } ], }); diff --git a/src/plugins/betterActivities/settings.tsx b/src/plugins/betterActivities/settings.tsx index e6231f41d..b34b27ce4 100644 --- a/src/plugins/betterActivities/settings.tsx +++ b/src/plugins/betterActivities/settings.tsx @@ -45,15 +45,9 @@ const settings = definePluginSettings({ }}/> ), }, - profileSidebar: { + profiles: { type: OptionType.BOOLEAN, - description: "Show all activities in the profile sidebar", - default: true, - restartNeeded: true, - }, - userPopout: { - type: OptionType.BOOLEAN, - description: "Show all activities in the user popout", + description: "Show all activities in the profile popout/sidebar", default: true, restartNeeded: true, }, From 811a47ba669dfff409a175418788d354b9984d0b Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 2 Jul 2024 00:35:22 +0200 Subject: [PATCH 47/59] fix(betterActivities): correct patch --- src/plugins/betterActivities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index f7949ded0..7ba4cd3a7 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -254,7 +254,7 @@ export default definePlugin({ // Show all activities in the user popout/sidebar find: "\"BiteSizeProfileActivitySection\"", replacement: { - match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{type:\i.\i.USER_POPOUT_V2,activity:\i,className:\i\.activity,user:\in)/, + match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{type:\i.\i.BITE_SIZE_POPOUT,activity:\i,className:\i\.activity,source:\i,user:\i)/, replace: "$self.showAllActivitiesComponent" }, predicate: () => settings.store.profiles From 661686b255c0b631b6e925cdc7bf6e1f810866fa Mon Sep 17 00:00:00 2001 From: D3SOX Date: Tue, 2 Jul 2024 16:42:23 +0200 Subject: [PATCH 48/59] feat(betterActivities): setting for showing descriptions --- src/plugins/betterActivities/components/ActivityTooltip.tsx | 2 ++ src/plugins/betterActivities/settings.tsx | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/plugins/betterActivities/components/ActivityTooltip.tsx b/src/plugins/betterActivities/components/ActivityTooltip.tsx index 7776aa304..74f109fc2 100644 --- a/src/plugins/betterActivities/components/ActivityTooltip.tsx +++ b/src/plugins/betterActivities/components/ActivityTooltip.tsx @@ -10,6 +10,7 @@ import { findComponentByCodeLazy } from "@webpack"; import { moment, React, useMemo } from "@webpack/common"; import { User } from "discord-types/general"; +import settings from "../settings"; import { Activity, Application } from "../types"; import { formatElapsedTime, @@ -55,6 +56,7 @@ export default function ActivityTooltip({ activity, application, user, cl }: Rea
{activity.details}
{activity.state}
+ {settings.store.showAppDescriptions && application?.description &&
{application.description}
} {!timestamps && startTime &&
{formatElapsedTime(moment(startTime), moment())} diff --git a/src/plugins/betterActivities/settings.tsx b/src/plugins/betterActivities/settings.tsx index b34b27ce4..6c60df3d7 100644 --- a/src/plugins/betterActivities/settings.tsx +++ b/src/plugins/betterActivities/settings.tsx @@ -32,6 +32,12 @@ const settings = definePluginSettings({ description: "Allow rendering GIFs", default: true, }, + showAppDescriptions: { + type: OptionType.BOOLEAN, + description: "Show application descriptions in the activity tooltip", + default: true, + restartNeeded: false, + }, divider: { type: OptionType.COMPONENT, description: "", From c6560e844699ff76f0cf9e2e9eec9a539c2bf403 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 8 Jul 2024 22:43:45 +0200 Subject: [PATCH 49/59] fix(betterActivities): use newer activity view Discord removed the old ones now --- src/plugins/betterActivities/index.tsx | 28 ++++++++++++++++---------- src/plugins/betterActivities/types.ts | 18 ++++++++++++++--- src/plugins/betterActivities/utils.ts | 3 +-- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 7ba4cd3a7..2bb52f68e 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -31,14 +31,21 @@ import { Caret } from "./components/Caret"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; import settings from "./settings"; -import { Activity, ActivityListIcon, ActivityViewProps, ApplicationIcon, IconCSSProperties } from "./types"; +import { + Activity, + ActivityListIcon, + ActivityViewProps, + ActivityViewType, + ApplicationIcon, + IconCSSProperties +} from "./types"; import { getApplicationIcons } from "./utils"; const cl = classNameFactory("vc-bactivities-"); -const ActivityView = findComponentByCodeLazy("onOpenGameProfile:", "USER_POPOUT_V2"); +const ActivityView = findComponentByCodeLazy(",onOpenGameProfileModal:"); // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); @@ -128,7 +135,7 @@ export default definePlugin({ return null; }, - showAllActivitiesComponent({ activity, user, guild, channelId, onClose }: ActivityViewProps) { + showAllActivitiesComponent({ activity, user, activityGuild }: ActivityViewProps) { const [currentActivity, setCurrentActivity] = React.useState( activity?.type !== 4 ? activity! : null ); @@ -145,7 +152,6 @@ export default definePlugin({ if (!currentActivity || !activities.includes(currentActivity)) setCurrentActivity(activities[0]); - }, [activities]); if (!activities.length) return null; @@ -154,11 +160,11 @@ export default definePlugin({ return (
+ activityGuild={activityGuild} + showChannelDetails={true}/>
( ))}
@@ -252,7 +258,7 @@ export default definePlugin({ }, { // Show all activities in the user popout/sidebar - find: "\"BiteSizeProfileActivitySection\"", + find: '"BiteSizeProfileActivitySection"', replacement: { match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{type:\i.\i.BITE_SIZE_POPOUT,activity:\i,className:\i\.activity,source:\i,user:\i)/, replace: "$self.showAllActivitiesComponent" diff --git a/src/plugins/betterActivities/types.ts b/src/plugins/betterActivities/types.ts index 843df5455..fbca5fd58 100644 --- a/src/plugins/betterActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -82,10 +82,22 @@ export interface IconCSSProperties extends CSSProperties { "--icon-size": string; } +export enum ActivityViewType { + USER_POPOUT = "UserPopout", + USER_POPOUT_V2 = "UserPopoutV2", + ACTIVITY_FEED = "ActivityFeed", + PROFILE = "Profile", + PROFILE_V2 = "ProfileV2", + STREAM_PREVIEW = "StreamPreview", + VOICE_CHANNEL = "VoiceChannel", + SIMPLIFIED_PROFILE = "SimplifiedProfile", + BITE_SIZE_POPOUT = "BiteSizePopout" +} + export interface ActivityViewProps { activity: Activity | null; user: User; - guild: Guild; - channelId: string; - onClose: () => void; + activityGuild: Guild; + type: ActivityViewType; + showChannelDetails: boolean; } diff --git a/src/plugins/betterActivities/utils.ts b/src/plugins/betterActivities/utils.ts index d1511acc0..1e5f6165e 100644 --- a/src/plugins/betterActivities/utils.ts +++ b/src/plugins/betterActivities/utils.ts @@ -32,7 +32,7 @@ export function getActivityImage(activity: Activity, application?: Application): const image = activity.assets?.large_image; // image needs to replace 'twitch:' if (image?.startsWith("twitch:")) { - // twitch images are always https://static-cdn.jtvnw.net/previews-ttv/live_user_USERNAME-RESOLTUON.jpg + // twitch images are always https://static-cdn.jtvnw.net/previews-ttv/live_user_USERNAME-RESOLUTION.jpg return `${image.replace("twitch:", "https://static-cdn.jtvnw.net/previews-ttv/live_user_")}-108x60.jpg`; } } @@ -54,7 +54,6 @@ export function getApplicationIcons(activities: Activity[], preferSmall = false) continue; } if (assets) { - const addImage = (image: string, alt: string) => { if (image.startsWith("mp:")) { const discordMediaLink = `https://media.discordapp.net/${image.replace(/mp:/, "")}`; From 917ae898c2316f89b6e62604c0617a86a6425427 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Wed, 10 Jul 2024 14:32:48 +0200 Subject: [PATCH 50/59] fix(betterActivities): correctly pass props --- src/plugins/betterActivities/index.tsx | 12 ++++-------- src/plugins/betterActivities/types.ts | 17 +---------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 2bb52f68e..27fbed9f0 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -35,7 +35,6 @@ import { Activity, ActivityListIcon, ActivityViewProps, - ActivityViewType, ApplicationIcon, IconCSSProperties } from "./types"; @@ -135,7 +134,7 @@ export default definePlugin({ return null; }, - showAllActivitiesComponent({ activity, user, activityGuild }: ActivityViewProps) { + showAllActivitiesComponent({ activity, user, ...props }: ActivityViewProps) { const [currentActivity, setCurrentActivity] = React.useState( activity?.type !== 4 ? activity! : null ); @@ -160,11 +159,10 @@ export default definePlugin({ return (
+ {...props} + />
( ))}
diff --git a/src/plugins/betterActivities/types.ts b/src/plugins/betterActivities/types.ts index fbca5fd58..22306612c 100644 --- a/src/plugins/betterActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { Guild, User } from "discord-types/general"; +import { User } from "discord-types/general"; import { CSSProperties, ImgHTMLAttributes } from "react"; export interface Timestamp { @@ -82,22 +82,7 @@ export interface IconCSSProperties extends CSSProperties { "--icon-size": string; } -export enum ActivityViewType { - USER_POPOUT = "UserPopout", - USER_POPOUT_V2 = "UserPopoutV2", - ACTIVITY_FEED = "ActivityFeed", - PROFILE = "Profile", - PROFILE_V2 = "ProfileV2", - STREAM_PREVIEW = "StreamPreview", - VOICE_CHANNEL = "VoiceChannel", - SIMPLIFIED_PROFILE = "SimplifiedProfile", - BITE_SIZE_POPOUT = "BiteSizePopout" -} - export interface ActivityViewProps { activity: Activity | null; user: User; - activityGuild: Guild; - type: ActivityViewType; - showChannelDetails: boolean; } From f80593aef83a6352c2e399a78d93e0015ee26c7f Mon Sep 17 00:00:00 2001 From: D3SOX Date: Wed, 10 Jul 2024 21:03:58 +0200 Subject: [PATCH 51/59] fix(betterActivities): patch location including application prop --- src/plugins/betterActivities/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 27fbed9f0..612657383 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -254,7 +254,7 @@ export default definePlugin({ }, { // Show all activities in the user popout/sidebar - find: '"BiteSizeProfileActivitySection"', + find: '"UserActivityContainer"', replacement: { match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{type:\i.\i.BITE_SIZE_POPOUT,activity:\i,className:\i\.activity,source:\i,user:\i)/, replace: "$self.showAllActivitiesComponent" From 853efa7a9061d1a7c2371b09139ede832cdee8ed Mon Sep 17 00:00:00 2001 From: D3SOX Date: Wed, 10 Jul 2024 21:12:27 +0200 Subject: [PATCH 52/59] fix(betterActivities): handle xbox edge case --- src/plugins/betterActivities/utils.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/betterActivities/utils.ts b/src/plugins/betterActivities/utils.ts index 1e5f6165e..4123bc1bb 100644 --- a/src/plugins/betterActivities/utils.ts +++ b/src/plugins/betterActivities/utils.ts @@ -117,14 +117,17 @@ export function getApplicationIcons(activities: Activity[], preferSmall = false) application }); } - } - } else { - if (platform === "xbox") { + } else if (platform === "xbox") { applicationIcons.push({ image: { src: xboxUrl, alt: "Xbox" }, activity }); } + } else if (platform === "xbox") { + applicationIcons.push({ + image: { src: xboxUrl, alt: "Xbox" }, + activity + }); } } From 5824528adda7adb5eabb41ad333f40d16d5c6025 Mon Sep 17 00:00:00 2001 From: Nico Date: Wed, 10 Jul 2024 21:17:58 +0200 Subject: [PATCH 53/59] fix(betterActivities): handle fetchApplication errors --- src/plugins/betterActivities/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/betterActivities/utils.ts b/src/plugins/betterActivities/utils.ts index 4123bc1bb..e18c3ddd9 100644 --- a/src/plugins/betterActivities/utils.ts +++ b/src/plugins/betterActivities/utils.ts @@ -98,7 +98,7 @@ export function getApplicationIcons(activities: Activity[], preferSmall = false) fetchedApplications.set(application_id, null); fetchApplication(application_id).then(app => { fetchedApplications.set(application_id, app); - }); + }).catch(console.error); } } From a2e089716a257dc965b05ffd069a59d90b8abaa4 Mon Sep 17 00:00:00 2001 From: Nico Date: Thu, 11 Jul 2024 22:16:37 +0200 Subject: [PATCH 54/59] fix(betterActivities): only patch BiteSizePopout type We don't want to patch the user modal activity tab for example --- src/plugins/betterActivities/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 612657383..625b4e03d 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -256,8 +256,8 @@ export default definePlugin({ // Show all activities in the user popout/sidebar find: '"UserActivityContainer"', replacement: { - match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{type:\i.\i.BITE_SIZE_POPOUT,activity:\i,className:\i\.activity,source:\i,user:\i)/, - replace: "$self.showAllActivitiesComponent" + match: /(?<=\(0,\i\.jsx\)\()(\i\.\i)(?=,{...(\i),activity:\i,user:\i,application:\i)/, + replace: "$2.type==='BiteSizePopout'?$self.showAllActivitiesComponent:$1" }, predicate: () => settings.store.profiles }, From 4a95c367e32be8b16447c4608bafb69878d5a0f4 Mon Sep 17 00:00:00 2001 From: D3SOX Date: Fri, 19 Jul 2024 06:23:45 +0200 Subject: [PATCH 55/59] feat(betterActivities): use ActivityView in tooltip --- .../components/ActivityTooltip.tsx | 58 +++---------------- src/plugins/betterActivities/index.tsx | 14 ++--- src/plugins/betterActivities/settings.tsx | 2 +- src/plugins/betterActivities/styles.css | 40 +------------ src/plugins/betterActivities/types.ts | 2 + 5 files changed, 20 insertions(+), 96 deletions(-) diff --git a/src/plugins/betterActivities/components/ActivityTooltip.tsx b/src/plugins/betterActivities/components/ActivityTooltip.tsx index 74f109fc2..c74f04693 100644 --- a/src/plugins/betterActivities/components/ActivityTooltip.tsx +++ b/src/plugins/betterActivities/components/ActivityTooltip.tsx @@ -6,26 +6,10 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; -import { findComponentByCodeLazy } from "@webpack"; -import { moment, React, useMemo } from "@webpack/common"; import { User } from "discord-types/general"; -import settings from "../settings"; +import { ActivityView } from "../index"; import { Activity, Application } from "../types"; -import { - formatElapsedTime, - getActivityImage, - getApplicationIcons, - getValidStartTimeStamp, - getValidTimestamps -} from "../utils"; - -const TimeBar = findComponentByCodeLazy<{ - start: number; - end: number; - themed: boolean; - className: string; -}>("isSingleLine"); interface ActivityTooltipProps { activity: Activity; @@ -35,41 +19,15 @@ interface ActivityTooltipProps { } export default function ActivityTooltip({ activity, application, user, cl }: Readonly) { - const image = useMemo(() => { - const activityImage = getActivityImage(activity, application); - if (activityImage) { - return activityImage; - } - const icon = getApplicationIcons([activity], true)[0]; - return icon?.image.src; - }, [activity]); - const timestamps = useMemo(() => getValidTimestamps(activity), [activity]); - const startTime = useMemo(() => getValidStartTimeStamp(activity), [activity]); - - const hasDetails = activity.details ?? activity.state; return ( -
- {image && Activity logo} -
{activity.name}
- {hasDetails &&
} -
-
{activity.details}
-
{activity.state}
- {settings.store.showAppDescriptions && application?.description &&
{application.description}
} - {!timestamps && startTime && -
- {formatElapsedTime(moment(startTime), moment())} -
- } -
- {timestamps && ( - - )} +
+
); diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 625b4e03d..e0bfaf4ed 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -23,7 +23,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { findComponentByCodeLazy } from "@webpack"; -import { PresenceStore, React, Tooltip, useStateFromStores } from "@webpack/common"; +import { PresenceStore, React, Tooltip, useEffect, useState, useStateFromStores } from "@webpack/common"; import { User } from "discord-types/general"; import ActivityTooltip from "./components/ActivityTooltip"; @@ -44,7 +44,7 @@ import { const cl = classNameFactory("vc-bactivities-"); -const ActivityView = findComponentByCodeLazy(",onOpenGameProfileModal:"); +export const ActivityView = findComponentByCodeLazy(",onOpenGameProfileModal:"); // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); @@ -135,7 +135,7 @@ export default definePlugin({ }, showAllActivitiesComponent({ activity, user, ...props }: ActivityViewProps) { - const [currentActivity, setCurrentActivity] = React.useState( + const [currentActivity, setCurrentActivity] = useState( activity?.type !== 4 ? activity! : null ); @@ -143,7 +143,7 @@ export default definePlugin({ [PresenceStore], () => PresenceStore.getActivities(user.id).filter((activity: Activity) => activity.type !== 4) ) ?? []; - React.useEffect(() => { + useEffect(() => { if (!activities.length) { setCurrentActivity(null); return; @@ -186,7 +186,7 @@ export default definePlugin({ > + direction="left" /> ; }} @@ -195,7 +195,7 @@ export default definePlugin({
setCurrentActivity(activity)} - className={`dot ${currentActivity === activity ? "selected" : ""}`}/> + className={`dot ${currentActivity === activity ? "selected" : ""}`} /> ))}
@@ -214,7 +214,7 @@ export default definePlugin({ > = activities.length - 1} - direction="right"/> + direction="right" /> ; }}
diff --git a/src/plugins/betterActivities/settings.tsx b/src/plugins/betterActivities/settings.tsx index 6c60df3d7..9064b0150 100644 --- a/src/plugins/betterActivities/settings.tsx +++ b/src/plugins/betterActivities/settings.tsx @@ -48,7 +48,7 @@ const settings = definePluginSettings({ borderTop: "thin solid var(--background-modifier-accent)", paddingTop: 5, paddingBottom: 5 - }}/> + }} /> ), }, profiles: { diff --git a/src/plugins/betterActivities/styles.css b/src/plugins/betterActivities/styles.css index 1990c1730..7421b0ce5 100644 --- a/src/plugins/betterActivities/styles.css +++ b/src/plugins/betterActivities/styles.css @@ -19,44 +19,8 @@ border-radius: 50%; } -.vc-bactivities-activity { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - gap: 5px; -} - -.vc-bactivities-activity-title { - font-weight: bold; - text-align: center; -} - -.vc-bactivities-activity-image { - height: 20px; - width: 20px; - border-radius: 50%; - object-fit: cover; -} - -.vc-bactivities-activity-divider { - width: 100%; - border-top: 1px dotted rgb(255 255 255 / 20%); - margin-top: 3px; - margin-bottom: 3px; -} - -.vc-bactivities-activity-details { - display: flex; - flex-direction: column; - color: var(--text-muted); - word-break: break-word; -} - -.vc-bactivities-activity-time-bar { - width: 100%; - margin-top: 3px; - margin-bottom: 3px; +.vc-bactivities-activity-tooltip { + padding: 1px; } .vc-bactivities-caret-left, diff --git a/src/plugins/betterActivities/types.ts b/src/plugins/betterActivities/types.ts index 22306612c..14cc772fa 100644 --- a/src/plugins/betterActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -85,4 +85,6 @@ export interface IconCSSProperties extends CSSProperties { export interface ActivityViewProps { activity: Activity | null; user: User; + application?: Application; + type: string; } From 811397de3c72977715e7a18df3ccce9b1def07bb Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 29 Jul 2024 13:04:36 +0200 Subject: [PATCH 56/59] chore(betterActivities): remove unused code --- src/plugins/betterActivities/utils.ts | 49 +-------------------------- 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/src/plugins/betterActivities/utils.ts b/src/plugins/betterActivities/utils.ts index e18c3ddd9..072f4bd80 100644 --- a/src/plugins/betterActivities/utils.ts +++ b/src/plugins/betterActivities/utils.ts @@ -5,10 +5,9 @@ */ import { findByPropsLazy, findStoreLazy } from "@webpack"; -import { moment } from "@webpack/common"; import settings from "./settings"; -import { Activity, Application, ApplicationIcon, Timestamp } from "./types"; +import { Activity, Application, ApplicationIcon } from "./types"; const ApplicationStore: { getApplication: (id: string) => Application | null; @@ -18,27 +17,6 @@ const { fetchApplication }: { fetchApplication: (id: string) => Promise; } = findByPropsLazy("fetchApplication"); -export function getActivityImage(activity: Activity, application?: Application): string | undefined { - if (activity.type === 2 && activity.name === "Spotify") { - // get either from large or small image - const image = activity.assets?.large_image ?? activity.assets?.small_image; - // image needs to replace 'spotify:' - if (image?.startsWith("spotify:")) { - // spotify cover art is always https://i.scdn.co/image/ID - return image.replace("spotify:", "https://i.scdn.co/image/"); - } - } - if (activity.type === 1 && activity.name === "Twitch") { - const image = activity.assets?.large_image; - // image needs to replace 'twitch:' - if (image?.startsWith("twitch:")) { - // twitch images are always https://static-cdn.jtvnw.net/previews-ttv/live_user_USERNAME-RESOLUTION.jpg - return `${image.replace("twitch:", "https://static-cdn.jtvnw.net/previews-ttv/live_user_")}-108x60.jpg`; - } - } - // TODO: we could support other assets here -} - const fetchedApplications = new Map(); // TODO: replace with "renderXboxImage"? @@ -133,28 +111,3 @@ export function getApplicationIcons(activities: Activity[], preferSmall = false) return applicationIcons; } - -export function getValidTimestamps(activity: Activity): Required | null { - if (activity.timestamps?.start !== undefined && activity.timestamps?.end !== undefined) { - return activity.timestamps as Required; - } - return null; -} - -export function getValidStartTimeStamp(activity: Activity): number | null { - if (activity.timestamps?.start !== undefined) { - return activity.timestamps.start; - } - return null; -} - -const customFormat = (momentObj: moment.Moment): string => { - const hours = momentObj.hours(); - const formattedTime = momentObj.format("mm:ss"); - return hours > 0 ? `${momentObj.format("HH:")}${formattedTime}` : formattedTime; -}; - -export function formatElapsedTime(startTime: moment.Moment, endTime: moment.Moment): string { - const duration = moment.duration(endTime.diff(startTime)); - return `${customFormat(moment.utc(duration.asMilliseconds()))} elapsed`; -} From 32476dd1df232f28f031c2442b804db051fe61cd Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 29 Jul 2024 13:19:08 +0200 Subject: [PATCH 57/59] fix(betterActivities): avoid passing specific props to all activities Now only the general props are used and the application is fetched for other activities --- src/plugins/betterActivities/index.tsx | 54 +++++++++++++++++++------- src/plugins/betterActivities/types.ts | 1 + src/plugins/betterActivities/utils.ts | 9 +++++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index e0bfaf4ed..bb6ed17c4 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -23,7 +23,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { findComponentByCodeLazy } from "@webpack"; -import { PresenceStore, React, Tooltip, useEffect, useState, useStateFromStores } from "@webpack/common"; +import { PresenceStore, React, Tooltip, useEffect, useMemo, useState, useStateFromStores } from "@webpack/common"; import { User } from "discord-types/general"; import ActivityTooltip from "./components/ActivityTooltip"; @@ -39,6 +39,7 @@ import { IconCSSProperties } from "./types"; import { + getActivityApplication, getApplicationIcons } from "./utils"; @@ -155,14 +156,31 @@ export default definePlugin({ if (!activities.length) return null; + // we use these for other activities, it would be better to somehow get the corresponding activity props + const generalProps = useMemo(() => Object.keys(props).reduce((acc, key) => { + // exclude activity specific props to prevent copying them to all activities (e.g. buttons) + if (key !== "renderActions" && key !== "application") acc[key] = props[key]; + return acc; + }, {} as Omit), [props]); + if (settings.store.allActivitiesStyle === "carousel") { return (
- + {currentActivity?.id === activity?.id ? ( + + ) : ( + + )}
- {activities.map((activity, index) => ( - - ))} + {activities.map((activity, index) => + index === 0 ? ( + ) : ( + + ))}
); } diff --git a/src/plugins/betterActivities/types.ts b/src/plugins/betterActivities/types.ts index 14cc772fa..8925b5898 100644 --- a/src/plugins/betterActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -86,5 +86,6 @@ export interface ActivityViewProps { activity: Activity | null; user: User; application?: Application; + renderActions?: () => JSX.Element; type: string; } diff --git a/src/plugins/betterActivities/utils.ts b/src/plugins/betterActivities/utils.ts index 072f4bd80..dc274d8fe 100644 --- a/src/plugins/betterActivities/utils.ts +++ b/src/plugins/betterActivities/utils.ts @@ -19,6 +19,15 @@ const { fetchApplication }: { const fetchedApplications = new Map(); +export function getActivityApplication({ application_id }: Activity) { + if (!application_id) return undefined; + let application = ApplicationStore.getApplication(application_id); + if (!application && fetchedApplications.has(application_id)) { + application = fetchedApplications.get(application_id) ?? null; + } + return application ?? undefined; +} + // TODO: replace with "renderXboxImage"? const xboxUrl = "https://discord.com/assets/9a15d086141be29d9fcd.png"; From 57c8f6915c17ec54a4193e672756df0f5778bf8f Mon Sep 17 00:00:00 2001 From: Nico Date: Fri, 2 Aug 2024 10:14:35 +0200 Subject: [PATCH 58/59] fix(betterActivities): avoid conditional hook calls Prevents crashing when the activities length changes --- src/plugins/betterActivities/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index bb6ed17c4..73f3e816e 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -154,8 +154,6 @@ export default definePlugin({ setCurrentActivity(activities[0]); }, [activities]); - if (!activities.length) return null; - // we use these for other activities, it would be better to somehow get the corresponding activity props const generalProps = useMemo(() => Object.keys(props).reduce((acc, key) => { // exclude activity specific props to prevent copying them to all activities (e.g. buttons) @@ -163,6 +161,9 @@ export default definePlugin({ return acc; }, {} as Omit), [props]); + + if (!activities.length) return null; + if (settings.store.allActivitiesStyle === "carousel") { return (
From 726094aa6ffad2af424921716bd7273acf137f48 Mon Sep 17 00:00:00 2001 From: Nico Date: Fri, 2 Aug 2024 10:16:55 +0200 Subject: [PATCH 59/59] chore: thx github web editor.... --- src/plugins/betterActivities/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/betterActivities/index.tsx b/src/plugins/betterActivities/index.tsx index 73f3e816e..6eb301d06 100644 --- a/src/plugins/betterActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -161,7 +161,6 @@ export default definePlugin({ return acc; }, {} as Omit), [props]); - if (!activities.length) return null; if (settings.store.allActivitiesStyle === "carousel") {