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:
David Baker 2022-05-12 12:16:48 +01:00 committed by GitHub
commit 9fbe4278c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 20 deletions

View file

@ -43,23 +43,50 @@ export const PTTButton: React.FC<Props> = ({
stopTalking,
}) => {
const [isHeld, setHeld] = useState(false);
const onDocumentMouseUp = useCallback(() => {
const onWindowMouseUp = useCallback(
(e) => {
if (isHeld) stopTalking();
setHeld(false);
}, [isHeld, setHeld, stopTalking]);
},
[isHeld, setHeld, stopTalking]
);
const onButtonMouseDown = useCallback(() => {
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]);
},
[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

View file

@ -10,6 +10,12 @@
width: 100%;
}
@media (hover: none) {
.pttCallView {
user-select: none;
}
}
.center {
width: 100%;
display: flex;

View file

@ -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