/* * 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 {useLingui} from '@lingui/react/macro'; import {ArrowSquareOutIcon, ArrowsOutCardinalIcon, PencilSimpleIcon, StarIcon, TrashIcon} from '@phosphor-icons/react'; import {observer} from 'mobx-react-lite'; import type React from 'react'; import * as ModalActionCreators from '~/actions/ModalActionCreators'; import {modal} from '~/actions/ModalActionCreators'; import * as ToastActionCreators from '~/actions/ToastActionCreators'; import {Permissions} from '~/Constants'; import {RenameChannelModal} from '~/components/modals/RenameChannelModal'; import {Routes} from '~/Routes'; import type {ChannelRecord} from '~/records/ChannelRecord'; import type {GuildRecord} from '~/records/GuildRecord'; import FavoritesStore, {type FavoriteChannel} from '~/stores/FavoritesStore'; import PermissionStore from '~/stores/PermissionStore'; import * as RouterUtils from '~/utils/RouterUtils'; import { ChannelNotificationSettingsMenuItem, EditChannelMenuItem, InvitePeopleToChannelMenuItem, MarkChannelAsReadMenuItem, MuteChannelMenuItem, } from './items/ChannelMenuItems'; import {MenuGroup} from './MenuGroup'; import {MenuItem} from './MenuItem'; import {MenuItemSubmenu} from './MenuItemSubmenu'; interface FavoritesChannelContextMenuProps { favoriteChannel: FavoriteChannel; channel: ChannelRecord | null; guild: GuildRecord | null; onClose: () => void; } export const FavoritesChannelContextMenu: React.FC = observer( ({favoriteChannel, channel, guild: _guild, onClose}) => { const {t} = useLingui(); const handleSetNickname = () => { onClose(); ModalActionCreators.push( modal(() => ( { FavoritesStore.setChannelNickname(favoriteChannel.channelId, nickname || null); }} /> )), ); }; const handleRemoveFromFavorites = () => { FavoritesStore.removeChannel(favoriteChannel.channelId); ToastActionCreators.createToast({type: 'success', children: t`Channel removed from favorites`}); onClose(); }; const handleMoveTo = (categoryId: string | null) => { const currentChannel = FavoritesStore.getChannel(favoriteChannel.channelId); if (!currentChannel) return; const channelsInTarget = FavoritesStore.getChannelsInCategory(categoryId); const newPosition = channelsInTarget.length; FavoritesStore.moveChannel(favoriteChannel.channelId, categoryId, newPosition); onClose(); }; const handleOpenInGuild = () => { if (!channel?.guildId) return; RouterUtils.transitionTo(Routes.guildChannel(channel.guildId, channel.id)); onClose(); }; if (!channel) { return ( } onClick={handleRemoveFromFavorites} danger> {t`Remove from Favorites`} ); } const canManageChannel = channel.guildId && PermissionStore.can(Permissions.MANAGE_CHANNELS, {channelId: channel.id, guildId: channel.guildId}); return ( <> {channel.guildId && ( )} } onClick={handleSetNickname}> {t`Change Nickname`} {channel.guildId && ( } onClick={handleOpenInGuild}> {t`Open in Community`} )} {(favoriteChannel.parentId !== null || FavoritesStore.sortedCategories.some((category) => category.id !== favoriteChannel.parentId)) && ( } render={() => ( {favoriteChannel.parentId !== null && ( handleMoveTo(null)}>{t`Uncategorized`} )} {FavoritesStore.sortedCategories .filter((category) => category.id !== favoriteChannel.parentId) .map((category) => ( handleMoveTo(category.id)}> {category.name} ))} )} /> )} {channel.guildId && ( )} {canManageChannel && ( )} } onClick={handleRemoveFromFavorites} danger> {t`Remove from Favorites`} ); }, );