Moments across up to four pages: stacked in Flow, side by side in Page/Book (BL-0055)
The save sheet gets "+ Previous page" / "+ Next page" (right to left for rtl in Page/Book) for a picture that runs over several pages. Moments store a layout (row | column); pages the selected region does not touch are dropped. Crops, viewer and gallery draw both layouts. Dialogs now clean up directly instead of waiting for the "close" event, which a backgrounded page can deliver late (a closed sheet stayed in the page and M stopped working). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
74842c59e0
commit
5497e8bfbc
9 files changed
+175
-92
No files matched your search
+19
-17
@@ -502,39 +502,41 @@
|
||||
if (action) keyActions[action](e);
|
||||
});
|
||||
function showKeys() {
|
||||
const dialog = h('dialog', { class: 'moment-dialog key-dialog' },
|
||||
const dialog = openDialog('key-dialog', () => stage.focus({ preventScroll: true }));
|
||||
dialog.append(
|
||||
h('div', { class: 'moment-head' }, h('h2', {}, 'Keyboard shortcuts'),
|
||||
h('button', { class: 'btn icon', type: 'button', 'aria-label': 'Close', onclick: () => dialog.close() }, '×')),
|
||||
h('button', { class: 'btn icon', type: 'button', 'aria-label': 'Close', onclick: () => dialog.done() }, '×')),
|
||||
keyTable([{ title: 'Reader', keys: READER_KEYS }]),
|
||||
h('p', { class: 'muted small' }, 'Also listed in Settings → Keyboard shortcuts.'));
|
||||
dialog.addEventListener('close', () => { dialog.remove(); stage.focus({ preventScroll: true }); });
|
||||
document.body.append(dialog);
|
||||
dialog.showModal();
|
||||
}
|
||||
|
||||
// ---------- moments ----------
|
||||
const momentPages = new Set((D.moments || []).flatMap(x => x.pages));
|
||||
// The page(s) on screen, left to right as displayed. In Flow the page at the reading line.
|
||||
const momentPage = p => ({ i: p.i, u: p.u, w: D.pages[p.i].w, h: D.pages[p.i].h, r: p.r });
|
||||
// Positions in `list` of the page(s) on screen, in reading order. In Flow the page at the reading line.
|
||||
function currentRange() {
|
||||
if (atEnd && mode !== 'flow') return null;
|
||||
const ks = (mode === 'book' ? shown : [cur]).filter(k => list[k]);
|
||||
return ks.length ? [Math.min(...ks), Math.max(...ks)] : null;
|
||||
}
|
||||
function currentPages() {
|
||||
if (atEnd && mode !== 'flow') return [];
|
||||
const ks = mode === 'book' ? shown.slice() : [cur];
|
||||
if (mode === 'book' && rtl) ks.reverse();
|
||||
return ks.filter(k => list[k]).map(k => {
|
||||
const p = list[k], raw = D.pages[p.i];
|
||||
return { i: p.i, u: p.u, w: raw.w, h: raw.h, r: p.r };
|
||||
});
|
||||
const range = currentRange();
|
||||
return range ? list.slice(range[0], range[1] + 1).map(momentPage) : [];
|
||||
}
|
||||
let momentOpen = false;
|
||||
async function saveMoment() {
|
||||
const pages = currentPages();
|
||||
if (!pages.length) return toast('No page here');
|
||||
const range = currentRange();
|
||||
if (!range) return toast('No page here');
|
||||
if (momentOpen) return;
|
||||
momentOpen = true;
|
||||
const chapter = D.chapters.find(c => c.id === D.chapter.id), book = D.books.length > 1 && chapter && D.books.find(b => b.key === chapter.book);
|
||||
// A picture can run over several pages: the sheet can add neighbours, stacked in Flow, side by side in Page/Book.
|
||||
const saved = await momentSheet({
|
||||
heading: 'Save moment', pages,
|
||||
context: [D.manga.title, [book && book.label, D.chapter.label + (D.chapter.title ? ' · ' + D.chapter.title : ''), momentPageLabel(pages)].filter(Boolean).join(' · ')],
|
||||
save: async v => (await api('api/moments', { m: D.manga.id, c: D.chapter.id, v: D.version, pages: v.pages.map(p => p.i), region: v.region, cat: v.cat, note: v.note })).moment,
|
||||
heading: 'Save moment', sequence: list.map(momentPage), range, layout: mode === 'flow' ? 'column' : 'row', rtl,
|
||||
context: [D.manga.title, [book && book.label, D.chapter.label + (D.chapter.title ? ' · ' + D.chapter.title : '')].filter(Boolean).join(' · ')],
|
||||
save: async v => (await api('api/moments', { m: D.manga.id, c: D.chapter.id, v: D.version, pages: v.pages.map(p => p.i), layout: v.layout,
|
||||
region: v.region, cat: v.cat, note: v.note })).moment,
|
||||
});
|
||||
momentOpen = false;
|
||||
stage.focus({ preventScroll: true });
|
||||
|
||||
Reference in new issue
Block a user