From 6a9e2224ec37dfdbc8c3db86f46f23ebe1df52a4 Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Wed, 7 Feb 2024 17:31:41 +1300 Subject: [PATCH] Add more information to rest timer notifications From homepage - Name of exercise From plans - Name (count/total) --- EditSet.tsx | 2 +- .../src/main/java/com/massive/AlarmModule.kt | 133 ++++++++++-------- 2 files changed, 72 insertions(+), 63 deletions(-) diff --git a/EditSet.tsx b/EditSet.tsx index 55a8e2a..36d775e 100644 --- a/EditSet.tsx +++ b/EditSet.tsx @@ -76,7 +76,7 @@ export default function EditSet() { const canNotify = await check(PERMISSIONS.ANDROID.POST_NOTIFICATIONS); if (canNotify === RESULTS.DENIED) await request(PERMISSIONS.ANDROID.POST_NOTIFICATIONS); - if (milliseconds) NativeModules.AlarmModule.timer(milliseconds); + if (milliseconds) NativeModules.AlarmModule.timer(milliseconds, `${first.name}`); }, [settings] ); diff --git a/android/app/src/main/java/com/massive/AlarmModule.kt b/android/app/src/main/java/com/massive/AlarmModule.kt index 3674aa7..a7642b5 100644 --- a/android/app/src/main/java/com/massive/AlarmModule.kt +++ b/android/app/src/main/java/com/massive/AlarmModule.kt @@ -15,32 +15,34 @@ import com.facebook.react.bridge.* import com.facebook.react.modules.core.DeviceEventManagerModule import kotlin.math.floor - class AlarmModule constructor(context: ReactApplicationContext?) : - ReactContextBaseJavaModule(context) { + ReactContextBaseJavaModule(context) { private var countdownTimer: CountDownTimer? = null var currentMs: Long = 0 - var running = false + private var running = false + private var currentDescription = "" override fun getName(): String { return "AlarmModule" } - private val stopReceiver = object : BroadcastReceiver() { - @RequiresApi(Build.VERSION_CODES.O) - override fun onReceive(context: Context?, intent: Intent?) { - Log.d("AlarmModule", "Received stop broadcast intent") - stop() - } - } + private val stopReceiver = + object : BroadcastReceiver() { + @RequiresApi(Build.VERSION_CODES.O) + override fun onReceive(context: Context?, intent: Intent?) { + Log.d("AlarmModule", "Received stop broadcast intent") + stop() + } + } - private val addReceiver = object : BroadcastReceiver() { - @RequiresApi(Build.VERSION_CODES.O) - override fun onReceive(context: Context?, intent: Intent?) { - add() - } - } + private val addReceiver = + object : BroadcastReceiver() { + @RequiresApi(Build.VERSION_CODES.O) + override fun onReceive(context: Context?, intent: Intent?) { + add() + } + } init { reactApplicationContext.registerReceiver(stopReceiver, IntentFilter(STOP_BROADCAST)) @@ -71,9 +73,8 @@ class AlarmModule constructor(context: ReactApplicationContext?) : @ReactMethod(isBlockingSynchronousMethod = true) fun getCurrent(): Int { Log.d("AlarmModule", "currentMs=$currentMs") - if (running) - return currentMs.toInt(); - return 0; + if (running) return currentMs.toInt() + return 0 } @RequiresApi(api = Build.VERSION_CODES.O) @@ -87,19 +88,21 @@ class AlarmModule constructor(context: ReactApplicationContext?) : val manager = getManager() manager.cancel(AlarmService.NOTIFICATION_ID_DONE) manager.cancel(NOTIFICATION_ID_PENDING) - val params = Arguments.createMap().apply { - putString("minutes", "00") - putString("seconds", "00") - } + val params = + Arguments.createMap().apply { + putString("minutes", "00") + putString("seconds", "00") + } reactApplicationContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) - .emit("tick", params) + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) + .emit("tick", params) } @RequiresApi(api = Build.VERSION_CODES.O) @ReactMethod - fun timer(milliseconds: Int) { + fun timer(milliseconds: Int, description: String) { Log.d("AlarmModule", "Queue alarm for $milliseconds delay") + currentDescription = description val manager = getManager() manager.cancel(AlarmService.NOTIFICATION_ID_DONE) val intent = Intent(reactApplicationContext, AlarmService::class.java) @@ -112,7 +115,7 @@ class AlarmModule constructor(context: ReactApplicationContext?) : @RequiresApi(Build.VERSION_CODES.M) private fun getTimer( - endMs: Int, + endMs: Int, ): CountDownTimer { val builder = getBuilder() return object : CountDownTimer(endMs.toLong(), 1000) { @@ -120,34 +123,39 @@ class AlarmModule constructor(context: ReactApplicationContext?) : override fun onTick(current: Long) { currentMs = current val seconds = - floor((current / 1000).toDouble() % 60).toInt().toString().padStart(2, '0') + floor((current / 1000).toDouble() % 60).toInt().toString().padStart(2, '0') val minutes = - floor((current / 1000).toDouble() / 60).toInt().toString().padStart(2, '0') - builder.setContentText("$minutes:$seconds").setAutoCancel(false).setDefaults(0) - .setProgress(endMs, current.toInt(), false) - .setCategory(NotificationCompat.CATEGORY_PROGRESS).priority = - NotificationCompat.PRIORITY_LOW + floor((current / 1000).toDouble() / 60).toInt().toString().padStart(2, '0') + builder.setContentText("$minutes:$seconds") + .setAutoCancel(false) + .setDefaults(0) + .setProgress(endMs, current.toInt(), false) + .setCategory(NotificationCompat.CATEGORY_PROGRESS) + .priority = NotificationCompat.PRIORITY_LOW val manager = getManager() manager.notify(NOTIFICATION_ID_PENDING, builder.build()) - val params = Arguments.createMap().apply { - putString("minutes", minutes) - putString("seconds", seconds) - } + val params = + Arguments.createMap().apply { + putString("minutes", minutes) + putString("seconds", seconds) + } reactApplicationContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) - .emit("tick", params) + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) + .emit("tick", params) } @RequiresApi(Build.VERSION_CODES.O) override fun onFinish() { val context = reactApplicationContext context.startService(Intent(context, AlarmService::class.java)) - context - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) - .emit("tick", Arguments.createMap().apply { - putString("minutes", "00") - putString("seconds", "00") - }) + context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) + .emit( + "tick", + Arguments.createMap().apply { + putString("minutes", "00") + putString("seconds", "00") + } + ) } } } @@ -158,32 +166,33 @@ class AlarmModule constructor(context: ReactApplicationContext?) : val context = reactApplicationContext val contentIntent = Intent(context, MainActivity::class.java) val pendingContent = - PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE) - val addBroadcast = Intent(ADD_BROADCAST).apply { - setPackage(context.packageName) - } + PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE) + val addBroadcast = Intent(ADD_BROADCAST).apply { setPackage(context.packageName) } val pendingAdd = - PendingIntent.getBroadcast(context, 0, addBroadcast, PendingIntent.FLAG_MUTABLE) + PendingIntent.getBroadcast(context, 0, addBroadcast, PendingIntent.FLAG_MUTABLE) val stopBroadcast = Intent(STOP_BROADCAST) stopBroadcast.setPackage(context.packageName) val pendingStop = - PendingIntent.getBroadcast(context, 0, stopBroadcast, PendingIntent.FLAG_IMMUTABLE) + PendingIntent.getBroadcast(context, 0, stopBroadcast, PendingIntent.FLAG_IMMUTABLE) return NotificationCompat.Builder(context, CHANNEL_ID_PENDING) - .setSmallIcon(R.drawable.ic_baseline_hourglass_bottom_24).setContentTitle("Resting") - .setContentIntent(pendingContent) - .addAction(R.drawable.ic_baseline_stop_24, "Stop", pendingStop) - .addAction(R.drawable.ic_baseline_stop_24, "Add 1 min", pendingAdd) - .setDeleteIntent(pendingStop) + .setSmallIcon(R.drawable.ic_baseline_hourglass_bottom_24) + .setContentTitle(currentDescription) + .setContentIntent(pendingContent) + .addAction(R.drawable.ic_baseline_stop_24, "Stop", pendingStop) + .addAction(R.drawable.ic_baseline_stop_24, "Add 1 min", pendingAdd) + .setDeleteIntent(pendingStop) } @RequiresApi(Build.VERSION_CODES.O) private fun getManager(): NotificationManager { - val notificationManager = reactApplicationContext.getSystemService( - NotificationManager::class.java - ) - val timersChannel = NotificationChannel( - CHANNEL_ID_PENDING, CHANNEL_ID_PENDING, NotificationManager.IMPORTANCE_LOW - ) + val notificationManager = + reactApplicationContext.getSystemService(NotificationManager::class.java) + val timersChannel = + NotificationChannel( + CHANNEL_ID_PENDING, + CHANNEL_ID_PENDING, + NotificationManager.IMPORTANCE_LOW + ) timersChannel.setSound(null, null) timersChannel.description = "Progress on rest timers." notificationManager.createNotificationChannel(timersChannel)