diff --git a/app/src/main/java/com/github/libretube/MyApp.kt b/app/src/main/java/com/github/libretube/MyApp.kt index 7105f1920..db0245d32 100644 --- a/app/src/main/java/com/github/libretube/MyApp.kt +++ b/app/src/main/java/com/github/libretube/MyApp.kt @@ -6,16 +6,8 @@ import android.app.NotificationManager import android.os.Build import android.os.StrictMode import android.os.StrictMode.VmPolicy -import androidx.work.Constraints -import androidx.work.ExistingPeriodicWorkPolicy -import androidx.work.NetworkType -import androidx.work.PeriodicWorkRequest -import androidx.work.WorkManager import com.github.libretube.preferences.PreferenceHelper import com.github.libretube.util.NotificationHelper -import com.github.libretube.util.NotificationWorker -import java.util.concurrent.TimeUnit - class MyApp : Application() { override fun onCreate() { diff --git a/app/src/main/java/com/github/libretube/preferences/MainSettings.kt b/app/src/main/java/com/github/libretube/preferences/MainSettings.kt index b21b41bd4..3622e3ee7 100644 --- a/app/src/main/java/com/github/libretube/preferences/MainSettings.kt +++ b/app/src/main/java/com/github/libretube/preferences/MainSettings.kt @@ -62,6 +62,13 @@ class MainSettings : PreferenceFragmentCompat() { true } + val notifications = findPreference("notifications") + notifications?.setOnPreferenceClickListener { + val newFragment = NotificationSettings() + navigateToSettingsFragment(newFragment) + true + } + val advanced = findPreference("advanced") advanced?.setOnPreferenceClickListener { val newFragment = AdvancedSettings() diff --git a/app/src/main/java/com/github/libretube/preferences/NotificationSettings.kt b/app/src/main/java/com/github/libretube/preferences/NotificationSettings.kt new file mode 100644 index 000000000..d90e4f71e --- /dev/null +++ b/app/src/main/java/com/github/libretube/preferences/NotificationSettings.kt @@ -0,0 +1,32 @@ +package com.github.libretube.preferences + +import android.os.Bundle +import androidx.preference.ListPreference +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.SwitchPreferenceCompat +import com.github.libretube.R +import com.github.libretube.activities.SettingsActivity +import com.github.libretube.util.NotificationHelper + +class NotificationSettings : PreferenceFragmentCompat() { + val TAG = "SettingsFragment" + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + setPreferencesFromResource(R.xml.notification_settings, rootKey) + + val settingsActivity = activity as SettingsActivity + settingsActivity.changeTopBarText(getString(R.string.notifications)) + + val notificationsEnabled = findPreference(PreferenceKeys.NOTIFICATION_ENABLED) + notificationsEnabled?.setOnPreferenceChangeListener { _, _ -> + NotificationHelper.enqueueWork(requireContext()) + true + } + + val checkingFrequency = findPreference(PreferenceKeys.CHECKING_FREQUENCY) + checkingFrequency?.setOnPreferenceChangeListener { _, _ -> + NotificationHelper.enqueueWork(requireContext()) + true + } + } +} diff --git a/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt b/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt index 89522853d..b38db03ef 100644 --- a/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt +++ b/app/src/main/java/com/github/libretube/preferences/PreferenceHelper.kt @@ -246,6 +246,14 @@ object PreferenceHelper { } } + fun setLatestVideoId(videoId: String) { + setString(PreferenceKeys.LAST_STREAM_VIDEO_ID, videoId) + } + + fun getLatestVideoId(): String { + return getString(PreferenceKeys.LAST_STREAM_VIDEO_ID, "") + } + private fun getDefaultSharedPreferences(context: Context): SharedPreferences { return PreferenceManager.getDefaultSharedPreferences(context) } diff --git a/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt b/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt index 1c9af9206..2dd315501 100644 --- a/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt +++ b/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt @@ -69,7 +69,8 @@ object PreferenceKeys { * Notifications */ const val NOTIFICATION_ENABLED = "notification_toggle" - const val NOTIFICATION_DELAY = "notifcation_delay" + const val CHECKING_FREQUENCY = "checking_frequency" + const val LAST_STREAM_VIDEO_ID = "last_stream_video_id" /** * Advanced diff --git a/app/src/main/java/com/github/libretube/util/NotificationHelper.kt b/app/src/main/java/com/github/libretube/util/NotificationHelper.kt index f33cc4e6e..a113930e2 100644 --- a/app/src/main/java/com/github/libretube/util/NotificationHelper.kt +++ b/app/src/main/java/com/github/libretube/util/NotificationHelper.kt @@ -6,62 +6,105 @@ import android.content.Intent import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.work.Constraints -import androidx.work.CoroutineWorker 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.activities.MainActivity -import com.github.libretube.obj.StreamItem import com.github.libretube.preferences.PreferenceHelper -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers +import com.github.libretube.preferences.PreferenceKeys import kotlinx.coroutines.async -import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import java.util.concurrent.TimeUnit -import java.util.stream.Stream object NotificationHelper { fun enqueueWork( context: Context ) { - val constraints = Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build() - - val myWorkBuilder = PeriodicWorkRequest.Builder( - NotificationWorker::class.java, - 1, - TimeUnit.SECONDS + PreferenceHelper.setContext(context) + val notificationsEnabled = PreferenceHelper.getBoolean( + PreferenceKeys.NOTIFICATION_ENABLED, + true ) - .setConstraints(constraints) - val myWork = myWorkBuilder.build() - WorkManager.getInstance(context) - .enqueueUniquePeriodicWork( - "NotificationService", - ExistingPeriodicWorkPolicy.REPLACE, - myWork + val checkingFrequency = PreferenceHelper.getString( + PreferenceKeys.CHECKING_FREQUENCY, + "60" + ).toLong() + + val uniqueWorkName = "NotificationService" + + if (notificationsEnabled) { + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build() + + val myWorkBuilder = PeriodicWorkRequest.Builder( + NotificationWorker::class.java, + checkingFrequency, + TimeUnit.MINUTES ) + .setConstraints(constraints) + + val myWork = myWorkBuilder.build() + WorkManager.getInstance(context) + .enqueueUniquePeriodicWork( + uniqueWorkName, + ExistingPeriodicWorkPolicy.REPLACE, + myWork + ) + } else { + WorkManager.getInstance(context) + .cancelUniqueWork(uniqueWorkName) + } } + /** + * check whether new streams are available in subscriptions + */ fun checkForNewStreams(context: Context) { val token = PreferenceHelper.getToken() - var response: List runBlocking { val task = async { RetrofitInstance.authApi.getFeed(token) } - response = task.await() - } - createNotification( - context, - response[0].title.toString(), - response[0].uploaderName.toString() - ) + val videoFeed = task.await() + val lastSeenStreamId = PreferenceHelper.getLatestVideoId() + val latestFeedStreamId = videoFeed[0].url?.replace("/watch?v=", "") + // first time notifications enabled + if (lastSeenStreamId == "") PreferenceHelper.setLatestVideoId(lastSeenStreamId) + else if (lastSeenStreamId != latestFeedStreamId) { + // get the index of the last user-seen video + var newStreamIndex = -1 + videoFeed.forEachIndexed { index, stream -> + if (stream.url?.replace("/watch?v=", "") == lastSeenStreamId) { + newStreamIndex = index + } + } + val (title, description) = when (newStreamIndex) { + // only one new stream available + 1 -> { + Pair(videoFeed[0].title, videoFeed[0].uploaderName) + } + else -> { + Pair( + // return the amount of new streams as title + context.getString( + R.string.new_streams_count, + newStreamIndex.toString() + ), + // return the first few uploader as description + context.getString( + R.string.new_streams_by, + videoFeed[0].uploaderName + ", " + videoFeed[1].uploaderName + ", " + videoFeed[2].uploaderName + ) + ) + } + } + createNotification(context, title!!, description!!) + } + } } fun createNotification(context: Context, title: String, description: String) { @@ -82,7 +125,5 @@ object NotificationHelper { // notificationId is a unique int for each notification that you must define notify(2, builder.build()) } - } - } diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml new file mode 100644 index 000000000..5abed7187 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index e28789a05..56cfb59a0 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -760,4 +760,22 @@ worst + + 15 minutes + 30 minutes + 60 minutes + 2 hours + 6 hours + 12 hours + + + + 15 + 30 + 60 + 120 + 360 + 720 + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f60c5d1c0..cc8a791ed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -265,4 +265,10 @@ Best quality Worst quality Default subtitle language + Notifications + New streams notifications + Notify when new streams from subscriptions are available + Checking frequency + %1$s new streams are available + New streams by %1$s … \ No newline at end of file diff --git a/app/src/main/res/xml/notification_settings.xml b/app/src/main/res/xml/notification_settings.xml new file mode 100644 index 000000000..9bd0e37f6 --- /dev/null +++ b/app/src/main/res/xml/notification_settings.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index f9bfcaea8..0d79b3805 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -40,6 +40,12 @@ app:key="history" app:title="@string/history" /> + +