From 03ad387a7910c3b578d45c716052acb674e989bb Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:28:46 -0400 Subject: [PATCH] ClipsEnhancements by niko --- README.md | 1 + .../clipsEnhancements/index.tsx | 116 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/equicordplugins/clipsEnhancements/index.tsx diff --git a/README.md b/README.md index 49e1105bf..80539e338 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch - CharacterCounter by Creations & Panniku - CleanChannelName by AutumnVN - ClientSideBlock by Samwich +- ClipsEnhancements by niko - CommandPalette by Ethan - CopyUserMention by Cortex & castdrian - CustomSounds by TheKodeToad & SpikeHD diff --git a/src/equicordplugins/clipsEnhancements/index.tsx b/src/equicordplugins/clipsEnhancements/index.tsx new file mode 100644 index 000000000..d9c8b964e --- /dev/null +++ b/src/equicordplugins/clipsEnhancements/index.tsx @@ -0,0 +1,116 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { definePluginSettings } from "@api/Settings"; +import { Link } from "@components/Link"; +import { Devs } from "@utils/constants"; +import { ModalAPI } from "@utils/modal"; +import definePlugin, { OptionType } from "@utils/types"; +import { findStoreLazy } from "@webpack"; +import { PresenceStore, UserStore } from "@webpack/common"; +import { SelectOption } from "@webpack/types"; + +interface Activity { + name: string; + application_id?: string; + type: number; +} + +const settings = definePluginSettings({ + richPresenceTagging: { + type: OptionType.SELECT, + description: "When should clips be tagged with the current Rich Presence?", + options: [ + { label: "Always", value: "always" }, + { label: "Only when beginning or end of activity name matches", value: "whenMatched", default: true }, + { label: "Never", value: "never" }, + ] + }, + clipsLink: { + type: OptionType.COMPONENT, + description: "", + component: () => { + return ( + <> + { + ModalAPI.closeAllModals(); + }} + > + Change FPS and duration options in Clips settings! + + + ); + } + }, +}); + +export default definePlugin({ + name: "ClipsEnhancements", + description: "Add more Clip FPS and duration options, plus RPC tagging!", + authors: [Devs.niko], + + settings, + + patches: [ + { + find: "clips_recording_settings", + replacement: [ + { + match: /\[\{.{0,10}\i.\i.FPS_15.{0,250}\}\]/, + replace: "$self.patchFramerates($&)" + }, + { + match: /\[\{.{0,10}\i.\i.SECONDS_30.{0,250}\}\]/, + replace: "$self.patchTimeslots($&)" + }, + ] + }, + { + find: "clipMethod:\"manual\"", + replacement: { + match: /(applicationName:)(.{0,50})(,applicationId:)(\i)/, + replace: "$1$2$3$self.getApplicationId($2)??$4" + } + } + ], + + patchTimeslots(timeslots: SelectOption[]) { + const newTimeslots = [...timeslots]; + const extraTimeslots = [3, 5, 7, 10]; + + extraTimeslots.forEach(timeslot => newTimeslots.push({ value: timeslot * 60000, label: `${timeslot} Minutes` })); + + return newTimeslots; + }, + + patchFramerates(framerates: SelectOption[]) { + const newFramerates = [...framerates]; + const extraFramerates = [45, 90, 120, 144, 165, 240]; + + // Lower framerates than 15FPS have adverse affects on compression, 3 minute clips at 10FPS skyrocket the filesize to 200mb!! + extraFramerates.forEach(framerate => newFramerates.push({ value: framerate, label: `${framerate}FPS` })); + + return newFramerates.toSorted(); + }, + + getApplicationId(activityName: string) { + if (settings.store.richPresenceTagging === "never") { + return null; + } + + const activities: Activity[] = PresenceStore.getActivities(UserStore.getCurrentUser().id); + const validActivities = activities.filter(activity => activity.type === 0 && activity.application_id !== null); + + const splitName = activityName.split(" "); + + // Try to match activity by it's start and end + const matchedActivities = validActivities.filter(activity => activity.name.endsWith(splitName.at(-1)!) || activity.name.startsWith(splitName.at(0)!)); + + return (matchedActivities ?? (settings.store.richPresenceTagging === "whenMatched" ? null : validActivities))[0]?.application_id; + } +});