From 17f1ef275ef52c8ab539f528247df50022d81550 Mon Sep 17 00:00:00 2001
From: AutumnVN <autumnvnchino@gmail.com>
Date: Thu, 23 Jan 2025 07:33:11 +0700
Subject: [PATCH] CustomRPC: improve rich presence preview & UX (#3159)

Co-authored-by: Vendicated <vendicated@riseup.net>
---
 src/plugins/customRPC/index.tsx | 57 ++++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 23 deletions(-)

diff --git a/src/plugins/customRPC/index.tsx b/src/plugins/customRPC/index.tsx
index f4b9ab06..64aea76a 100644
--- a/src/plugins/customRPC/index.tsx
+++ b/src/plugins/customRPC/index.tsx
@@ -19,6 +19,7 @@
 import { definePluginSettings, Settings } from "@api/Settings";
 import { getUserSettingLazy } from "@api/UserSettings";
 import { ErrorCard } from "@components/ErrorCard";
+import { Flex } from "@components/Flex";
 import { Link } from "@components/Link";
 import { Devs } from "@utils/constants";
 import { isTruthy } from "@utils/guards";
@@ -27,15 +28,14 @@ import { classes } from "@utils/misc";
 import { useAwaiter } from "@utils/react";
 import definePlugin, { OptionType } from "@utils/types";
 import { findByCodeLazy, findComponentByCodeLazy } from "@webpack";
-import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from "@webpack/common";
+import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, React, UserStore } from "@webpack/common";
 
 const useProfileThemeStyle = findByCodeLazy("profileThemeStyle:", "--profile-gradient-primary-color");
-const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile");
+const ActivityView = findComponentByCodeLazy('location:"UserProfileActivityCard",');
 
 const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
 
 async function getApplicationAsset(key: string): Promise<string> {
-    if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");
     return (await ApplicationAssetUtils.fetchAssetIds(settings.store.appID!, [key]))[0];
 }
 
@@ -169,7 +169,7 @@ const settings = definePluginSettings({
                 value: TimestampMode.NOW
             },
             {
-                label: "Same as your current time",
+                label: "Same as your current time (not reset after 24h)",
                 value: TimestampMode.TIME
             },
             {
@@ -269,6 +269,7 @@ function isStreamLinkDisabled() {
 
 function isStreamLinkValid(value: string) {
     if (!isStreamLinkDisabled() && !/https?:\/\/(www\.)?(twitch\.tv|youtube\.com)\/\w+/.test(value)) return "Streaming link must be a valid URL.";
+    if (value && value.length > 512) return "Streaming link must be not longer than 512 characters.";
     return true;
 }
 
@@ -277,8 +278,9 @@ function isTimestampDisabled() {
 }
 
 function isImageKeyValid(value: string) {
-    if (/https?:\/\/(?!i\.)?imgur\.com\//.test(value)) return "Imgur link must be a direct link to the image. (e.g. https://i.imgur.com/...)";
-    if (/https?:\/\/(?!media\.)?tenor\.com\//.test(value)) return "Tenor link must be a direct link to the image. (e.g. https://media.tenor.com/...)";
+    if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//.test(value)) return "Don't use a Discord link. Use an Imgur image link instead.";
+    if (/https?:\/\/(?!i\.)?imgur\.com\//.test(value)) return "Imgur link must be a direct link to the image (e.g. https://i.imgur.com/...). Right click the image and click 'Copy image address'";
+    if (/https?:\/\/(?!media\.)?tenor\.com\//.test(value)) return "Tenor link must be a direct link to the image (e.g. https://media.tenor.com/...). Right click the GIF and click 'Copy image address'";
     return true;
 }
 
@@ -390,7 +392,7 @@ async function setRpc(disable?: boolean) {
 
 export default definePlugin({
     name: "CustomRPC",
-    description: "Allows you to set a custom rich presence.",
+    description: "Add a fully customisable Rich Presence (Game status) to your Discord profile",
     authors: [Devs.captain, Devs.AutumnVN, Devs.nin0dev],
     dependencies: ["UserSettingsAPI"],
     start: setRpc,
@@ -410,7 +412,7 @@ export default definePlugin({
                         style={{ padding: "1em" }}
                     >
                         <Forms.FormTitle>Notice</Forms.FormTitle>
-                        <Forms.FormText>Game activity isn't enabled, people won't be able to see your custom rich presence!</Forms.FormText>
+                        <Forms.FormText>Activity Sharing isn't enabled, people won't be able to see your custom rich presence!</Forms.FormText>
 
                         <Button
                             color={Button.Colors.TRANSPARENT}
@@ -422,24 +424,33 @@ export default definePlugin({
                     </ErrorCard>
                 )}
 
-                <Forms.FormText>
-                    Go to <Link href="https://discord.com/developers/applications">Discord Developer Portal</Link> to create an application and
-                    get the application ID.
-                </Forms.FormText>
-                <Forms.FormText>
-                    Upload images in the Rich Presence tab to get the image keys.
-                </Forms.FormText>
-                <Forms.FormText>
-                    If you want to use image link, download your image and reupload the image to <Link href="https://imgur.com">Imgur</Link> and get the image link by right-clicking the image and select "Copy image address".
-                </Forms.FormText>
+                <Flex flexDirection="column" style={{ gap: ".5em" }} className={Margins.top16}>
+                    <Forms.FormText>
+                        Go to the <Link href="https://discord.com/developers/applications">Discord Developer Portal</Link> to create an application and
+                        get the application ID.
+                    </Forms.FormText>
+                    <Forms.FormText>
+                        Upload images in the Rich Presence tab to get the image keys.
+                    </Forms.FormText>
+                    <Forms.FormText>
+                        If you want to use an image link, download your image and reupload the image to <Link href="https://imgur.com">Imgur</Link> and get the image link by right-clicking the image and selecting "Copy image address".
+                    </Forms.FormText>
+                    <Forms.FormText>
+                        You can't see your own buttons on your profile, but everyone else can see it fine.
+                    </Forms.FormText>
+                    <Forms.FormText>
+                        Some weird unicode text ("fonts" 𝖑𝖎𝖐𝖊 𝖙𝖍𝖎𝖘) may cause the rich presence to not show up, try using normal letters instead.
+                    </Forms.FormText>
+                </Flex>
 
                 <Forms.FormDivider className={Margins.top8} />
 
-                <div style={{ width: "284px", ...profileThemeStyle, padding: 8, marginTop: 8, borderRadius: 8, background: "var(--bg-mod-faint)" }}>
-                    {activity[0] && <ActivityComponent activity={activity[0]} channelId={SelectedChannelStore.getChannelId()}
-                        guild={GuildStore.getGuild(SelectedGuildStore.getLastSelectedGuildId())}
-                        application={{ id: settings.store.appID }}
-                        user={UserStore.getCurrentUser()} />}
+                <div style={{ width: "284px", ...profileThemeStyle, marginTop: 8, borderRadius: 8, background: "var(--bg-mod-faint)" }}>
+                    {activity[0] && <ActivityView
+                        activity={activity[0]}
+                        user={UserStore.getCurrentUser()}
+                        currentUser={{ id: "0" }}
+                    />}
                 </div>
             </>
         );