fix: Use correct material 3 colors for notification

This commit is contained in:
Nishant Mishra
2025-09-15 19:30:00 +05:30
parent f4f81ee94c
commit 2333bb98aa
3 changed files with 65 additions and 46 deletions

View File

@@ -6,6 +6,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.runtime.LaunchedEffect
import org.nsh07.pomodoro.ui.AppScreen import org.nsh07.pomodoro.ui.AppScreen
import org.nsh07.pomodoro.ui.NavItem import org.nsh07.pomodoro.ui.NavItem
import org.nsh07.pomodoro.ui.Screen import org.nsh07.pomodoro.ui.Screen
@@ -27,6 +28,11 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
TomatoTheme { TomatoTheme {
val colorScheme = colorScheme
LaunchedEffect(colorScheme) {
appContainer.appTimerRepository.colorScheme = colorScheme
}
timerViewModel.setCompositionLocals(colorScheme) timerViewModel.setCompositionLocals(colorScheme)
AppScreen(timerViewModel = timerViewModel, statsViewModel = statsViewModel) AppScreen(timerViewModel = timerViewModel, statsViewModel = statsViewModel)
} }

View File

@@ -7,6 +7,9 @@
package org.nsh07.pomodoro.data package org.nsh07.pomodoro.data
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.lightColorScheme
/** /**
* Interface that holds the timer durations for each timer type. This repository maintains a single * Interface that holds the timer durations for each timer type. This repository maintains a single
* source of truth for the timer durations for the various ViewModels in the app. * source of truth for the timer durations for the various ViewModels in the app.
@@ -19,6 +22,8 @@ interface TimerRepository {
var timerFrequency: Float var timerFrequency: Float
var alarmEnabled: Boolean var alarmEnabled: Boolean
var vibrateEnabled: Boolean var vibrateEnabled: Boolean
var colorScheme: ColorScheme
} }
/** /**
@@ -32,4 +37,5 @@ class AppTimerRepository : TimerRepository {
override var timerFrequency: Float = 10f override var timerFrequency: Float = 10f
override var alarmEnabled = true override var alarmEnabled = true
override var vibrateEnabled = true override var vibrateEnabled = true
override var colorScheme = lightColorScheme()
} }

View File

@@ -11,8 +11,6 @@ import android.os.VibrationEffect
import android.os.Vibrator import android.os.Vibrator
import android.os.VibratorManager import android.os.VibratorManager
import android.provider.Settings import android.provider.Settings
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
@@ -74,7 +72,7 @@ class TimerService : Service() {
} }
} }
private var cs: ColorScheme = lightColorScheme() private val cs by lazy { timerRepository.colorScheme }
override fun onBind(intent: Intent?): IBinder? { override fun onBind(intent: Intent?): IBinder? {
return null return null
@@ -185,52 +183,61 @@ class TimerService : Service() {
else (remainingTime.toFloat() / 60000f).toInt() else (remainingTime.toFloat() / 60000f).toInt()
notificationManager.notify( notificationManager.notify(
1, notificationBuilder.setContentTitle( 1,
if (!complete) { notificationBuilder
"$currentTimer $middleDot $remainingTimeString min remaining" + if (paused) " $middleDot Paused" else "" .setContentTitle(
} else "$currentTimer $middleDot Completed" if (!complete) {
).setContentText("Up next: $nextTimer (${timerState.value.nextTimeStr})") "$currentTimer $middleDot $remainingTimeString min remaining" + if (paused) " $middleDot Paused" else ""
.setStyle(NotificationCompat.ProgressStyle().also { } else "$currentTimer $middleDot Completed"
// Add all the Focus, Short break and long break intervals in order )
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) { .setContentText("Up next: $nextTimer (${timerState.value.nextTimeStr})")
// Android 16 and later supports live updates .setStyle(
// Set progress bar sections if on Baklava or later NotificationCompat.ProgressStyle()
for (i in 0..<timerRepository.sessionLength * 2) { .also {
if (i % 2 == 0) it.addProgressSegment( // Add all the Focus, Short break and long break intervals in order
NotificationCompat.ProgressStyle.Segment( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) {
timerRepository.focusTime.toInt() // Android 16 and later supports live updates
).setColor(cs.primary.toArgb()) // Set progress bar sections if on Baklava or later
) for (i in 0..<timerRepository.sessionLength * 2) {
else if (i != (timerRepository.sessionLength * 2 - 1)) it.addProgressSegment( if (i % 2 == 0) it.addProgressSegment(
NotificationCompat.ProgressStyle.Segment( NotificationCompat.ProgressStyle.Segment(
timerRepository.shortBreakTime.toInt() timerRepository.focusTime.toInt()
).setColor(cs.tertiary.toArgb()) )
) .setColor(cs.primary.toArgb())
else it.addProgressSegment( )
NotificationCompat.ProgressStyle.Segment( else if (i != (timerRepository.sessionLength * 2 - 1)) it.addProgressSegment(
timerRepository.longBreakTime.toInt() NotificationCompat.ProgressStyle.Segment(
).setColor(cs.tertiary.toArgb()) timerRepository.shortBreakTime.toInt()
) ).setColor(cs.tertiary.toArgb())
} )
} else { else it.addProgressSegment(
it.addProgressSegment( NotificationCompat.ProgressStyle.Segment(
NotificationCompat.ProgressStyle.Segment( timerRepository.longBreakTime.toInt()
when (timerState.value.timerMode) { ).setColor(cs.tertiary.toArgb())
TimerMode.FOCUS -> timerRepository.focusTime.toInt() )
TimerMode.SHORT_BREAK -> timerRepository.shortBreakTime.toInt()
else -> timerRepository.longBreakTime.toInt()
} }
) } else {
it.addProgressSegment(
NotificationCompat.ProgressStyle.Segment(
when (timerState.value.timerMode) {
TimerMode.FOCUS -> timerRepository.focusTime.toInt()
TimerMode.SHORT_BREAK -> timerRepository.shortBreakTime.toInt()
else -> timerRepository.longBreakTime.toInt()
}
)
)
}
}
.setProgress( // Set the current progress by filling the previous intervals and part of the current interval
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) {
(totalTime - remainingTime) + ((cycles + 1) / 2) * timerRepository.focusTime.toInt() + (cycles / 2) * timerRepository.shortBreakTime.toInt()
} else (totalTime - remainingTime)
) )
} )
}
.setProgress( // Set the current progress by filling the previous intervals and part of the current interval
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) {
(totalTime - remainingTime) + ((cycles + 1) / 2) * timerRepository.focusTime.toInt() + (cycles / 2) * timerRepository.shortBreakTime.toInt()
} else (totalTime - remainingTime)
))
.setWhen(System.currentTimeMillis() + remainingTime) // Sets the Live Activity/Now Bar chip time .setWhen(System.currentTimeMillis() + remainingTime) // Sets the Live Activity/Now Bar chip time
.setShortCriticalText(millisecondsToStr(time.coerceAtLeast(0))).build()) .setShortCriticalText(millisecondsToStr(time.coerceAtLeast(0)))
.build()
)
if (complete) { if (complete) {
startAlarm() startAlarm()