New keyboard shortcuts: Ctrl+1..9, Ctrl+Tab/Ctrl+Shift+Tab
* New keyboard shortcuts: Ctrl+1..9, Ctrl+Tab/Ctrl+Shift+Tab * Add new shortcuts to the shortcut guide
This commit is contained in:
parent
aaa91c441b
commit
ebb3864f58
4 changed files with 178 additions and 77 deletions
|
@ -1969,6 +1969,10 @@
|
|||
"message": "Remove all draft attachments",
|
||||
"description": "Shown in the shortcuts guide"
|
||||
},
|
||||
"Keyboard--conversation-by-index": {
|
||||
"message": "Jump to conversation",
|
||||
"description": "A shortcut allowing direct navigation to conversations 1 to 9 in list"
|
||||
},
|
||||
"Keyboard--Key--ctrl": {
|
||||
"message": "Ctrl",
|
||||
"description": "Key shown in shortcut combination in shortcuts guide"
|
||||
|
@ -1989,6 +1993,14 @@
|
|||
"message": "Enter",
|
||||
"description": "Key shown in shortcut combination in shortcuts guide"
|
||||
},
|
||||
"Keyboard--Key--tab": {
|
||||
"message": "Tab",
|
||||
"description": "Key shown in shortcut combination in shortcuts guide"
|
||||
},
|
||||
"Keyboard--Key--one-to-nine-range": {
|
||||
"message": "1 to 9",
|
||||
"description": "Expresses that 1, 2, 3, up to 9 are available shortcut keys"
|
||||
},
|
||||
"Keyboard--header": {
|
||||
"message": "Keyboard Shortcuts",
|
||||
"description": "Title header of the keyboard shortcuts guide"
|
||||
|
|
|
@ -702,6 +702,24 @@
|
|||
}
|
||||
};
|
||||
|
||||
function getConversationByIndex(index) {
|
||||
const state = store.getState();
|
||||
const lists = Signal.State.Selectors.conversations.getLeftPaneLists(
|
||||
state
|
||||
);
|
||||
const toSearch = state.conversations.showArchived
|
||||
? lists.archivedConversations
|
||||
: lists.conversations;
|
||||
|
||||
const target = toSearch[index];
|
||||
|
||||
if (target) {
|
||||
return target.id;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findConversation(conversationId, direction, unreadOnly) {
|
||||
const state = store.getState();
|
||||
const lists = Signal.State.Selectors.conversations.getLeftPaneLists(
|
||||
|
@ -739,6 +757,18 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
const NUMBERS = {
|
||||
'1': 1,
|
||||
'2': 2,
|
||||
'3': 3,
|
||||
'4': 4,
|
||||
'5': 5,
|
||||
'6': 6,
|
||||
'7': 7,
|
||||
'8': 8,
|
||||
'9': 9,
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', event => {
|
||||
const { altKey, ctrlKey, key, metaKey, shiftKey } = event;
|
||||
|
||||
|
@ -911,8 +941,24 @@
|
|||
return;
|
||||
}
|
||||
|
||||
// Change currently selected conversation - up/down, to next/previous unread
|
||||
if (!isSearching && optionOrAlt && !shiftKey && key === 'ArrowUp') {
|
||||
// Change currently selected conversation by index
|
||||
if (!isSearching && commandOrCtrl && NUMBERS[key]) {
|
||||
const targetId = getConversationByIndex(NUMBERS[key] - 1);
|
||||
|
||||
if (targetId) {
|
||||
window.Whisper.events.trigger('showConversation', targetId);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Change currently selected conversation
|
||||
// up/previous
|
||||
if (
|
||||
(!isSearching && optionOrAlt && !shiftKey && key === 'ArrowUp') ||
|
||||
(!isSearching && ctrlKey && shiftKey && key === 'Tab')
|
||||
) {
|
||||
const unreadOnly = false;
|
||||
const targetId = findConversation(
|
||||
conversation ? conversation.id : null,
|
||||
|
@ -927,7 +973,11 @@
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (!isSearching && optionOrAlt && !shiftKey && key === 'ArrowDown') {
|
||||
// down/next
|
||||
if (
|
||||
(!isSearching && optionOrAlt && !shiftKey && key === 'ArrowDown') ||
|
||||
(!isSearching && ctrlKey && key === 'Tab')
|
||||
) {
|
||||
const unreadOnly = false;
|
||||
const targetId = findConversation(
|
||||
conversation ? conversation.id : null,
|
||||
|
@ -942,6 +992,7 @@
|
|||
return;
|
||||
}
|
||||
}
|
||||
// previous unread
|
||||
if (!isSearching && optionOrAlt && shiftKey && key === 'ArrowUp') {
|
||||
const unreadOnly = true;
|
||||
const targetId = findConversation(
|
||||
|
@ -957,6 +1008,7 @@
|
|||
return;
|
||||
}
|
||||
}
|
||||
// next unread
|
||||
if (!isSearching && optionOrAlt && shiftKey && key === 'ArrowDown') {
|
||||
const unreadOnly = true;
|
||||
const targetId = findConversation(
|
||||
|
|
|
@ -7697,11 +7697,15 @@ button.module-image__border-overlay:focus {
|
|||
margin-bottom: 4px;
|
||||
}
|
||||
.module-shortcut-guide__shortcut__key-container {
|
||||
text-align: right;
|
||||
margin-right: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.module-shortcut-guide__shortcut__key-inner-container {
|
||||
text-align: right;
|
||||
margin-top: 4px;
|
||||
margin-right: 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.module-shortcut-guide__shortcut__key {
|
||||
display: inline-block;
|
||||
|
||||
|
@ -7709,7 +7713,6 @@ button.module-image__border-overlay:focus {
|
|||
padding: 3px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
margin-top: 4px;
|
||||
margin-left: 4px;
|
||||
|
||||
height: 30px;
|
||||
|
|
|
@ -15,6 +15,8 @@ type KeyType =
|
|||
| 'optionOrAlt'
|
||||
| 'shift'
|
||||
| 'enter'
|
||||
| 'tab'
|
||||
| 'ctrl'
|
||||
| '↑'
|
||||
| '↓'
|
||||
| ','
|
||||
|
@ -33,142 +35,153 @@ type KeyType =
|
|||
| 'T'
|
||||
| 'U'
|
||||
| 'V'
|
||||
| 'X';
|
||||
| 'X'
|
||||
| '1 to 9';
|
||||
type ShortcutType = {
|
||||
description: string;
|
||||
keys: Array<KeyType>;
|
||||
keys: Array<Array<KeyType>>;
|
||||
};
|
||||
|
||||
const NAVIGATION_SHORTCUTS: Array<ShortcutType> = [
|
||||
{
|
||||
description: 'Keyboard--navigate-by-section',
|
||||
keys: ['commandOrCtrl', 'T'],
|
||||
keys: [['commandOrCtrl', 'T']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--previous-conversation',
|
||||
keys: ['optionOrAlt', '↑'],
|
||||
keys: [
|
||||
['optionOrAlt', '↑'],
|
||||
['ctrl', 'shift', 'tab'],
|
||||
],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--next-conversation',
|
||||
keys: ['optionOrAlt', '↓'],
|
||||
keys: [
|
||||
['optionOrAlt', '↓'],
|
||||
['ctrl', 'tab'],
|
||||
],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--previous-unread-conversation',
|
||||
keys: ['optionOrAlt', 'shift', '↑'],
|
||||
keys: [['optionOrAlt', 'shift', '↑']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--next-unread-conversation',
|
||||
keys: ['optionOrAlt', 'shift', '↓'],
|
||||
keys: [['optionOrAlt', 'shift', '↓']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--conversation-by-index',
|
||||
keys: [['commandOrCtrl', '1 to 9']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--preferences',
|
||||
keys: ['commandOrCtrl', ','],
|
||||
keys: [['commandOrCtrl', ',']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--open-conversation-menu',
|
||||
keys: ['commandOrCtrl', 'shift', 'L'],
|
||||
keys: [['commandOrCtrl', 'shift', 'L']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--search',
|
||||
keys: ['commandOrCtrl', 'F'],
|
||||
keys: [['commandOrCtrl', 'F']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--search-in-conversation',
|
||||
keys: ['commandOrCtrl', 'shift', 'F'],
|
||||
keys: [['commandOrCtrl', 'shift', 'F']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--focus-composer',
|
||||
keys: ['commandOrCtrl', 'shift', 'T'],
|
||||
keys: [['commandOrCtrl', 'shift', 'T']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--open-all-media-view',
|
||||
keys: ['commandOrCtrl', 'shift', 'M'],
|
||||
keys: [['commandOrCtrl', 'shift', 'M']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--open-emoji-chooser',
|
||||
keys: ['commandOrCtrl', 'shift', 'J'],
|
||||
keys: [['commandOrCtrl', 'shift', 'J']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--open-sticker-chooser',
|
||||
keys: ['commandOrCtrl', 'shift', 'S'],
|
||||
keys: [['commandOrCtrl', 'shift', 'S']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--begin-recording-voice-note',
|
||||
keys: ['commandOrCtrl', 'shift', 'V'],
|
||||
keys: [['commandOrCtrl', 'shift', 'V']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--archive-conversation',
|
||||
keys: ['commandOrCtrl', 'shift', 'A'],
|
||||
keys: [['commandOrCtrl', 'shift', 'A']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--unarchive-conversation',
|
||||
keys: ['commandOrCtrl', 'shift', 'U'],
|
||||
keys: [['commandOrCtrl', 'shift', 'U']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--scroll-to-top',
|
||||
keys: ['commandOrCtrl', '↑'],
|
||||
keys: [['commandOrCtrl', '↑']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--scroll-to-bottom',
|
||||
keys: ['commandOrCtrl', '↓'],
|
||||
keys: [['commandOrCtrl', '↓']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--close-curent-conversation',
|
||||
keys: ['commandOrCtrl', 'shift', 'C'],
|
||||
keys: [['commandOrCtrl', 'shift', 'C']],
|
||||
},
|
||||
];
|
||||
|
||||
const MESSAGE_SHORTCUTS: Array<ShortcutType> = [
|
||||
{
|
||||
description: 'Keyboard--default-message-action',
|
||||
keys: ['enter'],
|
||||
keys: [['enter']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--view-details-for-selected-message',
|
||||
keys: ['commandOrCtrl', 'D'],
|
||||
keys: [['commandOrCtrl', 'D']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--toggle-reply',
|
||||
keys: ['commandOrCtrl', 'shift', 'R'],
|
||||
keys: [['commandOrCtrl', 'shift', 'R']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--toggle-reaction-picker',
|
||||
keys: ['commandOrCtrl', 'shift', 'E'],
|
||||
keys: [['commandOrCtrl', 'shift', 'E']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--save-attachment',
|
||||
keys: ['commandOrCtrl', 'S'],
|
||||
keys: [['commandOrCtrl', 'S']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--delete-message',
|
||||
keys: ['commandOrCtrl', 'shift', 'D'],
|
||||
keys: [['commandOrCtrl', 'shift', 'D']],
|
||||
},
|
||||
];
|
||||
|
||||
const COMPOSER_SHORTCUTS: Array<ShortcutType> = [
|
||||
{
|
||||
description: 'Keyboard--add-newline',
|
||||
keys: ['shift', 'enter'],
|
||||
keys: [['shift', 'enter']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--expand-composer',
|
||||
keys: ['commandOrCtrl', 'shift', 'X'],
|
||||
keys: [['commandOrCtrl', 'shift', 'X']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--send-in-expanded-composer',
|
||||
keys: ['commandOrCtrl', 'enter'],
|
||||
keys: [['commandOrCtrl', 'enter']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--attach-file',
|
||||
keys: ['commandOrCtrl', 'U'],
|
||||
keys: [['commandOrCtrl', 'U']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--remove-draft-link-preview',
|
||||
keys: ['commandOrCtrl', 'P'],
|
||||
keys: [['commandOrCtrl', 'P']],
|
||||
},
|
||||
{
|
||||
description: 'Keyboard--remove-draft-attachments',
|
||||
keys: ['commandOrCtrl', 'shift', 'P'],
|
||||
keys: [['commandOrCtrl', 'shift', 'P']],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -253,46 +266,67 @@ function renderShortcut(
|
|||
{i18n(shortcut.description)}
|
||||
</div>
|
||||
<div className="module-shortcut-guide__shortcut__key-container">
|
||||
{shortcut.keys.map((key, mapIndex) => {
|
||||
let label: string = key;
|
||||
let isSquare = true;
|
||||
{shortcut.keys.map((keys, outerIndex) => (
|
||||
<div
|
||||
key={outerIndex}
|
||||
className="module-shortcut-guide__shortcut__key-inner-container"
|
||||
>
|
||||
{keys.map((key, mapIndex) => {
|
||||
let label: string = key;
|
||||
let isSquare = true;
|
||||
|
||||
if (key === 'commandOrCtrl' && isMacOS) {
|
||||
label = '⌘';
|
||||
}
|
||||
if (key === 'commandOrCtrl' && !isMacOS) {
|
||||
label = i18n('Keyboard--Key--ctrl');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'optionOrAlt' && isMacOS) {
|
||||
label = i18n('Keyboard--Key--option');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'optionOrAlt' && !isMacOS) {
|
||||
label = i18n('Keyboard--Key--alt');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'shift') {
|
||||
label = i18n('Keyboard--Key--shift');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'enter') {
|
||||
label = i18n('Keyboard--Key--enter');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'commandOrCtrl' && isMacOS) {
|
||||
label = '⌘';
|
||||
}
|
||||
if (key === 'commandOrCtrl' && !isMacOS) {
|
||||
label = i18n('Keyboard--Key--ctrl');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'optionOrAlt' && isMacOS) {
|
||||
label = i18n('Keyboard--Key--option');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'optionOrAlt' && !isMacOS) {
|
||||
label = i18n('Keyboard--Key--alt');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'ctrl') {
|
||||
label = i18n('Keyboard--Key--ctrl');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'shift') {
|
||||
label = i18n('Keyboard--Key--shift');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'enter') {
|
||||
label = i18n('Keyboard--Key--enter');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === 'tab') {
|
||||
label = i18n('Keyboard--Key--tab');
|
||||
isSquare = false;
|
||||
}
|
||||
if (key === '1 to 9') {
|
||||
label = i18n('Keyboard--Key--one-to-nine-range');
|
||||
isSquare = false;
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
key={mapIndex}
|
||||
className={classNames(
|
||||
'module-shortcut-guide__shortcut__key',
|
||||
isSquare ? 'module-shortcut-guide__shortcut__key--square' : null
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<span
|
||||
key={mapIndex}
|
||||
className={classNames(
|
||||
'module-shortcut-guide__shortcut__key',
|
||||
isSquare
|
||||
? 'module-shortcut-guide__shortcut__key--square'
|
||||
: null
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue