diff --git a/activities/EbookReader.activity/css/activity.css b/activities/EbookReader.activity/css/activity.css index a0208fc0b8..122be3c367 100644 --- a/activities/EbookReader.activity/css/activity.css +++ b/activities/EbookReader.activity/css/activity.css @@ -349,3 +349,23 @@ body { box-shadow: 0 0 0 0rem rgba(158, 158, 158, .5); border: 0px; } + +#read-button { + background-image: url("../icons/read.svg"); + background-size: contain; + background-repeat: no-repeat; + width: 47px; + height: 47px; + border: none; + outline: none; +} + +#read-play { + background-image: url("../icons/read-play.svg"); + background-size: contain; + background-repeat: no-repeat; + width: 47px; + height: 47px; + border: none; + outline: none; + } \ No newline at end of file diff --git a/activities/EbookReader.activity/icons/read-play.svg b/activities/EbookReader.activity/icons/read-play.svg new file mode 100644 index 0000000000..772bab3e6a --- /dev/null +++ b/activities/EbookReader.activity/icons/read-play.svg @@ -0,0 +1,23 @@ + + image/svg+xml + + background + + + + Layer 1 + + + + + + + + + + + + + + + diff --git a/activities/EbookReader.activity/icons/read.svg b/activities/EbookReader.activity/icons/read.svg new file mode 100644 index 0000000000..e1e2a5f81a --- /dev/null +++ b/activities/EbookReader.activity/icons/read.svg @@ -0,0 +1,53 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/activities/EbookReader.activity/js/activity.js b/activities/EbookReader.activity/js/activity.js index e8988ed952..f15ff5ed0b 100644 --- a/activities/EbookReader.activity/js/activity.js +++ b/activities/EbookReader.activity/js/activity.js @@ -15,7 +15,10 @@ var app = new Vue({ currentEpub: null, currentView: LibraryViewer, currentLibrary: {database: []}, - timer: null + timer: null, + isSpeaking: false, + isPaused: false, + utterance: null }, created: function() { @@ -59,6 +62,8 @@ var app = new Vue({ }); }); + this.$refs.toolbar.$on("read-aloud-clicked", this.toggleReadAloud); + // Handle resize window.addEventListener("resize", function() { vm.onResize(); @@ -235,6 +240,64 @@ var app = new Vue({ } }, + toggleReadAloud: function() { + + if (!('speechSynthesis' in window)) { + alert("Text-to-Speech is not supported in your browser."); + return; + } + + + if (!this.utterance) { + + let iframe = document.querySelector("#area iframe"); + if (!iframe || !iframe.contentDocument) { + alert("Content not available for reading."); + return; + } + + + let storyText = iframe.contentDocument.body.innerText; + console.log("Extracted full iframe text:", storyText); + + if (!storyText || storyText.trim() === "") { + alert("No text available for narration."); + return; + } + + this.utterance = new SpeechSynthesisUtterance(storyText); + this.utterance.rate = 1.0; + this.utterance.pitch = 1.0; + this.utterance.onend = () => { + + this.isSpeaking = false; + this.isPaused = false; + this.utterance = null; + }; + } + + + if (!this.isSpeaking && !this.isPaused) { + + window.speechSynthesis.speak(this.utterance); + this.isSpeaking = true; + this.isPaused = false; + console.log("Speech started from the beginning"); + } else if (this.isSpeaking && !this.isPaused) { + + window.speechSynthesis.pause(); + this.isSpeaking = false; + this.isPaused = true; + console.log("Speech paused"); + } else if (!this.isSpeaking && this.isPaused) { + + window.speechSynthesis.resume(); + this.isSpeaking = true; + this.isPaused = false; + console.log("Speech resumed from paused position"); + } + }, + onHelp: function() { var options = {}; options.switchbutton = this.$refs.toolbar.$refs.switchbutton.$el; @@ -278,7 +341,12 @@ var app = new Vue({ }, onStop: function() { + + window.speechSynthesis.cancel(); + this.utterance = null; + this.isSpeaking = false; + this.isPaused = false; this.saveContextToJournal(); - } + } } }); diff --git a/activities/EbookReader.activity/js/toolbar.js b/activities/EbookReader.activity/js/toolbar.js index 564f3db5ca..7d4fd3a745 100644 --- a/activities/EbookReader.activity/js/toolbar.js +++ b/activities/EbookReader.activity/js/toolbar.js @@ -27,7 +27,10 @@ var Toolbar = {
- + +
+ + @@ -43,10 +46,21 @@ var Toolbar = { stringSettings: '', stringHelp: '', stringFullscreen: '', - stringContents: '' + stringContents: '', + stringReadAloud: '' } } }, + + computed: { + readButtonIcon() { + if (this.$root.isSpeaking && !this.$root.isPaused) { + return "read-play"; + } + return "read-button"; + } + }, + methods: { localized: function(localization) { var vm = this; @@ -66,6 +80,10 @@ var Toolbar = { getReader: function() { return EbookReader; - } + }, + + onReadAloud: function() { + this.$emit("read-aloud-clicked"); + }, } }