feat: global long-press context menus for all mobile touch targets

Add useGlobalLongPress to ContextMenuRenderer that detects 500ms hold
with <10px movement and dispatches a synthetic contextmenu event on the
touched element. All existing onContextMenu handlers (spaces, channels,
voice users, messages, etc.) now work on touch devices automatically.

Remove per-message useLongPress integration from Message.tsx since the
global handler covers it.
This commit is contained in:
Jannis Braun
2026-03-23 15:12:58 +01:00
parent 05a4b23d88
commit ce33d8f7ea
2 changed files with 93 additions and 32 deletions
+1 -32
View File
@@ -16,7 +16,6 @@ import { Username } from '../ui/Username';
import { EmojiPicker } from './EmojiPicker';
import { hasPermissionBit, PermissionBits } from '../../utils/permissions';
import { isSelf, resolveDisplayIdentity } from '../../utils/identity';
import { useLongPress } from '../../hooks/useLongPress';
interface MessageProps {
message: MessageWithUser;
@@ -202,36 +201,6 @@ export function Message({ message, isCompact, isFirstInGroup, previousMessageId
useContextMenuStore.getState().open({ x: e.clientX, y: e.clientY }, items);
};
const isMobile = useUIStore((s) => s.isMobile);
const longPressHandlers = useLongPress((position) => {
const selectedText = window.getSelection()?.toString() ?? '';
const items = buildMessageMenuItems({
message,
selectedText,
previousMessageId,
isAuthor,
isDm: isDmMessage,
canAddReactions,
canSendMessages,
canManageMessages,
onReply: () => setReplyTo(message),
onEdit: () => {
setEditContent(message.content ?? '');
setIsEditing(true);
},
onDelete: () => deleteMessage(message.id, channelKey),
onReaction: (emoji: string) => toggleReaction(emoji),
onOpenEmojiPicker: () => {
useContextMenuStore.getState().close();
setShowReactionPicker(true);
},
onMarkUnread: (msgId: string) => markUnread(channelKey, msgId),
});
if (items.length === 0) return;
useContextMenuStore.getState().open({ x: position.clientX, y: position.clientY }, items);
});
const handleEditSubmit = async (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
@@ -555,7 +524,7 @@ export function Message({ message, isCompact, isFirstInGroup, previousMessageId
);
return (
<div onContextMenu={handleContextMenu} {...(isMobile ? longPressHandlers : {})}>
<div onContextMenu={handleContextMenu}>
{content}
</div>
);