Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
thororen 2026-08-26 13:43:44 -04:00
commit 7deeb66803
No known key found for this signature in database
6 changed files with 49 additions and 34 deletions

View file

@ -1,7 +1,7 @@
{
"name": "equicord",
"private": "true",
"version": "1.15.2.0",
"version": "1.15.3.0",
"description": "The other cutest Discord client mod",
"homepage": "https://github.com/Equicord/Equicord#readme",
"bugs": {
@ -101,4 +101,4 @@
"engines": {
"node": ">=22"
}
}
}

View file

@ -327,8 +327,8 @@ export default definePlugin({
},
makeInfoElements(Component: ComponentType<PropsWithChildren<{ className?: string; }>>, className: string) {
return this.getInfoRows().map((text, i) => (
return this.getInfoRows().map((text, i) =>
<Component key={i} className={className}>{text}</Component>
));
},
);
}
});

View file

@ -266,7 +266,7 @@ export default definePlugin({
{
// Disallow the emoji for premium locked if the intention doesn't allow it
match: /(?<=!\(\i\|\|)\i\.\i\.canUseEmojisEverywhere\(\i\)/,
replace: check => `(${check}&&!${IS_BYPASSEABLE_INTENTION})`
replace: check => `(${check}||${IS_BYPASSEABLE_INTENTION})`
},
{
// Allow animated emojis to be used if the intention allows it

View file

@ -23,14 +23,14 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { isNonNullish } from "@utils/guards";
import { Logger } from "@utils/Logger";
import { classes } from "@utils/misc";
import definePlugin from "@utils/types";
import { Channel, User } from "@vencord/discord-types";
import { findByPropsLazy, findCssClassesLazy } from "@webpack";
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore } from "@webpack/common";
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UsernameUtils, UserStore } from "@webpack/common";
import { ComponentType, JSX } from "react";
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
const UserUtils = findByPropsLazy("getGlobalName");
const ProfileListClasses = findCssClassesLazy("empty", "textContainer", "connectionIcon");
const TabBarClasses = findCssClassesLazy("tabPanelScroller", "tabBarPanel");
@ -38,12 +38,14 @@ const MutualsListClasses = findCssClassesLazy("row", "icon", "name", "details");
let ExpandableList: ComponentType<any> = () => null;
const logger = new Logger("MutualGroupDMs");
function getGroupDMName(channel: Channel) {
return channel.name ||
channel.recipients
.map(UserStore.getUser)
.filter(isNonNullish)
.map(c => RelationshipStore.getNickname(c.id) || UserUtils.getName(c))
.map(c => RelationshipStore.getNickname(c.id) || UsernameUtils.getName(c))
.join(", ");
}
@ -58,13 +60,13 @@ function getMutualGDMCountText(user: User) {
return `${count === 0 ? "No" : count} Mutual Group${count !== 1 ? "s" : ""}`;
}
function renderClickableGDMs(mutualDms: Channel[], onClose: () => void) {
function renderClickableGDMs(mutualDms: Channel[], onClose?: () => void) {
return mutualDms.map(c => (
<Clickable
key={c.id}
className={MutualsListClasses.row}
onClick={() => {
onClose();
onClose?.();
SelectedChannelActionCreators.selectPrivateChannel(c.id);
}}
>
@ -82,8 +84,6 @@ function renderClickableGDMs(mutualDms: Channel[], onClose: () => void) {
));
}
const IS_PATCHED = Symbol("MutualGroupDMs.Patched");
export default definePlugin({
name: "MutualGroupDMs",
description: "Shows mutual group dms in profiles",
@ -91,17 +91,17 @@ export default definePlugin({
authors: [Devs.amia],
patches: [
// User Profile Modal
// Legacy User Profile Modal
{
find: ".BOT_DATA_ACCESS?(",
replacement: [
{
match: /\i\.useEffect.{0,100}(\i)\[0\]\.section/,
replace: "$self.pushSection($1,arguments[0].user);$&"
match: /(?<=initialSection:\i=\i\.\i\.USER_INFO,onClose:\i\}=)(\i)/,
replace: "$self.getProps($1)"
},
{
match: /\(0,\i\.jsx\)\(\i,\{items:\i,section:(\i)/,
replace: "$1==='MUTUAL_GDMS'?$self.renderMutualGDMs(arguments[0]):$&"
replace: "$1==='MUTUAL_GDMS'?$self.renderMutualGDMs({...arguments[0],isLegacy:true}):$&"
},
// Discord adds spacing between each item which pushes our tab off screen.
// set the gap to zero to ensure ours stays on screen
@ -116,12 +116,12 @@ export default definePlugin({
find: ".WIDGETS?",
replacement: [
{
match: /items:(\i),initialSection:\i,onClose:\i\}=\i.{0,200}?(?=return.{0,30}?\(0,\i\.jsxs?\)\()/,
replace: "$&$self.pushSection($1,arguments[0].user);"
match: /(?<=items:\i,initialSection:\i,onClose:\i\}=)(\i)/,
replace: "$self.getProps($1)"
},
{
match: /children:(?=.{0,100}?component:.+?section:(\i))/,
replace: "$&$1==='MUTUAL_GDMS'?$self.renderMutualGDMs(arguments[0]):"
replace: "$&$1.section==='MUTUAL_GDMS'?$self.renderMutualGDMs(arguments[0]):"
},
// Make the gap between each item smaller so our tab can fit.
{
@ -130,6 +130,7 @@ export default definePlugin({
},
]
},
// Legacy DM Sidebar
{
find: 'section:"MUTUAL_FRIENDS"',
replacement: [
@ -158,33 +159,33 @@ export default definePlugin({
try {
return getMutualGroupDms(userId);
} catch (e) {
new Logger("MutualGroupDMs").error("Failed to get mutual group dms:", e);
logger.error("Failed to get mutual group dms:", e);
}
return [];
},
pushSection(sections: any[], user: User) {
getProps(props: { user: User, items: any[]; }) {
try {
if (isBotOrSelf(user) || sections[IS_PATCHED]) return;
if (isBotOrSelf(props.user)) return props;
sections[IS_PATCHED] = true;
sections.push({
text: getMutualGDMCountText(user),
section: "MUTUAL_GDMS",
});
} catch (e) {
new Logger("MutualGroupDMs").error("Failed to push mutual group dms section:", e);
const section = { text: getMutualGDMCountText(props.user), section: "MUTUAL_GDMS" };
return { ...props, items: [...props.items, section] };
}
catch (e) {
logger.error("Failed to append mutual group dms section:", e);
}
return props;
},
renderMutualGDMs: ErrorBoundary.wrap(({ user, onClose }: { user: User, onClose: () => void; }) => {
renderMutualGDMs: ErrorBoundary.wrap(({ user, onClose, isLegacy }: { user: User, onClose: () => void; isLegacy: boolean; }) => {
const mutualGDms = useMemo(() => getMutualGroupDms(user.id), [user.id]);
const entries = renderClickableGDMs(mutualGDms, onClose);
return (
<ScrollerThin
className={TabBarClasses.tabPanelScroller}
className={classes(TabBarClasses.tabPanelScroller, !isLegacy && "vc-mutual-gdms-scroller")}
fade={true}
onClose={onClose}
>
@ -210,10 +211,10 @@ export default definePlugin({
<>
{hasDivider && Divider}
<ExpandableList
listClassName={listStyle}
listClassName={classes(listStyle, "vc-mutual-gdms-dm-page-list")}
header={"Mutual Groups"}
isLoading={false}
items={renderClickableGDMs(mutualGDms, () => { })}
items={renderClickableGDMs(mutualGDms)}
/>
</>
);

View file

@ -5,3 +5,13 @@
.vc-mutual-gdms-modal-v2-tab-bar {
--space-xl: 16px;
}
.vc-mutual-gdms-scroller {
gap: 12px;
margin-inline-start: -12px;
}
.vc-mutual-gdms-dm-page-list {
gap: 0;
margin-inline-start: -8px;
}

View file

@ -15,6 +15,10 @@ export class TTLMap<K, V> extends Map<K, V> {
}
public set(key: K, value: V) {
if (this._timers.has(key)) {
clearTimeout(this._timers.get(key));
}
const timeoutId = setTimeout(() => {
this.delete(key);
this.onExpire?.(key, value);