minwork / use-long-press

React hook for detecting click (or tap) and hold event
MIT License
120 stars 12 forks source link

Unpredictable long press detection on Android browsers #34

Closed petertjmills closed 2 years ago

petertjmills commented 2 years ago

Hi, thanks for this library!

I am trying to use it to select images on mobile browsers. However I have run into an issue with the context/right click menu on an android device.

import { useState } from 'react';
import Lightbox from 'react-image-lightbox';
import 'react-image-lightbox/style.css';
import { useLongPress } from 'use-long-press';

function Gallery({ imageUrls }) {
    const [isOpen, setIsOpen] = useState(false);
    const [photoIndex, setPhotoIndex] = useState(0);

    const openLightbox = (event, {context}) => {
        setIsOpen(true);
        setPhotoIndex(context);
    }

    const bind = useLongPress(() => {
        alert('long press');
    },{
        onCancel: openLightbox
    })

    return (
        <div>
            <div>
                {imageUrls.map((imageUrl, index) => (
                    <div key={index}>

                        <img {...bind(index)} onContextMenu={(e) => e.preventDefault()} src={imageUrl} />

                    </div>
                ))}
            </div>

            <div>
                {isOpen && (
                    <Lightbox 
                         ...
                    />
                )}
            </div>
        </div>
    )
}

export default Gallery;

On desktop long-press works fine, however on the Chrome browser on android (and on desktop using Device Mode), the long press callback only triggers every other time. Before adding onContextMenu={(e) => e.preventDefault()} long press would show the right click menu. On firefox on android, long press is detected every time, but immediately then shows the right click menu. For both of the above, I have tried the solutions outlined in #2, #7, and #24, to no avail. I was briefly able to test on iOS safari, using WebkitUserSelect: 'none', and onContextMenu={(e) => e.preventDefault()}, neither of which worked at all, both showing the right click menu.

Have I made a mistake? Thanks!

minwork commented 2 years ago

Hey, unfortunately different browser handle context menu differently so there isn't one solution to prevent it from showing which is why it is not built-in this library. In my opinion it is better to approach it from CSS side than from React because React onContextMenu may possibly interfere with long press detection. You may try something like -webkit-touch-callout: none! important; or other CSS solution suggested in other issues but without onContextMenu callback.

github-actions[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.