Attempt to fix nav menu not closable when click outside

This commit is contained in:
Lim Chee Aun 2023-04-26 13:23:54 +08:00
parent 211e4ff74d
commit 960ce07501

View file

@ -1,4 +1,11 @@
import { Menu, MenuDivider, MenuItem } from '@szhsin/react-menu'; import {
ControlledMenu,
MenuDivider,
MenuItem,
useClick,
useMenuState,
} from '@szhsin/react-menu';
import { useRef } from 'preact/hooks';
import { useLongPress } from 'use-long-press'; import { useLongPress } from 'use-long-press';
import { useSnapshot } from 'valtio'; import { useSnapshot } from 'valtio';
@ -39,147 +46,162 @@ function NavMenu(props) {
}, },
); );
const buttonRef = useRef();
const [menuState, toggleMenu] = useMenuState();
const anchorProps = useClick(menuState.state, toggleMenu);
return ( return (
<Menu <>
portal={{ <button
target: document.body, ref={buttonRef}
}} type="button"
{...props} class={`button plain nav-menu-button ${
overflow="auto" moreThanOneAccount ? 'with-avatar' : ''
viewScroll="close" } ${open ? 'active' : ''}`}
boundingBoxPadding="8 8 8 8" style={{ position: 'relative' }}
unmountOnClose {...anchorProps}
menuButton={({ open }) => ( onContextMenu={(e) => {
<button e.preventDefault();
type="button" states.showAccounts = true;
class={`button plain nav-menu-button ${ }}
moreThanOneAccount ? 'with-avatar' : '' {...bindLongPress()}
} ${open ? 'active' : ''}`} >
style={{ position: 'relative' }} {moreThanOneAccount && (
onContextMenu={(e) => { <Avatar
e.preventDefault(); url={
states.showAccounts = true; currentAccount?.info?.avatar || currentAccount?.info?.avatarStatic
}} }
{...bindLongPress()} size="l"
> squircle={currentAccount?.info?.bot}
{moreThanOneAccount && ( />
<Avatar )}
url={ <Icon icon="menu" size={moreThanOneAccount ? 's' : 'l'} />
currentAccount?.info?.avatar || </button>
currentAccount?.info?.avatarStatic <ControlledMenu
} {...menuState}
size="l" anchorRef={buttonRef}
squircle={currentAccount?.info?.bot} onClose={() => {
/> toggleMenu(false);
}}
containerProps={{
onClick: () => {
toggleMenu(false);
},
}}
portal={{
target: document.body,
}}
{...props}
overflow="auto"
viewScroll="close"
boundingBoxPadding="8 8 8 8"
unmountOnClose
>
{!!snapStates.appVersion?.commitHash &&
__COMMIT_HASH__ !== snapStates.appVersion.commitHash && (
<>
<MenuItem
onClick={() => {
const yes = confirm('Reload page now to update?');
if (yes) {
(async () => {
try {
location.reload();
} catch (e) {}
})();
}
}}
>
<Icon icon="sparkles" size="l" />{' '}
<span>New update available</span>
</MenuItem>
<MenuDivider />
</>
)} )}
<Icon icon="menu" size={moreThanOneAccount ? 's' : 'l'} /> <MenuLink to="/">
</button> <Icon icon="home" size="l" /> <span>Home</span>
)} </MenuLink>
> {authenticated && (
{!!snapStates.appVersion?.commitHash &&
__COMMIT_HASH__ !== snapStates.appVersion.commitHash && (
<> <>
<MenuItem {showFollowing && (
onClick={() => { <MenuLink to="/following">
const yes = confirm('Reload page now to update?'); <Icon icon="following" size="l" /> <span>Following</span>
if (yes) { </MenuLink>
(async () => { )}
try { <MenuLink to="/mentions">
location.reload(); <Icon icon="at" size="l" /> <span>Mentions</span>
} catch (e) {} </MenuLink>
})(); <MenuLink to="/notifications">
} <Icon icon="notification" size="l" /> <span>Notifications</span>
}} {snapStates.notificationsShowNew && (
> <sup title="New" style={{ opacity: 0.5 }}>
<Icon icon="sparkles" size="l" />{' '} {' '}
<span>New update available</span> &bull;
</MenuItem> </sup>
)}
</MenuLink>
<MenuDivider /> <MenuDivider />
<MenuLink to="/l">
<Icon icon="list" size="l" /> <span>Lists</span>
</MenuLink>
<MenuLink to="/ft">
<Icon icon="hashtag" size="l" /> <span>Followed Hashtags</span>
</MenuLink>
<MenuLink to="/b">
<Icon icon="bookmark" size="l" /> <span>Bookmarks</span>
</MenuLink>
<MenuLink to="/f">
<Icon icon="heart" size="l" /> <span>Favourites</span>
</MenuLink>
</> </>
)} )}
<MenuLink to="/"> <MenuDivider />
<Icon icon="home" size="l" /> <span>Home</span> <MenuLink to={`/search`}>
</MenuLink> <Icon icon="search" size="l" /> <span>Search</span>
{authenticated && ( </MenuLink>
<> <MenuLink to={`/${instance}/p/l`}>
{showFollowing && ( <Icon icon="group" size="l" /> <span>Local</span>
<MenuLink to="/following"> </MenuLink>
<Icon icon="following" size="l" /> <span>Following</span> <MenuLink to={`/${instance}/p`}>
</MenuLink> <Icon icon="earth" size="l" /> <span>Federated</span>
)} </MenuLink>
<MenuLink to="/mentions"> <MenuLink to={`/${instance}/trending`}>
<Icon icon="at" size="l" /> <span>Mentions</span> <Icon icon="chart" size="l" /> <span>Trending</span>
</MenuLink> </MenuLink>
<MenuLink to="/notifications"> {authenticated && (
<Icon icon="notification" size="l" /> <span>Notifications</span> <>
{snapStates.notificationsShowNew && ( <MenuDivider />
<sup title="New" style={{ opacity: 0.5 }}> {currentAccount?.info?.id && (
{' '} <MenuLink to={`/${instance}/a/${currentAccount.info.id}`}>
&bull; <Icon icon="user" size="l" /> <span>Profile</span>
</sup> </MenuLink>
)} )}
</MenuLink> <MenuItem
<MenuDivider /> onClick={() => {
<MenuLink to="/l"> states.showAccounts = true;
<Icon icon="list" size="l" /> <span>Lists</span> }}
</MenuLink> >
<MenuLink to="/ft"> <Icon icon="group" size="l" /> <span>Accounts&hellip;</span>
<Icon icon="hashtag" size="l" /> <span>Followed Hashtags</span> </MenuItem>
</MenuLink> <MenuItem
<MenuLink to="/b"> onClick={() => {
<Icon icon="bookmark" size="l" /> <span>Bookmarks</span> states.showShortcutsSettings = true;
</MenuLink> }}
<MenuLink to="/f"> >
<Icon icon="heart" size="l" /> <span>Favourites</span> <Icon icon="shortcut" size="l" />{' '}
</MenuLink> <span>Shortcuts Settings&hellip;</span>
</> </MenuItem>
)} <MenuItem
<MenuDivider /> onClick={() => {
<MenuLink to={`/search`}> states.showSettings = true;
<Icon icon="search" size="l" /> <span>Search</span> }}
</MenuLink> >
<MenuLink to={`/${instance}/p/l`}> <Icon icon="gear" size="l" /> <span>Settings&hellip;</span>
<Icon icon="group" size="l" /> <span>Local</span> </MenuItem>
</MenuLink> </>
<MenuLink to={`/${instance}/p`}> )}
<Icon icon="earth" size="l" /> <span>Federated</span> </ControlledMenu>
</MenuLink> </>
<MenuLink to={`/${instance}/trending`}>
<Icon icon="chart" size="l" /> <span>Trending</span>
</MenuLink>
{authenticated && (
<>
<MenuDivider />
{currentAccount?.info?.id && (
<MenuLink to={`/${instance}/a/${currentAccount.info.id}`}>
<Icon icon="user" size="l" /> <span>Profile</span>
</MenuLink>
)}
<MenuItem
onClick={() => {
states.showAccounts = true;
}}
>
<Icon icon="group" size="l" /> <span>Accounts&hellip;</span>
</MenuItem>
<MenuItem
onClick={() => {
states.showShortcutsSettings = true;
}}
>
<Icon icon="shortcut" size="l" />{' '}
<span>Shortcuts Settings&hellip;</span>
</MenuItem>
<MenuItem
onClick={() => {
states.showSettings = true;
}}
>
<Icon icon="gear" size="l" /> <span>Settings&hellip;</span>
</MenuItem>
</>
)}
</Menu>
); );
} }