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 }