diff --git a/src/js/Storage.js b/src/js/Storage.js index 2240caee..72c23825 100644 --- a/src/js/Storage.js +++ b/src/js/Storage.js @@ -315,6 +315,10 @@ export class Storage { * @param {string} htmlFileName - The name of the presentation HTML file. */ async createNarratedHTMLFile(name, location, htmlFileName) { + const t = this.presentation.narrativeType; + if (!t || t === "none") { + return; + } try { const fileDescriptor = await this.backend.find(name, location); await this.backend.save(fileDescriptor, this.exportNarratedHTML(htmlFileName)); diff --git a/src/js/model/Presentation.js b/src/js/model/Presentation.js index 08213f90..98c9d34c 100644 --- a/src/js/model/Presentation.js +++ b/src/js/model/Presentation.js @@ -701,6 +701,25 @@ export class Presentation extends EventEmitter { * @type {boolean} */ this.updateURLOnFrameChange = true; + /** The narrative file type or "none" if narration is disabled. + * + * @default + * @type {string} */ + this.narrativeType = "none"; + + /** The narrative file name or relative path. + * + * @default + * @type {string} */ + this.narrativeFile = "narrative.flac"; + + /** The narrative time-to-slide data mapping the time + * moments (in seconds) to their corresponding frame number (one-based). + * + * @default + * @type {string} */ + this.narrativeTimeToSlide = "0"; + /** The last export document type. * * @default @@ -846,6 +865,9 @@ export class Presentation extends EventEmitter { enableMouseRotation : this.enableMouseRotation, enableMouseNavigation : this.enableMouseNavigation, updateURLOnFrameChange : this.updateURLOnFrameChange, + narrativeType : this.narrativeType, + narrativeFile : this.narrativeFile, + narrativeTimeToSlide : this.narrativeTimeToSlide, exportType : this.exportType, exportToPDFPageSize : this.exportToPDFPageSize, exportToPDFPageOrientation: this.exportToPDFPageOrientation, @@ -902,6 +924,9 @@ export class Presentation extends EventEmitter { copyIfSet(this, storable, "enableMouseRotation"); copyIfSet(this, storable, "enableMouseNavigation"); copyIfSet(this, storable, "updateURLOnFrameChange"); + copyIfSet(this, storable, "narrativeType"); + copyIfSet(this, storable, "narrativeFile"); + copyIfSet(this, storable, "narrativeTimeToSlide"); copyIfSet(this, storable, "exportType"); copyIfSet(this, storable, "exportToPDFPageSize"); copyIfSet(this, storable, "exportToPDFPageOrientation"); diff --git a/src/js/view/Properties.js b/src/js/view/Properties.js index 7a89ac95..81506226 100644 --- a/src/js/view/Properties.js +++ b/src/js/view/Properties.js @@ -74,6 +74,7 @@ export class Properties extends VirtualDOMView { render() { switch (this.mode) { case "preferences": return this.renderPreferences(); + case "narration": return this.renderNarrationProperties(); case "export": return this.renderExportTool(); default: return this.renderPresentationProperties(); } @@ -351,6 +352,86 @@ export class Properties extends VirtualDOMView { ]); } + /** Render the properties view for a presentation-wide narrative. + * + * Three properties will be configured: + * 1. narrativeType: the audio tag type; this field is a hint to + * guide user in selection of an appropriate format, although + * the browser can automatically detect the correct type by + * itself. If this value is set to "none", narration will be + * disabled. If it is set to flac or ogg, the corresponding + * mimetype will be set for the