/* * Copyright (C) 2026 Fluxer Contributors * * This file is part of Fluxer. * * Fluxer is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Fluxer 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Fluxer. If not, see . */ import {observer} from 'mobx-react-lite'; import type React from 'react'; import {Permissions, RelationshipTypes} from '~/Constants'; import type {UserRecord} from '~/records/UserRecord'; import AuthenticationStore from '~/stores/AuthenticationStore'; import ChannelStore from '~/stores/ChannelStore'; import GuildMemberStore from '~/stores/GuildMemberStore'; import GuildStore from '~/stores/GuildStore'; import PermissionStore from '~/stores/PermissionStore'; import RelationshipStore from '~/stores/RelationshipStore'; import UserSettingsStore from '~/stores/UserSettingsStore'; import * as PermissionUtils from '~/utils/PermissionUtils'; import {StartVoiceCallMenuItem} from './items/CallMenuItems'; import {CopyUserIdMenuItem} from './items/CopyMenuItems'; import {DebugGuildMemberMenuItem, DebugUserMenuItem} from './items/DebugMenuItems'; import { BanMemberMenuItem, ChangeNicknameMenuItem, KickMemberMenuItem, ManageRolesMenuItem, TimeoutMemberMenuItem, TransferOwnershipMenuItem, } from './items/GuildMemberMenuItems'; import {InviteToCommunityMenuItem} from './items/InviteMenuItems'; import {MentionUserMenuItem} from './items/MentionUserMenuItem'; import {MessageUserMenuItem} from './items/MessageUserMenuItem'; import { BlockUserMenuItem, ChangeFriendNicknameMenuItem, RelationshipActionMenuItem, UnblockUserMenuItem, } from './items/RelationshipMenuItems'; import {AddNoteMenuItem} from './items/UserNoteMenuItems'; import {UserProfileMenuItem} from './items/UserProfileMenuItem'; import {MenuGroup} from './MenuGroup'; interface GuildMemberContextMenuProps { user: UserRecord; onClose: () => void; guildId: string; channelId?: string; } export const GuildMemberContextMenu: React.FC = observer( ({user, onClose, guildId, channelId}) => { const channel = channelId ? ChannelStore.getChannel(channelId) : null; const canSendMessages = channel ? PermissionStore.can(Permissions.SEND_MESSAGES, {channelId, guildId}) : true; const canMention = channel !== null && canSendMessages; const isCurrentUser = user.id === AuthenticationStore.currentUserId; const relationship = RelationshipStore.getRelationship(user.id); const relationshipType = relationship?.type; const guild = GuildStore.getGuild(guildId); const member = GuildMemberStore.getMember(guildId, user.id); const currentUserId = AuthenticationStore.currentUserId; const isBot = user.bot; const canKickMembers = PermissionStore.can(Permissions.KICK_MEMBERS, {guildId}); const canBanMembers = PermissionStore.can(Permissions.BAN_MEMBERS, {guildId}); const canModerateMembers = PermissionStore.can(Permissions.MODERATE_MEMBERS, {guildId}); const isOwner = guild?.ownerId === currentUserId; const canKick = !isCurrentUser && canKickMembers; const canBan = !isCurrentUser && canBanMembers; const guildSnapshot = guild?.toJSON(); const targetHasModerateMembersPermission = guildSnapshot !== undefined && PermissionUtils.can(Permissions.MODERATE_MEMBERS, user.id, guildSnapshot); const canTimeout = !isCurrentUser && canModerateMembers && !targetHasModerateMembersPermission; const canTransfer = !isCurrentUser && isOwner; const developerMode = UserSettingsStore.developerMode; const hasManageNicknamesPermission = PermissionStore.can(Permissions.MANAGE_NICKNAMES, {guildId}); const canManageNicknames = member && (isCurrentUser || hasManageNicknamesPermission); const hasRoles = guild && Object.values(guild.roles).some((r) => !r.isEveryone); return ( <> {canMention && } {!isCurrentUser && } {!isCurrentUser && !isBot && } {!isCurrentUser && } {canManageNicknames && member && ( )} {!isCurrentUser && !isBot && } {!isCurrentUser && !isBot && } {!isCurrentUser && (relationshipType === RelationshipTypes.BLOCKED ? ( ) : ( ))} {canTransfer && member && ( )} {(canTimeout || canKick || canBan) && member && ( {canTimeout && } {canKick && } {canBan && } )} {member && hasRoles && ( )} {developerMode && ( {member && } )} ); }, );