From bfea1edf63fc0a8aceccbf6b2d505b8cdbde592a Mon Sep 17 00:00:00 2001 From: Cooper Date: Sat, 29 Jun 2024 22:03:40 -0500 Subject: [PATCH 01/17] feat(plugin): OpenMoreConnections --- src/plugins/openMoreConnections/README.md | 12 +++++ src/plugins/openMoreConnections/index.ts | 59 +++++++++++++++++++++++ src/utils/constants.ts | 4 ++ 3 files changed, 75 insertions(+) create mode 100644 src/plugins/openMoreConnections/README.md create mode 100644 src/plugins/openMoreConnections/index.ts diff --git a/src/plugins/openMoreConnections/README.md b/src/plugins/openMoreConnections/README.md new file mode 100644 index 000000000..ef3eb93d2 --- /dev/null +++ b/src/plugins/openMoreConnections/README.md @@ -0,0 +1,12 @@ +# OpenMoreConnections + +Adds the Open Profile button to connections that don't natively have it in the regular Discord client. +## Supported Platforms +* Xbox +* Roblox +## Planned Platforms +* PSN +## Platforms that will never be supported +* Riot Games/League of Legends +* Battle.net +* Epic Games diff --git a/src/plugins/openMoreConnections/index.ts b/src/plugins/openMoreConnections/index.ts new file mode 100644 index 000000000..055abdf0a --- /dev/null +++ b/src/plugins/openMoreConnections/index.ts @@ -0,0 +1,59 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Cooper/coopeeo, Vendicated and contributors* + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; + + + +//* platforms that dont open +//* riot and leage (can't view profiles) +//* epic (can't view profiles) +//* psn (can't view profiles but I have a workaround for 3rd party stuff) +//* roblox +//* xbox +//* battle.net (can't view profiles) + +enum ConnectionType { + Roblox = "roblox", + PSN = "playstation", + Xbox = "xbox", +} + + +interface Connection { + type: ConnectionType | string; + id: string; + name: string; + verified: boolean; +} + + +export default definePlugin({ + name: "OpenMoreConnections", + description: "Adds the Open Profile button to connections that don't natively have it in the regular Discord client. Supported Platforms: Xbox, and Roblox. Planned Platforms: PSN. Platforms that will never be supported: Riot Games/League of Legends, Battle.net, and Epic Games", + authors: [Devs.coopeeo], + patches: [ + { + find: ".CONNECTED_ACCOUNT_VIEWED,", + replacement: { + match: /(?<=(\i)=null==\i\?void 0:null===\(\i=\i.getPlatformUserUrl\)\|\|void 0===\i\?void 0:\i.call\(\i,(\i)\);)/, + replace: "if ($1 == null) $1 = $self.addConnectionLink($2);" + } + } + ], + addConnectionLink(con: Connection) { + switch (con.type) { + case ConnectionType.Roblox: + return `https://www.roblox.com/users/${con.id}/profile`; + case ConnectionType.Xbox: + return `https://www.xbox.com/en-US/play/user/${con.name}`; + } + + + return null; + } +}); diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c399baafe..88d8e12d6 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -533,6 +533,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ Antti: { name: "Antti", id: 312974985876471810n + }, + coopeeo: { + name: "Cooper", + id: 594864203102158859n } } satisfies Record); From 9afcb7535839b7889a70a4d153449a2d0ae2dabe Mon Sep 17 00:00:00 2001 From: Cooper Date: Sat, 29 Jun 2024 22:04:40 -0500 Subject: [PATCH 02/17] fix: Add ShowConnections support for OpenMoreConnections --- src/plugins/showConnections/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/showConnections/index.tsx b/src/plugins/showConnections/index.tsx index d6909dc91..ef03b65b8 100644 --- a/src/plugins/showConnections/index.tsx +++ b/src/plugins/showConnections/index.tsx @@ -134,7 +134,7 @@ function ConnectionsComponent({ id, theme, simplified }: { id: string, theme: st function CompactConnectionComponent({ connection, theme }: { connection: Connection, theme: string; }) { const platform = platforms.get(useLegacyPlatformType(connection.type)); - const url = platform.getPlatformUserUrl?.(connection); + var url = platform.getPlatformUserUrl?.(connection); const img = ( ); + if (Vencord.Plugins.isPluginEnabled("OpenMoreConnections") && url == null) { + const OpenMoreConnections = Vencord.Plugins.plugins.OpenMoreConnections as any as typeof import("../openMoreConnections").default; + url = OpenMoreConnections.addConnectionLink(connection) as string; + } + const TooltipIcon = url ? LinkIcon : CopyIcon; return ( From 36f809f8cfe231d8d1022d19b6c2bdd9bbedea39 Mon Sep 17 00:00:00 2001 From: Cooper Date: Sat, 29 Jun 2024 22:24:11 -0500 Subject: [PATCH 03/17] revert the show connections edit (imma try to find a patch), and edit locale on the xbox link. --- src/plugins/openMoreConnections/index.ts | 2 +- src/plugins/showConnections/index.tsx | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/plugins/openMoreConnections/index.ts b/src/plugins/openMoreConnections/index.ts index 055abdf0a..aa5ceb617 100644 --- a/src/plugins/openMoreConnections/index.ts +++ b/src/plugins/openMoreConnections/index.ts @@ -50,7 +50,7 @@ export default definePlugin({ case ConnectionType.Roblox: return `https://www.roblox.com/users/${con.id}/profile`; case ConnectionType.Xbox: - return `https://www.xbox.com/en-US/play/user/${con.name}`; + return `https://www.xbox.com/play/user/${con.name}`; } diff --git a/src/plugins/showConnections/index.tsx b/src/plugins/showConnections/index.tsx index ef03b65b8..d45a2e11e 100644 --- a/src/plugins/showConnections/index.tsx +++ b/src/plugins/showConnections/index.tsx @@ -147,11 +147,6 @@ function CompactConnectionComponent({ connection, theme }: { connection: Connect /> ); - if (Vencord.Plugins.isPluginEnabled("OpenMoreConnections") && url == null) { - const OpenMoreConnections = Vencord.Plugins.plugins.OpenMoreConnections as any as typeof import("../openMoreConnections").default; - url = OpenMoreConnections.addConnectionLink(connection) as string; - } - const TooltipIcon = url ? LinkIcon : CopyIcon; return ( From 3e58b70b98859e1ac89b6784bf8b4b67a7afe8c8 Mon Sep 17 00:00:00 2001 From: Cooper Date: Sat, 29 Jun 2024 23:58:29 -0500 Subject: [PATCH 04/17] Switch to patch-only soulution --- src/plugins/openMoreConnections/index.ts | 45 ++++++++---------------- src/plugins/showConnections/index.tsx | 2 +- 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/plugins/openMoreConnections/index.ts b/src/plugins/openMoreConnections/index.ts index aa5ceb617..e69708844 100644 --- a/src/plugins/openMoreConnections/index.ts +++ b/src/plugins/openMoreConnections/index.ts @@ -7,8 +7,6 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; - - //* platforms that dont open //* riot and leage (can't view profiles) //* epic (can't view profiles) @@ -17,43 +15,28 @@ import definePlugin from "@utils/types"; //* xbox //* battle.net (can't view profiles) -enum ConnectionType { - Roblox = "roblox", - PSN = "playstation", - Xbox = "xbox", -} - - -interface Connection { - type: ConnectionType | string; - id: string; - name: string; - verified: boolean; -} - - +const uris = { // name = t, and id = l + roblox: "https://www.roblox.com/users/${l}/profile", + xbox: "https://www.xbox.com/play/user/${t}" +}; export default definePlugin({ name: "OpenMoreConnections", description: "Adds the Open Profile button to connections that don't natively have it in the regular Discord client. Supported Platforms: Xbox, and Roblox. Planned Platforms: PSN. Platforms that will never be supported: Riot Games/League of Legends, Battle.net, and Epic Games", authors: [Devs.coopeeo], patches: [ { - find: ".CONNECTED_ACCOUNT_VIEWED,", + find: "getPlatformUserUrl:e=>", replacement: { - match: /(?<=(\i)=null==\i\?void 0:null===\(\i=\i.getPlatformUserUrl\)\|\|void 0===\i\?void 0:\i.call\(\i,(\i)\);)/, - replace: "if ($1 == null) $1 = $self.addConnectionLink($2);" + match: /(?<=Roblox",.*},.+)(?=},)/, + replace: `, getPlatformUserUrl:e=>{let {name:t, id:l} = e; return \`${uris.roblox}\`;}` + } + }, + { + find: "getPlatformUserUrl:e=>", + replacement: { + match: /(?<=Xbox",.*},.+)(?=},)/, + replace: `, getPlatformUserUrl:e=>{let {name:t, id:l} = e; return \`${uris.xbox}\`;}` } } ], - addConnectionLink(con: Connection) { - switch (con.type) { - case ConnectionType.Roblox: - return `https://www.roblox.com/users/${con.id}/profile`; - case ConnectionType.Xbox: - return `https://www.xbox.com/play/user/${con.name}`; - } - - - return null; - } }); diff --git a/src/plugins/showConnections/index.tsx b/src/plugins/showConnections/index.tsx index d45a2e11e..d6909dc91 100644 --- a/src/plugins/showConnections/index.tsx +++ b/src/plugins/showConnections/index.tsx @@ -134,7 +134,7 @@ function ConnectionsComponent({ id, theme, simplified }: { id: string, theme: st function CompactConnectionComponent({ connection, theme }: { connection: Connection, theme: string; }) { const platform = platforms.get(useLegacyPlatformType(connection.type)); - var url = platform.getPlatformUserUrl?.(connection); + const url = platform.getPlatformUserUrl?.(connection); const img = ( Date: Tue, 2 Jul 2024 00:17:40 +0200 Subject: [PATCH 05/17] improve settings ui (again) --- .stylelintrc.json | 8 +- src/components/Icons.tsx | 15 +++ src/components/VencordSettings/ThemesTab.tsx | 88 ++++++++--------- src/components/VencordSettings/VencordTab.tsx | 77 ++++++--------- .../VencordSettings/quickActions.css | 34 +++++++ .../VencordSettings/quickActions.tsx | 39 ++++++++ .../VencordSettings/settingsStyles.css | 20 ---- src/utils/misc.ts | 2 +- src/webpack/common/types/utils.d.ts | 62 +++++++++++- src/webpack/common/utils.ts | 52 +++++----- src/webpack/webpack.ts | 98 ++++++++++--------- 11 files changed, 309 insertions(+), 186 deletions(-) create mode 100644 src/components/VencordSettings/quickActions.css create mode 100644 src/components/VencordSettings/quickActions.tsx diff --git a/.stylelintrc.json b/.stylelintrc.json index 6449c3f29..ec2549762 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,6 +1,12 @@ { "extends": "stylelint-config-standard", "rules": { - "indentation": 4 + "indentation": 4, + "selector-class-pattern": [ + "^[a-z][a-zA-Z0-9]*(-[a-z0-9][a-zA-Z0-9]*)*$", + { + "message": "Expected class selector to be kebab-case with camelCase segments" + } + ] } } diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index d82ce0b00..7ba078d33 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -392,6 +392,21 @@ export function PaintbrushIcon(props: IconProps) { ); } +export function PencilIcon(props: IconProps) { + return ( + + + + ); +} + const WebsiteIconDark = "/assets/e1e96d89e192de1997f73730db26e94f.svg"; const WebsiteIconLight = "/assets/730f58bcfd5a57a5e22460c445a0c6cf.svg"; const GithubIconLight = "/assets/3ff98ad75ac94fa883af5ed62d17c459.svg"; diff --git a/src/components/VencordSettings/ThemesTab.tsx b/src/components/VencordSettings/ThemesTab.tsx index 2eb91cb82..016371bed 100644 --- a/src/components/VencordSettings/ThemesTab.tsx +++ b/src/components/VencordSettings/ThemesTab.tsx @@ -19,21 +19,21 @@ import { useSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; import { Flex } from "@components/Flex"; -import { DeleteIcon } from "@components/Icons"; +import { DeleteIcon, FolderIcon, PaintbrushIcon, PencilIcon, PlusIcon, RestartIcon } from "@components/Icons"; import { Link } from "@components/Link"; -import PluginModal from "@components/PluginSettings/PluginModal"; +import { openPluginModal } from "@components/PluginSettings/PluginModal"; import type { UserThemeHeader } from "@main/themes"; import { openInviteModal } from "@utils/discord"; import { Margins } from "@utils/margins"; import { classes } from "@utils/misc"; -import { openModal } from "@utils/modal"; import { showItemInFolder } from "@utils/native"; import { useAwaiter } from "@utils/react"; import { findByPropsLazy, findLazy } from "@webpack"; -import { Button, Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common"; +import { Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common"; import type { ComponentType, Ref, SyntheticEvent } from "react"; import { AddonCard } from "./AddonCard"; +import { QuickAction, QuickActionCard } from "./quickActions"; import { SettingsTab, wrapTab } from "./shared"; type FileInput = ComponentType<{ @@ -213,60 +213,52 @@ function ThemesTab() { - + <> {IS_WEB ? ( - + + Upload Theme + + + } + Icon={PlusIcon} + /> ) : ( - + Icon={FolderIcon} + /> )} - - + + VencordNative.quickCss.openEditor()} + Icon={PaintbrushIcon} + /> {Vencord.Settings.plugins.ClientTheme.enabled && ( - + openPluginModal(Vencord.Plugins.plugins.ClientTheme)} + Icon={PencilIcon} + /> )} - +
{userThemes?.map(theme => ( diff --git a/src/components/VencordSettings/VencordTab.tsx b/src/components/VencordSettings/VencordTab.tsx index d13b43fb2..97f82e777 100644 --- a/src/components/VencordSettings/VencordTab.tsx +++ b/src/components/VencordSettings/VencordTab.tsx @@ -21,15 +21,16 @@ import { useSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; import DonateButton from "@components/DonateButton"; import { openPluginModal } from "@components/PluginSettings/PluginModal"; +import { gitRemote } from "@shared/vencordUserAgent"; import { Margins } from "@utils/margins"; import { identity } from "@utils/misc"; import { relaunch, showItemInFolder } from "@utils/native"; import { useAwaiter } from "@utils/react"; -import { Button, Card, Forms, React, Select, Switch, TooltipContainer } from "@webpack/common"; -import { ComponentType } from "react"; +import { Button, Card, Forms, React, Select, Switch } from "@webpack/common"; import { Flex, FolderIcon, GithubIcon, LogIcon, PaintbrushIcon, RestartIcon } from ".."; import { openNotificationSettingsModal } from "./NotificationSettings"; +import { QuickAction, QuickActionCard } from "./quickActions"; import { SettingsTab, wrapTab } from "./shared"; const cl = classNameFactory("vc-settings-"); @@ -41,17 +42,6 @@ type KeysOfType = { [K in keyof Object]: Object[K] extends Type ? K : never; }[keyof Object]; -const iconWithTooltip = (Icon: ComponentType<{ className?: string; }>, tooltip: string) => () => ( - - - -); - -const NotificationLogIcon = iconWithTooltip(LogIcon, "Open Notification Log"); -const QuickCssIcon = iconWithTooltip(PaintbrushIcon, "Edit QuickCSS"); -const RelaunchIcon = iconWithTooltip(RestartIcon, "Relaunch Discord"); -const OpenSettingsDirIcon = iconWithTooltip(FolderIcon, "Open Settings Directory"); -const OpenGithubIcon = iconWithTooltip(GithubIcon, "View Vencord's GitHub Repository"); function VencordSettings() { const [settingsDir, , settingsDirPending] = useAwaiter(VencordNative.settings.getSettingsDir, { @@ -111,44 +101,37 @@ function VencordSettings() { - - - + + + VencordNative.quickCss.openEditor()} + /> {!IS_WEB && ( - + )} {!IS_WEB && ( - + showItemInFolder(settingsDir)} + /> )} - - + VencordNative.native.openExternal("https://github.com/" + gitRemote)} + /> + diff --git a/src/components/VencordSettings/quickActions.css b/src/components/VencordSettings/quickActions.css new file mode 100644 index 000000000..897bc8c81 --- /dev/null +++ b/src/components/VencordSettings/quickActions.css @@ -0,0 +1,34 @@ +.vc-settings-quickActions-card { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, max-content)); + gap: 0.5em; + justify-content: center; + padding: 0.5em 0; + margin-bottom: 1em; +} + +.vc-settings-quickActions-pill { + all: unset; + + background: var(--background-secondary); + color: var(--header-secondary); + display: flex; + align-items: center; + gap: 0.5em; + padding: 8px 12px; + border-radius: 9999px; +} + +.vc-settings-quickActions-pill:hover { + background: var(--background-secondary-alt); +} + +.vc-settings-quickActions-pill:focus-visible { + outline: 2px solid var(--focus-primary); + outline-offset: 2px; +} + +.vc-settings-quickActions-img { + width: 24px; + height: 24px; +} diff --git a/src/components/VencordSettings/quickActions.tsx b/src/components/VencordSettings/quickActions.tsx new file mode 100644 index 000000000..6cc57180a --- /dev/null +++ b/src/components/VencordSettings/quickActions.tsx @@ -0,0 +1,39 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import "./quickActions.css"; + +import { classNameFactory } from "@api/Styles"; +import { Card } from "@webpack/common"; +import type { ComponentType, PropsWithChildren, ReactNode } from "react"; + +const cl = classNameFactory("vc-settings-quickActions-"); + +export interface QuickActionProps { + Icon: ComponentType<{ className?: string; }>; + text: ReactNode; + action?: () => void; + disabled?: boolean; +} + +export function QuickAction(props: QuickActionProps) { + const { Icon, action, text, disabled } = props; + + return ( + + ); +} + +export function QuickActionCard(props: PropsWithChildren) { + return ( + + {props.children} + + ); +} diff --git a/src/components/VencordSettings/settingsStyles.css b/src/components/VencordSettings/settingsStyles.css index 6e8826c52..13558be21 100644 --- a/src/components/VencordSettings/settingsStyles.css +++ b/src/components/VencordSettings/settingsStyles.css @@ -10,26 +10,6 @@ margin-bottom: -2px; } -.vc-settings-quick-actions-card { - color: var(--text-normal); - padding: 1em; - display: flex; - justify-content: space-evenly; - gap: 1em; - flex-wrap: wrap; - align-items: center; - margin-bottom: 1em; -} - -.vc-settings-quick-actions-card button { - min-width: unset; -} - -.vc-settings-quick-actions-img { - width: 30px; - height: 30px; -} - .vc-settings-donate { display: flex; flex-direction: row; diff --git a/src/utils/misc.ts b/src/utils/misc.ts index 7d6b4affc..28c371c5b 100644 --- a/src/utils/misc.ts +++ b/src/utils/misc.ts @@ -24,7 +24,7 @@ import { DevsById } from "./constants"; * Calls .join(" ") on the arguments * classes("one", "two") => "one two" */ -export function classes(...classes: Array) { +export function classes(...classes: Array) { return classes.filter(Boolean).join(" "); } diff --git a/src/webpack/common/types/utils.d.ts b/src/webpack/common/types/utils.d.ts index ee3f69944..ce1e3e268 100644 --- a/src/webpack/common/types/utils.d.ts +++ b/src/webpack/common/types/utils.d.ts @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { Guild, GuildMember } from "discord-types/general"; +import { Guild, GuildMember, User } from "discord-types/general"; import type { ReactNode } from "react"; import { LiteralUnion } from "type-fest"; @@ -256,3 +256,63 @@ export interface PopoutActions { close(key: string): void; setAlwaysOnTop(key: string, alwaysOnTop: boolean): void; } + +export type UserNameUtilsTagInclude = LiteralUnion<"auto" | "always" | "never", string>; +export interface UserNameUtilsTagOptions { + forcePomelo?: boolean; + identifiable?: UserNameUtilsTagInclude; + decoration?: UserNameUtilsTagInclude; + mode?: "full" | "username"; +} + +export interface UsernameUtils { + getGlobalName(user: User): string; + getFormattedName(user: User, useTagInsteadOfUsername?: boolean): string; + getName(user: User): string; + useName(user: User): string; + getUserTag(user: User, options?: UserNameUtilsTagOptions): string; + useUserTag(user: User, options?: UserNameUtilsTagOptions): string; + + + useDirectMessageRecipient: any; + humanizeStatus: any; +} + +export class DisplayProfile { + userId: string; + banner?: string; + bio?: string; + pronouns?: string; + accentColor?: number; + themeColors?: number[]; + popoutAnimationParticleType?: any; + profileEffectId?: string; + _userProfile?: any; + _guildMemberProfile?: any; + canUsePremiumProfileCustomization: boolean; + canEditThemes: boolean; + premiumGuildSince: Date | null; + premiumSince: Date | null; + premiumType?: number; + primaryColor?: number; + + getBadges(): Array<{ + id: string; + description: string; + icon: string; + link?: string; + }>; + getBannerURL(options: { canAnimate: boolean; size: number; }): string; + getLegacyUsername(): string | null; + hasFullProfile(): boolean; + hasPremiumCustomization(): boolean; + hasThemeColors(): boolean; + isUsingGuildMemberBanner(): boolean; + isUsingGuildMemberBio(): boolean; + isUsingGuildMemberPronouns(): boolean; +} + +export interface DisplayProfileUtils { + getDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null; + useDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null; +} diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index a6853c84a..280b2ba90 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -73,6 +73,25 @@ const ToastPosition = { BOTTOM: 1 }; +export interface ToastData { + message: string, + id: string, + /** + * Toasts.Type + */ + type: number, + options?: ToastOptions; +} + +export interface ToastOptions { + /** + * Toasts.Position + */ + position?: number; + component?: React.ReactNode, + duration?: number; +} + export const Toasts = { Type: ToastType, Position: ToastPosition, @@ -81,23 +100,9 @@ export const Toasts = { // hack to merge with the following interface, dunno if there's a better way ...{} as { - show(data: { - message: string, - id: string, - /** - * Toasts.Type - */ - type: number, - options?: { - /** - * Toasts.Position - */ - position?: number; - component?: React.ReactNode, - duration?: number; - }; - }): void; + show(data: ToastData): void; pop(): void; + create(message: string, type: number, options?: ToastOptions): ToastData; } }; @@ -105,18 +110,15 @@ export const Toasts = { waitFor("showToast", m => { Toasts.show = m.showToast; Toasts.pop = m.popToast; + Toasts.create = m.createToast; }); /** * Show a simple toast. If you need more options, use Toasts.show manually */ -export function showToast(message: string, type = ToastType.MESSAGE) { - Toasts.show({ - id: Toasts.genId(), - message, - type - }); +export function showToast(message: string, type = ToastType.MESSAGE, options?: ToastOptions) { + Toasts.show(Toasts.create(message, type, options)); } export const UserUtils = { @@ -172,3 +174,9 @@ export const PopoutActions: t.PopoutActions = mapMangledModuleLazy('type:"POPOUT close: filters.byCode('type:"POPOUT_WINDOW_CLOSE"'), setAlwaysOnTop: filters.byCode('type:"POPOUT_WINDOW_SET_ALWAYS_ON_TOP"'), }); + +export const UsernameUtils: t.UsernameUtils = findByPropsLazy("useName", "getGlobalName"); +export const DisplayProfileUtils: t.DisplayProfileUtils = mapMangledModuleLazy(/=\i\.getUserProfile\(\i\),\i=\i\.getGuildMemberProfile\(/, { + getDisplayProfile: filters.byCode(".getGuildMemberProfile("), + useDisplayProfile: filters.byCode(/\[\i\.\i,\i\.\i],\(\)=>/) +}); diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts index f776ab1c3..f21a38d67 100644 --- a/src/webpack/webpack.ts +++ b/src/webpack/webpack.ts @@ -38,31 +38,43 @@ export let cache: WebpackInstance["c"]; export type FilterFn = (mod: any) => boolean; +type PropsFilter = Array; +type CodeFilter = Array; +type StoreNameFilter = string; + +const stringMatches = (s: string, filter: CodeFilter) => + filter.every(f => + typeof f === "string" + ? s.includes(f) + : f.test(s) + ); + export const filters = { - byProps: (...props: string[]): FilterFn => + byProps: (...props: PropsFilter): FilterFn => props.length === 1 ? m => m[props[0]] !== void 0 : m => props.every(p => m[p] !== void 0), - byCode: (...code: string[]): FilterFn => m => { - if (typeof m !== "function") return false; - const s = Function.prototype.toString.call(m); - for (const c of code) { - if (!s.includes(c)) return false; - } - return true; + byCode: (...code: CodeFilter): FilterFn => { + code = code.map(canonicalizeMatch); + return m => { + if (typeof m !== "function") return false; + return stringMatches(Function.prototype.toString.call(m), code); + }; }, - byStoreName: (name: string): FilterFn => m => + byStoreName: (name: StoreNameFilter): FilterFn => m => m.constructor?.displayName === name, - componentByCode: (...code: string[]): FilterFn => { + componentByCode: (...code: CodeFilter): FilterFn => { const filter = filters.byCode(...code); return m => { if (filter(m)) return true; if (!m.$$typeof) return false; - if (m.type && m.type.render) return filter(m.type.render); // memo + forwardRef - if (m.type) return filter(m.type); // memos - if (m.render) return filter(m.render); // forwardRefs + if (m.type) + return m.type.render + ? filter(m.type.render) // memo + forwardRef + : filter(m.type); // memo + if (m.render) return filter(m.render); // forwardRef return false; }; } @@ -245,15 +257,9 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns * Find the id of the first module factory that includes all the given code * @returns string or null */ -export const findModuleId = traceFunction("findModuleId", function findModuleId(...code: string[]) { - outer: +export const findModuleId = traceFunction("findModuleId", function findModuleId(...code: CodeFilter) { for (const id in wreq.m) { - const str = wreq.m[id].toString(); - - for (const c of code) { - if (!str.includes(c)) continue outer; - } - return id; + if (stringMatches(wreq.m[id].toString(), code)) return id; } const err = new Error("Didn't find module with code(s):\n" + code.join("\n")); @@ -272,7 +278,7 @@ export const findModuleId = traceFunction("findModuleId", function findModuleId( * Find the first module factory that includes all the given code * @returns The module factory or null */ -export function findModuleFactory(...code: string[]) { +export function findModuleFactory(...code: CodeFilter) { const id = findModuleId(...code); if (!id) return null; @@ -325,7 +331,7 @@ export function findLazy(filter: FilterFn) { /** * Find the first module that has the specified properties */ -export function findByProps(...props: string[]) { +export function findByProps(...props: PropsFilter) { const res = find(filters.byProps(...props), { isIndirect: true }); if (!res) handleModuleNotFound("findByProps", ...props); @@ -335,7 +341,7 @@ export function findByProps(...props: string[]) { /** * Find the first module that has the specified properties, lazily */ -export function findByPropsLazy(...props: string[]) { +export function findByPropsLazy(...props: PropsFilter) { if (IS_REPORTER) lazyWebpackSearchHistory.push(["findByProps", props]); return proxyLazy(() => findByProps(...props)); @@ -344,7 +350,7 @@ export function findByPropsLazy(...props: string[]) { /** * Find the first function that includes all the given code */ -export function findByCode(...code: string[]) { +export function findByCode(...code: CodeFilter) { const res = find(filters.byCode(...code), { isIndirect: true }); if (!res) handleModuleNotFound("findByCode", ...code); @@ -354,7 +360,7 @@ export function findByCode(...code: string[]) { /** * Find the first function that includes all the given code, lazily */ -export function findByCodeLazy(...code: string[]) { +export function findByCodeLazy(...code: CodeFilter) { if (IS_REPORTER) lazyWebpackSearchHistory.push(["findByCode", code]); return proxyLazy(() => findByCode(...code)); @@ -363,7 +369,7 @@ export function findByCodeLazy(...code: string[]) { /** * Find a store by its displayName */ -export function findStore(name: string) { +export function findStore(name: StoreNameFilter) { const res = find(filters.byStoreName(name), { isIndirect: true }); if (!res) handleModuleNotFound("findStore", name); @@ -373,7 +379,7 @@ export function findStore(name: string) { /** * Find a store by its displayName, lazily */ -export function findStoreLazy(name: string) { +export function findStoreLazy(name: StoreNameFilter) { if (IS_REPORTER) lazyWebpackSearchHistory.push(["findStore", [name]]); return proxyLazy(() => findStore(name)); @@ -382,7 +388,7 @@ export function findStoreLazy(name: string) { /** * Finds the component which includes all the given code. Checks for plain components, memos and forwardRefs */ -export function findComponentByCode(...code: string[]) { +export function findComponentByCode(...code: CodeFilter) { const res = find(filters.componentByCode(...code), { isIndirect: true }); if (!res) handleModuleNotFound("findComponentByCode", ...code); @@ -407,7 +413,7 @@ export function findComponentLazy(filter: FilterFn) { /** * Finds the first component that includes all the given code, lazily */ -export function findComponentByCodeLazy(...code: string[]) { +export function findComponentByCodeLazy(...code: CodeFilter) { if (IS_REPORTER) lazyWebpackSearchHistory.push(["findComponentByCode", code]); return LazyComponent(() => { @@ -421,7 +427,7 @@ export function findComponentByCodeLazy(...code: string[ /** * Finds the first component that is exported by the first prop name, lazily */ -export function findExportedComponentLazy(...props: string[]) { +export function findExportedComponentLazy(...props: PropsFilter) { if (IS_REPORTER) lazyWebpackSearchHistory.push(["findExportedComponent", props]); return LazyComponent(() => { @@ -445,10 +451,13 @@ export function findExportedComponentLazy(...props: stri * closeModal: filters.byCode("key==") * }) */ -export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule(code: string, mappers: Record): Record { +export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule(code: string | RegExp | CodeFilter, mappers: Record): Record { + if (!Array.isArray(code)) code = [code]; + code = code.map(canonicalizeMatch); + const exports = {} as Record; - const id = findModuleId(code); + const id = findModuleId(...code); if (id === null) return exports; @@ -482,7 +491,7 @@ export const mapMangledModule = traceFunction("mapMangledModule", function mapMa * closeModal: filters.byCode("key==") * }) */ -export function mapMangledModuleLazy(code: string, mappers: Record): Record { +export function mapMangledModuleLazy(code: string | RegExp | CodeFilter, mappers: Record): Record { if (IS_REPORTER) lazyWebpackSearchHistory.push(["mapMangledModule", [code, mappers]]); return proxyLazy(() => mapMangledModule(code, mappers)); @@ -497,7 +506,7 @@ export const ChunkIdsRegex = /\("([^"]+?)"\)/g; * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the first lazy chunk loading found in the module factory * @returns A promise that resolves with a boolean whether the chunks were loaded */ -export async function extractAndLoadChunks(code: string[], matcher: RegExp = DefaultExtractAndLoadChunksRegex) { +export async function extractAndLoadChunks(code: CodeFilter, matcher: RegExp = DefaultExtractAndLoadChunksRegex) { const module = findModuleFactory(...code); if (!module) { const err = new Error("extractAndLoadChunks: Couldn't find module factory"); @@ -562,7 +571,7 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = Def * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the first lazy chunk loading found in the module factory * @returns A function that returns a promise that resolves with a boolean whether the chunks were loaded, on first call */ -export function extractAndLoadChunksLazy(code: string[], matcher = DefaultExtractAndLoadChunksRegex) { +export function extractAndLoadChunksLazy(code: CodeFilter, matcher = DefaultExtractAndLoadChunksRegex) { if (IS_REPORTER) lazyWebpackSearchHistory.push(["extractAndLoadChunks", [code, matcher]]); return makeLazy(() => extractAndLoadChunks(code, matcher)); @@ -572,7 +581,7 @@ export function extractAndLoadChunksLazy(code: string[], matcher = DefaultExtrac * Wait for a module that matches the provided filter to be registered, * then call the callback with the module as the first argument */ -export function waitFor(filter: string | string[] | FilterFn, callback: CallbackFn, { isIndirect = false }: { isIndirect?: boolean; } = {}) { +export function waitFor(filter: string | PropsFilter | FilterFn, callback: CallbackFn, { isIndirect = false }: { isIndirect?: boolean; } = {}) { if (IS_REPORTER && !isIndirect) lazyWebpackSearchHistory.push(["waitFor", Array.isArray(filter) ? filter : [filter]]); if (typeof filter === "string") @@ -593,21 +602,18 @@ export function waitFor(filter: string | string[] | FilterFn, callback: Callback /** * Search modules by keyword. This searches the factory methods, * meaning you can search all sorts of things, displayName, methodName, strings somewhere in the code, etc - * @param filters One or more strings or regexes + * @param code One or more strings or regexes * @returns Mapping of found modules */ -export function search(...filters: Array) { +export function search(...code: CodeFilter) { const results = {} as Record; const factories = wreq.m; - outer: + for (const id in factories) { const factory = factories[id].original ?? factories[id]; - const str: string = factory.toString(); - for (const filter of filters) { - if (typeof filter === "string" && !str.includes(filter)) continue outer; - if (filter instanceof RegExp && !filter.test(str)) continue outer; - } - results[id] = factory; + + if (stringMatches(factory.toString(), code)) + results[id] = factory; } return results; From e648bf92e21389e4c34b264b675dcf19741fac52 Mon Sep 17 00:00:00 2001 From: Cooper Date: Tue, 2 Jul 2024 14:13:05 -0500 Subject: [PATCH 06/17] change name, update code and readme --- src/plugins/extraConnectionLinks/README.md | 14 +++++ src/plugins/extraConnectionLinks/index.ts | 59 ++++++++++++++++++++++ src/plugins/openMoreConnections/README.md | 12 ----- src/plugins/openMoreConnections/index.ts | 42 --------------- 4 files changed, 73 insertions(+), 54 deletions(-) create mode 100644 src/plugins/extraConnectionLinks/README.md create mode 100644 src/plugins/extraConnectionLinks/index.ts delete mode 100644 src/plugins/openMoreConnections/README.md delete mode 100644 src/plugins/openMoreConnections/index.ts diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md new file mode 100644 index 000000000..c2af46278 --- /dev/null +++ b/src/plugins/extraConnectionLinks/README.md @@ -0,0 +1,14 @@ +# ExtraConnectionLinks + +Adds the Open Profile button to connections that don't natively have it in the regular Discord client. +## Supported Platforms +* Xbox +* Roblox +## Planned Platforms +* None as of currently +## Platforms that will never be supported +* Riot Games/League of Legends (Nothing made by Riot Games to view profiles online) +* Battle.net (Nothing made by Blizzard to view profiles online) +* Bungie.net (Nothing made by Bungie.net to view profiles online) +* Epic Games (Nothing made by Epic Games to view profiles online) +* PSN/PlayStation Network (Sony built a service called My PlayStation, but removed it for unknown reasons in 2021) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts new file mode 100644 index 000000000..0e36f39f2 --- /dev/null +++ b/src/plugins/extraConnectionLinks/index.ts @@ -0,0 +1,59 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Cooper/coopeeo, Vendicated and contributors* + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; + +/** + * platforms that dont open natively + * ! riot and leage (can't view profiles) + * ! epic (can't view profiles) + * ! psn (can't view profiles after sony removed My PlayStation) + * * roblox (Added) + * * xbox (Added) + * ! battle.net (can't view profiles) + * ! bungie.net (can't view profiles) + * ! facebook (don't have discord access token for facebook connection) + **/ + +/** */ +enum contypes { + Roblox = "Roblox", + Xbox = "Xbox", +} + +const uris = { // name (what shows up on connection on ui), id (an identifier thing) + [contypes.Roblox]: "https://www.roblox.com/users/${id}/profile", + [contypes.Xbox]: "https://www.xbox.com/play/user/${name}", +}; + +const serviceNames = { // What the name part in the discord code calls it. + [contypes.Roblox]: "Roblox", + [contypes.Xbox]: "Xbox", +}; + +export default definePlugin({ + name: "ExtraConnectionLinks", + description: "Adds the Open Profile button to connections that don't natively have it in the regular Discord client.", + authors: [Devs.coopeeo], + patches: makePatches(), +}); + + +function makePatches() { + return Object.keys(contypes) + .filter(v => isNaN(Number(v))) + .map(key => { + const contype = contypes[key as keyof typeof contypes]; + return { + find: "getPlatformUserUrl:", + replacement: { + match: new RegExp(`(?<=${serviceNames[contype]}",.*},.+)(?=},)`), + replace: `, getPlatformUserUrl:e=>{let {name, id} = e; return \`${uris[contype]}\`;}` + } + }; + }); +} diff --git a/src/plugins/openMoreConnections/README.md b/src/plugins/openMoreConnections/README.md deleted file mode 100644 index ef3eb93d2..000000000 --- a/src/plugins/openMoreConnections/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# OpenMoreConnections - -Adds the Open Profile button to connections that don't natively have it in the regular Discord client. -## Supported Platforms -* Xbox -* Roblox -## Planned Platforms -* PSN -## Platforms that will never be supported -* Riot Games/League of Legends -* Battle.net -* Epic Games diff --git a/src/plugins/openMoreConnections/index.ts b/src/plugins/openMoreConnections/index.ts deleted file mode 100644 index e69708844..000000000 --- a/src/plugins/openMoreConnections/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Cooper/coopeeo, Vendicated and contributors* - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { Devs } from "@utils/constants"; -import definePlugin from "@utils/types"; - -//* platforms that dont open -//* riot and leage (can't view profiles) -//* epic (can't view profiles) -//* psn (can't view profiles but I have a workaround for 3rd party stuff) -//* roblox -//* xbox -//* battle.net (can't view profiles) - -const uris = { // name = t, and id = l - roblox: "https://www.roblox.com/users/${l}/profile", - xbox: "https://www.xbox.com/play/user/${t}" -}; -export default definePlugin({ - name: "OpenMoreConnections", - description: "Adds the Open Profile button to connections that don't natively have it in the regular Discord client. Supported Platforms: Xbox, and Roblox. Planned Platforms: PSN. Platforms that will never be supported: Riot Games/League of Legends, Battle.net, and Epic Games", - authors: [Devs.coopeeo], - patches: [ - { - find: "getPlatformUserUrl:e=>", - replacement: { - match: /(?<=Roblox",.*},.+)(?=},)/, - replace: `, getPlatformUserUrl:e=>{let {name:t, id:l} = e; return \`${uris.roblox}\`;}` - } - }, - { - find: "getPlatformUserUrl:e=>", - replacement: { - match: /(?<=Xbox",.*},.+)(?=},)/, - replace: `, getPlatformUserUrl:e=>{let {name:t, id:l} = e; return \`${uris.xbox}\`;}` - } - } - ], -}); From 402cb1cad93bb0e6cfbf41ecd545f0ee87407103 Mon Sep 17 00:00:00 2001 From: Cooper Date: Tue, 2 Jul 2024 14:50:29 -0500 Subject: [PATCH 07/17] remove a star --- src/plugins/extraConnectionLinks/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index 0e36f39f2..c38dbd0cd 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -1,6 +1,6 @@ /* * Vencord, a Discord client mod - * Copyright (c) 2024 Cooper/coopeeo, Vendicated and contributors* + * Copyright (c) 2024 Cooper/coopeeo, Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ From 6a617016a771bbcfbddc03a40091b920a0038eb9 Mon Sep 17 00:00:00 2001 From: Cooper Date: Sat, 6 Jul 2024 12:31:58 -0500 Subject: [PATCH 08/17] add images to readme, and change description. --- src/plugins/extraConnectionLinks/README.md | 15 +++++++++++---- src/plugins/extraConnectionLinks/index.ts | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index c2af46278..f182dd7e8 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -1,12 +1,19 @@ # ExtraConnectionLinks +Allows you to open more connections in browser! -Adds the Open Profile button to connections that don't natively have it in the regular Discord client. -## Supported Platforms +## Before and After +### Before +![Shows the Roblox connection in the Discord client without the open profile button (the default).](https://github.com/Vendicated/Vencord/assets/73203995/734efd94-c61a-4f90-987d-3a4bbcc9311f) +### After +![Shows the Roblox connection in the Discord client with the open profile button.](https://github.com/Vendicated/Vencord/assets/73203995/eef59d09-78d9-4859-b722-242fc6aa7c8e) + +## Platform Status +### Supported Platforms * Xbox * Roblox -## Planned Platforms +### Planned Platforms * None as of currently -## Platforms that will never be supported +### Platforms that will never be supported * Riot Games/League of Legends (Nothing made by Riot Games to view profiles online) * Battle.net (Nothing made by Blizzard to view profiles online) * Bungie.net (Nothing made by Bungie.net to view profiles online) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index c38dbd0cd..a830c5bcf 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -37,7 +37,7 @@ const serviceNames = { // What the name part in the discord code calls it. export default definePlugin({ name: "ExtraConnectionLinks", - description: "Adds the Open Profile button to connections that don't natively have it in the regular Discord client.", + description: "Allows you to open more connections in browser!", authors: [Devs.coopeeo], patches: makePatches(), }); From d435e0a28e21e11b2bdc9c9e00a7ea8a702b225c Mon Sep 17 00:00:00 2001 From: Cooper Date: Tue, 23 Jul 2024 15:42:55 -0500 Subject: [PATCH 09/17] feat: add Epic Games profile support --- src/plugins/extraConnectionLinks/README.md | 2 +- src/plugins/extraConnectionLinks/index.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index f182dd7e8..61668550b 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -11,11 +11,11 @@ Allows you to open more connections in browser! ### Supported Platforms * Xbox * Roblox +* Epic Games ### Planned Platforms * None as of currently ### Platforms that will never be supported * Riot Games/League of Legends (Nothing made by Riot Games to view profiles online) * Battle.net (Nothing made by Blizzard to view profiles online) * Bungie.net (Nothing made by Bungie.net to view profiles online) -* Epic Games (Nothing made by Epic Games to view profiles online) * PSN/PlayStation Network (Sony built a service called My PlayStation, but removed it for unknown reasons in 2021) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index a830c5bcf..3f1821795 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -10,7 +10,7 @@ import definePlugin from "@utils/types"; /** * platforms that dont open natively * ! riot and leage (can't view profiles) - * ! epic (can't view profiles) + * * epic (Added) * ! psn (can't view profiles after sony removed My PlayStation) * * roblox (Added) * * xbox (Added) @@ -23,16 +23,19 @@ import definePlugin from "@utils/types"; enum contypes { Roblox = "Roblox", Xbox = "Xbox", + Epic = "Epic" } const uris = { // name (what shows up on connection on ui), id (an identifier thing) [contypes.Roblox]: "https://www.roblox.com/users/${id}/profile", [contypes.Xbox]: "https://www.xbox.com/play/user/${name}", + [contypes.Epic]: "https://store.epicgames.com/en-US/u/${id}", }; const serviceNames = { // What the name part in the discord code calls it. [contypes.Roblox]: "Roblox", [contypes.Xbox]: "Xbox", + [contypes.Epic]: "Epic Games", }; export default definePlugin({ From e2c3c0655a2d1668b648b798f9e2b9af7d745c47 Mon Sep 17 00:00:00 2001 From: Cooper Date: Wed, 24 Jul 2024 12:07:40 -0500 Subject: [PATCH 10/17] tried to add more services (but none of them worked) :( --- src/plugins/extraConnectionLinks/README.md | 8 ++- src/plugins/extraConnectionLinks/index.ts | 76 +++++++++++++--------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index 61668550b..ec3e87da1 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -15,7 +15,11 @@ Allows you to open more connections in browser! ### Planned Platforms * None as of currently ### Platforms that will never be supported -* Riot Games/League of Legends (Nothing made by Riot Games to view profiles online) +* Riot Games (Nothing made by Riot Games to view profiles online) +* League of Legends (Same as above since it's the same company) * Battle.net (Nothing made by Blizzard to view profiles online) * Bungie.net (Nothing made by Bungie.net to view profiles online) -* PSN/PlayStation Network (Sony built a service called My PlayStation, but removed it for unknown reasons in 2021) +* PlayStation Network (Sony built a service called My PlayStation, but removed it for unknown reasons in 2021) +* Facebook (don't have discord's token for facebook apis why even would i have that...) +* Crunchyroll (can't view other peoples profiles nor your own profile) +* Amazon Music (nothing references to the actual amazon music user id in discord. I also went on the website for the first time and it decided to give me unlimited for free, then right after upgraded me to the family plan and that was not free and was a waste of $10.54, like bro, I was just trying to close all the popups then it froze and upgraded itself to the family plan) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index 3f1821795..e78fcb19f 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -8,55 +8,67 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; /** - * platforms that dont open natively - * ! riot and leage (can't view profiles) - * * epic (Added) - * ! psn (can't view profiles after sony removed My PlayStation) - * * roblox (Added) - * * xbox (Added) - * ! battle.net (can't view profiles) - * ! bungie.net (can't view profiles) - * ! facebook (don't have discord access token for facebook connection) + * platforms that dont open natively (and the status of them) + * * Roblox (Added) + * * Xbox/Xbox Live (Added) + * * Epic Games (Added) + * ! Riot Games (can't view profiles) + * ! Leage of Legends (can't view profiles) (same as Riot Games) + * ! PSN (no other known way to view profiles after Sony removed My PlayStation) + * ! Battle.net (can't view profiles) + * ! Bungie.net (can't view profiles) + * ! Facebook (don't have discord's token for facebook apis) + * ! Crunchyroll (can't view other peoples profiles nor your own profile) + * ! Amazon Music (the id that discord shows is "amzn1..") **/ -/** */ -enum contypes { - Roblox = "Roblox", - Xbox = "Xbox", - Epic = "Epic" +/** + * All the connection types implemented into this plugin + */ +enum connectionTypes { + Roblox, + Xbox, + Epic, } +/** + * The uri to use. + * There are also two variables that you can use, name and id. + * The "name" is well the name of the account and the name is what shows up when viewing a connection on a discord profile. + * The "id" is an identifier that normal users don't see, it will usually be an user id (, for example Roblox has user ids, and discord stores that user id in the id field of the connection). + * @example [connectionTypes.Xbox]: "https://www.xbox.com/play/user/${name}", + * @example [connectionTypes.Roblox]: "https://www.roblox.com/users/${id}/profile", + */ const uris = { // name (what shows up on connection on ui), id (an identifier thing) - [contypes.Roblox]: "https://www.roblox.com/users/${id}/profile", - [contypes.Xbox]: "https://www.xbox.com/play/user/${name}", - [contypes.Epic]: "https://store.epicgames.com/en-US/u/${id}", + [connectionTypes.Roblox]: "https://www.roblox.com/users/${id}/profile", + [connectionTypes.Xbox]: "https://www.xbox.com/play/user/${name}", + [connectionTypes.Epic]: "https://store.epicgames.com/u/${id}", }; -const serviceNames = { // What the name part in the discord code calls it. - [contypes.Roblox]: "Roblox", - [contypes.Xbox]: "Xbox", - [contypes.Epic]: "Epic Games", +/** + * What discord has the service named as. + * @example [connectionTypes.Epic]: "Epic Games", + */ +const serviceNames = { + [connectionTypes.Roblox]: "Roblox", + [connectionTypes.Xbox]: "Xbox", + [connectionTypes.Epic]: "Epic Games", }; export default definePlugin({ name: "ExtraConnectionLinks", description: "Allows you to open more connections in browser!", authors: [Devs.coopeeo], - patches: makePatches(), -}); - - -function makePatches() { - return Object.keys(contypes) + patches: Object.keys(connectionTypes) .filter(v => isNaN(Number(v))) .map(key => { - const contype = contypes[key as keyof typeof contypes]; + const connectionTypeSelected = connectionTypes[key as keyof typeof connectionTypes]; return { find: "getPlatformUserUrl:", replacement: { - match: new RegExp(`(?<=${serviceNames[contype]}",.*},.+)(?=},)`), - replace: `, getPlatformUserUrl:e=>{let {name, id} = e; return \`${uris[contype]}\`;}` + match: new RegExp(`(?<=${serviceNames[connectionTypeSelected]}",.*},.+)(?=},)`), + replace: `, getPlatformUserUrl:e=>{let {name, id} = e; return \`${uris[connectionTypeSelected]}\`;}` } }; - }); -} + }), +}); From 52d3c0aface87b6dc80f292ce64f5c0cafff8d99 Mon Sep 17 00:00:00 2001 From: Cooper Date: Mon, 5 Aug 2024 12:34:58 -0500 Subject: [PATCH 11/17] Remove platform info as that info is in README.md Co-authored-by: Scyye <97131358+Scyye@users.noreply.github.com> --- src/plugins/extraConnectionLinks/index.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index e78fcb19f..11443d8d0 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -7,20 +7,6 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; -/** - * platforms that dont open natively (and the status of them) - * * Roblox (Added) - * * Xbox/Xbox Live (Added) - * * Epic Games (Added) - * ! Riot Games (can't view profiles) - * ! Leage of Legends (can't view profiles) (same as Riot Games) - * ! PSN (no other known way to view profiles after Sony removed My PlayStation) - * ! Battle.net (can't view profiles) - * ! Bungie.net (can't view profiles) - * ! Facebook (don't have discord's token for facebook apis) - * ! Crunchyroll (can't view other peoples profiles nor your own profile) - * ! Amazon Music (the id that discord shows is "amzn1..") - **/ /** * All the connection types implemented into this plugin From 52c3a55449b047268699ea4e444975c2d3d873e3 Mon Sep 17 00:00:00 2001 From: Cooper Date: Mon, 5 Aug 2024 12:37:07 -0500 Subject: [PATCH 12/17] Remove planned platforms section Co-authored-by: Scyye <97131358+Scyye@users.noreply.github.com> --- src/plugins/extraConnectionLinks/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index ec3e87da1..3bbb8d730 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -12,8 +12,6 @@ Allows you to open more connections in browser! * Xbox * Roblox * Epic Games -### Planned Platforms -* None as of currently ### Platforms that will never be supported * Riot Games (Nothing made by Riot Games to view profiles online) * League of Legends (Same as above since it's the same company) From be5e2527aa2c69b15afb503afc9399ed9218867a Mon Sep 17 00:00:00 2001 From: Cooper Date: Mon, 5 Aug 2024 12:38:46 -0500 Subject: [PATCH 13/17] Remove "Before and After" section Co-authored-by: Scyye <97131358+Scyye@users.noreply.github.com> --- src/plugins/extraConnectionLinks/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index 3bbb8d730..f927882a7 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -1,7 +1,6 @@ # ExtraConnectionLinks Allows you to open more connections in browser! -## Before and After ### Before ![Shows the Roblox connection in the Discord client without the open profile button (the default).](https://github.com/Vendicated/Vencord/assets/73203995/734efd94-c61a-4f90-987d-3a4bbcc9311f) ### After From cb4071a3cebd03c8cac17a99bf294cb84d4fdb33 Mon Sep 17 00:00:00 2001 From: Cooper Date: Thu, 5 Sep 2024 10:20:48 -0500 Subject: [PATCH 14/17] Apply suggestions from code reviews Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> --- src/plugins/extraConnectionLinks/README.md | 4 ++-- src/plugins/extraConnectionLinks/index.ts | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index f927882a7..32a34e890 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -17,6 +17,6 @@ Allows you to open more connections in browser! * Battle.net (Nothing made by Blizzard to view profiles online) * Bungie.net (Nothing made by Bungie.net to view profiles online) * PlayStation Network (Sony built a service called My PlayStation, but removed it for unknown reasons in 2021) -* Facebook (don't have discord's token for facebook apis why even would i have that...) +* Facebook * Crunchyroll (can't view other peoples profiles nor your own profile) -* Amazon Music (nothing references to the actual amazon music user id in discord. I also went on the website for the first time and it decided to give me unlimited for free, then right after upgraded me to the family plan and that was not free and was a waste of $10.54, like bro, I was just trying to close all the popups then it froze and upgraded itself to the family plan) +* Amazon Music (nothing references to the actual amazon music user id in discord. diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index 11443d8d0..c761e74e1 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -7,7 +7,6 @@ import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; - /** * All the connection types implemented into this plugin */ @@ -20,8 +19,8 @@ enum connectionTypes { /** * The uri to use. * There are also two variables that you can use, name and id. - * The "name" is well the name of the account and the name is what shows up when viewing a connection on a discord profile. - * The "id" is an identifier that normal users don't see, it will usually be an user id (, for example Roblox has user ids, and discord stores that user id in the id field of the connection). + * The "name" is what shows up when viewing a connection on a discord profile. + * The "id" is the identifier of the account connected, the type depends on the service connected. * @example [connectionTypes.Xbox]: "https://www.xbox.com/play/user/${name}", * @example [connectionTypes.Roblox]: "https://www.roblox.com/users/${id}/profile", */ @@ -52,7 +51,7 @@ export default definePlugin({ return { find: "getPlatformUserUrl:", replacement: { - match: new RegExp(`(?<=${serviceNames[connectionTypeSelected]}",.*},.+)(?=},)`), + match: new RegExp(`(r`), replace: `, getPlatformUserUrl:e=>{let {name, id} = e; return \`${uris[connectionTypeSelected]}\`;}` } }; From 29de13fe4ea1c99556c1cddd35f52ec7042af4a7 Mon Sep 17 00:00:00 2001 From: Cooper Date: Thu, 5 Sep 2024 10:34:46 -0500 Subject: [PATCH 15/17] fix errors in readme and code --- src/plugins/extraConnectionLinks/README.md | 1 - src/plugins/extraConnectionLinks/index.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index 32a34e890..80243f778 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -9,7 +9,6 @@ Allows you to open more connections in browser! ## Platform Status ### Supported Platforms * Xbox -* Roblox * Epic Games ### Platforms that will never be supported * Riot Games (Nothing made by Riot Games to view profiles online) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index c761e74e1..682f49421 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -51,7 +51,7 @@ export default definePlugin({ return { find: "getPlatformUserUrl:", replacement: { - match: new RegExp(`(r`), + match: new RegExp("(r"), replace: `, getPlatformUserUrl:e=>{let {name, id} = e; return \`${uris[connectionTypeSelected]}\`;}` } }; From d6390658b739fa048e0b7b9599f5d4125570ac30 Mon Sep 17 00:00:00 2001 From: Cooper Date: Thu, 5 Sep 2024 10:36:33 -0500 Subject: [PATCH 16/17] oops also forgor this. --- src/plugins/extraConnectionLinks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/extraConnectionLinks/README.md b/src/plugins/extraConnectionLinks/README.md index 80243f778..722299622 100644 --- a/src/plugins/extraConnectionLinks/README.md +++ b/src/plugins/extraConnectionLinks/README.md @@ -18,4 +18,4 @@ Allows you to open more connections in browser! * PlayStation Network (Sony built a service called My PlayStation, but removed it for unknown reasons in 2021) * Facebook * Crunchyroll (can't view other peoples profiles nor your own profile) -* Amazon Music (nothing references to the actual amazon music user id in discord. +* Amazon Music (nothing references to the actual amazon music user id in discord.) From 70ea0c92a836bb66c02c3ffcd8f44ba156dd3df0 Mon Sep 17 00:00:00 2001 From: Cooper Date: Thu, 5 Sep 2024 10:37:06 -0500 Subject: [PATCH 17/17] Remove Roblox as a temp thing i will test when home. --- src/plugins/extraConnectionLinks/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/extraConnectionLinks/index.ts b/src/plugins/extraConnectionLinks/index.ts index 682f49421..c7b6af17f 100644 --- a/src/plugins/extraConnectionLinks/index.ts +++ b/src/plugins/extraConnectionLinks/index.ts @@ -25,7 +25,7 @@ enum connectionTypes { * @example [connectionTypes.Roblox]: "https://www.roblox.com/users/${id}/profile", */ const uris = { // name (what shows up on connection on ui), id (an identifier thing) - [connectionTypes.Roblox]: "https://www.roblox.com/users/${id}/profile", + //[connectionTypes.Roblox]: "https://www.roblox.com/users/${id}/profile", [connectionTypes.Xbox]: "https://www.xbox.com/play/user/${name}", [connectionTypes.Epic]: "https://store.epicgames.com/u/${id}", }; @@ -35,7 +35,7 @@ const uris = { // name (what shows up on connection on ui), id (an identifier th * @example [connectionTypes.Epic]: "Epic Games", */ const serviceNames = { - [connectionTypes.Roblox]: "Roblox", + //[connectionTypes.Roblox]: "Roblox", [connectionTypes.Xbox]: "Xbox", [connectionTypes.Epic]: "Epic Games", };