Merge pull request #321 from vector-im/dbkr/ptt_mobile_touch_prompt
Fix hold-to-speak and prompt text on mobile
This commit is contained in:
		
				commit
				
					
						9fbe4278c2
					
				
			
		
					 3 changed files with 90 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -43,23 +43,50 @@ export const PTTButton: React.FC<Props> = ({
 | 
			
		|||
  stopTalking,
 | 
			
		||||
}) => {
 | 
			
		||||
  const [isHeld, setHeld] = useState(false);
 | 
			
		||||
  const onDocumentMouseUp = useCallback(() => {
 | 
			
		||||
    if (isHeld) stopTalking();
 | 
			
		||||
    setHeld(false);
 | 
			
		||||
  }, [isHeld, setHeld, stopTalking]);
 | 
			
		||||
  const onWindowMouseUp = useCallback(
 | 
			
		||||
    (e) => {
 | 
			
		||||
      if (isHeld) stopTalking();
 | 
			
		||||
      setHeld(false);
 | 
			
		||||
    },
 | 
			
		||||
    [isHeld, setHeld, stopTalking]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const onButtonMouseDown = useCallback(() => {
 | 
			
		||||
    setHeld(true);
 | 
			
		||||
    startTalking();
 | 
			
		||||
  }, [setHeld, startTalking]);
 | 
			
		||||
  const onWindowTouchEnd = useCallback(
 | 
			
		||||
    (e: TouchEvent) => {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      if (isHeld) stopTalking();
 | 
			
		||||
      setHeld(false);
 | 
			
		||||
    },
 | 
			
		||||
    [isHeld, setHeld, stopTalking]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const onButtonMouseDown = useCallback(
 | 
			
		||||
    (e: React.MouseEvent<HTMLButtonElement>) => {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      setHeld(true);
 | 
			
		||||
      startTalking();
 | 
			
		||||
    },
 | 
			
		||||
    [setHeld, startTalking]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const onButtonTouchStart = useCallback(
 | 
			
		||||
    (e: React.TouchEvent<HTMLButtonElement>) => {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      setHeld(true);
 | 
			
		||||
      startTalking();
 | 
			
		||||
    },
 | 
			
		||||
    [setHeld, startTalking]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    window.addEventListener("mouseup", onDocumentMouseUp);
 | 
			
		||||
    window.addEventListener("mouseup", onWindowMouseUp);
 | 
			
		||||
    window.addEventListener("touchend", onWindowTouchEnd);
 | 
			
		||||
 | 
			
		||||
    return () => {
 | 
			
		||||
      window.removeEventListener("mouseup", onDocumentMouseUp);
 | 
			
		||||
      window.removeEventListener("mouseup", onWindowMouseUp);
 | 
			
		||||
      window.removeEventListener("touchend", onWindowTouchEnd);
 | 
			
		||||
    };
 | 
			
		||||
  }, [onDocumentMouseUp]);
 | 
			
		||||
  }, [onWindowMouseUp, onWindowTouchEnd]);
 | 
			
		||||
  return (
 | 
			
		||||
    <button
 | 
			
		||||
      className={classNames(styles.pttButton, {
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +94,7 @@ export const PTTButton: React.FC<Props> = ({
 | 
			
		|||
        [styles.error]: showTalkOverError,
 | 
			
		||||
      })}
 | 
			
		||||
      onMouseDown={onButtonMouseDown}
 | 
			
		||||
      onTouchStart={onButtonTouchStart}
 | 
			
		||||
    >
 | 
			
		||||
      {activeSpeakerIsLocalUser || !activeSpeakerUserId ? (
 | 
			
		||||
        <MicIcon
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,12 @@
 | 
			
		|||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (hover: none) {
 | 
			
		||||
  .pttCallView {
 | 
			
		||||
    user-select: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.center {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  display: flex;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,43 @@ import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
 | 
			
		|||
import { usePTTSounds } from "../sound/usePttSounds";
 | 
			
		||||
import { PTTClips } from "../sound/PTTClips";
 | 
			
		||||
 | 
			
		||||
function getPromptText(
 | 
			
		||||
  showTalkOverError: boolean,
 | 
			
		||||
  pttButtonHeld: boolean,
 | 
			
		||||
  activeSpeakerIsLocalUser: boolean,
 | 
			
		||||
  talkOverEnabled: boolean,
 | 
			
		||||
  activeSpeakerUserId: string,
 | 
			
		||||
  activeSpeakerDisplayName: string
 | 
			
		||||
): string {
 | 
			
		||||
  const isTouchScreen = Boolean(window.ontouchstart !== undefined);
 | 
			
		||||
 | 
			
		||||
  if (showTalkOverError) {
 | 
			
		||||
    return "You can't talk at the same time";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (pttButtonHeld && activeSpeakerIsLocalUser) {
 | 
			
		||||
    if (isTouchScreen) {
 | 
			
		||||
      return "Release to stop";
 | 
			
		||||
    } else {
 | 
			
		||||
      return "Release spacebar key to stop";
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (talkOverEnabled && activeSpeakerUserId && !activeSpeakerIsLocalUser) {
 | 
			
		||||
    if (isTouchScreen) {
 | 
			
		||||
      return `Press and hold to talk over ${activeSpeakerDisplayName}`;
 | 
			
		||||
    } else {
 | 
			
		||||
      return `Press and hold spacebar to talk over ${activeSpeakerDisplayName}`;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (isTouchScreen) {
 | 
			
		||||
    return "Press and hold to talk";
 | 
			
		||||
  } else {
 | 
			
		||||
    return "Press and hold spacebar to talk";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  client: MatrixClient;
 | 
			
		||||
  roomId: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -163,15 +200,14 @@ export const PTTCallView: React.FC<Props> = ({
 | 
			
		|||
            stopTalking={stopTalking}
 | 
			
		||||
          />
 | 
			
		||||
          <p className={styles.actionTip}>
 | 
			
		||||
            {showTalkOverError
 | 
			
		||||
              ? "You can't talk at the same time"
 | 
			
		||||
              : pttButtonHeld && activeSpeakerIsLocalUser
 | 
			
		||||
              ? "Release spacebar key to stop"
 | 
			
		||||
              : talkOverEnabled &&
 | 
			
		||||
                activeSpeakerUserId &&
 | 
			
		||||
                !activeSpeakerIsLocalUser
 | 
			
		||||
              ? `Press and hold spacebar to talk over ${activeSpeakerDisplayName}`
 | 
			
		||||
              : "Press and hold spacebar to talk"}
 | 
			
		||||
            {getPromptText(
 | 
			
		||||
              showTalkOverError,
 | 
			
		||||
              pttButtonHeld,
 | 
			
		||||
              activeSpeakerIsLocalUser,
 | 
			
		||||
              talkOverEnabled,
 | 
			
		||||
              activeSpeakerUserId,
 | 
			
		||||
              activeSpeakerDisplayName
 | 
			
		||||
            )}
 | 
			
		||||
          </p>
 | 
			
		||||
          {userMediaFeeds.map((callFeed) => (
 | 
			
		||||
            <PTTFeed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue