notifications cleanup

This commit is contained in:
Bnyro 2022-11-06 10:21:37 +01:00
parent 0c1f43bb2f
commit 8707059d6e
4 changed files with 142 additions and 142 deletions

View File

@ -52,7 +52,8 @@ class LibreTubeApp : Application() {
/**
* Initialize the notification listener in the background
*/
NotificationHelper(this).enqueueWork(
NotificationHelper.enqueueWork(
context = this,
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.KEEP
)

View File

@ -45,8 +45,9 @@ class NotificationSettings : BasePreferenceFragment() {
private fun updateNotificationPrefs() {
// replace the previous queued work request
NotificationHelper(requireContext())
NotificationHelper
.enqueueWork(
context = requireContext(),
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.REPLACE
)
}

View File

@ -1,46 +1,21 @@
package com.github.libretube.util
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.constants.NOTIFICATION_WORK_NAME
import com.github.libretube.constants.PUSH_CHANNEL_ID
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.extensions.toID
import com.github.libretube.ui.activities.MainActivity
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import java.util.concurrent.TimeUnit
class NotificationHelper(
private val context: Context
) {
val NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// the id where notification channels start
private var notificationId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
NotificationManager.activeNotifications.size + 5
} else {
5
}
object NotificationHelper {
/**
* Enqueue the work manager task
*/
fun enqueueWork(
context: Context,
existingPeriodicWorkPolicy: ExistingPeriodicWorkPolicy
) {
// get the notification preferences
@ -95,115 +70,4 @@ class NotificationHelper(
.cancelUniqueWork(NOTIFICATION_WORK_NAME)
}
}
/**
* check whether new streams are available in subscriptions
*/
fun checkForNewStreams(): Boolean {
var success = true
val token = PreferenceHelper.getToken()
runBlocking {
val task = async {
if (token != "") {
RetrofitInstance.authApi.getFeed(token)
} else {
RetrofitInstance.authApi.getUnauthenticatedFeed(
SubscriptionHelper.getFormattedLocalSubscriptions()
)
}
}
// fetch the users feed
val videoFeed = try {
task.await()
} catch (e: Exception) {
success = false
return@runBlocking
}
val lastSeenStreamId = PreferenceHelper.getLastSeenVideoId()
val latestFeedStreamId = videoFeed[0].url!!.toID()
// first time notifications enabled or no new video available
if (lastSeenStreamId == "" || lastSeenStreamId == latestFeedStreamId) {
PreferenceHelper.setLatestVideoId(lastSeenStreamId)
return@runBlocking
}
// filter the new videos out
val lastSeenStreamItem = videoFeed.filter { it.url!!.toID() == lastSeenStreamId }
// previous video not found
if (lastSeenStreamItem.isEmpty()) return@runBlocking
val lastStreamIndex = videoFeed.indexOf(lastSeenStreamItem[0])
val newVideos = videoFeed.filterIndexed { index, _ ->
index < lastStreamIndex
}
// group the new streams by the uploader
val channelGroups = newVideos.groupBy { it.uploaderUrl }
// create a notification for each new stream
channelGroups.forEach { (_, streams) ->
createNotification(
group = streams[0].uploaderUrl!!.toID(),
title = streams[0].uploaderName.toString(),
isSummary = true
)
streams.forEach { streamItem ->
notificationId += 1
createNotification(
title = streamItem.title.toString(),
description = streamItem.uploaderName.toString(),
group = streamItem.uploaderUrl!!.toID()
)
}
}
// save the latest streams that got notified about
PreferenceHelper.setLatestVideoId(videoFeed[0].url!!.toID())
}
// return whether the work succeeded
return success
}
/**
* Notification that is created when new streams are found
*/
private fun createNotification(
title: String,
group: String,
description: String? = null,
isSummary: Boolean = false
) {
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
val builder = NotificationCompat.Builder(context, PUSH_CHANNEL_ID)
.setContentTitle(title)
.setGroup(group)
.setSmallIcon(R.drawable.ic_notification)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true)
if (isSummary) {
builder.setGroupSummary(true)
} else {
builder.setContentText(description)
}
with(NotificationManagerCompat.from(context)) {
// notificationId is a unique int for each notification that you must define
notify(notificationId, builder.build())
}
}
}

View File

@ -1,8 +1,22 @@
package com.github.libretube.util
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.constants.PUSH_CHANNEL_ID
import com.github.libretube.extensions.toID
import com.github.libretube.ui.activities.MainActivity
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
/**
* The notification worker which checks for new streams in a certain frequency
@ -10,11 +24,131 @@ import androidx.work.WorkerParameters
class NotificationWorker(appContext: Context, parameters: WorkerParameters) :
Worker(appContext, parameters) {
val NotificationManager =
appContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// the id where notification channels start
private var notificationId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
NotificationManager.activeNotifications.size + 5
} else {
5
}
override fun doWork(): Result {
// check whether there are new streams and notify if there are some
val result = NotificationHelper(applicationContext)
.checkForNewStreams()
val result = checkForNewStreams()
// return success if the API request succeeded
return if (result) Result.success() else Result.retry()
}
/**
* check whether new streams are available in subscriptions
*/
fun checkForNewStreams(): Boolean {
var success = true
val token = PreferenceHelper.getToken()
runBlocking {
val task = async {
if (token != "") {
RetrofitInstance.authApi.getFeed(token)
} else {
RetrofitInstance.authApi.getUnauthenticatedFeed(
SubscriptionHelper.getFormattedLocalSubscriptions()
)
}
}
// fetch the users feed
val videoFeed = try {
task.await()
} catch (e: Exception) {
success = false
return@runBlocking
}
val lastSeenStreamId = PreferenceHelper.getLastSeenVideoId()
val latestFeedStreamId = videoFeed[0].url!!.toID()
// first time notifications enabled or no new video available
if (lastSeenStreamId == "" || lastSeenStreamId == latestFeedStreamId) {
PreferenceHelper.setLatestVideoId(lastSeenStreamId)
return@runBlocking
}
// filter the new videos out
val lastSeenStreamItem = videoFeed.filter { it.url!!.toID() == lastSeenStreamId }
// previous video not found
if (lastSeenStreamItem.isEmpty()) return@runBlocking
val lastStreamIndex = videoFeed.indexOf(lastSeenStreamItem[0])
val newVideos = videoFeed.filterIndexed { index, _ ->
index < lastStreamIndex
}
// group the new streams by the uploader
val channelGroups = newVideos.groupBy { it.uploaderUrl }
// create a notification for each new stream
channelGroups.forEach { (_, streams) ->
createNotification(
group = streams[0].uploaderUrl!!.toID(),
title = streams[0].uploaderName.toString(),
isSummary = true
)
streams.forEach { streamItem ->
notificationId += 1
createNotification(
title = streamItem.title.toString(),
description = streamItem.uploaderName.toString(),
group = streamItem.uploaderUrl!!.toID()
)
}
}
// save the latest streams that got notified about
PreferenceHelper.setLatestVideoId(videoFeed[0].url!!.toID())
}
// return whether the work succeeded
return success
}
/**
* Notification that is created when new streams are found
*/
private fun createNotification(
title: String,
group: String,
description: String? = null,
isSummary: Boolean = false
) {
val intent = Intent(applicationContext, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(
applicationContext,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
val builder = NotificationCompat.Builder(applicationContext, PUSH_CHANNEL_ID)
.setContentTitle(title)
.setGroup(group)
.setSmallIcon(R.drawable.ic_notification)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true)
if (isSummary) {
builder.setGroupSummary(true)
} else {
builder.setContentText(description)
}
with(NotificationManagerCompat.from(applicationContext)) {
// notificationId is a unique int for each notification that you must define
notify(notificationId, builder.build())
}
}
}