Latest state before reworking with cluade 4.6.

This commit is contained in:
2026-02-12 22:44:44 +00:00
parent b1387f4833
commit c745efd1d2
6 changed files with 565 additions and 570 deletions
+8 -205
View File
@@ -16,44 +16,21 @@ class UIDisplayHandlerModule extends BaseModule {
this.pageLeft = null;
this.pageRight = null;
this.paragraphContainer = null;
// State
this.currentParagraphId = 0;
this.pendingParagraphs = [];
// Resources to preload
this.cssPath = '/css/style.css';
this.imagesToPreload = [
'/images/book-3057904.png',
'/images/brown-wooden-flooring.jpg'
];
// Configuration
this.updateConfig({
typography: {
fontFamily: "'EB Garamond', serif",
fontSize: '1.15rem',
lineHeight: 1.5,
maxWidth: 600
},
animation: {
speed: 0.05, // Speed multiplier
useTypingAnimation: true
},
display: {
showChoices: true
}
});
// Bind methods using parent's bindMethods utility
this.bindMethods([
'initializeContainers',
'displayText',
'showChoices',
'processNextParagraph',
'measureText',
'updateTypographySettings',
'loadCSS',
'showChoices',
'preloadImages'
]);
@@ -75,38 +52,16 @@ class UIDisplayHandlerModule extends BaseModule {
this.paragraphLayout = this.getModule('paragraph-layout');
this.layoutRenderer = this.getModule('layout-renderer');
this.animationQueue = this.getModule('animation-queue');
if (!this.paragraphLayout) {
console.error("UIDisplayHandler: Missing paragraph-layout module");
return false;
}
if (!this.layoutRenderer) {
console.error("UIDisplayHandler: Missing layout-renderer module");
return false;
}
if (!this.animationQueue) {
console.error("UIDisplayHandler: Missing animation-queue module");
return false;
}
this.reportProgress(50, "Initializing display containers");
// Initialize container elements
this.initializeContainers();
this.reportProgress(70, "Setting up typography");
// Set up measure function for paragraph layout
const { fontSize, fontFamily } = this.config.typography;
this.paragraphLayout.updateFont(fontSize, fontFamily);
this.reportProgress(90, "Setting up event listeners");
// Set up event listeners
this.setupEventListeners();
this.reportProgress(100, "UI Display Handler ready");
return true;
} catch (error) {
@@ -114,25 +69,7 @@ class UIDisplayHandlerModule extends BaseModule {
return false;
}
}
/**
* Set up event listeners
*/
setupEventListeners() {
// Listen for typography setting changes
this.addEventListener(document, 'ui:typography:update', (event) => {
if (event.detail) {
this.updateTypographySettings(event.detail);
}
});
// Listen for animation speed changes
this.addEventListener(document, 'ui:animation:speed', (event) => {
if (event.detail && typeof event.detail.speed === 'number') {
this.config.animation.speed = event.detail.speed;
}
});
}
/**
* Load CSS file asynchronously and wait for it to be applied
@@ -141,16 +78,6 @@ class UIDisplayHandlerModule extends BaseModule {
*/
loadCSS(cssPath) {
return new Promise((resolve, reject) => {
// Check if the stylesheet is already loaded
const existingLinks = document.querySelectorAll('link[rel="stylesheet"]');
for (const link of existingLinks) {
if (link.href.includes(cssPath)) {
console.log(`UIDisplayHandler: CSS ${cssPath} already loaded`);
resolve();
return;
}
}
// Create link element
const link = document.createElement('link');
link.rel = 'stylesheet';
@@ -159,11 +86,7 @@ class UIDisplayHandlerModule extends BaseModule {
// Set up load and error handlers
link.onload = () => {
console.log(`UIDisplayHandler: CSS ${cssPath} loaded successfully`);
// Give a small delay for the CSS to be applied
setTimeout(() => {
resolve();
}, 50);
resolve();
};
link.onerror = (error) => {
@@ -347,49 +270,6 @@ class UIDisplayHandlerModule extends BaseModule {
return this.context.measureText(text).width;
}
/**
* Update typography settings
* @param {Object} settings - Typography settings
*/
updateTypographySettings(settings) {
let changed = false;
if (settings.fontSize && settings.fontSize !== this.config.typography.fontSize) {
this.config.typography.fontSize = settings.fontSize;
changed = true;
}
if (settings.fontFamily && settings.fontFamily !== this.config.typography.fontFamily) {
this.config.typography.fontFamily = settings.fontFamily;
changed = true;
}
if (settings.lineHeight && settings.lineHeight !== this.config.typography.lineHeight) {
this.config.typography.lineHeight = settings.lineHeight;
changed = true;
}
// If font settings changed, update the paragraph layout
if (changed && this.paragraphLayout) {
// Use the existing updateFont method
this.paragraphLayout.updateFont(
this.config.typography.fontSize,
this.config.typography.fontFamily
);
// Also update our local canvas context
if (this.context) {
this.context.font = `${this.config.typography.fontSize} ${this.config.typography.fontFamily}`;
}
// Dispatch event about typography changes
this.dispatchEvent('ui:font:change', {
fontSize: this.config.typography.fontSize,
fontFamily: this.config.typography.fontFamily,
lineHeight: this.config.typography.lineHeight
});
}
}
/**
* Display text in the UI
@@ -421,83 +301,6 @@ class UIDisplayHandlerModule extends BaseModule {
});
}
/**
* Process the next paragraph in the queue
*/
processNextParagraph() {
if (this.pendingParagraphs.length === 0) return;
const paragraph = this.pendingParagraphs[0];
const { id, text, options, resolve } = paragraph;
try {
// Use the paragraph layout to calculate the optimal layout
const layout = this.paragraphLayout.calculateLayout(text, {
width: this.config.typography.maxWidth,
fontSize: options.fontSize || this.config.typography.fontSize,
fontFamily: options.fontFamily || this.config.typography.fontFamily,
lineHeight: options.lineHeight || this.config.typography.lineHeight
});
if (!layout) {
console.error("UIDisplayHandler: Failed to calculate paragraph layout");
this.pendingParagraphs.shift(); // Remove this paragraph
resolve(null);
// Process next paragraph if any
if (this.pendingParagraphs.length > 0) {
this.processNextParagraph();
}
return;
}
// Store the original text in the layout for TTS
layout.originalText = text;
// Use the layout renderer to create the DOM elements
const paragraphElement = this.layoutRenderer.renderParagraph(layout, {
container: this.paragraphContainer,
id: id,
className: options.className || '',
style: options.style || {},
animateWords: this.config.animation.useTypingAnimation,
animationSpeed: this.config.animation.speed,
tts: options.speak !== false, // Enable TTS by default
onComplete: () => {
// Dispatch event when paragraph is complete
this.dispatchEvent('ui:paragraph:complete', { id });
// Remove this paragraph from the queue
this.pendingParagraphs.shift();
// Resolve the promise with the paragraph element
resolve(paragraphElement);
// Process next paragraph if any
if (this.pendingParagraphs.length > 0) {
this.processNextParagraph();
}
}
});
// Scroll to the new paragraph
if (paragraphElement) {
paragraphElement.scrollIntoView({ behavior: 'smooth', block: 'end' });
}
} catch (error) {
console.error("UIDisplayHandler: Error processing paragraph:", error);
// Remove this paragraph from the queue
this.pendingParagraphs.shift();
resolve(null);
// Process next paragraph if any
if (this.pendingParagraphs.length > 0) {
this.processNextParagraph();
}
}
}
/**
* Show choices in the UI
* @param {Array<Object>} choices - Array of choice objects