diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt index 9cb3f2d8e..b3e6f26d2 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -574,6 +574,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { const val KEY_CF_CONTRAST = "cf_contrast" const val KEY_CF_INVERTED = "cf_inverted" const val KEY_CF_GRAYSCALE = "cf_grayscale" + const val KEY_IGNORE_DOZE = "ignore_dose" // About const val KEY_APP_UPDATE = "app_update" diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt index cc87f160b..271b3090d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt @@ -5,7 +5,9 @@ import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import androidx.work.WorkInfo import coil.ImageLoader import coil.request.SuccessResult @@ -59,6 +61,7 @@ fun downloadItemAD( val chaptersAdapter = BaseListAdapter() .addDelegate(ListItemType.CHAPTER, downloadChapterAD()) + binding.recyclerViewChapters.addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL)) binding.recyclerViewChapters.adapter = chaptersAdapter binding.buttonCancel.setOnClickListener(clickListener) binding.buttonPause.setOnClickListener(clickListener) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/DownloadsSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/DownloadsSettingsFragment.kt index 7572b3965..5769cb73c 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/DownloadsSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/DownloadsSettingsFragment.kt @@ -17,6 +17,7 @@ import org.koitharu.kotatsu.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.local.data.LocalStorageManager import org.koitharu.kotatsu.settings.storage.MangaDirectorySelectDialog import org.koitharu.kotatsu.settings.storage.directories.MangaDirectoriesActivity +import org.koitharu.kotatsu.settings.utils.DozeHelper import javax.inject.Inject @AndroidEntryPoint @@ -24,6 +25,8 @@ class DownloadsSettingsFragment : BasePreferenceFragment(R.string.downloads), SharedPreferences.OnSharedPreferenceChangeListener { + private val dozeHelper = DozeHelper(this) + @Inject lateinit var storageManager: LocalStorageManager @@ -32,6 +35,7 @@ class DownloadsSettingsFragment : override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_downloads) + dozeHelper.updatePreference() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -74,6 +78,10 @@ class DownloadsSettingsFragment : true } + AppSettings.KEY_IGNORE_DOZE -> { + dozeHelper.startIgnoreDoseActivity() + } + else -> super.onPreferenceTreeClick(preference) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt index 18a2289ba..3875156a6 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt @@ -1,43 +1,36 @@ package org.koitharu.kotatsu.settings.tracker -import android.annotation.SuppressLint -import android.content.ActivityNotFoundException -import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.net.Uri import android.os.Build import android.os.Bundle -import android.os.PowerManager import android.provider.Settings import android.text.style.URLSpan import android.view.View -import androidx.core.net.toUri import androidx.core.text.buildSpannedString import androidx.core.text.inSpans import androidx.fragment.app.viewModels import androidx.preference.MultiSelectListPreference import androidx.preference.Preference -import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.util.ext.observe -import org.koitharu.kotatsu.core.util.ext.powerManager import org.koitharu.kotatsu.settings.tracker.categories.TrackerCategoriesConfigSheet +import org.koitharu.kotatsu.settings.utils.DozeHelper import org.koitharu.kotatsu.settings.utils.MultiSummaryProvider import org.koitharu.kotatsu.tracker.work.TrackerNotificationChannels import javax.inject.Inject -private const val KEY_IGNORE_DOZE = "ignore_dose" - @AndroidEntryPoint class TrackerSettingsFragment : BasePreferenceFragment(R.string.check_for_new_chapters), SharedPreferences.OnSharedPreferenceChangeListener { private val viewModel by viewModels() + private val dozeHelper = DozeHelper(this) @Inject lateinit var channels: TrackerNotificationChannels @@ -57,13 +50,12 @@ class TrackerSettingsFragment : } } } - updateDozePreference() + dozeHelper.updatePreference() updateCategoriesEnabled() } override fun onResume() { super.onResume() - updateDozePreference() updateNotificationsSummary() } @@ -111,8 +103,8 @@ class TrackerSettingsFragment : true } - KEY_IGNORE_DOZE -> { - startIgnoreDoseActivity(preference.context) + AppSettings.KEY_IGNORE_DOZE -> { + dozeHelper.startIgnoreDoseActivity() true } @@ -120,12 +112,6 @@ class TrackerSettingsFragment : } } - private fun updateDozePreference() { - findPreference(KEY_IGNORE_DOZE)?.run { - isVisible = isDozeIgnoreAvailable(context) - } - } - private fun updateNotificationsSummary() { val pref = findPreference(AppSettings.KEY_NOTIFICATIONS_SETTINGS) ?: return pref.setSummary( @@ -148,34 +134,4 @@ class TrackerSettingsFragment : getString(R.string.enabled_d_of_d, count[0], count[1]) } } - - @SuppressLint("BatteryLife") - private fun startIgnoreDoseActivity(context: Context) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - Snackbar.make(listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() - return - } - val packageName = context.packageName - val powerManager = context.powerManager ?: return - if (!powerManager.isIgnoringBatteryOptimizations(packageName)) { - try { - val intent = Intent( - Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, - "package:$packageName".toUri(), - ) - startActivity(intent) - } catch (e: ActivityNotFoundException) { - Snackbar.make(listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() - } - } - } - - private fun isDozeIgnoreAvailable(context: Context): Boolean { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return false - } - val packageName = context.packageName - val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager - return !powerManager.isIgnoringBatteryOptimizations(packageName) - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/utils/DozeHelper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/utils/DozeHelper.kt new file mode 100644 index 000000000..35d0dc359 --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/utils/DozeHelper.kt @@ -0,0 +1,69 @@ +package org.koitharu.kotatsu.settings.utils + +import android.annotation.SuppressLint +import android.content.ActivityNotFoundException +import android.content.Context +import android.content.Intent +import android.os.Build +import android.os.PowerManager +import android.provider.Settings +import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.net.toUri +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import com.google.android.material.snackbar.Snackbar +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.core.util.ext.powerManager + +@SuppressLint("BatteryLife") +class DozeHelper( + private val fragment: PreferenceFragmentCompat, +) { + + private val startForDozeResult = fragment.registerForActivityResult( + ActivityResultContracts.StartActivityForResult(), + ) { + updatePreference() + } + + fun updatePreference() { + val preference = fragment.findPreference(AppSettings.KEY_IGNORE_DOZE) ?: return + preference.isVisible = isDozeIgnoreAvailable() + } + + fun startIgnoreDoseActivity(): Boolean { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + Snackbar.make(fragment.listView ?: return false, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() + return false + } + val context = fragment.context ?: return false + val packageName = context.packageName + val powerManager = context.powerManager ?: return false + return if (!powerManager.isIgnoringBatteryOptimizations(packageName)) { + try { + val intent = Intent( + Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, + "package:$packageName".toUri(), + ) + startForDozeResult.launch(intent) + true + } catch (e: ActivityNotFoundException) { + Snackbar.make(fragment.listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() + false + } + } else { + false + } + } + + private fun isDozeIgnoreAvailable(): Boolean { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return false + } + val context = fragment.context ?: return false + val packageName = context.packageName + val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager + return !powerManager.isIgnoringBatteryOptimizations(packageName) + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 623d2a328..517127409 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -543,4 +543,5 @@ Filtering by both genres and locale is not supported by this source Filtering by both genres and states is not supported by this source Start typing the genre name + Might help with getting the download started if you have any issues with it diff --git a/app/src/main/res/xml/pref_downloads.xml b/app/src/main/res/xml/pref_downloads.xml index a9e792269..b2a05bcfe 100644 --- a/app/src/main/res/xml/pref_downloads.xml +++ b/app/src/main/res/xml/pref_downloads.xml @@ -19,6 +19,14 @@ android:summary="@string/downloads_wifi_only_summary" android:title="@string/downloads_wifi_only" /> + +