fix: Next timer not starting when current timer was completed

This commit is contained in:
Nishant Mishra
2025-09-14 16:48:25 +05:30
parent f28fc8a2c1
commit c1c2f57ddc
3 changed files with 70 additions and 47 deletions

View File

@@ -19,44 +19,56 @@ fun NotificationCompat.Builder.addTimerActions(
context: Context,
@DrawableRes playPauseIcon: Int,
playPauseText: String
): NotificationCompat.Builder {
this
.addAction(
playPauseIcon,
playPauseText,
PendingIntent.getService(
context,
0,
Intent(context, TimerService::class.java).also {
it.action = TimerService.Actions.TOGGLE.toString()
},
FLAG_IMMUTABLE
)
): NotificationCompat.Builder = this
.addAction(
playPauseIcon,
playPauseText,
PendingIntent.getService(
context,
0,
Intent(context, TimerService::class.java).also {
it.action = TimerService.Actions.TOGGLE.toString()
},
FLAG_IMMUTABLE
)
.addAction(
R.drawable.restart,
"Reset",
PendingIntent.getService(
context,
0,
Intent(context, TimerService::class.java).also {
it.action = TimerService.Actions.RESET.toString()
},
FLAG_IMMUTABLE
)
)
.addAction(
R.drawable.restart,
"Reset",
PendingIntent.getService(
context,
0,
Intent(context, TimerService::class.java).also {
it.action = TimerService.Actions.RESET.toString()
},
FLAG_IMMUTABLE
)
.addAction(
R.drawable.skip_next,
"Skip",
PendingIntent.getService(
context,
0,
Intent(context, TimerService::class.java).also {
it.action = TimerService.Actions.SKIP.toString()
},
FLAG_IMMUTABLE
)
)
.addAction(
R.drawable.skip_next,
"Skip",
PendingIntent.getService(
context,
0,
Intent(context, TimerService::class.java).also {
it.action = TimerService.Actions.SKIP.toString()
},
FLAG_IMMUTABLE
)
)
return this
}
fun NotificationCompat.Builder.addStopAlarmAction(
context: Context
): NotificationCompat.Builder = this
.addAction(
R.drawable.alarm,
"Stop alarm",
PendingIntent.getService(
context,
0,
Intent(context, TimerService::class.java).also {
it.action = TimerService.Actions.STOP_ALARM.toString()
},
FLAG_IMMUTABLE
)
)

View File

@@ -57,9 +57,9 @@ class TimerService : Service() {
private var pauseTime = 0L
private var pauseDuration = 0L
private val timerJob = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.IO + timerJob)
private val skipScope = CoroutineScope(Dispatchers.IO)
private var job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.IO + job)
private val skipScope = CoroutineScope(Dispatchers.IO + job)
private lateinit var alarm: MediaPlayer
@@ -145,11 +145,10 @@ class TimerService : Service() {
if (time < 0) {
skipTimer()
_timerState.update { currentState ->
currentState.copy(timerRunning = false)
}
timerJob.cancel()
break
} else {
_timerState.update { currentState ->
currentState.copy(
@@ -168,6 +167,8 @@ class TimerService : Service() {
fun showTimerNotification(
remainingTime: Int, paused: Boolean = false, complete: Boolean = false
) {
if (complete) notificationBuilder.clearActions().addStopAlarmAction(this)
val totalTime = when (timerState.value.timerMode) {
TimerMode.FOCUS -> timerRepository.focusTime.toInt()
TimerMode.SHORT_BREAK -> timerRepository.shortBreakTime.toInt()
@@ -224,7 +225,7 @@ class TimerService : Service() {
)
)
.setWhen(System.currentTimeMillis() + remainingTime) // Sets the Live Activity/Now Bar chip time
.setShortCriticalText(millisecondsToStr(time))
.setShortCriticalText(millisecondsToStr(time.coerceAtLeast(0)))
.build()
)
@@ -309,6 +310,16 @@ class TimerService : Service() {
_timerState.update { currentState ->
currentState.copy(alarmRinging = false)
}
notificationBuilder.clearActions().addTimerActions(this, R.drawable.play, "Start")
showTimerNotification(
when (timerState.value.timerMode) {
TimerMode.FOCUS -> timerRepository.focusTime.toInt()
TimerMode.SHORT_BREAK -> timerRepository.shortBreakTime.toInt()
else -> timerRepository.longBreakTime.toInt()
},
paused = true,
complete = false
)
}
suspend fun saveTimeToDb() {
@@ -336,7 +347,7 @@ class TimerService : Service() {
override fun onDestroy() {
super.onDestroy()
runBlocking {
timerJob.cancel()
job.cancel()
saveTimeToDb()
notificationManager.cancel(1)
}

View File

@@ -205,7 +205,7 @@ fun TimerScreen(
color = color,
trackColor = colorContainer,
strokeWidth = 16.dp,
gapSize = 16.dp
gapSize = 8.dp
)
} else {
CircularWavyProgressIndicator(
@@ -229,7 +229,7 @@ fun TimerScreen(
cap = StrokeCap.Round,
),
wavelength = 60.dp,
gapSize = 16.dp
gapSize = 8.dp
)
}
var expanded by remember { mutableStateOf(timerState.showBrandTitle) }
@@ -300,10 +300,10 @@ fun TimerScreen(
{
FilledIconToggleButton(
onCheckedChange = { checked ->
onAction(TimerAction.ToggleTimer)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && checked) {
permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
onAction(TimerAction.ToggleTimer)
},
checked = timerState.timerRunning,
colors = IconButtonDefaults.filledIconToggleButtonColors(