Pressing Esc in left pane composer menu should go back
This commit is contained in:
parent
2d35fa8f57
commit
f05d45ac9b
12 changed files with 168 additions and 5 deletions
|
@ -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,
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue