mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 13:35:42 +09:00
526 lines
18 KiB
TypeScript
526 lines
18 KiB
TypeScript
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import {Routes} from '@app/app/Routes';
|
|
import Authentication from '@app/features/auth/state/Authentication';
|
|
import {CategoryCreateModal} from '@app/features/channel/components/modals/CategoryCreateModal';
|
|
import {ChannelCreateModal} from '@app/features/channel/components/modals/ChannelCreateModal';
|
|
import Channels from '@app/features/channel/state/Channels';
|
|
import {DELETE_MY_MESSAGES_DESCRIPTOR} from '@app/features/channel/utils/ChannelMessageDescriptors';
|
|
import {GuildDebugModal} from '@app/features/devtools/components/debug/GuildDebugModal';
|
|
import {GuildNotificationSettingsModal} from '@app/features/guild/components/modals/GuildNotificationSettingsModal';
|
|
import {GuildPrivacySettingsModal} from '@app/features/guild/components/modals/GuildPrivacySettingsModal';
|
|
import {GuildSettingsModal} from '@app/features/guild/components/modals/GuildSettingsModal';
|
|
import {useDeleteMyMessagesInGuild} from '@app/features/guild/hooks/useDeleteMyMessagesInGuild';
|
|
import {useLeaveGuild} from '@app/features/guild/hooks/useLeaveGuild';
|
|
import type {Guild} from '@app/features/guild/models/Guild';
|
|
import GuildMatureContentAgree from '@app/features/guild/state/GuildMatureContentAgree';
|
|
import {isStockCommunityGuild} from '@app/features/guild/utils/GuildCommunityUtils';
|
|
import {
|
|
COPY_COMMUNITY_ID_DESCRIPTOR,
|
|
CREATE_CATEGORY_DESCRIPTOR,
|
|
CREATE_CHANNEL_DESCRIPTOR,
|
|
HIDE_MUTED_CHANNELS_DESCRIPTOR,
|
|
LEAVE_COMMUNITY_DESCRIPTOR,
|
|
MARK_AS_READ_DESCRIPTOR,
|
|
MUTE_COMMUNITY_DESCRIPTOR,
|
|
NOTIFICATION_SETTINGS_DESCRIPTOR,
|
|
PRIVACY_SETTINGS_DESCRIPTOR,
|
|
RESET_MATURE_CONTENT_AGREE_STATE_DESCRIPTOR,
|
|
UNMUTE_COMMUNITY_DESCRIPTOR,
|
|
} from '@app/features/i18n/utils/CommonMessageDescriptors';
|
|
import {InviteModal} from '@app/features/invite/components/modals/InviteModal';
|
|
import * as InviteUtils from '@app/features/invite/utils/InviteUtils';
|
|
import {REPORT_COMMUNITY_DESCRIPTOR} from '@app/features/moderation/utils/ModerationMessageDescriptors';
|
|
import {openReportGuildModal} from '@app/features/moderation/utils/ReportActionUtils';
|
|
import * as RouterUtils from '@app/features/navigation/utils/RouterUtils';
|
|
import Permission from '@app/features/permissions/state/Permission';
|
|
import * as ReadStateCommands from '@app/features/read_state/commands/ReadStateCommands';
|
|
import ReadStates from '@app/features/read_state/state/ReadStates';
|
|
import {
|
|
CopyIdIcon,
|
|
CreateCategoryIcon,
|
|
CreateChannelIcon,
|
|
DebugChannelIcon,
|
|
DeleteIcon,
|
|
EditProfileIcon,
|
|
InviteIcon,
|
|
LeaveIcon,
|
|
MarkAsReadIcon,
|
|
MuteIcon,
|
|
NotificationSettingsIcon,
|
|
PrivacySettingsIcon,
|
|
ReportUserIcon,
|
|
SettingsIcon,
|
|
} from '@app/features/ui/action_menu/ContextMenuIcons';
|
|
import * as ModalCommands from '@app/features/ui/commands/ModalCommands';
|
|
import {modal} from '@app/features/ui/commands/ModalCommands';
|
|
import * as TextCopyCommands from '@app/features/ui/commands/TextCopyCommands';
|
|
import type {
|
|
MenuCheckboxType,
|
|
MenuGroupType,
|
|
MenuItemType,
|
|
MenuSubmenuItemType,
|
|
} from '@app/features/ui/menu_bottom_sheet/MenuBottomSheet';
|
|
import * as UserGuildSettingsCommands from '@app/features/user/commands/UserGuildSettingsCommands';
|
|
import {UserSettingsModal} from '@app/features/user/components/modals/UserSettingsModal';
|
|
import {
|
|
GUILD_SETTINGS_LABEL_DESCRIPTOR,
|
|
getGuildSettingsTabs,
|
|
} from '@app/features/user/components/settings_utils/GuildSettingsConstants';
|
|
import UserGuildSettings from '@app/features/user/state/UserGuildSettings';
|
|
import UserSettings from '@app/features/user/state/UserSettings';
|
|
import Users from '@app/features/user/state/Users';
|
|
import {getMutedText} from '@app/lib/overlay/OverlayContextMenu';
|
|
import {Permissions} from '@fluxer/constants/src/ChannelConstants';
|
|
import {ContentWarningLevel} from '@fluxer/constants/src/GuildConstants';
|
|
import {msg} from '@lingui/core/macro';
|
|
import {useLingui} from '@lingui/react/macro';
|
|
import {useMemo} from 'react';
|
|
|
|
const COMMUNITY_DEBUG_DESCRIPTOR = msg({
|
|
message: 'Community debug',
|
|
comment: 'Title of the developer-mode community debug modal.',
|
|
});
|
|
const INVITE_MEMBERS_DESCRIPTOR = msg({
|
|
message: 'Invite members',
|
|
comment: 'Action label that opens the invite flow.',
|
|
});
|
|
const EDIT_COMMUNITY_PROFILE_DESCRIPTOR = msg({
|
|
message: 'Edit community profile',
|
|
comment: 'Action that opens the community profile editor for the current member.',
|
|
});
|
|
const DEBUG_COMMUNITY_DESCRIPTOR = msg({
|
|
message: 'Debug community',
|
|
comment: 'Developer-mode action that opens the community debug modal.',
|
|
});
|
|
|
|
interface UseGuildMenuDataOptions {
|
|
onClose: () => void;
|
|
onOpenMuteSheet?: () => void;
|
|
preserveInitialMarkAsReadVisibility?: boolean;
|
|
}
|
|
|
|
export interface GuildMenuHandlers {
|
|
handleMarkAsRead: () => void;
|
|
handleInviteMembers: () => void;
|
|
handleCommunitySettings: () => void;
|
|
handleCreateChannel: () => void;
|
|
handleCreateCategory: () => void;
|
|
handleNotificationSettings: () => void;
|
|
handlePrivacySettings: () => void;
|
|
handleEditCommunityProfile: () => void;
|
|
handleLeaveCommunity: () => void;
|
|
handleDeleteMyMessagesInCommunity: () => void;
|
|
handleCopyGuildId: () => void;
|
|
handleDebugGuild: () => void;
|
|
handleResetMatureContentAgreeState: () => void;
|
|
handleReportGuild: () => void;
|
|
handleToggleHideMutedChannels: (checked: boolean) => void;
|
|
}
|
|
|
|
export interface GuildMenuPermissions {
|
|
canManageGuild: boolean;
|
|
canManageChannels: boolean;
|
|
canInvite: boolean;
|
|
canAccessGuildSettings: boolean;
|
|
isOwner: boolean;
|
|
hasGuildUnread: boolean;
|
|
developerMode: boolean;
|
|
}
|
|
|
|
export interface GuildMenuData {
|
|
groups: Array<MenuGroupType>;
|
|
handlers: GuildMenuHandlers;
|
|
permissions: GuildMenuPermissions;
|
|
isMuted: boolean;
|
|
mutedText: string | null;
|
|
hideMutedChannels: boolean;
|
|
}
|
|
|
|
export function useGuildMenuData(guild: Guild, options: UseGuildMenuDataOptions): GuildMenuData {
|
|
const {i18n} = useLingui();
|
|
const {onClose, onOpenMuteSheet, preserveInitialMarkAsReadVisibility = false} = options;
|
|
const leaveGuild = useLeaveGuild();
|
|
const deleteMyMessagesInGuild = useDeleteMyMessagesInGuild();
|
|
const channels = Channels.getGuildChannels(guild.id);
|
|
const canManageGuild = Permission.can(Permissions.MANAGE_GUILD, {guildId: guild.id});
|
|
const canManageChannels = Permission.can(Permissions.MANAGE_CHANNELS, {guildId: guild.id});
|
|
const invitableChannelId = InviteUtils.getInvitableChannelId(guild.id);
|
|
const canInvite = InviteUtils.canInviteToChannel(invitableChannelId, guild.id);
|
|
const canManageRoles = Permission.can(Permissions.MANAGE_ROLES, {guildId: guild.id});
|
|
const canViewAuditLog = Permission.can(Permissions.VIEW_AUDIT_LOG, {guildId: guild.id});
|
|
const canManageWebhooks = Permission.can(Permissions.MANAGE_WEBHOOKS, {guildId: guild.id});
|
|
const canManageEmojis = Permission.can(Permissions.MANAGE_EXPRESSIONS, {guildId: guild.id});
|
|
const canCreateExpressions = Permission.can(Permissions.CREATE_EXPRESSIONS, {guildId: guild.id});
|
|
const canBanMembers = Permission.can(Permissions.BAN_MEMBERS, {guildId: guild.id});
|
|
const canAccessGuildSettings =
|
|
canManageGuild ||
|
|
canManageRoles ||
|
|
canViewAuditLog ||
|
|
canManageWebhooks ||
|
|
canManageEmojis ||
|
|
canCreateExpressions ||
|
|
canBanMembers;
|
|
const isOwner = guild.isOwner(Authentication.currentUserId);
|
|
const developerMode = UserSettings.developerMode;
|
|
const canEditCommunityProfile = Users.getCurrentUser()?.isClaimed() ?? true;
|
|
const settings = UserGuildSettings.getSettings(guild.id);
|
|
const hideMutedChannels = settings?.hide_muted_channels ?? false;
|
|
const isMuted = settings?.muted ?? false;
|
|
const muteConfig = settings?.mute_config;
|
|
const mutedText = getMutedText(isMuted, muteConfig);
|
|
const hasCurrentGuildMatureContentGate =
|
|
guild.nsfw || guild.contentWarningLevel === ContentWarningLevel.CONTENT_WARNING;
|
|
const initialHasGuildUnread = useMemo(
|
|
() => Channels.getGuildChannels(guild.id).some((channel) => ReadStates.hasUnread(channel.id)),
|
|
[guild.id],
|
|
);
|
|
const hasGuildUnread = preserveInitialMarkAsReadVisibility
|
|
? initialHasGuildUnread
|
|
: channels.some((channel) => ReadStates.hasUnread(channel.id));
|
|
const handlers = useMemo(
|
|
() => ({
|
|
handleMarkAsRead: () => {
|
|
const channelIds = channels
|
|
.filter((channel) => ReadStates.getUnreadCount(channel.id) > 0)
|
|
.map((channel) => channel.id);
|
|
if (channelIds.length > 0) {
|
|
void ReadStateCommands.bulkAckChannels(channelIds);
|
|
}
|
|
onClose();
|
|
},
|
|
handleInviteMembers: () => {
|
|
const invitableChannelId = InviteUtils.getInvitableChannelId(guild.id);
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<InviteModal
|
|
channelId={invitableChannelId ?? ''}
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-invite-members.invite-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handleCommunitySettings: () => {
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<GuildSettingsModal
|
|
guildId={guild.id}
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-community-settings.guild-settings-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handleCreateChannel: () => {
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<ChannelCreateModal
|
|
guildId={guild.id}
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-create-channel.channel-create-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handleCreateCategory: () => {
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<CategoryCreateModal
|
|
guildId={guild.id}
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-create-category.category-create-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handleNotificationSettings: () => {
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<GuildNotificationSettingsModal
|
|
guildId={guild.id}
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-notification-settings.guild-notification-settings-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handlePrivacySettings: () => {
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<GuildPrivacySettingsModal
|
|
guildId={guild.id}
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-privacy-settings.guild-privacy-settings-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handleEditCommunityProfile: () => {
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<UserSettingsModal
|
|
initialGuildId={guild.id}
|
|
initialTab="my_profile"
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-edit-community-profile.user-settings-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handleLeaveCommunity: () => {
|
|
ModalCommands.runAfterBottomSheetClose(onClose, () => leaveGuild(guild.id));
|
|
},
|
|
handleDeleteMyMessagesInCommunity: () => {
|
|
ModalCommands.runAfterBottomSheetClose(onClose, () => deleteMyMessagesInGuild(guild.id));
|
|
},
|
|
handleCopyGuildId: () => {
|
|
void TextCopyCommands.copy(i18n, guild.id);
|
|
onClose();
|
|
},
|
|
handleDebugGuild: () => {
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<GuildDebugModal
|
|
title={i18n._(COMMUNITY_DEBUG_DESCRIPTOR)}
|
|
guild={guild}
|
|
data-flx="ui.action-menu.items.guild-menu-data.handle-debug-guild.guild-debug-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
handleResetMatureContentAgreeState: () => {
|
|
GuildMatureContentAgree.revokeGuild(guild.id);
|
|
onClose();
|
|
},
|
|
handleReportGuild: () => {
|
|
ModalCommands.runAfterBottomSheetClose(onClose, () => openReportGuildModal({i18n, guild}));
|
|
},
|
|
handleToggleHideMutedChannels: (checked: boolean) => {
|
|
const currentSettings = UserGuildSettings.getSettings(guild.id);
|
|
const currentValue = currentSettings?.hide_muted_channels ?? false;
|
|
if (checked === currentValue) return;
|
|
UserGuildSettingsCommands.toggleHideMutedChannels(guild.id);
|
|
},
|
|
}),
|
|
[channels, deleteMyMessagesInGuild, guild, i18n.locale, leaveGuild, onClose],
|
|
);
|
|
const permissions: GuildMenuPermissions = useMemo(
|
|
() => ({
|
|
canManageGuild,
|
|
canManageChannels,
|
|
canInvite,
|
|
canAccessGuildSettings,
|
|
isOwner,
|
|
hasGuildUnread,
|
|
developerMode,
|
|
}),
|
|
[canManageGuild, canManageChannels, canInvite, canAccessGuildSettings, isOwner, hasGuildUnread, developerMode],
|
|
);
|
|
const availableSettingsTabs = useMemo(() => {
|
|
const allTabs = getGuildSettingsTabs(i18n);
|
|
return allTabs.filter((tab) => {
|
|
if (tab.permission) {
|
|
const perms = Array.isArray(tab.permission) ? tab.permission : [tab.permission];
|
|
if (!perms.some((p) => Permission.can(p, {guildId: guild.id}))) {
|
|
return false;
|
|
}
|
|
}
|
|
if (tab.requireFeature && !guild.features.has(tab.requireFeature)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
}, [guild.features, guild.id, i18n.locale]);
|
|
const groups = useMemo(() => {
|
|
const menuGroups: Array<MenuGroupType> = [];
|
|
const quickActions: Array<MenuItemType | MenuSubmenuItemType> = [];
|
|
if (hasGuildUnread) {
|
|
quickActions.push({
|
|
icon: <MarkAsReadIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.mark-as-read-icon" />,
|
|
label: i18n._(MARK_AS_READ_DESCRIPTOR),
|
|
onClick: handlers.handleMarkAsRead,
|
|
});
|
|
}
|
|
if (canInvite) {
|
|
quickActions.push({
|
|
icon: <InviteIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.invite-icon" />,
|
|
label: i18n._(INVITE_MEMBERS_DESCRIPTOR),
|
|
onClick: handlers.handleInviteMembers,
|
|
});
|
|
}
|
|
if (canAccessGuildSettings) {
|
|
const settingsSubItems: Array<MenuItemType> = availableSettingsTabs.map((tab) => ({
|
|
id: tab.type,
|
|
label: tab.label,
|
|
onClick: () => {
|
|
if (tab.type === 'members') {
|
|
ModalCommands.runAfterBottomSheetClose(onClose, () =>
|
|
RouterUtils.transitionTo(Routes.guildMembers(guild.id)),
|
|
);
|
|
return;
|
|
}
|
|
ModalCommands.pushAfterBottomSheetClose(
|
|
onClose,
|
|
modal(() => (
|
|
<GuildSettingsModal
|
|
guildId={guild.id}
|
|
initialTab={tab.type}
|
|
data-flx="ui.action-menu.items.guild-menu-data.on-click.guild-settings-modal"
|
|
/>
|
|
)),
|
|
);
|
|
},
|
|
}));
|
|
quickActions.push({
|
|
icon: <SettingsIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.settings-icon" />,
|
|
label: i18n._(GUILD_SETTINGS_LABEL_DESCRIPTOR),
|
|
items: settingsSubItems,
|
|
onTriggerSelect: handlers.handleCommunitySettings,
|
|
});
|
|
}
|
|
if (canManageChannels) {
|
|
quickActions.push({
|
|
icon: (
|
|
<CreateChannelIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.create-channel-icon" />
|
|
),
|
|
label: i18n._(CREATE_CHANNEL_DESCRIPTOR),
|
|
onClick: handlers.handleCreateChannel,
|
|
});
|
|
quickActions.push({
|
|
icon: (
|
|
<CreateCategoryIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.create-category-icon" />
|
|
),
|
|
label: i18n._(CREATE_CATEGORY_DESCRIPTOR),
|
|
onClick: handlers.handleCreateCategory,
|
|
});
|
|
}
|
|
if (quickActions.length > 0) {
|
|
menuGroups.push({items: quickActions});
|
|
}
|
|
const settingsItems: Array<MenuItemType> = [
|
|
{
|
|
icon: (
|
|
<NotificationSettingsIcon
|
|
size={20}
|
|
data-flx="ui.action-menu.items.guild-menu-data.groups.notification-settings-icon"
|
|
/>
|
|
),
|
|
label: i18n._(NOTIFICATION_SETTINGS_DESCRIPTOR),
|
|
onClick: handlers.handleNotificationSettings,
|
|
},
|
|
{
|
|
icon: (
|
|
<PrivacySettingsIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.privacy-settings-icon" />
|
|
),
|
|
label: i18n._(PRIVACY_SETTINGS_DESCRIPTOR),
|
|
onClick: handlers.handlePrivacySettings,
|
|
},
|
|
];
|
|
if (canEditCommunityProfile) {
|
|
settingsItems.push({
|
|
icon: <EditProfileIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.edit-profile-icon" />,
|
|
label: i18n._(EDIT_COMMUNITY_PROFILE_DESCRIPTOR),
|
|
onClick: handlers.handleEditCommunityProfile,
|
|
});
|
|
}
|
|
menuGroups.push({items: settingsItems});
|
|
const muteItems: Array<MenuItemType | MenuCheckboxType> = [];
|
|
if (onOpenMuteSheet) {
|
|
muteItems.push({
|
|
icon: <MuteIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.mute-icon" />,
|
|
label: isMuted ? i18n._(UNMUTE_COMMUNITY_DESCRIPTOR) : i18n._(MUTE_COMMUNITY_DESCRIPTOR),
|
|
onClick: onOpenMuteSheet,
|
|
});
|
|
}
|
|
const hideMutedChannelsItem: MenuCheckboxType = {
|
|
label: i18n._(HIDE_MUTED_CHANNELS_DESCRIPTOR),
|
|
checked: hideMutedChannels,
|
|
onChange: handlers.handleToggleHideMutedChannels,
|
|
};
|
|
muteItems.push(hideMutedChannelsItem);
|
|
menuGroups.push({items: muteItems});
|
|
const dangerActions: Array<MenuItemType> = [
|
|
{
|
|
icon: <DeleteIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.delete-icon" />,
|
|
label: i18n._(DELETE_MY_MESSAGES_DESCRIPTOR),
|
|
onClick: handlers.handleDeleteMyMessagesInCommunity,
|
|
danger: true,
|
|
},
|
|
];
|
|
if (!isOwner) {
|
|
if (!isStockCommunityGuild(guild.id)) {
|
|
dangerActions.push({
|
|
icon: <LeaveIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.leave-icon" />,
|
|
label: i18n._(LEAVE_COMMUNITY_DESCRIPTOR),
|
|
onClick: handlers.handleLeaveCommunity,
|
|
danger: true,
|
|
});
|
|
}
|
|
dangerActions.push({
|
|
icon: <ReportUserIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.report-user-icon" />,
|
|
label: i18n._(REPORT_COMMUNITY_DESCRIPTOR),
|
|
onClick: handlers.handleReportGuild,
|
|
danger: true,
|
|
});
|
|
}
|
|
menuGroups.push({items: dangerActions});
|
|
if (developerMode) {
|
|
const debugItems: Array<MenuItemType> = [
|
|
{
|
|
icon: (
|
|
<DebugChannelIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.debug-channel-icon" />
|
|
),
|
|
label: i18n._(DEBUG_COMMUNITY_DESCRIPTOR),
|
|
onClick: handlers.handleDebugGuild,
|
|
},
|
|
];
|
|
if (hasCurrentGuildMatureContentGate && GuildMatureContentAgree.hasAgreedToGuild(guild.id)) {
|
|
debugItems.push({
|
|
icon: (
|
|
<DebugChannelIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.debug-channel-icon--2" />
|
|
),
|
|
label: i18n._(RESET_MATURE_CONTENT_AGREE_STATE_DESCRIPTOR),
|
|
onClick: handlers.handleResetMatureContentAgreeState,
|
|
});
|
|
}
|
|
menuGroups.push({items: debugItems});
|
|
}
|
|
const utilityItems: Array<MenuItemType> = [
|
|
{
|
|
icon: <CopyIdIcon size={20} data-flx="ui.action-menu.items.guild-menu-data.groups.copy-id-icon" />,
|
|
label: i18n._(COPY_COMMUNITY_ID_DESCRIPTOR),
|
|
onClick: handlers.handleCopyGuildId,
|
|
},
|
|
];
|
|
menuGroups.push({items: utilityItems});
|
|
return menuGroups;
|
|
}, [
|
|
hasGuildUnread,
|
|
canInvite,
|
|
canAccessGuildSettings,
|
|
canManageChannels,
|
|
canEditCommunityProfile,
|
|
availableSettingsTabs,
|
|
guild.id,
|
|
isMuted,
|
|
hideMutedChannels,
|
|
hasCurrentGuildMatureContentGate,
|
|
isOwner,
|
|
developerMode,
|
|
handlers,
|
|
onClose,
|
|
onOpenMuteSheet,
|
|
i18n.locale,
|
|
]);
|
|
return {
|
|
groups,
|
|
handlers,
|
|
permissions,
|
|
isMuted,
|
|
mutedText: mutedText ?? null,
|
|
hideMutedChannels,
|
|
};
|
|
}
|