-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runfix: address keyboard navigation issues in call ui (WPB-6075) #16538
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,7 @@ import {ConversationClassifiedBar} from 'Components/input/ClassifiedBar'; | |
import {isMediaDevice} from 'src/script/guards/MediaDevice'; | ||
import {MediaDeviceType} from 'src/script/media/MediaDeviceType'; | ||
import {useKoSubscribableChildren} from 'Util/ComponentUtil'; | ||
import {isEnterKey, KEY} from 'Util/KeyboardUtil'; | ||
import {handleKeyDown, isEscapeKey} from 'Util/KeyboardUtil'; | ||
import {t} from 'Util/LocalizerUtil'; | ||
import {preventFocusOutside} from 'Util/util'; | ||
|
||
|
@@ -206,7 +206,6 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
setSelectedAudioOptions([microphone, speaker]); | ||
switchMicrophoneInput(microphone.id); | ||
switchSpeakerOutput(speaker.id); | ||
setAudioOptionsOpen(false); | ||
}; | ||
|
||
const videoOptions = [ | ||
|
@@ -239,7 +238,6 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
const camera = videoOptions[0].options.find(item => item.value === selectedOption) ?? selectedVideoOptions[0]; | ||
setSelectedVideoOptions([camera]); | ||
switchCameraInput(camera.id); | ||
setVideoOptionsOpen(false); | ||
}; | ||
|
||
const unreadMessagesCount = useAppState(state => state.unreadMessagesCount); | ||
|
@@ -249,27 +247,14 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
|
||
const totalPages = callPages.length; | ||
|
||
const isSpaceOrEnterKey = (event: React.KeyboardEvent<HTMLButtonElement>) => | ||
[KEY.ENTER, KEY.SPACE].includes(event.key); | ||
|
||
const handleToggleCameraKeydown = (event: React.KeyboardEvent<HTMLButtonElement>) => { | ||
if (isSpaceOrEnterKey(event)) { | ||
toggleCamera(call); | ||
} | ||
|
||
return true; | ||
}; | ||
|
||
Comment on lines
-252
to
-262
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic can be achieved with the |
||
// To be changed when design chooses a breakpoint, the conditional can be integrated to the ui-kit directly | ||
const horizontalSmBreakpoint = useMatchMedia('max-width: 680px'); | ||
const horizontalXsBreakpoint = useMatchMedia('max-width: 500px'); | ||
const verticalBreakpoint = useMatchMedia('max-height: 420px'); | ||
|
||
useEffect(() => { | ||
const onKeyDown = (event: KeyboardEvent): void => { | ||
if (!isEnterKey(event)) { | ||
event.preventDefault(); | ||
} | ||
event.preventDefault(); | ||
Comment on lines
-270
to
+257
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We |
||
preventFocusOutside(event, 'video-calling'); | ||
}; | ||
document.addEventListener('keydown', onKeyDown); | ||
|
@@ -361,6 +346,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
<button | ||
data-uie-name="pagination-next" | ||
onClick={() => changePage(currentPage + 1, call)} | ||
onKeyDown={event => handleKeyDown(event, () => changePage(currentPage + 1, call))} | ||
type="button" | ||
className="button-reset-default" | ||
css={{ | ||
|
@@ -378,6 +364,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
data-uie-name="pagination-previous" | ||
type="button" | ||
onClick={() => changePage(currentPage - 1, call)} | ||
onKeyDown={event => handleKeyDown(event, () => changePage(currentPage - 1, call))} | ||
className="button-reset-default" | ||
css={{ | ||
...paginationButtonStyles, | ||
|
@@ -411,6 +398,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
className="video-controls__button" | ||
css={videoControlInActiveStyles} | ||
onClick={minimize} | ||
onKeyDown={event => handleKeyDown(event, () => minimize())} | ||
type="button" | ||
aria-labelledby="minimize-label" | ||
data-uie-name="do-call-controls-video-minimize" | ||
|
@@ -437,6 +425,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
className="video-controls__button" | ||
data-uie-value={!isMuted ? 'inactive' : 'active'} | ||
onClick={() => toggleMute(call, !isMuted)} | ||
onKeyDown={event => handleKeyDown(event, () => toggleMute(call, !isMuted))} | ||
css={!isMuted ? videoControlActiveStyles : videoControlInActiveStyles} | ||
type="button" | ||
aria-labelledby="mute-label" | ||
|
@@ -455,13 +444,8 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
<button | ||
className="device-toggle-button" | ||
css={audioOptionsOpen ? videoControlActiveStyles : videoControlInActiveStyles} | ||
onClick={event => { | ||
const target = event.target as Element; | ||
// We want to ensure to only toggling the menu open or closed when clicking the icon, not the select menu | ||
if (!target.closest('#select-microphone')) { | ||
setAudioOptionsOpen(prev => !prev); | ||
} | ||
}} | ||
onClick={() => setAudioOptionsOpen(prev => !prev)} | ||
onKeyDown={event => handleKeyDown(event, () => setAudioOptionsOpen(prev => !prev))} | ||
Comment on lines
-458
to
+448
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need to filter out the select element in that iteration, both clicks and keypresses to select an option will toggle the menu off |
||
onBlur={event => { | ||
if (!event.currentTarget.contains(event.relatedTarget)) { | ||
setAudioOptionsOpen(false); | ||
|
@@ -487,6 +471,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
String(selectedOption?.value).includes('input'), | ||
); | ||
}} | ||
onKeyDown={event => isEscapeKey(event) && setAudioOptionsOpen(false)} | ||
menuPlacement="top" | ||
menuIsOpen | ||
wrapperCSS={{marginBottom: 0}} | ||
|
@@ -506,7 +491,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
className="video-controls__button" | ||
data-uie-value={selfSharesCamera ? 'active' : 'inactive'} | ||
onClick={() => toggleCamera(call)} | ||
onKeyDown={handleToggleCameraKeydown} | ||
onKeyDown={event => handleKeyDown(event, () => toggleCamera(call))} | ||
role="switch" | ||
aria-checked={selfSharesCamera} | ||
tabIndex={TabIndex.FOCUSABLE} | ||
|
@@ -529,13 +514,8 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
<button | ||
className="device-toggle-button" | ||
css={videoOptionsOpen ? videoControlActiveStyles : videoControlInActiveStyles} | ||
onClick={event => { | ||
const target = event.target as Element; | ||
// We want to ensure to only toggling the menu open or closed when clicking the icon, not the select menu | ||
if (!target.closest('#select-camera')) { | ||
setVideoOptionsOpen(prev => !prev); | ||
} | ||
}} | ||
onClick={() => setVideoOptionsOpen(prev => !prev)} | ||
onKeyDown={event => handleKeyDown(event, () => setVideoOptionsOpen(prev => !prev))} | ||
onBlur={event => { | ||
if (!event.currentTarget.contains(event.relatedTarget)) { | ||
setVideoOptionsOpen(false); | ||
|
@@ -549,6 +529,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
autoFocus | ||
value={selectedVideoOptions} | ||
onChange={selectedOption => updateVideoOptions(String(selectedOption?.value))} | ||
onKeyDown={event => isEscapeKey(event) && setVideoOptionsOpen(false)} | ||
id="select-camera" | ||
dataUieName="select-camera" | ||
controlShouldRenderValue={false} | ||
|
@@ -582,6 +563,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
: videoControlInActiveStyles | ||
} | ||
onClick={() => toggleScreenshare(call)} | ||
onKeyDown={event => handleKeyDown(event, () => toggleScreenshare(call))} | ||
type="button" | ||
aria-labelledby="screen-share-label" | ||
data-uie-value={selfSharesScreen ? 'active' : 'inactive'} | ||
|
@@ -603,6 +585,7 @@ const FullscreenVideoCall: React.FC<FullscreenVideoCallProps> = ({ | |
<button | ||
className="video-controls__button video-controls__button--red" | ||
onClick={() => leave(call)} | ||
onKeyDown={event => handleKeyDown(event, () => leave(call))} | ||
type="button" | ||
aria-labelledby="leave-label" | ||
data-uie-name="do-call-controls-video-call-cancel" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now rely on the
onClick
oronKeyDown
event to toggle the menu off