feat: Add notification icons to play, pause reset and skip the timer

This commit is contained in:
Nishant Mishra
2025-09-14 15:31:27 +05:30
parent 672571764d
commit 781c103f59
4 changed files with 73 additions and 15 deletions

View File

@@ -15,6 +15,7 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import org.nsh07.pomodoro.R import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.service.addTimerActions
import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerState import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerState
import org.nsh07.pomodoro.utils.millisecondsToStr import org.nsh07.pomodoro.utils.millisecondsToStr
@@ -56,6 +57,7 @@ class DefaultAppContainer(context: Context) : AppContainer {
PendingIntent.FLAG_IMMUTABLE PendingIntent.FLAG_IMMUTABLE
) )
) )
.addTimerActions(context, R.drawable.play, "Start")
.setShowWhen(true) .setShowWhen(true)
.setSilent(true) .setSilent(true)
.setOngoing(true) .setOngoing(true)

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.nsh07.pomodoro.service
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.content.Context
import android.content.Intent
import androidx.annotation.DrawableRes
import androidx.core.app.NotificationCompat
import org.nsh07.pomodoro.R
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
)
)
.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
)
)
return this
}

View File

@@ -7,7 +7,6 @@ import android.media.MediaPlayer
import android.os.IBinder import android.os.IBinder
import android.os.SystemClock import android.os.SystemClock
import android.provider.Settings import android.provider.Settings
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.material3.ColorScheme import androidx.compose.material3.ColorScheme
import androidx.compose.material3.lightColorScheme import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
@@ -23,6 +22,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.nsh07.pomodoro.R
import org.nsh07.pomodoro.TomatoApplication import org.nsh07.pomodoro.TomatoApplication
import org.nsh07.pomodoro.data.AppContainer import org.nsh07.pomodoro.data.AppContainer
import org.nsh07.pomodoro.data.StatRepository import org.nsh07.pomodoro.data.StatRepository
@@ -32,7 +32,6 @@ import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerState
import org.nsh07.pomodoro.utils.millisecondsToStr import org.nsh07.pomodoro.utils.millisecondsToStr
import kotlin.text.Typography.middleDot import kotlin.text.Typography.middleDot
@ExperimentalAnimationApi
class TimerService : Service() { class TimerService : Service() {
private lateinit var appContainer: AppContainer private lateinit var appContainer: AppContainer
@@ -108,6 +107,13 @@ class TimerService : Service() {
} }
private fun toggleTimer() { private fun toggleTimer() {
notificationBuilder
.clearActions()
.addTimerActions(
this,
if (timerState.value.timerRunning) R.drawable.pause else R.drawable.play,
if (timerState.value.timerRunning) "Stop" else "Start"
)
if (timerState.value.timerRunning) { if (timerState.value.timerRunning) {
showTimerNotification(time.toInt(), paused = true) showTimerNotification(time.toInt(), paused = true)
_timerState.update { currentState -> _timerState.update { currentState ->
@@ -326,14 +332,6 @@ class TimerService : Service() {
stopSelf() stopSelf()
} }
private fun setStopButton() {
// TODO
}
private fun setResumeButton() {
// TODO
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
runBlocking { runBlocking {

View File

@@ -10,7 +10,6 @@ package org.nsh07.pomodoro.ui
import android.content.Intent import android.content.Intent
import androidx.compose.animation.ContentTransform import androidx.compose.animation.ContentTransform
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleOut import androidx.compose.animation.scaleOut
@@ -55,10 +54,7 @@ import org.nsh07.pomodoro.ui.timerScreen.TimerScreen
import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerAction import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerAction
import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerViewModel import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerViewModel
@OptIn( @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class,
ExperimentalAnimationApi::class
)
@Composable @Composable
fun AppScreen( fun AppScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,