import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { getSettings } from 'soapbox/actions/settings'; import DropdownMenu from 'soapbox/containers/dropdown_menu_container'; import ComposeButton from 'soapbox/features/ui/components/compose-button'; import { useAppSelector, useOwnAccount } from 'soapbox/hooks'; import { getFeatures } from 'soapbox/utils/features'; import SidebarNavigationLink from './sidebar-navigation-link'; import type { Menu } from 'soapbox/components/dropdown-menu'; const messages = defineMessages({ follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, bookmarks: { id: 'column.bookmarks', defaultMessage: 'Bookmarks' }, lists: { id: 'column.lists', defaultMessage: 'Lists' }, developers: { id: 'navigation.developers', defaultMessage: 'Developers' }, dashboard: { id: 'tabs_bar.dashboard', defaultMessage: 'Dashboard' }, all: { id: 'tabs_bar.all', defaultMessage: 'All' }, fediverse: { id: 'tabs_bar.fediverse', defaultMessage: 'Fediverse' }, }); /** Desktop sidebar with links to different views in the app. */ const SidebarNavigation = () => { const intl = useIntl(); const instance = useAppSelector((state) => state.instance); const settings = useAppSelector((state) => getSettings(state)); const account = useOwnAccount(); const notificationCount = useAppSelector((state) => state.notifications.unread); const chatsCount = useAppSelector((state) => state.chats.items.reduce((acc, curr) => acc + Math.min(curr.unread || 0, 1), 0)); const followRequestsCount = useAppSelector((state) => state.user_lists.follow_requests.items.count()); const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count()); const features = getFeatures(instance); const makeMenu = (): Menu => { const menu: Menu = []; if (account) { if (account.locked || followRequestsCount > 0) { menu.push({ to: '/follow_requests', text: intl.formatMessage(messages.follow_requests), icon: require('@tabler/icons/user-plus.svg'), count: followRequestsCount, }); } if (features.bookmarks) { menu.push({ to: '/bookmarks', text: intl.formatMessage(messages.bookmarks), icon: require('@tabler/icons/bookmark.svg'), }); } if (features.lists) { menu.push({ to: '/lists', text: intl.formatMessage(messages.lists), icon: require('@tabler/icons/list.svg'), }); } if (settings.get('isDeveloper')) { menu.push({ to: '/developers', icon: require('@tabler/icons/code.svg'), text: intl.formatMessage(messages.developers), }); } if (account.staff) { menu.push({ to: '/soapbox/admin', icon: require('@tabler/icons/dashboard.svg'), text: intl.formatMessage(messages.dashboard), count: dashboardCount, }); } if (features.publicTimeline) { menu.push(null); } } if (features.publicTimeline) { menu.push({ to: '/timeline/local', icon: features.federating ? require('@tabler/icons/users.svg') : require('@tabler/icons/world.svg'), text: features.federating ? instance.title : intl.formatMessage(messages.all), }); } if (features.publicTimeline && features.federating) { menu.push({ to: '/timeline/fediverse', icon: require('assets/icons/fediverse.svg'), text: intl.formatMessage(messages.fediverse), }); } return menu; }; const menu = makeMenu(); /** Conditionally render the supported messages link */ const renderMessagesLink = (): React.ReactNode => { if (features.chats) { return ( } /> ); } if (features.directTimeline || features.conversations) { return ( } /> ); } return null; }; return (
} /> } /> {account && ( <> } /> {renderMessagesLink()} } /> } /> )} {menu.length > 0 && ( } /> )}
{account && ( )}
); }; export default SidebarNavigation;