mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 16:30:31 +05:30
notifications cleanup
This commit is contained in:
parent
0c1f43bb2f
commit
8707059d6e
@ -52,7 +52,8 @@ class LibreTubeApp : Application() {
|
|||||||
/**
|
/**
|
||||||
* Initialize the notification listener in the background
|
* Initialize the notification listener in the background
|
||||||
*/
|
*/
|
||||||
NotificationHelper(this).enqueueWork(
|
NotificationHelper.enqueueWork(
|
||||||
|
context = this,
|
||||||
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.KEEP
|
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.KEEP
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,8 +45,9 @@ class NotificationSettings : BasePreferenceFragment() {
|
|||||||
|
|
||||||
private fun updateNotificationPrefs() {
|
private fun updateNotificationPrefs() {
|
||||||
// replace the previous queued work request
|
// replace the previous queued work request
|
||||||
NotificationHelper(requireContext())
|
NotificationHelper
|
||||||
.enqueueWork(
|
.enqueueWork(
|
||||||
|
context = requireContext(),
|
||||||
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.REPLACE
|
existingPeriodicWorkPolicy = ExistingPeriodicWorkPolicy.REPLACE
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,46 +1,21 @@
|
|||||||
package com.github.libretube.util
|
package com.github.libretube.util
|
||||||
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Context
|
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.Constraints
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
import androidx.work.NetworkType
|
import androidx.work.NetworkType
|
||||||
import androidx.work.PeriodicWorkRequest
|
import androidx.work.PeriodicWorkRequest
|
||||||
import androidx.work.WorkManager
|
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.NOTIFICATION_WORK_NAME
|
||||||
import com.github.libretube.constants.PUSH_CHANNEL_ID
|
|
||||||
import com.github.libretube.constants.PreferenceKeys
|
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
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class NotificationHelper(
|
object 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
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueue the work manager task
|
* Enqueue the work manager task
|
||||||
*/
|
*/
|
||||||
fun enqueueWork(
|
fun enqueueWork(
|
||||||
|
context: Context,
|
||||||
existingPeriodicWorkPolicy: ExistingPeriodicWorkPolicy
|
existingPeriodicWorkPolicy: ExistingPeriodicWorkPolicy
|
||||||
) {
|
) {
|
||||||
// get the notification preferences
|
// get the notification preferences
|
||||||
@ -95,115 +70,4 @@ class NotificationHelper(
|
|||||||
.cancelUniqueWork(NOTIFICATION_WORK_NAME)
|
.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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,22 @@
|
|||||||
package com.github.libretube.util
|
package com.github.libretube.util
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
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.Worker
|
||||||
import androidx.work.WorkerParameters
|
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
|
* 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) :
|
class NotificationWorker(appContext: Context, parameters: WorkerParameters) :
|
||||||
Worker(appContext, parameters) {
|
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 {
|
override fun doWork(): Result {
|
||||||
// check whether there are new streams and notify if there are some
|
// check whether there are new streams and notify if there are some
|
||||||
val result = NotificationHelper(applicationContext)
|
val result = checkForNewStreams()
|
||||||
.checkForNewStreams()
|
|
||||||
// return success if the API request succeeded
|
// return success if the API request succeeded
|
||||||
return if (result) Result.success() else Result.retry()
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user