Skip to content

Add alert when set stopwatch reaches target - #108

Open
GhostCodeByte wants to merge 1 commit into
LibreFitOrg:mainfrom
GhostCodeByte:codex/benachrichtigungssound-ergnzen
Open

Add alert when set stopwatch reaches target#108
GhostCodeByte wants to merge 1 commit into
LibreFitOrg:mainfrom
GhostCodeByte:codex/benachrichtigungssound-ergnzen

Conversation

@GhostCodeByte

Copy link
Copy Markdown

Fixes missing alert sound when a duration-based set timer reaches its configured time, using the existing rest timer sound preference.
Issue #101

@IamDg IamDg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

Thank you for your contribution!

The implementation might work but it will suffer from the following bugs:

  • Bug A: Editing While Paused

    • The Scenario: A user sets a 60s target, runs the stopwatch, and pauses it at 20s. They realize they want a 90s target instead, so they manually edit the text field to 01:30 (90s) while paused.
    • The Problem:
      • set.elapsedTime is updated to 90.
      • When they click Play to resume, setStopwatchTargets already has an entry for this set ID (60).
      • targetElapsedTime evaluates to 60 (the old target), while initialElapsedTime evaluates to 90 (the newly edited value).
      • In the very first iteration of the loop, newElapsedTime starts at 90. Since 90 >= 60 is true, the stopwatch immediately terminates and sounds the completion alert, ignoring the user's manual change.
  • Bug B: Resume Bug (Major UX Breakdown)

    • The Scenario: A user completes 20s of a 60s duration set. The app is put into the background, gets killed by the OS (process death), or is closed and reopened. The workout is restored from the local database.

    • The Problem:

      • In the ViewModel's init, _idsOfSetsWithStopwatchNotStartedAtLeastOnce is repopulated with all restored set IDs:
       _idsOfSetsWithStopwatchNotStartedAtLeastOnce.update {
       		exercises.value.flatMap { it.sets }.map { it.id }.toSet()
       }
      • The setStopwatchTargets map is a pure in-memory MutableMap and is now completely empty.
      • When the user taps Play to resume their progress:
        • targetElapsedTime is computed via getOrPut(id) { set.elapsedTime }. Since the map is empty, it puts the current set.elapsedTime (20) as the target duration!
        • initialElapsedTime is set to 0 because the set ID is found in idsOfSetsWithStopwatchNotStartedAtLeastOnce.
        • Result: The set's elapsed time resets to 0 and will stop/alert when it hits 20 seconds instead of the original 60 seconds. The user's progress is completely ruined.
  • Bug C: Memory Leaks on Exercise Deletion

    • When a set is deleted individually via deleteSet(id), its target is cleaned up: setStopwatchTargets.remove(id).
    • However, when an entire exercise is deleted via deleteExercise(exerciseId), its associated set IDs are never cleared from setStopwatchTargets, leading to minor memory accumulation during long workout sessions.

Comment on lines +108 to 116
if (targetElapsedTime > 0 && newElapsedTime >= targetElapsedTime) {
if (userPreferences.restTimerSoundOn.value) {
soundPlayer.playAlert()
}
updateIdSetWithRunningStopwatch(null)
return
}

delay(1000)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition can be simplified as shown. Also delay now uses the modern overload with duration instead of integer.

Suggested change
if (targetElapsedTime > 0 && newElapsedTime >= targetElapsedTime) {
if (userPreferences.restTimerSoundOn.value) {
soundPlayer.playAlert()
}
updateIdSetWithRunningStopwatch(null)
return
}
delay(1000)
if (targetElapsedTime in 1..newElapsedTime) {
if (userPreferences.restTimerSoundOn.value) {
soundPlayer.playAlert()
}
updateIdSetWithRunningStopwatch(null)
return
}
delay(1000.milliseconds)

@GhostCodeByte

Copy link
Copy Markdown
Author

Sry about that yeah the implementation was way to simple and I didn't thought about the edge cases. I will do a proper commit later.

@IamDg

IamDg commented Jul 9, 2026

Copy link
Copy Markdown
Member

Sry about that yeah the implementation was way to simple and I didn't thought about the edge cases. I will do a proper commit later.

No worries. Take your time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants