Checkpoint before line-grid scrolling refactor
This commit is contained in:
@@ -23,6 +23,7 @@ class SentenceQueueModule extends BaseModule {
|
||||
this.autoplay = true;
|
||||
this.inputMode = 'text';
|
||||
this.lastContinueAt = 0;
|
||||
this.pauseBeforeNextReason = null;
|
||||
|
||||
// Bind methods
|
||||
this.bindMethods([
|
||||
@@ -30,6 +31,7 @@ class SentenceQueueModule extends BaseModule {
|
||||
'addSentence',
|
||||
'processNextSentence',
|
||||
'setOnSentenceReady',
|
||||
'pauseBeforeNext',
|
||||
'completeSentence',
|
||||
'getCacheKey',
|
||||
'getPreparedSentence',
|
||||
@@ -105,6 +107,10 @@ class SentenceQueueModule extends BaseModule {
|
||||
this.onSentenceReadyCallback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
pauseBeforeNext(reason = 'manual-pause') {
|
||||
this.pauseBeforeNextReason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sentence to the queue
|
||||
@@ -139,6 +145,12 @@ class SentenceQueueModule extends BaseModule {
|
||||
const item = this.sentenceQueue[0];
|
||||
|
||||
try {
|
||||
if (this.pauseBeforeNextReason) {
|
||||
const reason = this.pauseBeforeNextReason;
|
||||
this.pauseBeforeNextReason = null;
|
||||
await this.waitForManualContinue(reason);
|
||||
}
|
||||
|
||||
const sentence = await this.getPreparedSentence(item);
|
||||
|
||||
// Prefetch far enough ahead that media pauses do not block TTS
|
||||
@@ -294,6 +306,8 @@ class SentenceQueueModule extends BaseModule {
|
||||
kind: metadata.type,
|
||||
text: text || '',
|
||||
turnId: metadata.turnId ?? null,
|
||||
blockId: metadata.blockId ?? null,
|
||||
gameId: metadata.gameId ?? null,
|
||||
status: 'ready',
|
||||
metadata: imageLayout ? { ...metadata, imageLayout } : metadata,
|
||||
tts: { duration: 0, provider: null, audioData: null, play: null, stop: null, enabled: false },
|
||||
@@ -325,6 +339,8 @@ class SentenceQueueModule extends BaseModule {
|
||||
kind: metadata.type === 'heading' ? 'heading' : 'paragraph',
|
||||
text,
|
||||
turnId: metadata.turnId ?? null,
|
||||
blockId: metadata.blockId ?? null,
|
||||
gameId: metadata.gameId ?? null,
|
||||
paragraphIndex: metadata.paragraphIndex ?? null,
|
||||
isFirstParagraphInChapter: Boolean(metadata.isFirstParagraphInChapter),
|
||||
role: metadata.role || (metadata.type === 'heading' ? 'chapter-heading' : 'body'),
|
||||
@@ -746,20 +762,27 @@ class SentenceQueueModule extends BaseModule {
|
||||
probe.remove();
|
||||
|
||||
const pageWidth = storyElement.clientWidth;
|
||||
const size = String(metadata.size || 'landscape').toLowerCase();
|
||||
const aspect = size === 'portrait' ? (9 / 16) : size === 'square' ? 1 : (16 / 9);
|
||||
const imageGap = lineHeight * 0.9;
|
||||
const maxWidth = size === 'portrait' ? pageWidth * 0.5 : pageWidth;
|
||||
const naturalHeight = maxWidth / aspect;
|
||||
const requestedSize = String(metadata.size || 'landscape').toLowerCase();
|
||||
const size = requestedSize === 'widescreen' ? 'landscape' : requestedSize;
|
||||
const isPortrait = size === 'portrait';
|
||||
const aspect = isPortrait ? (9 / 16) : size === 'square' ? 1 : (16 / 9);
|
||||
const imageGap = lineHeight;
|
||||
const maxOuterWidth = isPortrait ? pageWidth * 0.5 : pageWidth;
|
||||
const maxImageWidth = isPortrait
|
||||
? Math.max(lineHeight * 4, maxOuterWidth - imageGap)
|
||||
: maxOuterWidth;
|
||||
const naturalHeight = maxImageWidth / aspect;
|
||||
const imageLineCount = Math.max(1, Math.floor(naturalHeight / lineHeight));
|
||||
const height = imageLineCount * lineHeight;
|
||||
const width = Math.min(maxWidth, height * aspect);
|
||||
const verticalMargin = lineHeight / 2;
|
||||
const lineCount = imageLineCount + 1;
|
||||
const verticalMargin = isPortrait ? lineHeight / 2 : 0;
|
||||
const lineCount = isPortrait ? imageLineCount + 1 : imageLineCount;
|
||||
const height = isPortrait
|
||||
? Math.max(lineHeight, (lineCount * lineHeight) - (verticalMargin * 2))
|
||||
: imageLineCount * lineHeight;
|
||||
const width = Math.min(maxImageWidth, height * aspect);
|
||||
|
||||
if (size === 'portrait') {
|
||||
if (isPortrait) {
|
||||
this.activeImageWrap = {
|
||||
lines: lineCount,
|
||||
lines: lineCount + 1,
|
||||
width: width + imageGap,
|
||||
imageWidth: width,
|
||||
gap: imageGap,
|
||||
|
||||
Reference in New Issue
Block a user