@ -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 (