From e26986f66adb1784d5ab62f9c165014296698c84 Mon Sep 17 00:00:00 2001 From: Lumap Date: Tue, 17 Sep 2024 17:29:46 +0200 Subject: [PATCH 1/4] AppleMusicRichPresence: fix formatting when listening to radio (#2869) Co-authored-by: Ryan Cao <70191398+ryanccn@users.noreply.github.com> Co-authored-by: v --- src/plugins/appleMusic.desktop/index.tsx | 30 +++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/plugins/appleMusic.desktop/index.tsx b/src/plugins/appleMusic.desktop/index.tsx index 327fafc30..f3148c36d 100644 --- a/src/plugins/appleMusic.desktop/index.tsx +++ b/src/plugins/appleMusic.desktop/index.tsx @@ -24,7 +24,7 @@ interface ActivityButton { } interface Activity { - state: string; + state?: string; details?: string; timestamps?: { start?: number; @@ -52,8 +52,8 @@ const enum ActivityFlag { export interface TrackData { name: string; - album: string; - artist: string; + album?: string; + artist?: string; appleMusicLink?: string; songLink?: string; @@ -61,8 +61,8 @@ export interface TrackData { albumArtwork?: string; artistArtwork?: string; - playerPosition: number; - duration: number; + playerPosition?: number; + duration?: number; } const enum AssetImageType { @@ -155,8 +155,8 @@ const settings = definePluginSettings({ function customFormat(formatStr: string, data: TrackData) { return formatStr .replaceAll("{name}", data.name) - .replaceAll("{album}", data.album) - .replaceAll("{artist}", data.artist); + .replaceAll("{album}", data.album ?? "") + .replaceAll("{artist}", data.artist ?? ""); } function getImageAsset(type: AssetImageType, data: TrackData) { @@ -212,14 +212,16 @@ export default definePlugin({ const assets: ActivityAssets = {}; + const isRadio = Number.isNaN(trackData.duration) && (trackData.playerPosition === 0); + if (settings.store.largeImageType !== AssetImageType.Disabled) { assets.large_image = largeImageAsset; - assets.large_text = customFormat(settings.store.largeTextString, trackData); + if (!isRadio) assets.large_text = customFormat(settings.store.largeTextString, trackData); } if (settings.store.smallImageType !== AssetImageType.Disabled) { assets.small_image = smallImageAsset; - assets.small_text = customFormat(settings.store.smallTextString, trackData); + if (!isRadio) assets.small_text = customFormat(settings.store.smallTextString, trackData); } const buttons: ActivityButton[] = []; @@ -243,17 +245,17 @@ export default definePlugin({ name: customFormat(settings.store.nameString, trackData), details: customFormat(settings.store.detailsString, trackData), - state: customFormat(settings.store.stateString, trackData), + state: isRadio ? undefined : customFormat(settings.store.stateString, trackData), - timestamps: (settings.store.enableTimestamps ? { + timestamps: (trackData.playerPosition && trackData.duration && settings.store.enableTimestamps) ? { start: Date.now() - (trackData.playerPosition * 1000), end: Date.now() - (trackData.playerPosition * 1000) + (trackData.duration * 1000), - } : undefined), + } : undefined, assets, - buttons: buttons.length ? buttons.map(v => v.label) : undefined, - metadata: { button_urls: buttons.map(v => v.url) || undefined, }, + buttons: !isRadio && buttons.length ? buttons.map(v => v.label) : undefined, + metadata: !isRadio && buttons.length ? { button_urls: buttons.map(v => v.url) } : undefined, type: settings.store.activityType, flags: ActivityFlag.INSTANCE, From c572116b97a8b59d71bd48aea3d731e23c9fd62b Mon Sep 17 00:00:00 2001 From: Kyuuhachi <1547062+Kyuuhachi@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:40:11 +0200 Subject: [PATCH 2/4] BetterSettings: Add submenu for plugins (#2858) Co-authored-by: Vendicated --- src/plugins/betterSettings/PluginsSubmenu.tsx | 68 +++++++++++++++++++ src/plugins/betterSettings/index.tsx | 20 ++++-- src/webpack/common/types/menu.d.ts | 5 ++ 3 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 src/plugins/betterSettings/PluginsSubmenu.tsx diff --git a/src/plugins/betterSettings/PluginsSubmenu.tsx b/src/plugins/betterSettings/PluginsSubmenu.tsx new file mode 100644 index 000000000..b22f82a67 --- /dev/null +++ b/src/plugins/betterSettings/PluginsSubmenu.tsx @@ -0,0 +1,68 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { openPluginModal } from "@components/PluginSettings/PluginModal"; +import { isObjectEmpty } from "@utils/misc"; +import { Alerts, i18n, Menu, useMemo, useState } from "@webpack/common"; + +import Plugins from "~plugins"; + +function onRestartNeeded() { + Alerts.show({ + title: "Restart required", + body:

You have changed settings that require a restart.

, + confirmText: "Restart now", + cancelText: "Later!", + onConfirm: () => location.reload() + }); +} + +export default function PluginsSubmenu() { + const sortedPlugins = useMemo(() => Object.values(Plugins) + .sort((a, b) => a.name.localeCompare(b.name)), []); + const [query, setQuery] = useState(""); + + const search = query.toLowerCase(); + const include = (p: typeof Plugins[keyof typeof Plugins]) => ( + Vencord.Plugins.isPluginEnabled(p.name) + && p.options && !isObjectEmpty(p.options) + && ( + p.name.toLowerCase().includes(search) + || p.description.toLowerCase().includes(search) + || p.tags?.some(t => t.toLowerCase().includes(search)) + ) + ); + + const plugins = sortedPlugins.filter(include); + + return ( + <> + ( + + )} + /> + + {!!plugins.length && } + + {plugins.map(p => ( + openPluginModal(p, onRestartNeeded)} + /> + ))} + + ); +} diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx index 6a3ded3c1..f0dd89a7a 100644 --- a/src/plugins/betterSettings/index.tsx +++ b/src/plugins/betterSettings/index.tsx @@ -13,6 +13,8 @@ import { waitFor } from "@webpack"; import { ComponentDispatch, FocusLock, i18n, Menu, useEffect, useRef } from "@webpack/common"; import type { HTMLAttributes, ReactElement } from "react"; +import PluginsSubmenu from "./PluginsSubmenu"; + type SettingsEntry = { section: string, label: string; }; const cl = classNameFactory(""); @@ -118,13 +120,21 @@ export default definePlugin({ }, { // Settings cog context menu find: "Messages.USER_SETTINGS_ACTIONS_MENU_LABEL", - replacement: { - match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/, - replace: "$1$self.wrapMenu($2)" - } - } + replacement: [ + { + match: /(EXPERIMENTS:.+?)(\(0,\i.\i\)\(\))(?=\.filter\(\i=>\{let\{section:\i\}=)/, + replace: "$1$self.wrapMenu($2)" + }, + { + match: /case \i\.\i\.DEVELOPER_OPTIONS:return \i;/, + replace: "$&case 'VencordPlugins':return $self.PluginsSubmenu();" + } + ] + }, ], + PluginsSubmenu, + // This is the very outer layer of the entire ui, so we can't wrap this in an ErrorBoundary // without possibly also catching unrelated errors of children. // diff --git a/src/webpack/common/types/menu.d.ts b/src/webpack/common/types/menu.d.ts index 0b8ab5c66..5ae9062c3 100644 --- a/src/webpack/common/types/menu.d.ts +++ b/src/webpack/common/types/menu.d.ts @@ -72,6 +72,11 @@ export interface Menu { onChange(value: number): void, renderValue?(value: number): string, }>; + MenuSearchControl: RC<{ + query: string + onChange(query: string): void; + placeholder?: string; + }>; } export interface ContextMenuApi { From 1848b1653694f2797e42ef84f0102833fb7ce55c Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:30:06 -0300 Subject: [PATCH 3/4] ReviewDB: Fix in panel profile --- src/plugins/consoleJanitor/index.ts | 2 +- src/plugins/reviewDB/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/consoleJanitor/index.ts b/src/plugins/consoleJanitor/index.ts index e847c4124..f5f43c06b 100644 --- a/src/plugins/consoleJanitor/index.ts +++ b/src/plugins/consoleJanitor/index.ts @@ -126,7 +126,7 @@ export default definePlugin({ } }, { - find: '"Handling ping: "', + find: '"_handleLocalVideoDisabled: ', predicate: () => settings.store.disableNoisyLoggers, replacement: { match: /new \i\.\i\("RTCConnection\("\.concat.+?\)\)(?=,)/, diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx index 1164a2c5b..9d93e53a3 100644 --- a/src/plugins/reviewDB/index.tsx +++ b/src/plugins/reviewDB/index.tsx @@ -91,7 +91,7 @@ export default definePlugin({ } }, { - find: ".PANEL,isInteractionSource:", + find: ".PANEL,interactionType:", replacement: { match: /{profileType:\i\.\i\.PANEL,children:\[/, replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user})," From 6cce8a8bc43506eb3e2f18292e649a12d05905cf Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:30:16 -0300 Subject: [PATCH 4/4] Experiments: Allow clips to be recorded without streaming --- src/plugins/experiments/index.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/plugins/experiments/index.tsx b/src/plugins/experiments/index.tsx index 33c32b1a0..82e20f734 100644 --- a/src/plugins/experiments/index.tsx +++ b/src/plugins/experiments/index.tsx @@ -23,12 +23,13 @@ import { ErrorCard } from "@components/ErrorCard"; import { Devs } from "@utils/constants"; import { Margins } from "@utils/margins"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy } from "@webpack"; +import { findByPropsLazy, findLazy } from "@webpack"; import { Forms, React } from "@webpack/common"; import hideBugReport from "./hideBugReport.css?managed"; const KbdStyles = findByPropsLazy("key", "combo"); +const BugReporterExperiment = findLazy(m => m?.definition?.id === "2024-09_bug_reporter"); const settings = definePluginSettings({ toolbarDevMenu: { @@ -78,8 +79,8 @@ export default definePlugin({ { find: "toolbar:function", replacement: { - match: /\i\.isStaff\(\)/, - replace: "true" + match: /hasBugReporterAccess:(\i)/, + replace: "_hasBugReporterAccess:$1=true" }, predicate: () => settings.store.toolbarDevMenu }, @@ -91,10 +92,18 @@ export default definePlugin({ match: /\i\.isDM\(\)\|\|\i\.isThread\(\)/, replace: "false", } + }, + // enable option to always record clips even if you are not streaming + { + find: "isDecoupledGameClippingEnabled(){", + replacement: { + match: /\i\.isStaff\(\)/, + replace: "true" + } } ], - start: () => enableStyle(hideBugReport), + start: () => !BugReporterExperiment.getCurrentConfig().hasBugReporterAccess && enableStyle(hideBugReport), stop: () => disableStyle(hideBugReport), settingsAboutComponent: () => {