-
Notifications
You must be signed in to change notification settings - Fork 34
fix: resumeInfinity/onresume interaction #544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tuncayuk
wants to merge
25
commits into
lightning-js:dev
Choose a base branch
from
tuncayuk:fix/announcer-issue
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
3170c73
fix: resumeInfinity/onresume interaction
tuncayuk 15614f1
chore: ensure target is a SpeechSynthesisUtterance in resumeInfinity …
tuncayuk f35ab5e
fix: ensure infinityTimer is checked against null in clear and resume…
tuncayuk 910df0c
fix: ensure resumeFromKeepAlive is strictly checked for true in onres…
tuncayuk ecb2ddc
fix: improve utterance management and error handling in speech synthesis
tuncayuk d43ee72
chore: add placeholder for getVoices method in speech synthesis
tuncayuk 3e56c9d
chore: improve error handling in speak function of speech synthesis
tuncayuk d2721b6
chore: enhance queue management and debounce handling in announcer
tuncayuk 6aa4a19
fix: add optional chaining to safely check timer state in resumeInfin…
tuncayuk a1ebc94
fix: enhance stop and clear functions to ensure clean state in speech…
tuncayuk 9910a08
fix: add double-check for utterance existence before resuming in resu…
tuncayuk 624604f
fix: add early return in clear function to handle non-existent state
tuncayuk fa88731
chore: remove unused pause event handling in speak function
tuncayuk 4fb38de
fix: add cancelPrevious option to AnnouncerUtterance for managing spe…
tuncayuk cc30b5e
chore: simplify stop api
tuncayuk 3a1a66e
fix: increase debounce duration in processQueue to improve performance
tuncayuk 7d842ee
fix: add waitForSynthReady function to ensure speech synthesis engine…
tuncayuk 41aa289
fix: add enableUtteranceKeepAlive option to improve speech synthesis …
tuncayuk 6f3a1ae
fix: remove previous resolve function in clear method
tuncayuk 2c5255f
fix: remove redundant utterances.delete calls in clear and startKeepA…
tuncayuk 8e9d109
fix: log result of speaking in processQueue for better debugging
tuncayuk 4dc14df
fix: include result in onend callback of speak function for better ha…
tuncayuk 8441944
Removed unneeded variable assignments.
michielvandergeest 9959d92
Removed debug log.
michielvandergeest 1d4884e
Removed debug log and renamed variable.
michielvandergeest File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,8 +25,13 @@ let isProcessing = false | |
| let currentId = null | ||
| let debounce = null | ||
|
|
||
| const isAndroid = /android/i.test((window.navigator || {}).userAgent || '') | ||
| const defaultUtteranceKeepAlive = !isAndroid | ||
|
|
||
| // Global default utterance options | ||
| let globalDefaultOptions = {} | ||
| let globalDefaultOptions = { | ||
| enableUtteranceKeepAlive: defaultUtteranceKeepAlive, | ||
| } | ||
|
|
||
| const noopAnnouncement = { | ||
| then() {}, | ||
|
|
@@ -51,6 +56,11 @@ const toggle = (v) => { | |
| const speak = (message, politeness = 'off', options = {}) => { | ||
| if (active === false) return noopAnnouncement | ||
|
|
||
| // if cancelPrevious option is set, clear the queue and stop current speech | ||
| if (options.cancelPrevious === true) { | ||
| clear() | ||
| } | ||
|
|
||
| return addToQueue(message, politeness, false, options) | ||
| } | ||
|
|
||
|
|
@@ -106,18 +116,22 @@ const addToQueue = (message, politeness, delay = false, options = {}) => { | |
| return done | ||
| } | ||
|
|
||
| let currentResolveFn = null | ||
|
|
||
| const processQueue = async () => { | ||
| if (isProcessing === true || queue.length === 0) return | ||
| isProcessing = true | ||
|
|
||
| const { message, resolveFn, delay, id, options = {} } = queue.shift() | ||
|
|
||
| currentId = id | ||
| currentResolveFn = resolveFn | ||
|
|
||
| if (delay) { | ||
| setTimeout(() => { | ||
| isProcessing = false | ||
| currentId = null | ||
| currentResolveFn = null | ||
| resolveFn('finished') | ||
| processQueue() | ||
| }, delay) | ||
|
|
@@ -134,37 +148,86 @@ const processQueue = async () => { | |
| ...globalDefaultOptions, | ||
| ...options, | ||
| }) | ||
| .then(() => { | ||
| .then((result) => { | ||
| Log.debug(`Announcer - finished speaking: "${message}" (id: ${id})`) | ||
| Log.debug('Announcer - finished result: ', result) | ||
|
|
||
| currentId = null | ||
| currentResolveFn = null | ||
| isProcessing = false | ||
| resolveFn('finished') | ||
| processQueue() | ||
| }) | ||
| .catch((e) => { | ||
| currentId = null | ||
| currentResolveFn = null | ||
| isProcessing = false | ||
| Log.debug(`Announcer - error ("${e.error}") while speaking: "${message}" (id: ${id})`) | ||
| resolveFn(e.error) | ||
| processQueue() | ||
| }) | ||
| debounce = null | ||
| }, 200) | ||
| }, 300) | ||
| } | ||
| } | ||
|
|
||
| const polite = (message, options = {}) => speak(message, 'polite', options) | ||
|
|
||
| const assertive = (message, options = {}) => speak(message, 'assertive', options) | ||
|
|
||
| // Clear debounce timer | ||
| const clearDebounceTimer = () => { | ||
| if (debounce !== null) { | ||
| clearTimeout(debounce) | ||
| debounce = null | ||
| } | ||
| } | ||
|
|
||
| const stop = () => { | ||
| Log.debug('Announcer - stop() called') | ||
|
|
||
| // Clear debounce timer if speech hasn't started yet | ||
| clearDebounceTimer() | ||
|
|
||
| // Always cancel speech synthesis to ensure clean state | ||
| speechSynthesis.cancel() | ||
|
|
||
| // Store resolve function before resetting state | ||
| const prevResolveFn = currentResolveFn | ||
|
|
||
| // Reset state | ||
| currentId = null | ||
| currentResolveFn = null | ||
| isProcessing = false | ||
|
|
||
| // Resolve promise if there was an active utterance | ||
| if (prevResolveFn) { | ||
| prevResolveFn('interrupted') | ||
| } | ||
| } | ||
|
|
||
| const clear = () => { | ||
| Log.debug('Announcer - clear() called') | ||
|
|
||
| // Clear debounce timer | ||
| clearDebounceTimer() | ||
|
|
||
| // Cancel any active speech synthesis | ||
| speechSynthesis.cancel() | ||
|
Comment on lines
+207
to
+208
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does clearing the queue also mean that we want to cancel the current message being spoken out? I'm not sure that it should always be so .. |
||
|
|
||
| // Resolve all pending items in queue | ||
| while (queue.length > 0) { | ||
| const item = queue.shift() | ||
| if (item.resolveFn) { | ||
| Log.debug(`Announcer - clearing queued item: "${item.message}" (id: ${item.id})`) | ||
| item.resolveFn('cleared') | ||
| } | ||
| } | ||
|
|
||
| // Reset state | ||
| currentId = null | ||
| currentResolveFn = null | ||
| isProcessing = false | ||
| queue.length = 0 | ||
| } | ||
|
|
||
| const configure = (options = {}) => { | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there a specific reason for increasing the timeout from 200 to 300?