From 904022a2f76b74d3360cc7d3124f30e720eb9196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?rini=20=E2=98=94?= Date: Sun, 18 Aug 2024 15:20:03 -0300 Subject: [PATCH 1/7] [Webkeybinds] Don't override browser keybinds (#2792) --- src/plugins/webKeybinds.web/index.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/webKeybinds.web/index.ts b/src/plugins/webKeybinds.web/index.ts index 12d485aa..1c43dc0c 100644 --- a/src/plugins/webKeybinds.web/index.ts +++ b/src/plugins/webKeybinds.web/index.ts @@ -35,6 +35,7 @@ export default definePlugin({ if (hasCtrl) switch (e.key) { case "t": case "T": + if (!IS_VESKTOP) return; e.preventDefault(); if (e.shiftKey) { if (SelectedGuildStore.getGuildId()) NavigationRouter.transitionToGuild("@me"); @@ -47,14 +48,15 @@ export default definePlugin({ }); } break; + case "Tab": + if (!IS_VESKTOP) return; + const handler = e.shiftKey ? KeyBinds.SERVER_PREV : KeyBinds.SERVER_NEXT; + handler.action(e); + break; case ",": e.preventDefault(); SettingsRouter.open("My Account"); break; - case "Tab": - const handler = e.shiftKey ? KeyBinds.SERVER_PREV : KeyBinds.SERVER_NEXT; - handler.action(e); - break; default: if (e.key >= "1" && e.key <= "9") { e.preventDefault(); From 6ed8d49a2461569143d8cd46386ff3ac116917c9 Mon Sep 17 00:00:00 2001 From: verticalsync <60797172+verticalsync@users.noreply.github.com> Date: Sun, 18 Aug 2024 21:53:35 +0300 Subject: [PATCH 2/7] update nyx's discord id --- src/utils/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/constants.ts b/src/utils/constants.ts index ad4b1feb..aabccef2 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -522,7 +522,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({ }, nyx: { name: "verticalsync", - id: 328165170536775680n + id: 1207087393929171095n }, nekohaxx: { name: "nekohaxx", @@ -557,7 +557,7 @@ export const EquicordDevs = Object.freeze({ }, nyx: { name: "verticalsync", - id: 328165170536775680n, + id: 1207087393929171095n, }, Cortex: { name: "Cortex", From 74dcba6968c8e6961e2648efff36d4b0941659e4 Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Mon, 19 Aug 2024 09:53:34 -0400 Subject: [PATCH 3/7] Update SoundboardLogger --- src/equicordplugins/soundBoardLogger/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/equicordplugins/soundBoardLogger/index.tsx b/src/equicordplugins/soundBoardLogger/index.tsx index 65836ccf..889d7238 100644 --- a/src/equicordplugins/soundBoardLogger/index.tsx +++ b/src/equicordplugins/soundBoardLogger/index.tsx @@ -8,7 +8,6 @@ import { addChatBarButton, removeChatBarButton } from "@api/ChatButtons"; import { disableStyle, enableStyle } from "@api/Styles"; import { Devs, EquicordDevs } from "@utils/constants"; import definePlugin from "@utils/types"; -import { findExportedComponentLazy } from "@webpack"; import { FluxDispatcher } from "@webpack/common"; import { ChatBarIcon } from "./components/Icons"; @@ -17,8 +16,6 @@ import { updateLoggedSounds } from "./store"; import styles from "./styles.css?managed"; import { getListeners } from "./utils"; -const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider"); - export default definePlugin({ name: "SoundBoardLogger", authors: [Devs.Moxxie, EquicordDevs.Fres, Devs.echo, EquicordDevs.thororen], From f78c8cef26276c5d4c46e2190a64d4f9d5a6b6db Mon Sep 17 00:00:00 2001 From: thororen1234 <78185467+thororen1234@users.noreply.github.com> Date: Mon, 19 Aug 2024 12:19:43 -0400 Subject: [PATCH 4/7] Add Timezones --- README.md | 3 +- src/equicordplugins/channelTabs/index.tsx | 16 +- src/equicordplugins/emojiDumper/index.tsx | 10 +- .../timezones/TimezoneModal.tsx | 84 ++++++++ src/equicordplugins/timezones/index.tsx | 189 ++++++++++++++++++ src/equicordplugins/timezones/styles.css | 41 ++++ 6 files changed, 325 insertions(+), 18 deletions(-) create mode 100644 src/equicordplugins/timezones/TimezoneModal.tsx create mode 100644 src/equicordplugins/timezones/index.tsx create mode 100644 src/equicordplugins/timezones/styles.css diff --git a/README.md b/README.md index d8fae276..e483d801 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - Request for plugins from Discord.
-Extra included plugins (122 additional plugins) +Extra included plugins (123 additional plugins) - AllCallTimers by MaxHerbold and D3SOX - AltKrispSwitch by newwares @@ -129,6 +129,7 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend - TeX by Kyuuhachi - TextToSpeech by Samwich - ThemeLibrary by Fafa +- Timezones by Aria - Title by Kyuuhachi - TosuRPC by AutumnVN - Translate+ by Prince527 (Using Translate by Ven) diff --git a/src/equicordplugins/channelTabs/index.tsx b/src/equicordplugins/channelTabs/index.tsx index c87e90e9..70d706e0 100644 --- a/src/equicordplugins/channelTabs/index.tsx +++ b/src/equicordplugins/channelTabs/index.tsx @@ -6,7 +6,7 @@ import "./style.css"; -import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu"; +import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs, EquicordDevs } from "@utils/constants"; import definePlugin from "@utils/types"; @@ -38,6 +38,10 @@ export default definePlugin({ description: "Group your commonly visited channels in tabs, like a browser", authors: [Devs.TheSun, Devs.TheKodeToad, EquicordDevs.keifufu, Devs.Nickyux], dependencies: ["ContextMenuAPI"], + contextMenus: { + "channel-mention-context": contextMenuPatch, + "channel-context": contextMenuPatch + }, patches: [ // add the channel tab container at the top { @@ -91,16 +95,6 @@ export default definePlugin({ settings, - start() { - addContextMenuPatch("channel-mention-context", contextMenuPatch); - addContextMenuPatch("channel-context", contextMenuPatch); - }, - - stop() { - removeContextMenuPatch("channel-mention-context", contextMenuPatch); - removeContextMenuPatch("channel-context", contextMenuPatch); - }, - containerHeight: 0, render({ currentChannel, children }: { diff --git a/src/equicordplugins/emojiDumper/index.tsx b/src/equicordplugins/emojiDumper/index.tsx index 6c6b390e..9bc3f1c7 100644 --- a/src/equicordplugins/emojiDumper/index.tsx +++ b/src/equicordplugins/emojiDumper/index.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu"; +import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; import { Devs, EquicordDevs } from "@utils/constants"; import definePlugin from "@utils/types"; import { Menu } from "@webpack/common"; @@ -26,11 +26,9 @@ export default definePlugin({ name: "EmojiDumper", description: "Context menu to dump and download a server's emojis.", authors: [EquicordDevs.Cortex, Devs.Samwich, EquicordDevs.Woosh], - start() { - addContextMenuPatch(["guild-context", "guild-header-popout"], Patch); - }, - stop() { - removeContextMenuPatch(["guild-context", "guild-header-popout"], Patch); + contextMenus: { + "guild-context": Patch, + "guild-header-popout": Patch } }); diff --git a/src/equicordplugins/timezones/TimezoneModal.tsx b/src/equicordplugins/timezones/TimezoneModal.tsx new file mode 100644 index 00000000..1f01922d --- /dev/null +++ b/src/equicordplugins/timezones/TimezoneModal.tsx @@ -0,0 +1,84 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import * as DataStore from "@api/DataStore"; +import { classNameFactory } from "@api/Styles"; +import { Margins } from "@utils/margins"; +import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; +import { Button, Forms, SearchableSelect, useMemo, useState } from "@webpack/common"; + +import { DATASTORE_KEY, timezones } from "."; + +export async function setUserTimezone(userId: string, timezone: string | null) { + timezones[userId] = timezone; + await DataStore.set(DATASTORE_KEY, timezones); +} + +const cl = classNameFactory("vc-timezone-"); + +export function SetTimezoneModal({ userId, modalProps }: { userId: string, modalProps: ModalProps; }) { + const [currentValue, setCurrentValue] = useState(timezones[userId] ?? null); + + const options = useMemo(() => { + return Intl.supportedValuesOf("timeZone").map(timezone => { + const offset = new Intl.DateTimeFormat(undefined, { timeZone: timezone, timeZoneName: "short" }) + .formatToParts(new Date()) + .find(part => part.type === "timeZoneName")!.value; + + return { label: `${timezone} (${offset})`, value: timezone }; + }); + }, []); + + return ( + + + + Timezones + + + + + +
+ + Select Timezone + + + o.value === currentValue)} + placeholder={"Select a Timezone"} + maxVisibleItems={5} + closeOnSelect={true} + onChange={v => setCurrentValue(v)} + /> +
+
+ + + + + +
+ ); +} diff --git a/src/equicordplugins/timezones/index.tsx b/src/equicordplugins/timezones/index.tsx new file mode 100644 index 00000000..4af3a86c --- /dev/null +++ b/src/equicordplugins/timezones/index.tsx @@ -0,0 +1,189 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import "./styles.css"; + +import { NavContextMenuPatchCallback } from "@api/ContextMenu"; +import * as DataStore from "@api/DataStore"; +import { definePluginSettings } from "@api/Settings"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import { openModal } from "@utils/modal"; +import definePlugin, { OptionType } from "@utils/types"; +import { findByPropsLazy } from "@webpack"; +import { i18n, Menu, Tooltip, useEffect, useState } from "@webpack/common"; +import { Message, User } from "discord-types/general"; + +import { SetTimezoneModal } from "./TimezoneModal"; + +export const DATASTORE_KEY = "vencord-timezones"; + +export let timezones: Record = {}; +(async () => { + timezones = await DataStore.get>(DATASTORE_KEY) || {}; +})(); + +const classes = findByPropsLazy("timestamp", "compact", "contentOnly"); + +export const settings = definePluginSettings({ + "24h Time": { + type: OptionType.BOOLEAN, + description: "Show time in 24h format", + default: false + }, + + showMessageHeaderTime: { + type: OptionType.BOOLEAN, + description: "Show time in message headers", + default: true + }, + + showProfileTime: { + type: OptionType.BOOLEAN, + description: "Show time in profiles", + default: true + } +}); + +function getTime(timezone: string, timestamp: string | number, props: Intl.DateTimeFormatOptions = {}) { + const date = new Date(timestamp); + const formatter = new Intl.DateTimeFormat(i18n?.getLocale?.() ?? "en-US", { + hour12: !settings.store["24h Time"], + timeZone: timezone, + ...props + }); + return formatter.format(date); +} + +interface Props { + userId: string; + timestamp?: string; + type: "message" | "profile"; +} +const TimestampComponent = ErrorBoundary.wrap(({ userId, timestamp, type }: Props) => { + const [currentTime, setCurrentTime] = useState(timestamp || Date.now()); + const timezone = timezones[userId]; + + useEffect(() => { + let timer: NodeJS.Timeout; + + if (type === "profile") { + setCurrentTime(Date.now()); + + const now = new Date(); + const delay = (60 - now.getSeconds()) * 1000 + 1000 - now.getMilliseconds(); + + timer = setTimeout(() => { + setCurrentTime(Date.now()); + }, delay); + } + + return () => timer && clearTimeout(timer); + }, [type, currentTime]); + + if (!timezone) return null; + + const shortTime = getTime(timezone, currentTime, { hour: "numeric", minute: "numeric" }); + const longTime = getTime(timezone, currentTime, { + weekday: "long", + year: "numeric", + month: "long", + day: "numeric", + hour: "numeric", + minute: "numeric", + }); + return ( + + {toolTipProps => { + return ( + + { + type === "message" ? `(${shortTime})` : shortTime + } + + ); + }} + + ); +}, { noop: true }); + +const userContextMenuPatch: NavContextMenuPatchCallback = (children, { user }: { user: User; }) => { + if (user?.id == null) return; + + const setTimezoneItem = ( + openModal(modalProps => )} + /> + ); + + children.push(, setTimezoneItem); + +}; + + +export default definePlugin({ + name: "Timezone", + authors: [Devs.Aria], + description: "Shows the local time of users in profiles and message headers", + contextMenus: { + "user-context": userContextMenuPatch + }, + + patches: [ + // stolen from ViewIcons + ...[".NITRO_BANNER,", "=!1,canUsePremiumCustomization:"].map(find => ({ + find, + replacement: { + match: /(?<=hasProfileEffect.+?)children:\[/, + replace: "$&$self.renderProfileTimezone(arguments[0])," + } + })), + { + find: '"Message Username"', + replacement: { + // thanks https://github.com/Syncxv/vc-timezones/pull/4 + match: /(?<=isVisibleOnlyOnHover.+?)id:.{1,11},timestamp.{1,50}}\),/, + replace: "$&,$self.renderMessageTimezone(arguments[0])," + } + } + ], + settings, + getTime, + + + renderProfileTimezone: (props?: { user?: User; }) => { + if (!settings.store.showProfileTime || !props?.user?.id) return null; + + return ; + }, + + renderMessageTimezone: (props?: { message?: Message; }) => { + if (!settings.store.showMessageHeaderTime || !props?.message) return null; + + return ; + } +}); diff --git a/src/equicordplugins/timezones/styles.css b/src/equicordplugins/timezones/styles.css new file mode 100644 index 00000000..386e197a --- /dev/null +++ b/src/equicordplugins/timezones/styles.css @@ -0,0 +1,41 @@ +.timezone-profile-item { + position: absolute; + right: 0; + bottom: 0; + margin: 28px 16px 4px; + background: var(--profile-body-background-color, var(--background-primary)); + border-radius: 4px; + padding: 0.25rem 0.5rem; + font-size: 0.75rem; + color: var(--text-normal); +} + +[class*="topSection"] .timezone-profile-item { + margin: 16px; +} + +.timezone-message-item { + margin-left: 4px; +} + +.vc-timezone-modal-header { + place-content: center; + justify-content: space-between; +} + +.vc-timezone-modal-header h1 { + margin: 0; +} + +.vc-timezone-modal-content { + padding: 1em; +} + +.vc-timezone-modal-footer { + gap: 16px; +} + +.timezone-tooltip { + max-width: none!important; + white-space: nowrap +} From 3d80cb2d551b43c54d2e2accf5d7b45fb575c60a Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:50:21 -0300 Subject: [PATCH 5/7] Delete AutomodContext ~ Now a stock feature --- src/plugins/automodContext/README.md | 5 -- src/plugins/automodContext/index.tsx | 73 ---------------------------- 2 files changed, 78 deletions(-) delete mode 100644 src/plugins/automodContext/README.md delete mode 100644 src/plugins/automodContext/index.tsx diff --git a/src/plugins/automodContext/README.md b/src/plugins/automodContext/README.md deleted file mode 100644 index f70d71d9..00000000 --- a/src/plugins/automodContext/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# AutomodContext - -Allows you to jump to the messages surrounding an automod hit - -![Visualization](https://github.com/Vendicated/Vencord/assets/61953774/d13740c8-2062-4553-b975-82fd3d6cc08b) diff --git a/src/plugins/automodContext/index.tsx b/src/plugins/automodContext/index.tsx deleted file mode 100644 index 5425c552..00000000 --- a/src/plugins/automodContext/index.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import ErrorBoundary from "@components/ErrorBoundary"; -import { Devs } from "@utils/constants"; -import definePlugin from "@utils/types"; -import { findByPropsLazy } from "@webpack"; -import { Button, ChannelStore, Text } from "@webpack/common"; - -const { selectChannel } = findByPropsLazy("selectChannel", "selectVoiceChannel"); - -function jumpToMessage(channelId: string, messageId: string) { - const guildId = ChannelStore.getChannel(channelId)?.guild_id; - - selectChannel({ - guildId, - channelId, - messageId, - jumpType: "INSTANT" - }); -} - -function findChannelId(message: any): string | null { - const { embeds: [embed] } = message; - const channelField = embed.fields.find(({ rawName }) => rawName === "channel_id"); - - if (!channelField) { - return null; - } - - return channelField.rawValue; -} - -export default definePlugin({ - name: "AutomodContext", - description: "Allows you to jump to the messages surrounding an automod hit.", - authors: [Devs.JohnyTheCarrot], - - patches: [ - { - find: ".Messages.GUILD_AUTOMOD_REPORT_ISSUES", - replacement: { - match: /\.Messages\.ACTIONS.+?}\)(?=,(\(0.{0,40}\.dot.*?}\)),)/, - replace: (m, dot) => `${m},${dot},$self.renderJumpButton({message:arguments[0].message})` - } - } - ], - - renderJumpButton: ErrorBoundary.wrap(({ message }: { message: any; }) => { - const channelId = findChannelId(message); - - if (!channelId) { - return null; - } - - return ( - - ); - }, { noop: true }) -}); From 66b247b2d3e6f1fda1621f5c0e154d6120b13bb2 Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Tue, 20 Aug 2024 04:13:21 -0300 Subject: [PATCH 6/7] Fix persisting $$vencordPatchedSource when a module is loaded again --- src/webpack/patchWebpack.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/webpack/patchWebpack.ts b/src/webpack/patchWebpack.ts index 4629434a..fb640cea 100644 --- a/src/webpack/patchWebpack.ts +++ b/src/webpack/patchWebpack.ts @@ -355,8 +355,16 @@ function patchFactories(factories: Record Date: Tue, 20 Aug 2024 11:07:53 -0400 Subject: [PATCH 7/7] Remove Accidental Tag --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index e483d801..2f2c4977 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vend ![image](https://github.com/Equicord/Equicord/assets/78185467/81707ad9-3a04-4f76-88a0-60ee70684f81) -## WOMP WOMP - ## Features - Third-party plugins implemented into the main build.