mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-29 12:09:20 +03:00
Improved shortcuts handling
This commit is contained in:
parent
65a3b9e4c7
commit
1d63683cf9
7 changed files with 28 additions and 50 deletions
|
|
@ -3,8 +3,6 @@ import 'External/User/ko';
|
|||
import { isArray, pString } from 'Common/Utils';
|
||||
import { mailToHelper, setLayoutResizer } from 'Common/UtilsUser';
|
||||
|
||||
import { Scope } from 'Common/Enums';
|
||||
|
||||
import {
|
||||
FolderType,
|
||||
SetSystemFoldersNotification,
|
||||
|
|
@ -90,7 +88,7 @@ class AppUser extends AbstractApp {
|
|||
const fn = (ev=>$htmlCL.toggle('rl-ctrl-key-pressed', ev.ctrlKey)).debounce(500);
|
||||
addEventsListener(doc, ['keydown','keyup'], fn);
|
||||
|
||||
shortcuts.add('escape,enter', '', Scope.All, () => rl.Dropdowns.detectVisibility());
|
||||
shortcuts.add('escape,enter', '', () => rl.Dropdowns.detectVisibility());
|
||||
}
|
||||
|
||||
reload() {
|
||||
|
|
|
|||
13
dev/External/User/ko.js
vendored
13
dev/External/User/ko.js
vendored
|
|
@ -229,19 +229,6 @@ Object.assign(ko.bindingHandlers, {
|
|||
init: (element, fValueAccessor) => fValueAccessor()(element)
|
||||
},
|
||||
|
||||
onEsc: {
|
||||
init: (element, fValueAccessor, fAllBindings, viewModel) => {
|
||||
let fn = event => {
|
||||
if ('Escape' == event.key) {
|
||||
element.dispatchEvent(new Event('change'));
|
||||
fValueAccessor().call(viewModel);
|
||||
}
|
||||
};
|
||||
element.addEventListener('keyup', fn);
|
||||
ko.utils.domNodeDisposal.addDisposeCallback(element, () => element.removeEventListener('keyup', fn));
|
||||
}
|
||||
},
|
||||
|
||||
registerBootstrapDropdown: {
|
||||
init: element => {
|
||||
rl.Dropdowns.register(element);
|
||||
|
|
|
|||
|
|
@ -16,15 +16,11 @@ addObservablesTo(AppUserStore, {
|
|||
});
|
||||
|
||||
AppUserStore.focusedState.subscribe(value => {
|
||||
switch (value) {
|
||||
case Scope.MessageList:
|
||||
case Scope.MessageView:
|
||||
case Scope.FolderList:
|
||||
['FolderList','MessageList','MessageView'].forEach(name => {
|
||||
if (name === value) {
|
||||
keyScope(value);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(Scope.FolderList !== value);
|
||||
break;
|
||||
}
|
||||
['FolderList','MessageList','MessageView'].forEach(name => {
|
||||
}
|
||||
let dom = elementById('V-Mail'+name);
|
||||
dom && dom.classList.toggle('focused', name === value);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,14 +14,23 @@ const
|
|||
},
|
||||
toArray = v => Array.isArray(v) ? v : v.split(/\s*,\s*/),
|
||||
|
||||
// ignore keydown in any element that supports keyboard input
|
||||
filter = node => !(!node.closest || node.closest('input,select,textarea,[contenteditable]')),
|
||||
exec = (event, cmd) => {
|
||||
try {
|
||||
// call the handler and stop the event if neccessary
|
||||
if (!event.defaultPrevented && cmd(event) === false) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
shortcuts = {
|
||||
on: () => doc.addEventListener('keydown', keydown),
|
||||
off: () => doc.removeEventListener('keydown', keydown),
|
||||
add: (keys, modifiers, scopes, method) => {
|
||||
if (method === undefined) {
|
||||
if (null == method) {
|
||||
method = scopes;
|
||||
scopes = 'all';
|
||||
}
|
||||
|
|
@ -54,25 +63,13 @@ const
|
|||
|
||||
keydown = event => {
|
||||
let key = (event.key || '').toLowerCase().replace(' ','space'),
|
||||
scopes = [];
|
||||
scope[key] && scopes.push(scope[key]);
|
||||
_scope !== 'all' && _scopes.all[key] && scopes.push(_scopes.all[key]);
|
||||
if (scopes.length && filter(event.target)) {
|
||||
target = event.target;
|
||||
// ignore keydown in any element that supports keyboard input unless it's the Escape key
|
||||
if ('escape' === key || !target.closest || !target.closest('input,select,textarea,[contenteditable]')) {
|
||||
let modifiers = ['alt','ctrl','meta','shift'].filter(v => event[v+'Key']).join('+');
|
||||
scopes.forEach(actions => {
|
||||
// for each potential shortcut
|
||||
actions[modifiers] && actions[modifiers].forEach(cmd => {
|
||||
try {
|
||||
// call the handler and stop the event if neccessary
|
||||
if (!event.defaultPrevented && cmd(event) === false) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
scope[key] && scope[key][modifiers] && scope[key][modifiers].forEach(cmd => exec(event, cmd));
|
||||
!event.defaultPrevented && _scope !== 'all' && _scopes.all[key] && _scopes.all[key][modifiers]
|
||||
&& _scopes.all[key][modifiers].forEach(cmd => exec(event, cmd));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,22 +8,22 @@
|
|||
<div class="control-group">
|
||||
<label data-i18n="GLOBAL/FROM"></label>
|
||||
<input type="text" autofocus="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: from, onEsc: closeCommand">
|
||||
data-bind="value: from">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label data-i18n="GLOBAL/TO"></label>
|
||||
<input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: to, onEsc: closeCommand">
|
||||
data-bind="value: to">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label data-i18n="GLOBAL/SUBJECT"></label>
|
||||
<input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: subject, onEsc: closeCommand">
|
||||
data-bind="value: subject">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label data-i18n="SEARCH/LABEL_ADV_TEXT"></label>
|
||||
<input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: text, onEsc: closeCommand">
|
||||
data-bind="value: text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="span4">
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
</header>
|
||||
<div class="modal-body">
|
||||
<div class="b-list-toolbar">
|
||||
<input type="search" class="e-search" placeholder="Search" autocorrect="off" autocapitalize="off" data-i18n="[placeholder]GLOBAL/SEARCH" data-bind="value: search">
|
||||
<input type="search" class="e-search" placeholder="Search" autofocus="" autocorrect="off" autocapitalize="off" data-i18n="[placeholder]GLOBAL/SEARCH" data-bind="value: search">
|
||||
</div>
|
||||
<div class="b-list-content g-ui-user-select-none" data-bind="css: {'hideContactListCheckbox': !useCheckboxesInList()}">
|
||||
<div class="content">
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
tooltipErrorTip: errorMsg"></span>
|
||||
<input type="text"
|
||||
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="value: nameForEdit, visible: edited, hasfocus: edited, onEnter: function () { $root.folderEditOnEnter($data); }, onEsc: function () { $root.folderEditOnEsc($data); }">
|
||||
data-bind="value: nameForEdit, visible: edited, hasfocus: edited, onEnter: function () { $root.folderEditOnEnter($data); }">
|
||||
|
||||
<span class="folder-system-name" data-bind="text: manageFolderSystemName, visible: isSystemFolder"></span>
|
||||
</td>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue