Merge branch 'Vendicated:main' into listenbrainz

This commit is contained in:
ConfiG 2025-01-22 22:33:22 +03:00 committed by GitHub
commit bafaab4dd1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 100 additions and 47 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "vencord", "name": "vencord",
"private": "true", "private": "true",
"version": "1.10.9", "version": "1.11.0",
"description": "The cutest Discord client mod", "description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme", "homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": { "bugs": {

View file

@ -37,7 +37,8 @@ const CANARY = process.env.USE_CANARY === "true";
const browser = await pup.launch({ const browser = await pup.launch({
headless: true, headless: true,
executablePath: process.env.CHROMIUM_BIN executablePath: process.env.CHROMIUM_BIN,
args: ["--no-sandbox"]
}); });
const page = await browser.newPage(); const page = await browser.newPage();

View file

@ -79,7 +79,7 @@ export default definePlugin({
replace: "...$1.props,$& $1.image??" 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 }) :" replace: "children:$1.component ? $self.renderBadgeComponent({ ...$1 }) :"
}, },
// conditionally override their onClick with badge.onClick if it exists // conditionally override their onClick with badge.onClick if it exists

View file

@ -31,7 +31,7 @@ export default definePlugin({
replace: (match, args) => "" + replace: (match, args) => "" +
`async ${match}` + `async ${match}` +
`if(await Vencord.Api.MessageEvents._handlePreEdit(${args}))` + `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: { replacement: {
// props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); // 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) // 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 }; // 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) => "" + replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" +
`${rest1}async ${rest2}` + `${rest1}async ${rest2}` +
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` + `if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
"return{shoudClear:true,shouldRefocus:true};" "return{shouldClear:false,shouldRefocus:true};"
} }
}, },
{ {

View file

@ -34,7 +34,7 @@ export default definePlugin({
}, },
{ {
match: /(?<=,NOTICE_DISMISS:function\(\i\){)return null!=(\i)/, 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);$&"
} }
] ]
} }

View file

@ -16,7 +16,7 @@ import { User } from "discord-types/general";
interface UserProfileProps { interface UserProfileProps {
popoutProps: Record<string, any>; popoutProps: Record<string, any>;
currentUser: User; currentUser: User;
originalPopout: () => React.ReactNode; OriginalPopout: () => React.ReactNode;
} }
const UserProfile = findComponentByCodeLazy("UserProfilePopoutWrapper: user cannot be undefined"); const UserProfile = findComponentByCodeLazy("UserProfilePopoutWrapper: user cannot be undefined");
@ -73,12 +73,12 @@ export default definePlugin({
group: true, group: true,
replacement: [ replacement: [
{ {
match: /(?<=\.SIZE_32\)}\);)/, match: /(?<=\.AVATAR_SIZE\);)/,
replace: "$self.useAccountPanelRef();" replace: "$self.useAccountPanelRef();"
}, },
{ {
match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/, 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:)/, match: /\.AVATAR,children:.+?(?=renderPopout:)/,
@ -112,17 +112,17 @@ export default definePlugin({
openAlternatePopout = false; openAlternatePopout = false;
}, },
UserProfile: ErrorBoundary.wrap(({ popoutProps, currentUser, originalPopout }: UserProfileProps) => { UserProfile: ErrorBoundary.wrap(({ popoutProps, currentUser, OriginalPopout }: UserProfileProps) => {
if ( if (
(settings.store.prioritizeServerProfile && openAlternatePopout) || (settings.store.prioritizeServerProfile && openAlternatePopout) ||
(!settings.store.prioritizeServerProfile && !openAlternatePopout) (!settings.store.prioritizeServerProfile && !openAlternatePopout)
) { ) {
return originalPopout(); return <OriginalPopout />;
} }
const currentChannel = getCurrentChannel(); const currentChannel = getCurrentChannel();
if (currentChannel?.getGuildId() == null) { if (currentChannel?.getGuildId() == null) {
return originalPopout(); return <OriginalPopout />;
} }
return ( return (

View file

@ -114,7 +114,7 @@ export default definePlugin({
{ // Load menu TOC eagerly { // Load menu TOC eagerly
find: "#{intl::USER_SETTINGS_WITH_BUILD_OVERRIDE}", find: "#{intl::USER_SETTINGS_WITH_BUILD_OVERRIDE}",
replacement: { 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)()," replace: "$&(async ()=>$2)(),"
}, },
predicate: () => settings.store.eagerLoad predicate: () => settings.store.eagerLoad

View file

@ -179,6 +179,16 @@ export default definePlugin({
description: "Adds shorter Aliases for many things on the window. Run `shortcutList` for a list.", description: "Adds shorter Aliases for many things on the window. Run `shortcutList` for a list.",
authors: [Devs.Ven], 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, startAt: StartAt.Init,
start() { start() {
const shortcuts = makeShortcuts(); const shortcuts = makeShortcuts();

View file

@ -16,7 +16,7 @@ interface UserMentionComponentProps {
id: string; id: string;
channelId: string; channelId: string;
guildId: string; guildId: string;
OriginalComponent: ReactNode; OriginalComponent: () => ReactNode;
} }
export default definePlugin({ export default definePlugin({
@ -29,7 +29,7 @@ export default definePlugin({
find: ':"text":', find: ':"text":',
replacement: { replacement: {
match: /(hidePersonalInformation\).+?)(if\(null!=\i\){.+?return \i)(?=})/, 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} channelId={props.channelId}
/> />
), { ), {
fallback: ({ wrappedProps }) => wrappedProps.OriginalComponent fallback: ({ wrappedProps: { OriginalComponent } }) => <OriginalComponent />
}) })
}); });

View file

@ -33,7 +33,7 @@ interface ColorPickerWithSwatchesProps {
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)"); const ColorPicker = findComponentByCodeLazy<ColorPickerProps>("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", ".BACKGROUND_PRIMARY)");
const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("ColorPicker", "CustomColorPicker"); const ColorPickerWithSwatches = findExportedComponentLazy<ColorPickerWithSwatchesProps>("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-"); const cl = classNameFactory("vc-pindms-modal-");

View file

@ -9,16 +9,11 @@ import "./style.css";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import definePlugin from "@utils/types"; import definePlugin from "@utils/types";
import { filters, findByPropsLazy, mapMangledModuleLazy } from "@webpack"; import { findByPropsLazy } from "@webpack";
import { Timestamp } from "@webpack/common"; import { DateUtils, Timestamp } from "@webpack/common";
import type { Message } from "discord-types/general"; import type { Message } from "discord-types/general";
import type { HTMLAttributes } from "react"; 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"); const MessageClasses = findByPropsLazy("separator", "latin24CompactTimeStamp");
function Sep(props: HTMLAttributes<HTMLElement>) { function Sep(props: HTMLAttributes<HTMLElement>) {
@ -46,14 +41,14 @@ function ReplyTimestamp({
return ( return (
<Timestamp <Timestamp
className="vc-reply-timestamp" className="vc-reply-timestamp"
compact={isSameDay(refTimestamp, baseTimestamp)} compact={DateUtils.isSameDay(refTimestamp, baseTimestamp)}
timestamp={refTimestamp} timestamp={refTimestamp}
isInline={false} isInline={false}
> >
<Sep>[</Sep> <Sep>[</Sep>
{isSameDay(refTimestamp, baseTimestamp) {DateUtils.isSameDay(refTimestamp, baseTimestamp)
? dateFormat(refTimestamp, "LT") ? DateUtils.dateFormat(refTimestamp, "LT")
: calendarFormat(refTimestamp) : DateUtils.calendarFormat(refTimestamp)
} }
<Sep>]</Sep> <Sep>]</Sep>
</Timestamp> </Timestamp>

View file

@ -21,7 +21,7 @@ import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack"; import { findByPropsLazy } from "@webpack";
const SpoilerClasses = findByPropsLazy("spoilerContent"); const SpoilerClasses = findByPropsLazy("spoilerContent");
const MessagesClasses = findByPropsLazy("messagesWrapper"); const MessagesClasses = findByPropsLazy("messagesWrapper", "navigationDescription");
export default definePlugin({ export default definePlugin({
name: "RevealAllSpoilers", name: "RevealAllSpoilers",

View file

@ -16,12 +16,28 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import "./styles.css";
import { definePluginSettings } from "@api/Settings"; 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 { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types"; 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 { 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({ const settings = definePluginSettings({
showDates: { showDates: {
@ -48,28 +64,27 @@ export default definePlugin({
find: "#{intl::FRIEND_REQUEST_CANCEL}", find: "#{intl::FRIEND_REQUEST_CANCEL}",
replacement: { replacement: {
predicate: () => settings.store.showDates, predicate: () => settings.store.showDates,
match: /subText:(\i)(?<=user:(\i).+?)/, match: /(?<=\.listItemContents,children:\[)\(0,.+?(?=,\(0)(?<=user:(\i).+?)/,
replace: (_, subtext, user) => `subText:$self.makeSubtext(${subtext},${user})` replace: (children, user) => `$self.WrapperDateComponent({user:${user},children:${children}})`
} }
}], }],
wrapSort(comparator: Function, row: any) { wrapSort(comparator: Function, row: any) {
return row.type === 3 || row.type === 4 return row.type === 3 || row.type === 4
? -this.getSince(row.user) ? -getSince(row.user)
: comparator(row); : comparator(row);
}, },
getSince(user: User) { WrapperDateComponent: ErrorBoundary.wrap(({ user, children }: PropsWithChildren<{ user: User; }>) => {
return new Date(RelationshipStore.getSince(user.id)); const since = getSince(user);
},
makeSubtext(text: string, user: User) { return <div className={cl("wrapper")}>
const since = this.getSince(user); {children}
return ( {!isNaN(since.getTime()) && (
<Flex flexDirection="column" style={{ gap: 0, flexWrap: "wrap", lineHeight: "0.9rem" }}> <TooltipContainer text={DateUtils.dateFormat(since, "LLLL")} tooltipClassName={cl("tooltip")}>
<span>{text}</span> <Text variant="text-xs/normal" className={cl("date")}>{formatter.format(since)}</Text>
{!isNaN(since.getTime()) && <span>Received &mdash; {since.toDateString()}</span>} </TooltipContainer>
</Flex> )}
); </div>;
} })
}); });

View file

@ -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);
}

View file

@ -324,3 +324,10 @@ export interface DisplayProfileUtils {
getDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null; getDisplayProfile(userId: string, guildId?: string, customStores?: any): DisplayProfile | null;
useDisplayProfile(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>;
}

View file

@ -199,3 +199,10 @@ export const DisplayProfileUtils: t.DisplayProfileUtils = mapMangledModuleLazy(/
getDisplayProfile: filters.byCode(".getGuildMemberProfile("), getDisplayProfile: filters.byCode(".getGuildMemberProfile("),
useDisplayProfile: filters.byCode(/\[\i\.\i,\i\.\i],\(\)=>/) 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")
});