diff --git a/fluxer_app/src/components/modals/UserProfileModal.tsx b/fluxer_app/src/components/modals/UserProfileModal.tsx index a2142c4d..9b31890c 100644 --- a/fluxer_app/src/components/modals/UserProfileModal.tsx +++ b/fluxer_app/src/components/modals/UserProfileModal.tsx @@ -94,6 +94,7 @@ import type {ContextMenuTargetElement} from '~/stores/ContextMenuStore'; import ContextMenuStore, {isContextMenuNodeTarget} from '~/stores/ContextMenuStore'; import DeveloperOptionsStore from '~/stores/DeveloperOptionsStore'; import GuildMemberStore from '~/stores/GuildMemberStore'; +import GuildStore from '~/stores/GuildStore'; import MemberPresenceSubscriptionStore from '~/stores/MemberPresenceSubscriptionStore'; import ModalStore from '~/stores/ModalStore'; import PermissionStore from '~/stores/PermissionStore'; @@ -332,7 +333,22 @@ const ProfileModalContent: React.FC = observer( ModalActionCreators.push(modal(() => )); }, []); - const mutualGuilds = React.useMemo(() => GuildMemberStore.getMutualGuilds(user.id), [user.id]); + const profileMutualGuilds = profile?.mutualGuilds ?? []; + type MutualGuildDisplay = { + guild: GuildRecord; + nick: string | null; + }; + const mutualGuildDisplayItems = React.useMemo(() => { + return profileMutualGuilds + .map((mutualGuild) => { + const guild = GuildStore.getGuild(mutualGuild.id); + if (!guild) { + return null; + } + return {guild, nick: mutualGuild.nick}; + }) + .filter((item): item is MutualGuildDisplay => item !== null); + }, [profileMutualGuilds]); const mutualGroups = ChannelStore.dmChannels.filter( (channel) => channel.isGroupDM() && channel.recipientIds.includes(user.id), ); @@ -355,14 +371,14 @@ const ProfileModalContent: React.FC = observer( const count = mutualGroups.length; return t`Mutual Groups (${count})`; } - default: { - const count = mutualGuilds.length; - return t`Mutual Communities (${count})`; - } + default: { + const count = profileMutualGuilds.length; + return t`Mutual Communities (${count})`; } - }, - [t, mutualFriendsCount, mutualGroups.length, mutualGuilds.length], - ); + } + }, + [t, mutualFriendsCount, mutualGroups.length, profileMutualGuilds.length], + ); const openMutualMenu = React.useCallback( (event: React.MouseEvent) => { @@ -571,16 +587,17 @@ const ProfileModalContent: React.FC = observer( const renderMutualGuildsList = React.useCallback(() => { return (
- {mutualGuilds.map((guild) => ( + {mutualGuildDisplayItems.map(({guild, nick}) => ( handleGuildClick(guild)} onContextMenu={(e) => handleGuildContextMenu(e, guild)} isContextMenuOpen={isContextMenuOpenFor} /> ))} - {mutualGuilds.length === 0 && ( + {profileMutualGuilds.length === 0 && (
No mutual communities found. @@ -588,7 +605,13 @@ const ProfileModalContent: React.FC = observer( )}
); - }, [handleGuildClick, handleGuildContextMenu, isContextMenuOpenFor, mutualGuilds]); + }, [ + handleGuildClick, + handleGuildContextMenu, + isContextMenuOpenFor, + mutualGuildDisplayItems, + profileMutualGuilds.length, + ]); const renderMutualTabContent = React.useCallback(() => { switch (mutualView) { @@ -751,11 +774,13 @@ const MutualFriendItem = ({ const MutualGuildItem = ({ guild, + nick, onClick, onContextMenu, isContextMenuOpen, }: { guild: GuildRecord; + nick: string | null; onClick: () => void; onContextMenu: (e: React.MouseEvent) => void; isContextMenuOpen: (target: EventTarget | null) => boolean; @@ -782,6 +807,7 @@ const MutualGuildItem = ({ />
{guild.name} + {nick && {nick}}
); diff --git a/fluxer_app/src/records/ProfileRecord.tsx b/fluxer_app/src/records/ProfileRecord.tsx index f4a89876..edfaea71 100644 --- a/fluxer_app/src/records/ProfileRecord.tsx +++ b/fluxer_app/src/records/ProfileRecord.tsx @@ -24,6 +24,11 @@ import GuildMemberStore from '~/stores/GuildMemberStore'; import GuildStore from '~/stores/GuildStore'; import UserStore from '~/stores/UserStore'; +export type ProfileMutualGuild = Readonly<{ + id: string; + nick: string | null; +}>; + export type Profile = Readonly<{ user: UserPartial; user_profile: UserProfile; @@ -34,6 +39,7 @@ export type Profile = Readonly<{ premium_since?: string; premium_lifetime_sequence?: number; mutual_friends?: Array; + mutual_guilds?: Array; }>; export class ProfileRecord { @@ -46,6 +52,7 @@ export class ProfileRecord { readonly premiumSince: Date | null; readonly premiumLifetimeSequence: number | null; readonly mutualFriends: ReadonlyArray | null; + readonly mutualGuilds: ReadonlyArray | null; constructor(profile: Profile, guildId?: string) { this.userId = profile.user.id; @@ -57,6 +64,7 @@ export class ProfileRecord { this.premiumSince = profile.premium_since ? new Date(profile.premium_since) : null; this.premiumLifetimeSequence = profile.premium_lifetime_sequence ?? null; this.mutualFriends = profile.mutual_friends ? Object.freeze([...profile.mutual_friends]) : null; + this.mutualGuilds = profile.mutual_guilds ? Object.freeze([...profile.mutual_guilds]) : null; } withUpdates(updates: Partial): ProfileRecord { @@ -76,6 +84,7 @@ export class ProfileRecord { ? updates.premium_lifetime_sequence : (this.premiumLifetimeSequence ?? undefined), mutual_friends: updates.mutual_friends ?? (this.mutualFriends ? [...this.mutualFriends] : undefined), + mutual_guilds: updates.mutual_guilds ?? (this.mutualGuilds ? [...this.mutualGuilds] : undefined), }, this.guildId ?? undefined, ); @@ -129,7 +138,8 @@ export class ProfileRecord { this.premiumType === other.premiumType && this.premiumSince === other.premiumSince && this.premiumLifetimeSequence === other.premiumLifetimeSequence && - JSON.stringify(this.mutualFriends) === JSON.stringify(other.mutualFriends) + JSON.stringify(this.mutualFriends) === JSON.stringify(other.mutualFriends) && + JSON.stringify(this.mutualGuilds) === JSON.stringify(other.mutualGuilds) ); } @@ -143,6 +153,7 @@ export class ProfileRecord { premium_since: this.premiumSince?.toISOString() ?? undefined, premium_lifetime_sequence: this.premiumLifetimeSequence ?? undefined, mutual_friends: this.mutualFriends ? [...this.mutualFriends] : undefined, + mutual_guilds: this.mutualGuilds ? [...this.mutualGuilds] : undefined, }; } }