Pressing Esc in left pane composer menu should go back

This commit is contained in:
Evan Hahn 2021-04-02 16:43:39 -05:00 committed by Josh Perez
parent 2d35fa8f57
commit f05d45ac9b
12 changed files with 168 additions and 5 deletions

View File

@ -348,8 +348,30 @@ export const LeftPane: React.FC<PropsType> = ({
// It also ensures that we scroll to the top when switching views.
const listKey = preRowsNode ? 1 : 0;
// We disable this lint rule because we're trying to capture bubbled events. See [the
// lint rule's docs][0].
//
// [0]: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/645900a0e296ca7053dbf6cd9e12cc85849de2d5/docs/rules/no-static-element-interactions.md#case-the-event-handler-is-only-being-used-to-capture-bubbled-events
/* eslint-disable jsx-a11y/no-static-element-interactions */
return (
<div className="module-left-pane">
<div
className="module-left-pane"
onKeyDown={event => {
if (event.key === 'Escape') {
const backAction = helper.getBackAction({
showInbox,
startComposing,
showChooseGroupMembers,
});
if (backAction) {
event.preventDefault();
event.stopPropagation();
backAction();
}
}
}}
>
{/* eslint-enable jsx-a11y/no-static-element-interactions */}
<div className="module-left-pane__header">
{helper.getHeaderContents({
i18n,

View File

@ -39,7 +39,7 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<
return (
<div className="module-left-pane__header__contents">
<button
onClick={showInbox}
onClick={this.getBackAction({ showInbox })}
className="module-left-pane__header__contents__back-button"
title={i18n('backToInbox')}
aria-label={i18n('backToInbox')}
@ -52,6 +52,10 @@ export class LeftPaneArchiveHelper extends LeftPaneHelper<
);
}
getBackAction({ showInbox }: { showInbox: () => void }): () => void {
return showInbox;
}
getPreRowsNode({ i18n }: Readonly<{ i18n: LocalizerType }>): ReactChild {
return (
<div className="module-left-pane__archive-helper-text">

View File

@ -86,7 +86,7 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<
<button
aria-label={backButtonLabel}
className="module-left-pane__header__contents__back-button"
onClick={startComposing}
onClick={this.getBackAction({ startComposing })}
title={backButtonLabel}
type="button"
/>
@ -97,6 +97,14 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper<
);
}
getBackAction({
startComposing,
}: {
startComposing: () => void;
}): () => void {
return startComposing;
}
getPreRowsNode({
closeCantAddContactToGroupModal,
closeMaximumGroupSizeModal,

View File

@ -61,7 +61,7 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<
return (
<div className="module-left-pane__header__contents">
<button
onClick={showInbox}
onClick={this.getBackAction({ showInbox })}
className="module-left-pane__header__contents__back-button"
title={i18n('backToInbox')}
aria-label={i18n('backToInbox')}
@ -74,6 +74,10 @@ export class LeftPaneComposeHelper extends LeftPaneHelper<
);
}
getBackAction({ showInbox }: { showInbox: () => void }): () => void {
return showInbox;
}
getPreRowsNode({
i18n,
onChangeComposeSearchTerm,

View File

@ -30,6 +30,16 @@ export abstract class LeftPaneHelper<T> {
return null;
}
getBackAction(
_: Readonly<{
showInbox: () => void;
startComposing: () => void;
showChooseGroupMembers: () => void;
}>
): undefined | (() => void) {
return undefined;
}
shouldRenderNetworkStatusAndUpdateDialog(): boolean {
return false;
}

View File

@ -67,7 +67,7 @@ export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper<
aria-label={backButtonLabel}
className="module-left-pane__header__contents__back-button"
disabled={this.isCreating}
onClick={showChooseGroupMembers}
onClick={this.getBackAction({ showChooseGroupMembers })}
title={backButtonLabel}
type="button"
/>
@ -78,6 +78,14 @@ export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper<
);
}
getBackAction({
showChooseGroupMembers,
}: {
showChooseGroupMembers: () => void;
}): undefined | (() => void) {
return this.isCreating ? undefined : showChooseGroupMembers;
}
getPreRowsNode({
clearGroupCreationError,
createGroup,

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
@ -15,6 +16,15 @@ describe('LeftPaneArchiveHelper', () => {
type: 'direct' as const,
});
describe('getBackAction', () => {
it('returns the "show inbox" action', () => {
const showInbox = sinon.fake();
const helper = new LeftPaneArchiveHelper({ archivedConversations: [] });
assert.strictEqual(helper.getBackAction({ showInbox }), showInbox);
});
});
describe('getRowCount', () => {
it('returns the number of archived conversations', () => {
assert.strictEqual(

View File

@ -45,6 +45,18 @@ describe('LeftPaneChooseGroupMembersHelper', () => {
sinonSandbox.restore();
});
describe('getBackAction', () => {
it('returns the "show composer" action', () => {
const startComposing = sinon.fake();
const helper = new LeftPaneChooseGroupMembersHelper(defaults);
assert.strictEqual(
helper.getBackAction({ startComposing }),
startComposing
);
});
});
describe('getRowCount', () => {
it('returns 0 if there are no contacts', () => {
assert.strictEqual(

View File

@ -35,6 +35,19 @@ describe('LeftPaneComposeHelper', () => {
sinonSandbox.restore();
});
describe('getBackAction', () => {
it('returns the "show inbox" action', () => {
const showInbox = sinon.fake();
const helper = new LeftPaneComposeHelper({
composeContacts: [],
regionCode: 'US',
searchTerm: '',
});
assert.strictEqual(helper.getBackAction({ showInbox }), showInbox);
});
});
describe('getRowCount', () => {
it('returns 1 (for the "new group" button) if not searching and there are no contacts', () => {
assert.strictEqual(

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
@ -15,6 +16,24 @@ describe('LeftPaneInboxHelper', () => {
type: 'direct' as const,
});
describe('getBackAction', () => {
it("returns undefined; you can't go back from the main inbox", () => {
const helper = new LeftPaneInboxHelper({
conversations: [],
pinnedConversations: [],
archivedConversations: [],
});
assert.isUndefined(
helper.getBackAction({
showChooseGroupMembers: sinon.fake(),
showInbox: sinon.fake(),
startComposing: sinon.fake(),
})
);
});
});
describe('getRowCount', () => {
it('returns 0 if there are no conversations', () => {
const helper = new LeftPaneInboxHelper({

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
@ -19,6 +20,25 @@ describe('LeftPaneSearchHelper', () => {
conversationId: uuid(),
});
describe('getBackAction', () => {
it('returns undefined; going back is handled elsewhere in the app', () => {
const helper = new LeftPaneSearchHelper({
conversationResults: { isLoading: false, results: [] },
contactResults: { isLoading: false, results: [] },
messageResults: { isLoading: false, results: [] },
searchTerm: 'foo',
});
assert.isUndefined(
helper.getBackAction({
showChooseGroupMembers: sinon.fake(),
showInbox: sinon.fake(),
startComposing: sinon.fake(),
})
);
});
});
describe('getRowCount', () => {
it('returns 0 when there are no search results', () => {
const helper = new LeftPaneSearchHelper({

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
import * as sinon from 'sinon';
import { v4 as uuid } from 'uuid';
import { RowType } from '../../../components/ConversationList';
@ -14,6 +15,38 @@ describe('LeftPaneSetGroupMetadataHelper', () => {
type: 'direct' as const,
});
describe('getBackAction', () => {
it('returns the "show composer" action if a request is not active', () => {
const showChooseGroupMembers = sinon.fake();
const helper = new LeftPaneSetGroupMetadataHelper({
groupAvatar: undefined,
groupName: '',
hasError: false,
isCreating: false,
selectedContacts: [],
});
assert.strictEqual(
helper.getBackAction({ showChooseGroupMembers }),
showChooseGroupMembers
);
});
it("returns undefined (i.e., you can't go back) if a request is active", () => {
const helper = new LeftPaneSetGroupMetadataHelper({
groupAvatar: undefined,
groupName: 'Foo Bar',
hasError: false,
isCreating: true,
selectedContacts: [],
});
assert.isUndefined(
helper.getBackAction({ showChooseGroupMembers: sinon.fake() })
);
});
});
describe('getRowCount', () => {
it('returns 0 if there are no contacts', () => {
assert.strictEqual(