Reader: bookmark button and M save the page (Flow: page at the reading line, Book: the spread) with an optional dragged region, exactly one category (Twist, Hot, Awesome, Cute, Funny, Feels) and a note. I now toggles the bars; ? lists all keys. Keys dispatch through public/keys.js, which also feeds the new Settings -> Keyboard shortcuts section. Manga page: "Your moments" strip of crops (story or recent order, category filters), viewer with step, full page, edit, delete and "Open in reader" (read.html ...&p=). Moments point at pages by file name and show "page moved" when the file is gone. Private per user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
36 lines
2.2 KiB
JavaScript
36 lines
2.2 KiB
JavaScript
'use strict';
|
||
/*
|
||
* Keyboard shortcuts. The reader dispatches keys through READER_KEYS, and Settings and the reader's "?" list
|
||
* are drawn from the same tables, so the documentation cannot drift from what the keys do.
|
||
*/
|
||
const READER_KEYS = [
|
||
{ keys: ['ArrowLeft', 'ArrowRight'], label: '← →', action: 'turn', text: 'Previous / next page, following the reading direction' },
|
||
{ keys: [' ', 'PageDown'], label: 'Space · Page Down', action: 'forward', text: 'Next page (Shift + Space: previous) · Page and Book mode' },
|
||
{ keys: ['PageUp'], label: 'Page Up', action: 'back', text: 'Previous page · Page and Book mode' },
|
||
{ keys: ['+', '='], label: '+', action: 'zoomIn', text: 'Zoom in 5 %' },
|
||
{ keys: ['-'], label: '−', action: 'zoomOut', text: 'Zoom out 5 %' },
|
||
{ keys: ['0'], label: '0', action: 'zoomFit', text: 'Fit the screen (100 %)' },
|
||
{ keys: ['m', 'M'], label: 'M', action: 'moment', text: 'Save a moment of the page you are on' },
|
||
{ keys: ['i', 'I'], label: 'I', action: 'bars', text: 'Show or hide the controls' },
|
||
{ keys: ['Escape'], label: 'Esc', action: 'bars', text: 'Show or hide the controls (closes an open dialog first)' },
|
||
{ keys: ['f', 'F'], label: 'F', action: 'fullscreen', text: 'Fullscreen' },
|
||
{ keys: ['?'], label: '?', action: 'help', text: 'Show these shortcuts' },
|
||
];
|
||
const MOMENT_VIEWER_KEYS = [
|
||
{ keys: ['ArrowLeft', 'ArrowRight'], label: '← →', action: 'step', text: 'Previous / next moment' },
|
||
{ keys: ['Escape'], label: 'Esc', action: 'close', text: 'Close the viewer' },
|
||
];
|
||
const KEY_GROUPS = [
|
||
{ title: 'Reader', keys: READER_KEYS },
|
||
{ title: 'Moments viewer (manga page)', keys: MOMENT_VIEWER_KEYS },
|
||
];
|
||
const keyAction = (table, key) => (table.find(entry => entry.keys.includes(key)) || {}).action || null;
|
||
|
||
function keyTable(groups = KEY_GROUPS) {
|
||
return groups.map(group => h('section', { class: 'key-group' }, h('h3', {}, group.title),
|
||
h('table', { class: 'key-table' }, h('tbody', {}, group.keys.map(entry =>
|
||
h('tr', {}, h('td', {}, h('kbd', {}, entry.label)), h('td', {}, entry.text)))))));
|
||
}
|
||
|
||
if (typeof module !== 'undefined') module.exports = { READER_KEYS, MOMENT_VIEWER_KEYS, KEY_GROUPS, keyAction };
|