281 gap skipping fixes#285
Merged
Merged
Conversation
registerStrikeThrus rebuilds audioDataArray and re-attaches skip listeners against the current transcript with the current removeGapsEnabled / gapThreshold / gapBuffer values, but it was only bound to hyperaudioTranscriptLoaded — which only the localStorage load path dispatches. Transcribe (Deepgram/Whisper) and JSON/SRT/VTT import dispatch hyperaudioInit instead, so the skip pipeline kept pointing at the previous transcript's word data. Bind registerStrikeThrus to hyperaudioInit as well. The two events are disjoint, so no double-fire risk.
Sub-minute savings still render as "X.X seconds" so the decimal precision is visible at small durations. From 60 seconds upward, switch to labeled units (1m 30s, 1h 2m 5s) which reads naturally inline and drops zero components rather than forcing a leading "00:" the way HH:MM:SS would.
Two related changes so the savings message and skip pipeline stay in sync with the actual transcript content: - Call updateGapSavingsMessage() from registerStrikeThrus so the "Playback shortened by X" message reflects the new transcript on every rebuild (transcribe / import / localStorage load / strikethrough toggle). - Add a debounced input listener delegated on document that runs registerStrikeThrus after 150ms of edit inactivity on #hypertranscript. Deleting a word turns its time slot into a gap, which should be reflected in both the skip pipeline and the savings message. Delegated on document so the listener survives transcript element replacement via restoreTranscript.
The hyperaudio-lite library tracks the active word via a cached wordArr and a chained setTimeout that polls currentTime, but it only natively listens for play/pause — not seeked or DOM changes. That leaves two windows where the highlight freezes: - After the user edits the transcript, the polling chain crashes silently if it touches a now-detached span (word.n.parentNode is null, .classList throws inside the setTimeout callback). - After our gap-skip code seeks past a silent section, the library is unaware of the jump and waits for its stale timer to fire seconds later before re-locating the active word. Add a refreshHyperaudioInstance() helper that rebuilds wordArr and parentElements, updates the visual state, then kicks checkPlayHead to restart the polling chain. Call it from registerStrikeThrus so edits and new transcripts both refresh the library's caches. Also kick checkPlayHead from checkStrikeThrus right after a gap skip so the highlight resyncs immediately to the post-skip word.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Four small fixes around gap-skip so the feature feels live instead of stale. Addresses #281 and #284
1. Carry settings across to new transcripts (
483ef62)registerStrikeThrus(which rebuildsaudioDataArrayand re-attaches skip listeners against thecurrent transcript and gap settings) was only bound to
hyperaudioTranscriptLoaded, which only thelocalStorage load path dispatches. Deepgram, Whisper, and JSON/SRT/VTT import dispatch
hyperaudioInitinstead, so the skip pipeline kept pointing at the previous transcript's word data.
Fix: bind
registerStrikeThrustohyperaudioInitas well. The two events are disjoint, so nodouble-fire.
2. Labeled-units format for the savings line (
28e3507)"Playback shortened by 3725.4 seconds" doesn't scale well past a minute. Sub-minute savings still render
as
12.3 seconds(decimal preserved), but from 60s upward it switches to labeled units that drop zerocomponents:
1m 30s,1h 2m 5s,1h.3. Recalculate on transcript edits and new transcripts (
a2c43b6)updateGapSavingsMessage()fromregisterStrikeThrusso the "Playback shortened by X" linereflects the new transcript on every rebuild (transcribe / import / localStorage load / strikethrough
toggle).
inputlistener delegated ondocumentthat callsregisterStrikeThrusafter 150msof edit inactivity on
#hypertranscript. Deleting a word turns its time slot into a gap, which shouldbe reflected in both the skip pipeline and the savings message. Delegated on
documentso the listenersurvives transcript element replacement via
restoreTranscript.4. Keep the karaoke highlight in sync (
4983b0e)The hyperaudio-lite library tracks the active word via a cached
wordArrand a chainedsetTimeoutthat polls
currentTime, but it only natively listens forplay/pause— notseekedor DOMmutations. That leaves two windows where the highlight freezes:
(
word.n.parentNodeisnull,.classListthrows inside thesetTimeoutcallback), and nothingrestarts it.
myPlayer.currentTime = nextStart + 0.05directly; the libraryhas no idea we jumped and waits for its stale timer to fire seconds later before relocating the active
word.
Fix: a
refreshHyperaudioInstance()helper rebuildswordArrandparentElements, updates the visualstate, and kicks
checkPlayHeadto restart the polling chain. Called fromregisterStrikeThrussoedits and new transcripts both refresh the library's caches. Also kick
checkPlayHeadfromcheckStrikeThrusright after a gap skip so the highlight resyncs to the post-skip word immediatelyrather than waiting for the stale timer.
Test plan
fire and the savings line updates.
updates and the new gap (the deleted word's slot) is skipped on playback.
edited word).
of the gap).
X.X secondsunder 60s,Xm Ysbetween 1–59 min,Xh Ym Zsfor ≥ 1h.