Permissions popup context iso

This commit is contained in:
Josh Perez 2021-09-17 18:24:21 -04:00 committed by GitHub
parent f3715411c6
commit 7b5faa1cc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 562 additions and 506 deletions

View file

@ -1,8 +1,9 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useEffect } from 'react';
import React from 'react';
import { LocalizerType } from '../types/Util';
import { useEscapeHandling } from '../hooks/useEscapeHandling';
export type PropsType = {
closeAbout: () => unknown;
@ -17,21 +18,7 @@ export const About = ({
environment,
version,
}: PropsType): JSX.Element => {
useEffect(() => {
const handler = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
closeAbout();
event.preventDefault();
event.stopPropagation();
}
};
document.addEventListener('keydown', handler);
return () => {
document.removeEventListener('keydown', handler);
};
}, [closeAbout]);
useEscapeHandling(closeAbout);
return (
<div className="About">

View file

@ -9,7 +9,7 @@ import { Inbox } from './Inbox';
import { Install } from './Install';
import { StandaloneRegistration } from './StandaloneRegistration';
import { ThemeType } from '../types/Util';
import { usePageVisibility } from '../util/hooks';
import { usePageVisibility } from '../hooks/usePageVisibility';
type PropsType = {
appView: AppViewType;

View file

@ -5,7 +5,7 @@ import * as React from 'react';
import classNames from 'classnames';
import { Avatar, Props as AvatarProps } from './Avatar';
import { useRestoreFocus } from '../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../hooks/useRestoreFocus';
import { LocalizerType } from '../types/Util';

View file

@ -18,7 +18,7 @@ import {
import { AvatarColors } from '../types/Colors';
import { SetRendererCanvasType } from '../state/ducks/calling';
import { useGetCallingFrameBuffer } from '../calling/useGetCallingFrameBuffer';
import { usePageVisibility } from '../util/hooks';
import { usePageVisibility } from '../hooks/usePageVisibility';
import { missingCaseError } from '../util/missingCaseError';
import { nonRenderedRemoteParticipant } from '../util/ringrtc/nonRenderedRemoteParticipant';

View file

@ -9,7 +9,7 @@ import React, {
ReactNode,
} from 'react';
import { usePrevious } from '../util/hooks';
import { usePrevious } from '../hooks/usePrevious';
import { scrollToBottom } from '../util/scrollToBottom';
type PropsType = {

View file

@ -22,7 +22,7 @@ import { Avatar, AvatarSize } from './Avatar';
import { ConfirmationDialog } from './ConfirmationDialog';
import { Intl } from './Intl';
import { ContactName } from './conversation/ContactName';
import { useIntersectionObserver } from '../util/hooks';
import { useIntersectionObserver } from '../hooks/useIntersectionObserver';
import { MAX_FRAME_SIZE } from '../calling/constants';
const MAX_TIME_TO_SHOW_STALE_VIDEO_FRAMES = 5000;

View file

@ -16,7 +16,7 @@ import {
} from '../types/Calling';
import { useGetCallingFrameBuffer } from '../calling/useGetCallingFrameBuffer';
import { LocalizerType } from '../types/Util';
import { usePageVisibility } from '../util/hooks';
import { usePageVisibility } from '../hooks/usePageVisibility';
import { nonRenderedRemoteParticipant } from '../util/ringrtc/nonRenderedRemoteParticipant';
import * as log from '../logging/log';

View file

@ -37,7 +37,7 @@ import {
import * as OS from '../OS';
import { LocalizerType, ScrollBehavior } from '../types/Util';
import { usePrevious } from '../util/hooks';
import { usePrevious } from '../hooks/usePrevious';
import { missingCaseError } from '../util/missingCaseError';
import { ConversationList } from './ConversationList';

View file

@ -21,7 +21,7 @@ import { IMAGE_PNG, isImage, isVideo } from '../types/MIME';
import { LocalizerType } from '../types/Util';
import { MediaItemType, MessageAttributesType } from '../types/MediaItem';
import { formatDuration } from '../util/formatDuration';
import { useRestoreFocus } from '../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../hooks/useRestoreFocus';
import * as log from '../logging/log';
export type PropsType = {

View file

@ -10,7 +10,7 @@ import { LocalizerType } from '../types/Util';
import { ModalHost } from './ModalHost';
import { Theme } from '../util/theme';
import { getClassNamesFor } from '../util/getClassNamesFor';
import { useHasWrapped } from '../util/hooks';
import { useHasWrapped } from '../hooks/useHasWrapped';
type PropsType = {
children: ReactNode;

View file

@ -5,6 +5,7 @@ import React, { useEffect } from 'react';
import classNames from 'classnames';
import { createPortal } from 'react-dom';
import { Theme, themeClassName } from '../util/theme';
import { useEscapeHandling } from '../hooks/useEscapeHandling';
export type PropsType = {
readonly noMouseClose?: boolean;
@ -30,25 +31,7 @@ export const ModalHost = React.memo(
};
}, []);
useEffect(() => {
const handler = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
if (onEscape) {
onEscape();
} else {
onClose();
}
event.preventDefault();
event.stopPropagation();
}
};
document.addEventListener('keydown', handler);
return () => {
document.removeEventListener('keydown', handler);
};
}, [onEscape, onClose]);
useEscapeHandling(onEscape || onClose);
// This makes it easier to write dialogs to be hosted here; they won't have to worry
// as much about preventing propagation of mouse events.

View file

@ -0,0 +1,51 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { Button, ButtonVariant } from './Button';
import { LocalizerType } from '../types/Util';
import { useEscapeHandling } from '../hooks/useEscapeHandling';
export type PropsType = {
i18n: LocalizerType;
message: string;
onAccept: () => unknown;
onClose: () => unknown;
};
function focusRef(el: HTMLElement | null) {
if (el) {
el.focus();
}
}
export const PermissionsPopup = ({
i18n,
message,
onAccept,
onClose,
}: PropsType): JSX.Element => {
useEscapeHandling(onClose);
return (
<div className="PermissionsPopup">
<div className="PermissionsPopup__body">{message}</div>
<div className="PermissionsPopup__buttons">
<Button
onClick={onClose}
ref={focusRef}
variant={ButtonVariant.Secondary}
>
{i18n('confirmation-dialog--Cancel')}
</Button>
<Button
onClick={onAccept}
ref={focusRef}
variant={ButtonVariant.Primary}
>
{i18n('allowAccess')}
</Button>
</div>
</div>
);
};

View file

@ -33,6 +33,7 @@ import {
DEFAULT_DURATIONS_SET,
format as formatExpirationTimer,
} from '../util/expirationTimer';
import { useEscapeHandling } from '../hooks/useEscapeHandling';
type CheckboxChangeHandlerType = (value: boolean) => unknown;
type SelectChangeHandlerType<T = string | number> = (value: T) => unknown;
@ -280,21 +281,7 @@ export const Preferences = ({
doneRendering();
}, [doneRendering]);
useEffect(() => {
const handler = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
closeSettings();
event.preventDefault();
event.stopPropagation();
}
};
document.addEventListener('keydown', handler);
return () => {
document.removeEventListener('keydown', handler);
};
}, [closeSettings]);
useEscapeHandling(closeSettings);
const onZoomSelectChange = useCallback(
(value: string) => {

View file

@ -3,7 +3,7 @@
import * as React from 'react';
import classNames from 'classnames';
import { useRestoreFocus } from '../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../hooks/useRestoreFocus';
import { LocalizerType } from '../types/Util';
export type Props = {

View file

@ -15,7 +15,7 @@ import {
getCallingIcon,
getCallingNotificationText,
} from '../../util/callingNotification';
import { usePrevious } from '../../util/hooks';
import { usePrevious } from '../../hooks/usePrevious';
import { missingCaseError } from '../../util/missingCaseError';
import { Tooltip, TooltipPlacement } from '../Tooltip';
import type { TimelineItemType } from './TimelineItem';

View file

@ -6,7 +6,7 @@ import classNames from 'classnames';
import { Modal } from '../Modal';
import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../../hooks/useRestoreFocus';
import { LocalizerType } from '../../types/Util';

View file

@ -9,7 +9,7 @@ import { Modal } from '../Modal';
import { Intl } from '../Intl';
import { Emojify } from './Emojify';
import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../../hooks/useRestoreFocus';
import { LocalizerType } from '../../types/Util';

View file

@ -4,7 +4,7 @@
import * as React from 'react';
import { convertShortName } from '../emoji/lib';
import { Props as EmojiPickerProps } from '../emoji/EmojiPicker';
import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../../hooks/useRestoreFocus';
import { LocalizerType } from '../../types/Util';
import { canCustomizePreferredReactions } from '../../util/canCustomizePreferredReactions';
import {

View file

@ -7,9 +7,10 @@ import classNames from 'classnames';
import { ContactName } from './ContactName';
import { Avatar, Props as AvatarProps } from '../Avatar';
import { Emoji } from '../emoji/Emoji';
import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../../hooks/useRestoreFocus';
import { ConversationType } from '../../state/ducks/conversations';
import { emojiToData, EmojiData } from '../emoji/lib';
import { useEscapeHandling } from '../../hooks/useEscapeHandling';
export type Reaction = {
emoji: string;
@ -124,20 +125,9 @@ export const ReactionViewer = React.forwardRef<HTMLDivElement, Props>(
selectedReactionCategory,
setSelectedReactionCategory,
] = React.useState(pickedReaction || 'all');
// Handle escape key
React.useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (onClose && e.key === 'Escape') {
onClose();
}
};
document.addEventListener('keydown', handler);
return () => {
document.removeEventListener('keydown', handler);
};
}, [onClose]);
useEscapeHandling(onClose);
// Focus first button and restore focus on unmount
const [focusRef] = useRestoreFocus();

View file

@ -3,7 +3,7 @@
import * as React from 'react';
import classNames from 'classnames';
import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../../hooks/useRestoreFocus';
import { StickerPackType, StickerType } from '../../state/ducks/stickers';
import { LocalizerType } from '../../types/Util';

View file

@ -10,7 +10,7 @@ import { ConfirmationDialog } from '../ConfirmationDialog';
import { LocalizerType } from '../../types/Util';
import { StickerPackType } from '../../state/ducks/stickers';
import { Spinner } from '../Spinner';
import { useRestoreFocus } from '../../util/hooks/useRestoreFocus';
import { useRestoreFocus } from '../../hooks/useRestoreFocus';
export type OwnProps = {
readonly onClose: () => unknown;