flow icon indicating copy to clipboard operation
flow copied to clipboard

Mobile highlight text

Open sonht1109 opened this issue 1 year ago • 10 comments

Im using iPhone 13 with chrome but seem like i cannot select long text. It only can select one word. If I extends the selected word by dragging the blue stick, it will spread to the end of chapter (i mean, it will select the whole range from selected word to the end of chapter)

IMAGE 2024-06-29 18:21:25

Device: iPhone 13 Browser: chrome ver 120.0.6099.119

sonht1109 avatar Jun 29 '24 11:06 sonht1109

is any updates on this :((

sonht1109 avatar Jul 27 '24 11:07 sonht1109

is any updates on this :((

Hi, did you get the problem solved?

Nsenixx avatar Sep 19 '24 11:09 Nsenixx

Not yet sir

sonht1109 avatar Sep 19 '24 11:09 sonht1109

any ideas ?

Nsenixx avatar Sep 19 '24 11:09 Nsenixx

I have temp fix but only work on ios, not android. Also it's not totally working as expected so i think there's no ways

sonht1109 avatar Sep 19 '24 11:09 sonht1109

What was the temporary fix related to?

Nsenixx avatar Sep 19 '24 11:09 Nsenixx

@Nsenixx related to "touch" event. u can refer my code in red block (the old one is commented) image

and it only works if you PRESS LONG PRESS and then DRAG. the context menu will show as expected

it wont work if u select one word and then drag.

just try it yourself. Hope this help. and i heard that it didnt work on android (i dont have android device to test)

sonht1109 avatar Sep 19 '24 11:09 sonht1109

thx a lot! I'll be researching this

Nsenixx avatar Sep 19 '24 11:09 Nsenixx

Bro, try this, I have the highlighting working now on android and ios

import { useEventListener } from '@literal-ui/hooks';
import { useState } from 'react';

import { isTouchScreen } from '../platform';

import { useForceRender } from './useForceRender';

export function hasSelection(
  selection?: Selection | null,
): selection is Selection {
  return !(!selection || selection.isCollapsed);
}

// https://htmldom.dev/get-the-direction-of-the-text-selection/
export function isForwardSelection(selection: Selection) {
  if (selection.anchorNode && selection.focusNode) {
    const range = document.createRange();
    range.setStart(selection.anchorNode, selection.anchorOffset);
    range.setEnd(selection.focusNode, selection.focusOffset);

    return !range.collapsed;
  }

  return true;
}

export function useTextSelection(win?: Window) {
  const [selection, setSelection] = useState<Selection | undefined>();
  const render = useForceRender();

  const isAndroid = navigator.userAgent.toLowerCase().indexOf('android') > -1;

  useEventListener(
    isTouchScreen ? win?.document : win,
    isTouchScreen
      ? isAndroid
        ? 'selectionchange'
        : 'touchend'
      : 'mouseup',
    () => {
      const s = win?.getSelection();

      if (hasSelection(s)) {
        render();
        setSelection(s);
      }
    },
  );

  // https://stackoverflow.com/questions/3413683/disabling-the-context-menu-on-long-taps-on-android
  useEventListener(win, 'contextmenu', (e) => {
    if (isTouchScreen) {
      e.preventDefault();
    }
  });

  return [selection, setSelection] as const;
}

Nsenixx avatar Sep 19 '24 15:09 Nsenixx

I hope this is helpful to you! And thanks for your ideas and help! <3

Nsenixx avatar Sep 19 '24 15:09 Nsenixx