diff --git a/package.json b/package.json index 6113731d2..abb11ee5c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.10.9", + "version": "1.11.0", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/scripts/generateReport.ts b/scripts/generateReport.ts index c18bc14a3..24af628bd 100644 --- a/scripts/generateReport.ts +++ b/scripts/generateReport.ts @@ -37,7 +37,8 @@ const CANARY = process.env.USE_CANARY === "true"; const browser = await pup.launch({ headless: true, - executablePath: process.env.CHROMIUM_BIN + executablePath: process.env.CHROMIUM_BIN, + args: ["--no-sandbox"] }); const page = await browser.newPage(); diff --git a/src/plugins/_api/badges/index.tsx b/src/plugins/_api/badges/index.tsx index d02b5e1d8..acdfb1f1f 100644 --- a/src/plugins/_api/badges/index.tsx +++ b/src/plugins/_api/badges/index.tsx @@ -79,7 +79,7 @@ export default definePlugin({ replace: "...$1.props,$& $1.image??" }, { - match: /(?<=text:(\i)\.description,.{0,200})children:/, + match: /(?<="aria-label":(\i)\.description,.{0,200})children:/, replace: "children:$1.component ? $self.renderBadgeComponent({ ...$1 }) :" }, // conditionally override their onClick with badge.onClick if it exists diff --git a/src/plugins/_api/messageEvents.ts b/src/plugins/_api/messageEvents.ts index 0101b02c8..97ed1746d 100644 --- a/src/plugins/_api/messageEvents.ts +++ b/src/plugins/_api/messageEvents.ts @@ -31,7 +31,7 @@ export default definePlugin({ replace: (match, args) => "" + `async ${match}` + `if(await Vencord.Api.MessageEvents._handlePreEdit(${args}))` + - "return Promise.resolve({shoudClear:true,shouldRefocus:true});" + "return Promise.resolve({shouldClear:false,shouldRefocus:true});" } }, { @@ -39,12 +39,12 @@ export default definePlugin({ replacement: { // props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); // Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid) - match: /(type:this\.props\.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptionsForReply\(\i\);)(?<=\)\(({.+?})\)\.then.+?)/, + match: /(\{openWarningPopout:.{0,100}type:this.props.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);)(?<=\)\(({.+?})\)\.then.+?)/, // props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true }; replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" + `${rest1}async ${rest2}` + `if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` + - "return{shoudClear:true,shouldRefocus:true};" + "return{shouldClear:false,shouldRefocus:true};" } }, { diff --git a/src/plugins/_api/notices.ts b/src/plugins/_api/notices.ts index 0c6f6e1db..f0445924e 100644 --- a/src/plugins/_api/notices.ts +++ b/src/plugins/_api/notices.ts @@ -34,7 +34,7 @@ export default definePlugin({ }, { match: /(?<=,NOTICE_DISMISS:function\(\i\){)return null!=(\i)/, - replace: "if($1.id==\"VencordNotice\")return($1=null,Vencord.Api.Notices.nextNotice(),true);$&" + replace: "if($1?.id==\"VencordNotice\")return($1=null,Vencord.Api.Notices.nextNotice(),true);$&" } ] } diff --git a/src/plugins/accountPanelServerProfile/index.tsx b/src/plugins/accountPanelServerProfile/index.tsx index 1b468a6d8..b6218bf54 100644 --- a/src/plugins/accountPanelServerProfile/index.tsx +++ b/src/plugins/accountPanelServerProfile/index.tsx @@ -16,7 +16,7 @@ import { User } from "discord-types/general"; interface UserProfileProps { popoutProps: Record; currentUser: User; - originalPopout: () => React.ReactNode; + OriginalPopout: () => React.ReactNode; } const UserProfile = findComponentByCodeLazy("UserProfilePopoutWrapper: user cannot be undefined"); @@ -73,12 +73,12 @@ export default definePlugin({ group: true, replacement: [ { - match: /(?<=\.SIZE_32\)}\);)/, + match: /(?<=\.AVATAR_SIZE\);)/, replace: "$self.useAccountPanelRef();" }, { match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/, - replace: (_, rest, popoutProps, originalPopout, currentUser) => `${rest}$self.UserProfile({popoutProps:${popoutProps},currentUser:${currentUser},originalPopout:()=>{${originalPopout}}})` + replace: (_, rest, popoutProps, originalPopout, currentUser) => `${rest}$self.UserProfile({popoutProps:${popoutProps},currentUser:${currentUser},OriginalPopout:()=>{${originalPopout}}})` }, { match: /\.AVATAR,children:.+?(?=renderPopout:)/, @@ -112,17 +112,17 @@ export default definePlugin({ openAlternatePopout = false; }, - UserProfile: ErrorBoundary.wrap(({ popoutProps, currentUser, originalPopout }: UserProfileProps) => { + UserProfile: ErrorBoundary.wrap(({ popoutProps, currentUser, OriginalPopout }: UserProfileProps) => { if ( (settings.store.prioritizeServerProfile && openAlternatePopout) || (!settings.store.prioritizeServerProfile && !openAlternatePopout) ) { - return originalPopout(); + return ; } const currentChannel = getCurrentChannel(); if (currentChannel?.getGuildId() == null) { - return originalPopout(); + return ; } return ( diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx index 0a3f0bb84..5a97b0a6e 100644 --- a/src/plugins/betterSettings/index.tsx +++ b/src/plugins/betterSettings/index.tsx @@ -114,7 +114,7 @@ export default definePlugin({ { // Load menu TOC eagerly find: "#{intl::USER_SETTINGS_WITH_BUILD_OVERRIDE}", replacement: { - match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await Promise\.all[^};]*?\)\)).*?,(?=\1\(this)/, + match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await [^};]*?\)\)).*?,(?=\1\(this)/, replace: "$&(async ()=>$2)()," }, predicate: () => settings.store.eagerLoad diff --git a/src/plugins/consoleShortcuts/index.ts b/src/plugins/consoleShortcuts/index.ts index 25d48f1d8..be23d37c3 100644 --- a/src/plugins/consoleShortcuts/index.ts +++ b/src/plugins/consoleShortcuts/index.ts @@ -179,6 +179,16 @@ export default definePlugin({ description: "Adds shorter Aliases for many things on the window. Run `shortcutList` for a list.", authors: [Devs.Ven], + patches: [ + { + find: 'this,"_changeCallbacks",', + replacement: { + match: /\i\(this,"_changeCallbacks",/, + replace: "Reflect.defineProperty(this,Symbol.toStringTag,{value:this.getName(),configurable:!0,writable:!0,enumerable:!1}),$&" + } + } + ], + startAt: StartAt.Init, start() { const shortcuts = makeShortcuts(); diff --git a/src/plugins/fullUserInChatbox/index.tsx b/src/plugins/fullUserInChatbox/index.tsx index 792f0419f..4bcc95b6c 100644 --- a/src/plugins/fullUserInChatbox/index.tsx +++ b/src/plugins/fullUserInChatbox/index.tsx @@ -16,7 +16,7 @@ interface UserMentionComponentProps { id: string; channelId: string; guildId: string; - OriginalComponent: ReactNode; + OriginalComponent: () => ReactNode; } export default definePlugin({ @@ -29,7 +29,7 @@ export default definePlugin({ find: ':"text":', replacement: { match: /(hidePersonalInformation\).+?)(if\(null!=\i\){.+?return \i)(?=})/, - replace: "$1return $self.UserMentionComponent({...arguments[0],OriginalComponent:(()=>{$2})()});" + replace: "$1return $self.UserMentionComponent({...arguments[0],OriginalComponent:()=>{$2}});" } } ], @@ -42,6 +42,6 @@ export default definePlugin({ channelId={props.channelId} /> ), { - fallback: ({ wrappedProps }) => wrappedProps.OriginalComponent + fallback: ({ wrappedProps: { OriginalComponent } }) => }) }); diff --git a/src/plugins/pinDms/components/CreateCategoryModal.tsx b/src/plugins/pinDms/components/CreateCategoryModal.tsx index 7c4cf0d07..0568c1adb 100644 --- a/src/plugins/pinDms/components/CreateCategoryModal.tsx +++ b/src/plugins/pinDms/components/CreateCategoryModal.tsx @@ -33,7 +33,7 @@ interface ColorPickerWithSwatchesProps { const ColorPicker = findComponentByCodeLazy("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)"); const ColorPickerWithSwatches = findExportedComponentLazy("ColorPicker", "CustomColorPicker"); -export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\("?.+?"?\).+?\])\).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/); +export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/); const cl = classNameFactory("vc-pindms-modal-"); diff --git a/src/plugins/replyTimestamp/index.tsx b/src/plugins/replyTimestamp/index.tsx index dc31dd883..0be5dfec2 100644 --- a/src/plugins/replyTimestamp/index.tsx +++ b/src/plugins/replyTimestamp/index.tsx @@ -9,16 +9,11 @@ import "./style.css"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; -import { filters, findByPropsLazy, mapMangledModuleLazy } from "@webpack"; -import { Timestamp } from "@webpack/common"; +import { findByPropsLazy } from "@webpack"; +import { DateUtils, Timestamp } from "@webpack/common"; import type { Message } from "discord-types/general"; import type { HTMLAttributes } from "react"; -const { calendarFormat, dateFormat, isSameDay } = mapMangledModuleLazy("millisecondsInUnit:", { - calendarFormat: filters.byCode("sameElse"), - dateFormat: filters.byCode('":'), - isSameDay: filters.byCode("Math.abs(+"), -}); const MessageClasses = findByPropsLazy("separator", "latin24CompactTimeStamp"); function Sep(props: HTMLAttributes) { @@ -46,14 +41,14 @@ function ReplyTimestamp({ return ( [ - {isSameDay(refTimestamp, baseTimestamp) - ? dateFormat(refTimestamp, "LT") - : calendarFormat(refTimestamp) + {DateUtils.isSameDay(refTimestamp, baseTimestamp) + ? DateUtils.dateFormat(refTimestamp, "LT") + : DateUtils.calendarFormat(refTimestamp) } ] diff --git a/src/plugins/revealAllSpoilers/index.ts b/src/plugins/revealAllSpoilers/index.ts index 98e8423cf..ead746b2b 100644 --- a/src/plugins/revealAllSpoilers/index.ts +++ b/src/plugins/revealAllSpoilers/index.ts @@ -21,7 +21,7 @@ import definePlugin from "@utils/types"; import { findByPropsLazy } from "@webpack"; const SpoilerClasses = findByPropsLazy("spoilerContent"); -const MessagesClasses = findByPropsLazy("messagesWrapper"); +const MessagesClasses = findByPropsLazy("messagesWrapper", "navigationDescription"); export default definePlugin({ name: "RevealAllSpoilers", diff --git a/src/plugins/sortFriendRequests/index.tsx b/src/plugins/sortFriendRequests/index.tsx index 6ce1af14d..5f45902e8 100644 --- a/src/plugins/sortFriendRequests/index.tsx +++ b/src/plugins/sortFriendRequests/index.tsx @@ -16,12 +16,28 @@ * along with this program. If not, see . */ +import "./styles.css"; + import { definePluginSettings } from "@api/Settings"; -import { Flex } from "@components/Flex"; +import { classNameFactory } from "@api/Styles"; +import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { RelationshipStore } from "@webpack/common"; +import { DateUtils, RelationshipStore, Text, TooltipContainer } from "@webpack/common"; import { User } from "discord-types/general"; +import { PropsWithChildren } from "react"; + +const formatter = new Intl.DateTimeFormat(undefined, { + month: "numeric", + day: "numeric", + year: "numeric", +}); + +const cl = classNameFactory("vc-sortFriendRequests-"); + +function getSince(user: User) { + return new Date(RelationshipStore.getSince(user.id)); +} const settings = definePluginSettings({ showDates: { @@ -48,28 +64,27 @@ export default definePlugin({ find: "#{intl::FRIEND_REQUEST_CANCEL}", replacement: { predicate: () => settings.store.showDates, - match: /subText:(\i)(?<=user:(\i).+?)/, - replace: (_, subtext, user) => `subText:$self.makeSubtext(${subtext},${user})` + match: /(?<=\.listItemContents,children:\[)\(0,.+?(?=,\(0)(?<=user:(\i).+?)/, + replace: (children, user) => `$self.WrapperDateComponent({user:${user},children:${children}})` } }], wrapSort(comparator: Function, row: any) { return row.type === 3 || row.type === 4 - ? -this.getSince(row.user) + ? -getSince(row.user) : comparator(row); }, - getSince(user: User) { - return new Date(RelationshipStore.getSince(user.id)); - }, + WrapperDateComponent: ErrorBoundary.wrap(({ user, children }: PropsWithChildren<{ user: User; }>) => { + const since = getSince(user); - makeSubtext(text: string, user: User) { - const since = this.getSince(user); - return ( - - {text} - {!isNaN(since.getTime()) && Received — {since.toDateString()}} - - ); - } + return
+ {children} + {!isNaN(since.getTime()) && ( + + {formatter.format(since)} + + )} +
; + }) }); diff --git a/src/plugins/sortFriendRequests/styles.css b/src/plugins/sortFriendRequests/styles.css new file mode 100644 index 000000000..98be9da7c --- /dev/null +++ b/src/plugins/sortFriendRequests/styles.css @@ -0,0 +1,18 @@ +.vc-sortFriendRequests-wrapper { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + width: 100%; + margin-right: 0.5em; +} + +.vc-sortFriendRequests-tooltip { + max-width: none; + white-space: nowrap; +} + +.vc-sortFriendRequests-date { + color: var(--text-muted); + font-family: var(--font-code); +} diff --git a/src/webpack/common/types/utils.d.ts b/src/webpack/common/types/utils.d.ts index 00e3f4a0b..de1ce1829 100644 --- a/src/webpack/common/types/utils.d.ts +++ b/src/webpack/common/types/utils.d.ts @@ -324,3 +324,10 @@ export interface DisplayProfileUtils { getDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null; useDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null; } + +export interface DateUtils { + isSameDay(date1: Date, date2: Date): boolean; + calendarFormat(date: Date): string; + dateFormat(date: Date, format: string): string; + diffAsUnits(start: Date, end: Date, stopAtOneSecond?: boolean): Record<"days" | "hours" | "minutes" | "seconds", number>; +} diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts index 3699300b6..1bdf236ac 100644 --- a/src/webpack/common/utils.ts +++ b/src/webpack/common/utils.ts @@ -199,3 +199,10 @@ export const DisplayProfileUtils: t.DisplayProfileUtils = mapMangledModuleLazy(/ getDisplayProfile: filters.byCode(".getGuildMemberProfile("), useDisplayProfile: filters.byCode(/\[\i\.\i,\i\.\i],\(\)=>/) }); + +export const DateUtils: t.DateUtils = mapMangledModuleLazy("millisecondsInUnit:", { + calendarFormat: filters.byCode("sameElse"), + dateFormat: filters.byCode('":'), + isSameDay: filters.byCode("Math.abs(+"), + diffAsUnits: filters.byCode("days:0", "millisecondsInUnit") +});