/* * 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 {observer} from 'mobx-react-lite'; import React from 'react'; import * as ModalActionCreators from '~/actions/ModalActionCreators'; import {ChannelTypes} from '~/Constants'; import * as Modal from '~/components/modals/Modal'; import ChannelStore from '~/stores/ChannelStore'; import ConnectionStore from '~/stores/gateway/ConnectionStore'; import MobileLayoutStore from '~/stores/MobileLayoutStore'; import {isMobileExperienceEnabled} from '~/utils/mobileExperience'; import { type ChannelSettingsModalProps, createHandleClose, getAvailableTabs, getGroupedSettingsTabs, } from '~/utils/modals/ChannelSettingsModalUtils'; import {DesktopChannelSettingsView} from './components/DesktopChannelSettingsView'; import {MobileChannelSettingsView} from './components/MobileChannelSettingsView'; import {useMobileNavigation} from './hooks/useMobileNavigation'; import {SettingsModalContainer} from './shared/SettingsModalLayout'; import type {ChannelSettingsTabType} from './utils/channelSettingsConstants'; export const ChannelSettingsModal: React.FC = observer(({channelId, initialMobileTab}) => { const {t} = useLingui(); const channel = ChannelStore.getChannel(channelId); const guildId = channel?.guildId; const [selectedTab, setSelectedTab] = React.useState('overview'); const availableTabs = React.useMemo(() => { return getAvailableTabs(t, channelId); }, [t, channelId]); const isMobileExperience = isMobileExperienceEnabled(); const initialTab = React.useMemo(() => { if (!isMobileExperience || !initialMobileTab) return; const targetTab = availableTabs.find((tab) => tab.type === initialMobileTab); if (!targetTab) return; return {tab: initialMobileTab, title: targetTab.label}; }, [initialMobileTab, availableTabs, isMobileExperience]); const mobileNav = useMobileNavigation(initialTab); const {enabled: isMobile} = MobileLayoutStore; React.useEffect(() => { if (guildId) { ConnectionStore.syncGuildIfNeeded(guildId, 'channel-settings-modal'); } }, [guildId]); React.useEffect(() => { if (!channel) { ModalActionCreators.pop(); } }, [channel]); const groupedSettingsTabs = React.useMemo(() => { return getGroupedSettingsTabs(availableTabs); }, [availableTabs]); const currentTab = React.useMemo(() => { if (!isMobile) { return availableTabs.find((tab) => tab.type === selectedTab); } if (mobileNav.isRootView) return; return availableTabs.find((tab) => tab.type === mobileNav.currentView?.tab); }, [isMobile, selectedTab, mobileNav.isRootView, mobileNav.currentView, availableTabs]); const handleMobileBack = React.useCallback(() => { if (mobileNav.isRootView) { ModalActionCreators.pop(); } else { mobileNav.navigateBack(); } }, [mobileNav]); const handleTabSelect = React.useCallback( (tabType: string, title: string) => { mobileNav.navigateTo(tabType as ChannelSettingsTabType, title); }, [mobileNav], ); const handleClose = React.useCallback(createHandleClose(selectedTab), [selectedTab]); if (!channel) { return null; } const isCategory = channel.type === ChannelTypes.GUILD_CATEGORY; return ( {isMobile ? ( ) : ( )} ); });