Experimental right-click/long-press on compose button

This commit is contained in:
Lim Chee Aun 2025-03-03 17:56:35 +08:00
parent fb2c7d5ef7
commit 8ada3cebf8
2 changed files with 72 additions and 18 deletions
src
components
locales

View file

@ -1,17 +1,27 @@
import { useLingui } from '@lingui/react/macro';
import { Trans, useLingui } from '@lingui/react/macro';
import { ControlledMenu } from '@szhsin/react-menu';
import { useRef, useState } from 'preact/hooks';
import { useHotkeys } from 'react-hotkeys-hook';
import { useLongPress } from 'use-long-press';
import { useSnapshot } from 'valtio';
import openCompose from '../utils/open-compose';
import openOSK from '../utils/open-osk';
import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding';
import states from '../utils/states';
import Icon from './icon';
import MenuLink from './menu-link';
export default function ComposeButton() {
const { t } = useLingui();
const snapStates = useSnapshot(states);
// Context menu state
const [menuOpen, setMenuOpen] = useState(false);
const buttonRef = useRef(null);
const menuRef = useRef(null);
function handleButton(e) {
if (snapStates.composerState.minimized) {
states.composerState.minimized = false;
@ -38,16 +48,59 @@ export default function ComposeButton() {
},
});
// Setup longpress handler to open context menu
const bindLongPress = useLongPress(
() => {
setMenuOpen(true);
},
{
threshold: 600,
},
);
return (
<button
type="button"
id="compose-button"
onClick={handleButton}
class={`${snapStates.composerState.minimized ? 'min' : ''} ${
snapStates.composerState.publishing ? 'loading' : ''
} ${snapStates.composerState.publishingError ? 'error' : ''}`}
>
<Icon icon="quill" size="xl" alt={t`Compose`} />
</button>
<>
<button
ref={buttonRef}
type="button"
id="compose-button"
onClick={handleButton}
onContextMenu={(e) => {
e.preventDefault();
setMenuOpen(true);
}}
{...bindLongPress()}
class={`${snapStates.composerState.minimized ? 'min' : ''} ${
snapStates.composerState.publishing ? 'loading' : ''
} ${snapStates.composerState.publishingError ? 'error' : ''}`}
>
<Icon icon="quill" size="xl" alt={t`Compose`} />
</button>
<ControlledMenu
ref={menuRef}
state={menuOpen ? 'open' : undefined}
anchorRef={buttonRef}
onClose={() => setMenuOpen(false)}
direction="top"
gap={8} // Add gap between menu and button
unmountOnClose
portal={{
target: document.body,
}}
boundingBoxPadding={safeBoundingBoxPadding()}
containerProps={{
style: {
zIndex: 1001,
},
}}
>
<MenuLink to="/sp">
<Icon icon="schedule" size="l" />{' '}
<span>
<Trans>Scheduled Posts</Trans>
</span>
</MenuLink>
</ControlledMenu>
</>
);
}

15
src/locales/en.po generated
View file

@ -565,11 +565,18 @@ msgstr ""
msgid "Home"
msgstr ""
#: src/components/compose-button.jsx:50
#: src/components/compose-button.jsx:77
#: src/compose.jsx:38
msgid "Compose"
msgstr ""
#: src/components/compose-button.jsx:100
#: src/components/nav-menu.jsx:260
#: src/pages/scheduled-posts.jsx:31
#: src/pages/scheduled-posts.jsx:76
msgid "Scheduled Posts"
msgstr "Scheduled Posts"
#: src/components/compose.jsx:211
msgid "Add media"
msgstr "Add media"
@ -1412,12 +1419,6 @@ msgstr ""
msgid "Followed Hashtags"
msgstr ""
#: src/components/nav-menu.jsx:260
#: src/pages/scheduled-posts.jsx:31
#: src/pages/scheduled-posts.jsx:76
msgid "Scheduled Posts"
msgstr "Scheduled Posts"
#: src/components/nav-menu.jsx:268
#: src/pages/account-statuses.jsx:326
#: src/pages/filters.jsx:54