Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Textream/Textream/BrowserServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,21 +187,28 @@ class BrowserServer {

let charCount: Int
let mode = NotchSettings.shared.listeningMode
// Check if scroll already reached the end, to stop advancing the timer
let scrollDone = totalCharCount > 0 && charOffsetForWordProgress(timerWordProgress) >= totalCharCount
switch mode {
case .wordTracking:
charCount = speechRecognizer?.recognizedCharCount ?? 0
case .classic:
timerWordProgress += NotchSettings.shared.scrollSpeed * 0.1
if !scrollDone {
timerWordProgress += NotchSettings.shared.scrollSpeed * 0.1
}
charCount = charOffsetForWordProgress(timerWordProgress)
case .silencePaused:
if speechRecognizer?.isListening == true && (speechRecognizer?.isSpeaking ?? false) {
if !scrollDone && speechRecognizer?.isListening == true && (speechRecognizer?.isSpeaking ?? false) {
timerWordProgress += NotchSettings.shared.scrollSpeed * 0.1
}
charCount = charOffsetForWordProgress(timerWordProgress)
}

let effective = min(charCount, totalCharCount)
let isDone = totalCharCount > 0 && effective >= totalCharCount
let rawDone = totalCharCount > 0 && effective >= totalCharCount
// In classic/silence-paused modes on the last page, suppress Done so the
// browser keeps showing the prompter text (speaker may still be talking).
let isDone = rawDone && (mode == .wordTracking || hasNextPage)

let highlightWords = mode == .wordTracking

Expand Down
4 changes: 2 additions & 2 deletions Textream/Textream/ExternalDisplayController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ struct ExternalDisplayView: View {
ZStack {
Color.black.ignoresSafeArea()

if isDone {
if isDone && (listeningMode == .wordTracking || hasNextPage) {
doneView
} else {
prompterView
Expand All @@ -192,7 +192,7 @@ struct ExternalDisplayView: View {
.scaleEffect(x: mirrorAxis?.scaleX ?? 1, y: mirrorAxis?.scaleY ?? 1)
.animation(.easeInOut(duration: 0.5), value: isDone)
.onChange(of: isDone) { _, done in
if done {
if done && listeningMode == .wordTracking {
speechRecognizer.stop()
}
}
Expand Down
32 changes: 21 additions & 11 deletions Textream/Textream/NotchOverlayController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ struct NotchOverlayView: View {

if content.showPagePicker {
pagePickerView
} else if isDone {
} else if isDone && (listeningMode == .wordTracking || hasNextPage) {
doneView
} else {
prompterView
Expand Down Expand Up @@ -765,12 +765,19 @@ struct NotchOverlayView: View {
.animation(.easeInOut(duration: 0.5), value: isDone)
.onChange(of: isDone) { _, done in
if done {
// Stop listening when page is done
speechRecognizer.stop()
// In word tracking mode, stop listening when page is done
if listeningMode == .wordTracking {
speechRecognizer.stop()
}
if !hasNextPage {
// Show "Done" briefly, then auto-dismiss
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
speechRecognizer.shouldDismiss = true
// Only auto-dismiss in word tracking mode.
// In classic/silence-paused modes the speaker may still be
// talking after the auto-scroll finishes, so keep the text
// visible and let them dismiss manually (X button or Esc).
if listeningMode == .wordTracking {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
speechRecognizer.shouldDismiss = true
}
}
} else if NotchSettings.shared.autoNextPage {
startCountdown()
Expand Down Expand Up @@ -1213,7 +1220,7 @@ struct FloatingOverlayView: View {
VStack(spacing: 0) {
if content.showPagePicker {
floatingPagePickerView
} else if isDone {
} else if isDone && (listeningMode == .wordTracking || hasNextPage) {
floatingDoneView
} else {
floatingPrompterView
Expand Down Expand Up @@ -1260,11 +1267,14 @@ struct FloatingOverlayView: View {
.animation(.easeInOut(duration: 0.5), value: isDone)
.onChange(of: isDone) { _, done in
if done {
// Stop listening when page is done
speechRecognizer.stop()
if listeningMode == .wordTracking {
speechRecognizer.stop()
}
if !hasNextPage {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
speechRecognizer.shouldDismiss = true
if listeningMode == .wordTracking {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
speechRecognizer.shouldDismiss = true
}
}
} else if followingCursor || NotchSettings.shared.autoNextPage {
startCountdown()
Expand Down