Added shortcut input controls to make custom shortcuts work

This commit is contained in:
Dan Brown 2022-11-09 14:40:44 +00:00
parent 66c8809799
commit 9067902267
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
6 changed files with 90 additions and 11 deletions

View File

@ -35,7 +35,7 @@ class UserPreferencesController extends Controller
public function updateShortcuts(Request $request)
{
$enabled = $request->get('enabled') === 'true';
$providedShortcuts = $request->get('shortcuts', []);
$providedShortcuts = $request->get('shortcut', []);
$shortcuts = new UserShortcutMap($providedShortcuts);
setting()->putUser(user(), 'ui-shortcuts', $shortcuts->toJson());

View File

@ -44,6 +44,7 @@ import settingAppColorPicker from "./setting-app-color-picker.js"
import settingColorPicker from "./setting-color-picker.js"
import shelfSort from "./shelf-sort.js"
import shortcuts from "./shortcuts";
import shortcutInput from "./shortcut-input";
import sidebar from "./sidebar.js"
import sortableList from "./sortable-list.js"
import submitOnChange from "./submit-on-change.js"
@ -103,6 +104,7 @@ const componentMapping = {
"setting-color-picker": settingColorPicker,
"shelf-sort": shelfSort,
"shortcuts": shortcuts,
"shortcut-input": shortcutInput,
"sidebar": sidebar,
"sortable-list": sortableList,
"submit-on-change": submitOnChange,

View File

@ -0,0 +1,57 @@
/**
* Keys to ignore when recording shortcuts.
* @type {string[]}
*/
const ignoreKeys = ['Control', 'Alt', 'Shift', 'Meta', 'Super', ' ', '+', 'Tab', 'Escape'];
/**
* @extends {Component}
*/
class ShortcutInput {
setup() {
this.input = this.$el;
this.setupListeners();
}
setupListeners() {
this.listenerRecordKey = this.listenerRecordKey.bind(this);
this.input.addEventListener('focus', () => {
this.startListeningForInput();
});
this.input.addEventListener('blur', () => {
this.stopListeningForInput();
})
}
startListeningForInput() {
this.input.addEventListener('keydown', this.listenerRecordKey)
}
/**
* @param {KeyboardEvent} event
*/
listenerRecordKey(event) {
if (ignoreKeys.includes(event.key)) {
return;
}
const keys = [
event.ctrlKey ? 'Ctrl' : '',
event.metaKey ? 'Cmd' : '',
event.key,
];
this.input.value = keys.filter(s => Boolean(s)).join(' + ');
}
stopListeningForInput() {
this.input.removeEventListener('keydown', this.listenerRecordKey);
}
}
export default ShortcutInput;

View File

@ -30,13 +30,7 @@ class Shortcuts {
return;
}
const shortcutId = this.mapByShortcut[event.key];
if (shortcutId) {
const wasHandled = this.runShortcut(shortcutId);
if (wasHandled) {
event.preventDefault();
}
}
this.handleShortcutPress(event);
});
window.addEventListener('keydown', event => {
@ -46,6 +40,28 @@ class Shortcuts {
});
}
/**
* @param {KeyboardEvent} event
*/
handleShortcutPress(event) {
const keys = [
event.ctrlKey ? 'Ctrl' : '',
event.metaKey ? 'Cmd' : '',
event.key,
];
const combo = keys.filter(s => Boolean(s)).join(' + ');
const shortcutId = this.mapByShortcut[combo];
if (shortcutId) {
const wasHandled = this.runShortcut(shortcutId);
if (wasHandled) {
event.preventDefault();
}
}
}
/**
* Run the given shortcut, and return a boolean to indicate if the event
* was successfully handled by a shortcut action.

View File

@ -1,7 +1,8 @@
<div class="flex-container-row justify-space-between items-center gap-m item-list-row">
<label for="shortcut-{{ $label }}" class="bold flex px-m py-xs">{{ $label }}</label>
<label for="shortcut-{{ $id }}" class="bold flex px-m py-xs">{{ $label }}</label>
<div class="px-m py-xs">
<input type="text"
component="shortcut-input"
class="small flex-none shortcut-input px-s py-xs"
id="shortcut-{{ $id }}"
name="shortcut[{{ $id }}]"

View File

@ -13,9 +13,12 @@
<div class="flex-container-row items-center gap-m wrap mb-m">
<p class="flex mb-none min-width-m text-small text-muted">
Here you can enable or disable keyboard system interface shortcuts, used for navigation
and actions. You can customize each of the shortcuts below.
and actions.
You can customize each of the shortcuts below. Just press your desired key combination
after selecting the input for a shortcut.
</p>
<div class="flex min-width-m text-m-right">
<div class="flex min-width-m text-m-center">
@include('form.toggle-switch', [
'name' => 'enabled',
'value' => $enabled,