From e0512fcfbfb9f534433c8c342ee98e0c3a53d509 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Wed, 9 Nov 2022 18:01:59 +0100 Subject: [PATCH 1/3] time picker backend --- .../libretube/constants/PreferenceKeys.kt | 3 + .../ui/views/TimePickerPreference.kt | 65 +++++++++++++++++++ .../libretube/util/NotificationHelper.kt | 1 + .../com/github/libretube/util/TextUtils.kt | 4 ++ .../{util => workers}/NotificationWorker.kt | 3 +- app/src/main/res/values/strings.xml | 5 ++ .../main/res/xml/notification_settings.xml | 18 +++++ 7 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt rename app/src/main/java/com/github/libretube/{util => workers}/NotificationWorker.kt (98%) diff --git a/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt b/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt index 3675ac171..fd840c68f 100644 --- a/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt +++ b/app/src/main/java/com/github/libretube/constants/PreferenceKeys.kt @@ -94,6 +94,9 @@ object PreferenceKeys { const val REQUIRED_NETWORK = "required_network" const val LAST_STREAM_VIDEO_ID = "last_stream_video_id" const val IGNORED_NOTIFICATION_CHANNELS = "ignored_notification_channels" + const val NOTIFICATION_TIME_ENABLED = "notification_time" + const val NOTIFICATION_START_TIME = "notification_start_time" + const val NOTIFICATION_END_TIME = "notification_end_time" /** * Advanced diff --git a/app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt b/app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt new file mode 100644 index 000000000..3eabff8d8 --- /dev/null +++ b/app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt @@ -0,0 +1,65 @@ +package com.github.libretube.ui.views + +import android.app.Activity +import android.content.Context +import android.text.format.DateFormat.is24HourFormat +import android.util.AttributeSet +import androidx.appcompat.app.AppCompatActivity +import androidx.preference.Preference +import com.github.libretube.util.PreferenceHelper +import com.github.libretube.util.TextUtils +import com.google.android.material.timepicker.MaterialTimePicker +import com.google.android.material.timepicker.TimeFormat + +class TimePickerPreference( + context: Context, + attributeSet: AttributeSet +) : Preference(context, attributeSet) { + override fun getSummary(): CharSequence { + val prefStr = PreferenceHelper.getString(key, "") + return if (prefStr != "") prefStr else "00:00" + } + + override fun onClick() { + val picker = MaterialTimePicker.Builder() + .setInputMode(MaterialTimePicker.INPUT_MODE_CLOCK) + .setTimeFormat(getTimeFormat()) + .setHour(getHour()) + .setMinute(getMinutes()) + .build() + + picker.addOnPositiveButtonClickListener { + val timeStr = getTimeStr(picker) + PreferenceHelper.putString(key, timeStr) + summary = timeStr + } + picker.show((context as AppCompatActivity).supportFragmentManager, null) + } + + private fun getTimeFormat(): Int { + return if (is24HourFormat(context)) TimeFormat.CLOCK_24H else TimeFormat.CLOCK_12H + } + + private fun getPrefStringPart(index: Int): String? { + val prefStr = PreferenceHelper.getString(key, "").split(SEPARATOR).getOrNull(index) + return if (prefStr != "") prefStr else null + } + + private fun getHour(): Int { + return getPrefStringPart(0)?.toInt() ?: 0 + } + + private fun getMinutes(): Int { + return getPrefStringPart(1)?.toInt() ?: 0 + } + + private fun getTimeStr(picker: MaterialTimePicker): String { + val hour = TextUtils.toTwoDecimalsString(picker.hour) + val minute = TextUtils.toTwoDecimalsString(picker.minute) + return "$hour$SEPARATOR$minute" + } + + companion object { + const val SEPARATOR = ":" + } +} 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 ec467e9fb..046401f99 100644 --- a/app/src/main/java/com/github/libretube/util/NotificationHelper.kt +++ b/app/src/main/java/com/github/libretube/util/NotificationHelper.kt @@ -8,6 +8,7 @@ import androidx.work.PeriodicWorkRequest import androidx.work.WorkManager import com.github.libretube.constants.NOTIFICATION_WORK_NAME import com.github.libretube.constants.PreferenceKeys +import com.github.libretube.workers.NotificationWorker import java.util.concurrent.TimeUnit object NotificationHelper { diff --git a/app/src/main/java/com/github/libretube/util/TextUtils.kt b/app/src/main/java/com/github/libretube/util/TextUtils.kt index 63b8966f1..8b8cc4008 100644 --- a/app/src/main/java/com/github/libretube/util/TextUtils.kt +++ b/app/src/main/java/com/github/libretube/util/TextUtils.kt @@ -5,4 +5,8 @@ object TextUtils { * Separator used for descriptions */ const val SEPARATOR = " • " + + fun toTwoDecimalsString(num: Int): String { + return if (num >= 10) num.toString() else "0$num" + } } diff --git a/app/src/main/java/com/github/libretube/util/NotificationWorker.kt b/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt similarity index 98% rename from app/src/main/java/com/github/libretube/util/NotificationWorker.kt rename to app/src/main/java/com/github/libretube/workers/NotificationWorker.kt index 351918cad..d31b4a9c0 100644 --- a/app/src/main/java/com/github/libretube/util/NotificationWorker.kt +++ b/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt @@ -1,4 +1,4 @@ -package com.github.libretube.util +package com.github.libretube.workers import android.app.NotificationManager import android.app.PendingIntent @@ -15,6 +15,7 @@ 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 com.github.libretube.util.PreferenceHelper import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fe3fb8831..c8aa47125 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -360,6 +360,11 @@ Confirm unsubscribing Show a confirmation dialog before unsubscribing. Play all + Time + Start time + End time + Notification time + Time span in which notifications are allowed to show. Download Service diff --git a/app/src/main/res/xml/notification_settings.xml b/app/src/main/res/xml/notification_settings.xml index 4d6568710..b0b536dd2 100644 --- a/app/src/main/res/xml/notification_settings.xml +++ b/app/src/main/res/xml/notification_settings.xml @@ -31,4 +31,22 @@ + + + + + + + + + + \ No newline at end of file From 49bbe312d1b02e86d025f11d89a5c021fde891d8 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Wed, 9 Nov 2022 18:15:21 +0100 Subject: [PATCH 2/3] add logic --- .../ui/fragments/PlaylistFragment.kt | 1 - .../ui/views/TimePickerPreference.kt | 4 +-- .../libretube/workers/NotificationWorker.kt | 34 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt index 19368dff4..855810d84 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlaylistFragment.kt @@ -6,7 +6,6 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager diff --git a/app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt b/app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt index 3eabff8d8..3bb1830a2 100644 --- a/app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt +++ b/app/src/main/java/com/github/libretube/ui/views/TimePickerPreference.kt @@ -1,6 +1,5 @@ package com.github.libretube.ui.views -import android.app.Activity import android.content.Context import android.text.format.DateFormat.is24HourFormat import android.util.AttributeSet @@ -17,7 +16,7 @@ class TimePickerPreference( ) : Preference(context, attributeSet) { override fun getSummary(): CharSequence { val prefStr = PreferenceHelper.getString(key, "") - return if (prefStr != "") prefStr else "00:00" + return if (prefStr != "") prefStr else DEFAULT_VALUE } override fun onClick() { @@ -61,5 +60,6 @@ class TimePickerPreference( companion object { const val SEPARATOR = ":" + const val DEFAULT_VALUE = "12:00" } } diff --git a/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt b/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt index d31b4a9c0..5320780e5 100644 --- a/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt +++ b/app/src/main/java/com/github/libretube/workers/NotificationWorker.kt @@ -13,11 +13,14 @@ 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.constants.PreferenceKeys import com.github.libretube.extensions.toID import com.github.libretube.ui.activities.MainActivity +import com.github.libretube.ui.views.TimePickerPreference import com.github.libretube.util.PreferenceHelper import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking +import java.time.LocalTime /** * The notification worker which checks for new streams in a certain frequency @@ -36,12 +39,43 @@ class NotificationWorker(appContext: Context, parameters: WorkerParameters) : } override fun doWork(): Result { + if (!checkTime()) Result.success() // check whether there are new streams and notify if there are some val result = checkForNewStreams() // return success if the API request succeeded return if (result) Result.success() else Result.retry() } + /** + * Determine whether the time is valid to notify + */ + private fun checkTime(): Boolean { + if (!PreferenceHelper.getBoolean( + PreferenceKeys.NOTIFICATION_TIME_ENABLED, + false + ) + ) { + return true + } + + val start = getTimePickerPref(PreferenceKeys.NOTIFICATION_START_TIME) + val end = getTimePickerPref(PreferenceKeys.NOTIFICATION_END_TIME) + + val currentTime = LocalTime.now() + val isOverNight = start > end + + val startValid = if (isOverNight) start > currentTime else start < currentTime + val endValid = if (isOverNight) end < currentTime else start > currentTime + + return (startValid && endValid) + } + + private fun getTimePickerPref(key: String): LocalTime { + return LocalTime.parse( + PreferenceHelper.getString(key, TimePickerPreference.DEFAULT_VALUE) + ) + } + /** * check whether new streams are available in subscriptions */ From 67ec07f5730d06c592f7f2496171d56b1d1b4ddf Mon Sep 17 00:00:00 2001 From: Bnyro Date: Wed, 9 Nov 2022 18:20:37 +0100 Subject: [PATCH 3/3] grey out when disabled --- .../ui/preferences/NotificationSettings.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt b/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt index 3a1f20cd0..736e6fbf2 100644 --- a/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt +++ b/app/src/main/java/com/github/libretube/ui/preferences/NotificationSettings.kt @@ -8,6 +8,7 @@ import com.github.libretube.R import com.github.libretube.constants.PreferenceKeys import com.github.libretube.ui.activities.SettingsActivity import com.github.libretube.ui.base.BasePreferenceFragment +import com.github.libretube.ui.views.TimePickerPreference import com.github.libretube.util.NotificationHelper class NotificationSettings : BasePreferenceFragment() { @@ -41,6 +42,19 @@ class NotificationSettings : BasePreferenceFragment() { updateNotificationPrefs() true } + + val notificationTime = findPreference(PreferenceKeys.NOTIFICATION_TIME_ENABLED) + val notificationStartTime = findPreference(PreferenceKeys.NOTIFICATION_START_TIME) + val notificationEndTime = findPreference(PreferenceKeys.NOTIFICATION_END_TIME) + listOf(notificationStartTime, notificationEndTime).forEach { + it?.isEnabled = notificationTime?.isChecked == true + } + notificationTime?.setOnPreferenceChangeListener { _, newValue -> + listOf(notificationStartTime, notificationEndTime).forEach { + it?.isEnabled = newValue as Boolean + } + true + } } private fun updateNotificationPrefs() {