Option to disable dynamic shortcuts
This commit is contained in:
@@ -2,10 +2,12 @@ package org.koitharu.kotatsu.core.os
|
|||||||
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.ShortcutManager
|
import android.content.pm.ShortcutManager
|
||||||
import android.media.ThumbnailUtils
|
import android.media.ThumbnailUtils
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Size
|
import android.util.Size
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
@@ -22,6 +24,7 @@ import kotlinx.coroutines.launch
|
|||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.domain.MangaDataRepository
|
import org.koitharu.kotatsu.base.domain.MangaDataRepository
|
||||||
import org.koitharu.kotatsu.core.db.TABLE_HISTORY
|
import org.koitharu.kotatsu.core.db.TABLE_HISTORY
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
||||||
@@ -35,13 +38,18 @@ class ShortcutsUpdater @Inject constructor(
|
|||||||
private val coil: ImageLoader,
|
private val coil: ImageLoader,
|
||||||
private val historyRepository: HistoryRepository,
|
private val historyRepository: HistoryRepository,
|
||||||
private val mangaRepository: MangaDataRepository,
|
private val mangaRepository: MangaDataRepository,
|
||||||
) : InvalidationTracker.Observer(TABLE_HISTORY) {
|
private val settings: AppSettings,
|
||||||
|
) : InvalidationTracker.Observer(TABLE_HISTORY), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
private val iconSize by lazy { getIconSize(context) }
|
private val iconSize by lazy { getIconSize(context) }
|
||||||
private var shortcutsUpdateJob: Job? = null
|
private var shortcutsUpdateJob: Job? = null
|
||||||
|
|
||||||
override fun onInvalidated(tables: MutableSet<String>) {
|
init {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
settings.subscribe(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onInvalidated(tables: Set<String>) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1 || !settings.isDynamicShortcutsEnabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val prevJob = shortcutsUpdateJob
|
val prevJob = shortcutsUpdateJob
|
||||||
@@ -51,6 +59,16 @@ class ShortcutsUpdater @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1 && key == AppSettings.KEY_SHORTCUTS) {
|
||||||
|
if (settings.isDynamicShortcutsEnabled) {
|
||||||
|
onInvalidated(emptySet())
|
||||||
|
} else {
|
||||||
|
clearShortcuts()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun requestPinShortcut(manga: Manga): Boolean {
|
suspend fun requestPinShortcut(manga: Manga): Boolean {
|
||||||
return ShortcutManagerCompat.requestPinShortcut(
|
return ShortcutManagerCompat.requestPinShortcut(
|
||||||
context,
|
context,
|
||||||
@@ -64,6 +82,15 @@ class ShortcutsUpdater @Inject constructor(
|
|||||||
return shortcutsUpdateJob?.join() != null
|
return shortcutsUpdateJob?.join() != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isDynamicShortcutsAvailable(): Boolean {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val manager = context.getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager
|
||||||
|
return manager.maxShortcutCountPerActivity > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||||
private suspend fun updateShortcutsImpl() = runCatching {
|
private suspend fun updateShortcutsImpl() = runCatching {
|
||||||
val manager = context.getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager
|
val manager = context.getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager
|
||||||
val shortcuts = historyRepository.getList(0, manager.maxShortcutCountPerActivity)
|
val shortcuts = historyRepository.getList(0, manager.maxShortcutCountPerActivity)
|
||||||
@@ -74,6 +101,15 @@ class ShortcutsUpdater @Inject constructor(
|
|||||||
it.printStackTraceDebug()
|
it.printStackTraceDebug()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||||
|
private fun clearShortcuts() {
|
||||||
|
val manager = context.getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager
|
||||||
|
try {
|
||||||
|
manager.removeAllDynamicShortcuts()
|
||||||
|
} catch (_: IllegalStateException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun buildShortcutInfo(manga: Manga): ShortcutInfoCompat.Builder {
|
private suspend fun buildShortcutInfo(manga: Manga): ShortcutInfoCompat.Builder {
|
||||||
val icon = runCatching {
|
val icon = runCatching {
|
||||||
val bmp = coil.execute(
|
val bmp = coil.execute(
|
||||||
|
|||||||
@@ -134,6 +134,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
|||||||
val isExitConfirmationEnabled: Boolean
|
val isExitConfirmationEnabled: Boolean
|
||||||
get() = prefs.getBoolean(KEY_EXIT_CONFIRM, false)
|
get() = prefs.getBoolean(KEY_EXIT_CONFIRM, false)
|
||||||
|
|
||||||
|
val isDynamicShortcutsEnabled: Boolean
|
||||||
|
get() = prefs.getBoolean(KEY_SHORTCUTS, true)
|
||||||
|
|
||||||
var sourcesOrder: List<String>
|
var sourcesOrder: List<String>
|
||||||
get() = prefs.getString(KEY_SOURCES_ORDER, null)
|
get() = prefs.getString(KEY_SOURCES_ORDER, null)
|
||||||
?.split('|')
|
?.split('|')
|
||||||
@@ -317,6 +320,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
|||||||
const val KEY_INCOGNITO_MODE = "incognito"
|
const val KEY_INCOGNITO_MODE = "incognito"
|
||||||
const val KEY_SYNC = "sync"
|
const val KEY_SYNC = "sync"
|
||||||
const val KEY_READER_BAR = "reader_bar"
|
const val KEY_READER_BAR = "reader_bar"
|
||||||
|
const val KEY_SHORTCUTS = "dynamic_shortcuts"
|
||||||
|
|
||||||
// About
|
// About
|
||||||
const val KEY_APP_UPDATE = "app_update"
|
const val KEY_APP_UPDATE = "app_update"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import kotlinx.coroutines.launch
|
|||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.ui.BasePreferenceFragment
|
import org.koitharu.kotatsu.base.ui.BasePreferenceFragment
|
||||||
import org.koitharu.kotatsu.core.network.AndroidCookieJar
|
import org.koitharu.kotatsu.core.network.AndroidCookieJar
|
||||||
|
import org.koitharu.kotatsu.core.os.ShortcutsUpdater
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.local.data.CacheDir
|
import org.koitharu.kotatsu.local.data.CacheDir
|
||||||
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
import org.koitharu.kotatsu.local.data.LocalStorageManager
|
||||||
@@ -41,8 +42,13 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var cookieJar: AndroidCookieJar
|
lateinit var cookieJar: AndroidCookieJar
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var shortcutsUpdater: ShortcutsUpdater
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
addPreferencesFromResource(R.xml.pref_history)
|
addPreferencesFromResource(R.xml.pref_history)
|
||||||
|
findPreference<Preference>(AppSettings.KEY_SHORTCUTS)?.isVisible =
|
||||||
|
shortcutsUpdater.isDynamicShortcutsAvailable()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
|||||||
@@ -377,4 +377,6 @@
|
|||||||
<string name="import_will_start_soon">Import will start soon</string>
|
<string name="import_will_start_soon">Import will start soon</string>
|
||||||
<string name="feed">Feed</string>
|
<string name="feed">Feed</string>
|
||||||
<string name="manga_error_description_pattern">Error details:<br><tt>%1$s</tt><br><br>1. Try to <a href="%2$s">open manga in a web browser</a> to ensure it is available on its source<br>2. If it is available, send an error report to the developers.</string>
|
<string name="manga_error_description_pattern">Error details:<br><tt>%1$s</tt><br><br>1. Try to <a href="%2$s">open manga in a web browser</a> to ensure it is available on its source<br>2. If it is available, send an error report to the developers.</string>
|
||||||
|
<string name="history_shortcuts">Show recent manga shortcuts</string>
|
||||||
|
<string name="history_shortcuts_summary">Make recent manga available by long pressing on application icon</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -13,6 +13,12 @@
|
|||||||
android:summary="@string/exclude_nsfw_from_history_summary"
|
android:summary="@string/exclude_nsfw_from_history_summary"
|
||||||
android:title="@string/exclude_nsfw_from_history" />
|
android:title="@string/exclude_nsfw_from_history" />
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="dynamic_shortcuts"
|
||||||
|
android:summary="@string/history_shortcuts_summary"
|
||||||
|
android:title="@string/history_shortcuts" />
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/tracking">
|
<PreferenceCategory android:title="@string/tracking">
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
@@ -56,4 +62,4 @@
|
|||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|||||||
Reference in New Issue
Block a user