2023-06-15 03:39:15 +02:00
|
|
|
/*
|
|
|
|
* Vencord, a modification for Discord's desktop app
|
|
|
|
* Copyright (c) 2023 Vendicated and contributors
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2024-05-09 03:14:20 -03:00
|
|
|
import ErrorBoundary from "@components/ErrorBoundary";
|
2023-06-15 03:39:15 +02:00
|
|
|
import { Devs } from "@utils/constants";
|
|
|
|
import { isNonNullish } from "@utils/guards";
|
|
|
|
import definePlugin from "@utils/types";
|
2024-09-02 06:50:52 +03:00
|
|
|
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
2024-08-10 16:30:39 +02:00
|
|
|
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore } from "@webpack/common";
|
2023-06-15 03:39:15 +02:00
|
|
|
import { Channel, User } from "discord-types/general";
|
|
|
|
|
|
|
|
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
|
|
|
|
const UserUtils = findByPropsLazy("getGlobalName");
|
|
|
|
|
|
|
|
const ProfileListClasses = findByPropsLazy("emptyIconFriends", "emptyIconGuilds");
|
2024-10-22 22:28:30 -04:00
|
|
|
const ExpandableList = findComponentByCodeLazy('"PRESS_SECTION"');
|
2023-06-15 03:39:15 +02:00
|
|
|
const GuildLabelClasses = findByPropsLazy("guildNick", "guildAvatarWithoutIcon");
|
|
|
|
|
|
|
|
function getGroupDMName(channel: Channel) {
|
|
|
|
return channel.name ||
|
|
|
|
channel.recipients
|
|
|
|
.map(UserStore.getUser)
|
|
|
|
.filter(isNonNullish)
|
|
|
|
.map(c => RelationshipStore.getNickname(c.id) || UserUtils.getName(c))
|
|
|
|
.join(", ");
|
|
|
|
}
|
|
|
|
|
2024-08-10 16:30:39 +02:00
|
|
|
const getMutualGroupDms = (userId: string) =>
|
|
|
|
ChannelStore.getSortedPrivateChannels()
|
|
|
|
.filter(c => c.isGroupDM() && c.recipients.includes(userId));
|
|
|
|
|
|
|
|
const isBotOrSelf = (user: User) => user.bot || user.id === UserStore.getCurrentUser().id;
|
|
|
|
|
|
|
|
function getMutualGDMCountText(user: User) {
|
|
|
|
const count = getMutualGroupDms(user.id).length;
|
|
|
|
return `${count === 0 ? "No" : count} Mutual Group${count !== 1 ? "s" : ""}`;
|
|
|
|
}
|
|
|
|
|
2024-09-02 06:50:52 +03:00
|
|
|
function renderClickableGDMs(mutualDms: Channel[], onClose: () => void) {
|
|
|
|
return mutualDms.map(c => (
|
|
|
|
<Clickable
|
|
|
|
className={ProfileListClasses.listRow}
|
|
|
|
onClick={() => {
|
|
|
|
onClose();
|
|
|
|
SelectedChannelActionCreators.selectPrivateChannel(c.id);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Avatar
|
|
|
|
src={IconUtils.getChannelIconURL({ id: c.id, icon: c.icon, size: 32 })}
|
|
|
|
size="SIZE_40"
|
|
|
|
className={ProfileListClasses.listAvatar}
|
|
|
|
>
|
|
|
|
</Avatar>
|
|
|
|
<div className={ProfileListClasses.listRowContent}>
|
|
|
|
<div className={ProfileListClasses.listName}>{getGroupDMName(c)}</div>
|
|
|
|
<div className={GuildLabelClasses.guildNick}>{c.recipients.length + 1} Members</div>
|
|
|
|
</div>
|
|
|
|
</Clickable>
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2024-08-10 16:30:39 +02:00
|
|
|
const IS_PATCHED = Symbol("MutualGroupDMs.Patched");
|
|
|
|
|
2023-06-15 03:39:15 +02:00
|
|
|
export default definePlugin({
|
|
|
|
name: "MutualGroupDMs",
|
|
|
|
description: "Shows mutual group dms in profiles",
|
|
|
|
authors: [Devs.amia],
|
|
|
|
|
|
|
|
patches: [
|
2024-06-26 17:10:48 +02:00
|
|
|
{
|
2024-06-26 18:40:21 +02:00
|
|
|
find: ".MUTUAL_FRIENDS?(",
|
2024-06-26 17:10:48 +02:00
|
|
|
replacement: [
|
|
|
|
{
|
2024-08-10 16:30:39 +02:00
|
|
|
match: /\i\.useEffect.{0,100}(\i)\[0\]\.section/,
|
|
|
|
replace: "$self.pushSection($1, arguments[0].user);$&"
|
2024-06-26 17:10:48 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
match: /\(0,\i\.jsx\)\(\i,\{items:\i,section:(\i)/,
|
|
|
|
replace: "$1==='MUTUAL_GDMS'?$self.renderMutualGDMs(arguments[0]):$&"
|
|
|
|
}
|
|
|
|
]
|
2024-09-02 06:50:52 +03:00
|
|
|
},
|
|
|
|
{
|
|
|
|
find: 'section:"MUTUAL_FRIENDS"',
|
|
|
|
replacement: {
|
|
|
|
match: /\.openUserProfileModal.+?\)}\)}\)(?<=(\(0,\i\.jsxs?\)\(\i\.\i,{className:(\i)\.divider}\)).+?)/,
|
|
|
|
replace: "$&,$self.renderDMPageList({user: arguments[0].user, Divider: $1, listStyle: $2.list})"
|
|
|
|
}
|
2023-06-15 03:39:15 +02:00
|
|
|
}
|
|
|
|
],
|
|
|
|
|
2024-08-10 16:30:39 +02:00
|
|
|
pushSection(sections: any[], user: User) {
|
|
|
|
if (isBotOrSelf(user) || sections[IS_PATCHED]) return;
|
2024-06-26 18:40:21 +02:00
|
|
|
|
2024-08-10 16:30:39 +02:00
|
|
|
sections[IS_PATCHED] = true;
|
|
|
|
sections.push({
|
|
|
|
section: "MUTUAL_GDMS",
|
|
|
|
text: getMutualGDMCountText(user)
|
|
|
|
});
|
2024-08-01 10:10:30 +03:00
|
|
|
},
|
|
|
|
|
2024-05-14 03:22:49 +02:00
|
|
|
renderMutualGDMs: ErrorBoundary.wrap(({ user, onClose }: { user: User, onClose: () => void; }) => {
|
2024-09-02 06:50:52 +03:00
|
|
|
const mutualGDms = useMemo(() => getMutualGroupDms(user.id), [user.id]);
|
|
|
|
|
|
|
|
const entries = renderClickableGDMs(mutualGDms, onClose);
|
2023-06-15 03:39:15 +02:00
|
|
|
|
|
|
|
return (
|
|
|
|
<ScrollerThin
|
|
|
|
className={ProfileListClasses.listScroller}
|
|
|
|
fade={true}
|
|
|
|
onClose={onClose}
|
|
|
|
>
|
|
|
|
{entries.length > 0
|
|
|
|
? entries
|
|
|
|
: (
|
|
|
|
<div className={ProfileListClasses.empty}>
|
|
|
|
<div className={ProfileListClasses.emptyIconFriends}></div>
|
|
|
|
<div className={ProfileListClasses.emptyText}>No group dms in common</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
</ScrollerThin>
|
|
|
|
);
|
2024-09-02 06:50:52 +03:00
|
|
|
}),
|
|
|
|
|
|
|
|
renderDMPageList: ErrorBoundary.wrap(({ user, Divider, listStyle }: { user: User, Divider: JSX.Element, listStyle: string; }) => {
|
|
|
|
const mutualGDms = getMutualGroupDms(user.id);
|
|
|
|
if (mutualGDms.length === 0) return null;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{Divider}
|
|
|
|
<ExpandableList
|
2024-10-22 22:28:30 -04:00
|
|
|
listClassName={listStyle}
|
|
|
|
header={"Mutual Groups"}
|
|
|
|
isLoading={false}
|
|
|
|
items={renderClickableGDMs(mutualGDms, () => { })}
|
2024-09-02 06:50:52 +03:00
|
|
|
/>
|
|
|
|
</>
|
|
|
|
);
|
2024-05-09 03:14:20 -03:00
|
|
|
})
|
2023-06-15 03:39:15 +02:00
|
|
|
});
|