import './nav-menu.css'; import { ControlledMenu, MenuDivider, MenuItem } from '@szhsin/react-menu'; import { memo } from 'preact/compat'; import { useEffect, useMemo, useRef, useState } from 'preact/hooks'; import { useLongPress } from 'use-long-press'; import { useSnapshot } from 'valtio'; import { api } from '../utils/api'; import { getLists } from '../utils/lists'; import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding'; import states from '../utils/states'; import store from '../utils/store'; import Avatar from './avatar'; import Icon from './icon'; import MenuLink from './menu-link'; import SubMenu2 from './submenu2'; function NavMenu(props) { const snapStates = useSnapshot(states); const { masto, instance, authenticated } = api(); const [currentAccount, moreThanOneAccount] = useMemo(() => { const accounts = store.local.getJSON('accounts') || []; const acc = accounts.find( (account) => account.info.id === store.session.get('currentAccount'), ) || accounts[0]; return [acc, accounts.length > 1]; }, []); // Home = Following // But when in multi-column mode, Home becomes columns of anything // User may choose pin or not to pin Following // If user doesn't pin Following, we show it in the menu const showFollowing = (snapStates.settings.shortcutsViewMode === 'multi-column' || (!snapStates.settings.shortcutsViewMode && snapStates.settings.shortcutsColumnsMode)) && !snapStates.shortcuts.find((pin) => pin.type === 'following'); const bindLongPress = useLongPress( () => { states.showAccounts = true; }, { threshold: 600, detect: 'touch', cancelOnMovement: true, }, ); const buttonRef = useRef(); const [menuState, setMenuState] = useState(undefined); const boundingBoxPadding = safeBoundingBoxPadding([ 0, 0, snapStates.settings.shortcutsViewMode === 'tab-menu-bar' ? 50 : 0, 0, ]); const mutesIterator = useRef(); async function fetchMutes(firstLoad) { if (firstLoad || !mutesIterator.current) { mutesIterator.current = masto.v1.mutes.list({ limit: 80, }); } const results = await mutesIterator.current.next(); return results; } const blocksIterator = useRef(); async function fetchBlocks(firstLoad) { if (firstLoad || !blocksIterator.current) { blocksIterator.current = masto.v1.blocks.list({ limit: 80, }); } const results = await blocksIterator.current.next(); return results; } const [lists, setLists] = useState([]); useEffect(() => { if (menuState === 'open') { getLists().then(setLists); } }, [menuState === 'open']); const buttonClickTS = useRef(); return ( <> { setMenuState(undefined); }} containerProps={{ style: { zIndex: 10, }, onClick: () => { if (Date.now() - buttonClickTS.current < 300) { return; } // setMenuState(undefined); }, }} portal={{ target: document.body, }} {...props} overflow="auto" viewScroll="close" position="anchor" align="center" boundingBoxPadding={boundingBoxPadding} unmountOnClose > {!!snapStates.appVersion?.commitHash && __COMMIT_HASH__ !== snapStates.appVersion.commitHash && (
{ const yes = confirm('Reload page now to update?'); if (yes) { (async () => { try { location.reload(); } catch (e) {} })(); } }} > {' '} New update availableā€¦
)}
Home {authenticated ? ( <> {showFollowing && ( Following )} Catch-up Mentions Notifications {snapStates.notificationsShowNew && ( {' '} • )} {currentAccount?.info?.id && ( Profile )} {lists?.length > 0 ? ( Lists } > All Lists {lists?.length > 0 && ( <> {lists.map((list) => ( {list.title} ))} )} ) : ( Lists )} Bookmarks Moreā€¦ } > Likes {' '} Followed Hashtags Filters { states.showGenericAccounts = { id: 'mute', heading: 'Muted users', fetchAccounts: fetchMutes, excludeRelationshipAttrs: ['muting'], }; }} > Muted users… { states.showGenericAccounts = { id: 'block', heading: 'Blocked users', fetchAccounts: fetchBlocks, excludeRelationshipAttrs: ['blocking'], }; }} > Blocked users… {' '} { states.showAccounts = true; }} > Accounts… ) : ( <> Log in )}
Search Trending Local Federated {authenticated ? ( <> { states.showKeyboardShortcutsHelp = true; }} > {' '} Keyboard shortcuts { states.showShortcutsSettings = true; }} > {' '} Shortcuts / Columns… { states.showSettings = true; }} > Settings… ) : ( <> { states.showSettings = true; }} > Settings… )}
); } export default memo(NavMenu);