StreaksReminder.kt (5843B) - raw
1 package me.rhunk.snapenhance 2 3 import android.app.AlarmManager 4 import android.app.NotificationChannel 5 import android.app.NotificationManager 6 import android.app.PendingIntent 7 import android.content.BroadcastReceiver 8 import android.content.Context 9 import android.content.Intent 10 import androidx.core.app.NotificationCompat 11 import androidx.core.graphics.drawable.toBitmap 12 import kotlinx.coroutines.launch 13 import me.rhunk.snapenhance.bridge.ForceStartActivity 14 import me.rhunk.snapenhance.common.util.snap.BitmojiSelfie 15 import me.rhunk.snapenhance.storage.getFriendStreaks 16 import me.rhunk.snapenhance.storage.getFriends 17 import me.rhunk.snapenhance.ui.util.coil.ImageRequestHelper 18 import kotlin.time.Duration.Companion.hours 19 import kotlin.time.Duration.Companion.milliseconds 20 import kotlin.time.Duration.Companion.minutes 21 22 class StreaksReminder( 23 private val remoteSideContext: RemoteSideContext? = null 24 ): BroadcastReceiver() { 25 companion object { 26 private const val NOTIFICATION_CHANNEL_ID = "streaks" 27 } 28 29 private fun getNotificationManager(context: Context) = context.getSystemService(NotificationManager::class.java).apply { 30 createNotificationChannel( 31 NotificationChannel( 32 NOTIFICATION_CHANNEL_ID, 33 "Streaks", 34 NotificationManager.IMPORTANCE_HIGH 35 ) 36 ) 37 } 38 39 override fun onReceive(ctx: Context, intent: Intent) { 40 val remoteSideContext = this.remoteSideContext ?: SharedContextHolder.remote(ctx) 41 val streaksReminderConfig = remoteSideContext.config.root.streaksReminder 42 val sharedPreferences = remoteSideContext.sharedPreferences 43 44 if (streaksReminderConfig.globalState != true) return 45 46 val interval = streaksReminderConfig.interval.get().hours 47 val remainingHours = streaksReminderConfig.remainingHours.get() 48 49 if (sharedPreferences.getLong("lastStreaksReminder", 0).milliseconds + interval - 10.minutes > System.currentTimeMillis().milliseconds) return 50 sharedPreferences.edit().putLong("lastStreaksReminder", System.currentTimeMillis()).apply() 51 52 remoteSideContext.androidContext.getSystemService(AlarmManager::class.java).setRepeating( 53 AlarmManager.RTC_WAKEUP, 5000, interval.inWholeMilliseconds, 54 PendingIntent.getBroadcast(remoteSideContext.androidContext, 0, Intent(remoteSideContext.androidContext, StreaksReminder::class.java), 55 PendingIntent.FLAG_IMMUTABLE) 56 ) 57 58 val notifyFriendList = remoteSideContext.database.getFriends() 59 .associateBy { remoteSideContext.database.getFriendStreaks(it.userId) } 60 .filter { (streaks, _) -> streaks != null && streaks.notify && streaks.isAboutToExpire(remainingHours) } 61 62 val notificationManager = getNotificationManager(ctx) 63 val streaksReminderTranslation = remoteSideContext.translation.getCategory("streaks_reminder") 64 65 if (streaksReminderConfig.groupNotifications.get() && notifyFriendList.isNotEmpty()) { 66 notificationManager.notify(0, NotificationCompat.Builder(ctx, NOTIFICATION_CHANNEL_ID) 67 .setPriority(NotificationCompat.PRIORITY_HIGH) 68 .setAutoCancel(true) 69 .setGroup("streaks") 70 .setGroupSummary(true) 71 .setSmallIcon(R.drawable.streak_icon) 72 .build()) 73 } 74 75 notifyFriendList.forEach { (streaks, friend) -> 76 remoteSideContext.coroutineScope.launch { 77 val bitmojiUrl = BitmojiSelfie.getBitmojiSelfie(friend.selfieId, friend.bitmojiId, BitmojiSelfie.BitmojiSelfieType.NEW_THREE_D) 78 val bitmojiImage = remoteSideContext.imageLoader.execute( 79 ImageRequestHelper.newBitmojiImageRequest(ctx, bitmojiUrl) 80 ) 81 82 val notificationBuilder = NotificationCompat.Builder(ctx, NOTIFICATION_CHANNEL_ID) 83 .setContentTitle(streaksReminderTranslation["notification_title"]) 84 .setContentText(streaksReminderTranslation.format("notification_text", 85 "friend" to (friend.displayName ?: friend.mutableUsername), 86 "hoursLeft" to (streaks?.hoursLeft() ?: 0).toString() 87 )) 88 .setPriority(NotificationCompat.PRIORITY_DEFAULT) 89 .setAutoCancel(true) 90 .setGroup("streaks") 91 .setContentIntent(PendingIntent.getActivity( 92 ctx, 93 0, 94 Intent(ctx, ForceStartActivity::class.java).apply { 95 putExtra("streaks_notification_action", true) 96 }, 97 PendingIntent.FLAG_IMMUTABLE 98 )) 99 .apply { 100 setSmallIcon(R.drawable.streak_icon) 101 bitmojiImage.drawable?.let { 102 setLargeIcon(it.toBitmap()) 103 } 104 } 105 106 if (streaksReminderConfig.groupNotifications.get()) { 107 notificationBuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN) 108 } 109 110 notificationManager.notify(friend.userId.hashCode(), notificationBuilder.build().apply { 111 flags = NotificationCompat.FLAG_ONLY_ALERT_ONCE 112 }) 113 } 114 } 115 } 116 117 fun init() { 118 if (remoteSideContext == null) throw IllegalStateException("RemoteSideContext is null") 119 if (remoteSideContext.config.root.streaksReminder.globalState != true) return 120 121 onReceive(remoteSideContext.androidContext, Intent()) 122 } 123 124 fun dismissAllNotifications() = getNotificationManager(remoteSideContext!!.androidContext).cancelAll() 125 }