Fix page label and restore nav code after bad clone-removal revert
The previous commit's clone removal corrupted the flip (shared live canvas overwritten mid- animation -> flicker); reverting it fixed the flip but also discarded code that had ridden into that commit and broke the page label. Recovering: - Page label: the right-page pageNumber lookup returned null (meta not populated for the queried index) so every spread read 0. Now derive the printed number from the index (frontmatter pages 0-2 are unnumbered, so right-page index N prints as N-2), preferring the paginated pageNumber when present. Title still reads 0. - Restored the manual-navigation-busy guard and the written-content navigation cap (no flipping forward into blank leaves before content exists; title stays on its own spread). The flip flicker fix is the clone restoration in the prior revert; this restores the label and navigation behavior on top of it. Suite 182. Flip-flicker and per-paragraph stutter still need verification on a real (non-throttled) foreground tab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1950,14 +1950,24 @@ function getCurrentPagePosition() {
|
||||
function getMaxNavigableSpread() {
|
||||
const spreadCount = Math.max(1, Math.round(Number(bookPaginationState.spreadCount || 1)));
|
||||
const visitedSpread = pageToSpreadIndex(maxVisitedPagePosition);
|
||||
return Math.max(0, Math.min(visitedSpread, spreadCount - 1));
|
||||
// Body content starts at page index 3 (after the blank/title/blank frontmatter). Until any
|
||||
// content is written the book stays on the title spread — no flipping forward into blank
|
||||
// leaves. Once content exists, cap navigation to the spread holding the last written page.
|
||||
const writtenPageLimit = Math.max(0, Number(bookPaginationState.writtenPageLimit || 0));
|
||||
const contentSpread = writtenPageLimit >= 3 ? pageToSpreadIndex(writtenPageLimit) : 0;
|
||||
return Math.max(0, Math.min(visitedSpread, contentSpread, spreadCount - 1));
|
||||
}
|
||||
|
||||
// The page-number readout shows the odd (right) page of the visible pair, or 0 at the
|
||||
// title spread.
|
||||
// Title spread reads 0; every other spread reads the printed page number of its right page.
|
||||
// Frontmatter (blank/title/blank) occupies page indices 0-2 and is unnumbered, so the first
|
||||
// body page (index 3) prints as 1 and right-page index N prints as N-2. Prefer the paginated
|
||||
// page number when present, otherwise derive it from the index.
|
||||
function spreadPageLabel(spreadIndex) {
|
||||
const spread = Math.max(0, Math.round(Number(spreadIndex || 0)));
|
||||
return spread <= 0 ? '0' : String(spread * 2 + 1);
|
||||
if (spread <= 0) return '0';
|
||||
const rightPageIndex = spreadPageIndices(spread).right;
|
||||
const pageNumber = getPaginationPageMeta(rightPageIndex)?.pageNumber;
|
||||
return pageNumber != null ? String(pageNumber) : String(Math.max(0, rightPageIndex - 2));
|
||||
}
|
||||
|
||||
function scheduleBookRebuild(reason = 'scheduled') {
|
||||
@@ -2130,6 +2140,16 @@ function ensureBottomNavigation() {
|
||||
}
|
||||
|
||||
function navigateToSpread(targetSpread) {
|
||||
if (isManualBookNavigationBusy()) {
|
||||
markPageTextureTiming('navigation:blocked-busy', {
|
||||
targetSpread,
|
||||
activeFlips: activeFlips.length,
|
||||
revealActive: hasActivePageReveal(),
|
||||
playbackActive: document.documentElement.dataset.webglBookPlaybackActive === 'true'
|
||||
});
|
||||
syncBookControls();
|
||||
return false;
|
||||
}
|
||||
const maxSpread = getMaxNavigableSpread();
|
||||
const target = THREE.MathUtils.clamp(Math.round(Number(targetSpread || 0)), 0, maxSpread);
|
||||
const currentSpread = Math.max(0, Math.round(Number(bookPaginationState.spreadIndex || 0)));
|
||||
@@ -2159,7 +2179,7 @@ function navigateByPageDelta(delta) {
|
||||
}
|
||||
|
||||
function syncBookControls() {
|
||||
const busy = activeFlips.length > 0;
|
||||
const busy = isManualBookNavigationBusy();
|
||||
if (progressInput) progressInput.value = readingProgress.toFixed(3);
|
||||
if (progressValue) progressValue.textContent = readingProgress.toFixed(2);
|
||||
if (pageCountInput) pageCountInput.value = String(bookPageCount);
|
||||
@@ -2188,10 +2208,12 @@ function syncBottomNavigation() {
|
||||
bottomNavigation.root.style.setProperty('--book-nav-reserve-start', '1');
|
||||
bottomNavigation.root.dataset.bookSize = String(bookPageCount);
|
||||
bottomNavigation.root.dataset.pageReserve = String(pageReserve);
|
||||
bottomNavigation.startButton.disabled = activeFlips.length > 0 || currentSpread <= 0;
|
||||
bottomNavigation.backButton.disabled = activeFlips.length > 0 || currentSpread <= 0;
|
||||
bottomNavigation.forwardButton.disabled = activeFlips.length > 0 || currentSpread >= maxSpread;
|
||||
bottomNavigation.endButton.disabled = activeFlips.length > 0 || currentSpread >= maxSpread;
|
||||
const busy = isManualBookNavigationBusy();
|
||||
bottomNavigation.slider.disabled = busy;
|
||||
bottomNavigation.startButton.disabled = busy || currentSpread <= 0;
|
||||
bottomNavigation.backButton.disabled = busy || currentSpread <= 0;
|
||||
bottomNavigation.forwardButton.disabled = busy || currentSpread >= maxSpread;
|
||||
bottomNavigation.endButton.disabled = busy || currentSpread >= maxSpread;
|
||||
}
|
||||
|
||||
function handlePageTextureRecords(event) {
|
||||
@@ -3339,6 +3361,12 @@ function hasActivePageReveal() {
|
||||
});
|
||||
}
|
||||
|
||||
function isManualBookNavigationBusy() {
|
||||
return activeFlips.length > 0
|
||||
|| hasActivePageReveal()
|
||||
|| document.documentElement.dataset.webglBookPlaybackActive === 'true';
|
||||
}
|
||||
|
||||
function applyResidentSpreadTextures(spreadIndex, reason = 'resident-spread', options = {}) {
|
||||
const skipSides = Array.isArray(options.skipSides) ? options.skipSides : [];
|
||||
const pageIndices = spreadPageIndices(spreadIndex);
|
||||
|
||||
Reference in New Issue
Block a user