Adding Recent sources as a dynamic shortcut

Also fixed searchactivity centering the toolbar title
pull/7308/head
Jays2Kings 4 years ago
parent e893326c1f
commit 01536221fb

@ -161,6 +161,8 @@ class PreferencesHelper(val context: Context) {
fun lastUsedCategory() = rxPrefs.getInteger(Keys.lastUsedCategory, 0) fun lastUsedCategory() = rxPrefs.getInteger(Keys.lastUsedCategory, 0)
fun lastUsedSources() = flowPrefs.getStringSet("last_used_sources", emptySet())
fun lastVersionCode() = rxPrefs.getInteger("last_version_code", 0) fun lastVersionCode() = rxPrefs.getInteger("last_version_code", 0)
fun browseAsList() = rxPrefs.getBoolean(Keys.catalogueAsList, false) fun browseAsList() = rxPrefs.getBoolean(Keys.catalogueAsList, false)

@ -60,6 +60,8 @@ import eu.kanade.tachiyomi.ui.setting.AboutController
import eu.kanade.tachiyomi.ui.setting.SettingsController import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.ui.setting.SettingsMainController import eu.kanade.tachiyomi.ui.setting.SettingsMainController
import eu.kanade.tachiyomi.ui.source.BrowseController import eu.kanade.tachiyomi.ui.source.BrowseController
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
import eu.kanade.tachiyomi.util.manga.MangaShortcutManager
import eu.kanade.tachiyomi.util.system.contextCompatDrawable import eu.kanade.tachiyomi.util.system.contextCompatDrawable
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.hasSideNavBar import eu.kanade.tachiyomi.util.system.hasSideNavBar
@ -101,6 +103,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
private var animationSet: AnimatorSet? = null private var animationSet: AnimatorSet? = null
private val downloadManager: DownloadManager by injectLazy() private val downloadManager: DownloadManager by injectLazy()
private val mangaShortcutManager: MangaShortcutManager by injectLazy()
private val hideBottomNav private val hideBottomNav
get() = router.backstackSize > 1 && router.backstack[1].controller() !is DialogController get() = router.backstackSize > 1 && router.backstack[1].controller() !is DialogController
@ -417,6 +420,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
super.onPause() super.onPause()
snackBar?.dismiss() snackBar?.dismiss()
setStartingTab() setStartingTab()
mangaShortcutManager.updateShortcuts()
} }
private fun getAppUpdates() { private fun getAppUpdates() {
@ -494,6 +498,11 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
router.pushController(MangaDetailsController(extras).withFadeTransaction()) router.pushController(MangaDetailsController(extras).withFadeTransaction())
} }
SHORTCUT_SOURCE -> {
val extras = intent.extras ?: return false
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
router.pushController(BrowseSourceController(extras).withFadeTransaction())
}
SHORTCUT_DOWNLOADS -> { SHORTCUT_DOWNLOADS -> {
binding.bottomNav.selectedItemId = R.id.nav_recents binding.bottomNav.selectedItemId = R.id.nav_recents
router.popToRoot() router.popToRoot()
@ -528,6 +537,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
setStartingTab() setStartingTab()
} }
SecureActivityDelegate.locked = this !is SearchActivity SecureActivityDelegate.locked = this !is SearchActivity
mangaShortcutManager.updateShortcuts()
super.onBackPressed() super.onBackPressed()
} }
} }
@ -732,6 +742,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
const val SHORTCUT_BROWSE = "eu.kanade.tachiyomi.SHOW_BROWSE" const val SHORTCUT_BROWSE = "eu.kanade.tachiyomi.SHOW_BROWSE"
const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS" const val SHORTCUT_DOWNLOADS = "eu.kanade.tachiyomi.SHOW_DOWNLOADS"
const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA" const val SHORTCUT_MANGA = "eu.kanade.tachiyomi.SHOW_MANGA"
const val SHORTCUT_SOURCE = "eu.kanade.tachiyomi.SHOW_SOURCE"
const val SHORTCUT_READER_SETTINGS = "eu.kanade.tachiyomi.READER_SETTINGS" const val SHORTCUT_READER_SETTINGS = "eu.kanade.tachiyomi.READER_SETTINGS"
const val SHORTCUT_EXTENSIONS = "eu.kanade.tachiyomi.EXTENSIONS" const val SHORTCUT_EXTENSIONS = "eu.kanade.tachiyomi.EXTENSIONS"

@ -9,10 +9,13 @@ import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.ui.setting.SettingsReaderController import eu.kanade.tachiyomi.ui.setting.SettingsReaderController
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.withFadeTransaction import eu.kanade.tachiyomi.util.view.withFadeTransaction
@ -21,10 +24,12 @@ class SearchActivity : MainActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding.toolbar?.navigationIcon = drawerArrow binding.toolbar.navigationIcon = drawerArrow
binding.toolbar?.setNavigationOnClickListener { binding.toolbar.setNavigationOnClickListener {
popToRoot() popToRoot()
} }
(router.backstack.lastOrNull()?.controller() as? BaseController<*>)?.setTitle()
(router.backstack.lastOrNull()?.controller() as? SettingsController)?.setTitle()
} }
override fun onBackPressed() { override fun onBackPressed() {
@ -35,7 +40,7 @@ class SearchActivity : MainActivity() {
} }
private fun popToRoot() { private fun popToRoot() {
if (intent.action == SHORTCUT_MANGA || intent.action == SHORTCUT_READER_SETTINGS) { if (intentShouldGoBack()) {
onBackPressed() onBackPressed()
} else if (!router.handleBack()) { } else if (!router.handleBack()) {
val intent = Intent(this, MainActivity::class.java).apply { val intent = Intent(this, MainActivity::class.java).apply {
@ -46,6 +51,9 @@ class SearchActivity : MainActivity() {
} }
} }
private fun intentShouldGoBack() =
intent.action in listOf(SHORTCUT_MANGA, SHORTCUT_READER_SETTINGS, SHORTCUT_BROWSE)
override fun syncActivityViewWithController( override fun syncActivityViewWithController(
to: Controller?, to: Controller?,
from: Controller?, from: Controller?,
@ -98,6 +106,14 @@ class SearchActivity : MainActivity() {
.popChangeHandler(FadeChangeHandler()) .popChangeHandler(FadeChangeHandler())
) )
} }
SHORTCUT_SOURCE -> {
val extras = intent.extras ?: return false
router.replaceTopController(
RouterTransaction.with(BrowseSourceController(extras))
.pushChangeHandler(SimpleSwapChangeHandler())
.popChangeHandler(FadeChangeHandler())
)
}
SHORTCUT_READER_SETTINGS -> { SHORTCUT_READER_SETTINGS -> {
router.replaceTopController( router.replaceTopController(
RouterTransaction.with(SettingsReaderController()) RouterTransaction.with(SettingsReaderController())

@ -455,11 +455,11 @@ class RecentsPresenter(
const val VIEW_TYPE_ONLY_HISTORY = 2 const val VIEW_TYPE_ONLY_HISTORY = 2
const val VIEW_TYPE_ONLY_UPDATES = 3 const val VIEW_TYPE_ONLY_UPDATES = 3
suspend fun getRecentManga(): List<Manga> { suspend fun getRecentManga(): List<Pair<Manga, Long>> {
val presenter = RecentsPresenter(null) val presenter = RecentsPresenter(null)
presenter.viewType = 1 presenter.viewType = 1
presenter.runRecents(limit = true) presenter.runRecents(limit = true)
return presenter.recentItems.filter { it.mch.manga.id != null }.map { it.mch.manga } return presenter.recentItems.filter { it.mch.manga.id != null }.map { it.mch.manga to it.mch.history.last_read }
} }
} }
} }

@ -58,6 +58,7 @@ import eu.kanade.tachiyomi.util.view.withFadeTransaction
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -439,6 +440,11 @@ class BrowseController :
*/ */
private fun openCatalogue(source: CatalogueSource, controller: BrowseSourceController) { private fun openCatalogue(source: CatalogueSource, controller: BrowseSourceController) {
preferences.lastUsedCatalogueSource().set(source.id) preferences.lastUsedCatalogueSource().set(source.id)
val list = preferences.lastUsedSources().get().toMutableSet()
list.removeAll { it.startsWith("${source.id}:") }
list.add("${source.id}:${Date().time}")
val sortedList = list.filter { it.split(":").size == 2 }.sortedByDescending { it.split(":").last().toLong() }
preferences.lastUsedSources().set(sortedList.subList(0, min(sortedList.size, 2)).toSet())
router.pushController(controller.withFadeTransaction()) router.pushController(controller.withFadeTransaction())
} }

@ -592,7 +592,7 @@ open class BrowseSourceController(bundle: Bundle) :
} }
} }
protected companion object { companion object {
const val SOURCE_ID_KEY = "sourceId" const val SOURCE_ID_KEY = "sourceId"
const val SEARCH_QUERY_KEY = "searchQuery" const val SEARCH_QUERY_KEY = "searchQuery"

@ -6,17 +6,24 @@ import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.icon
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.main.SearchActivity import eu.kanade.tachiyomi.ui.main.SearchActivity
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.recents.RecentsPresenter import eu.kanade.tachiyomi.ui.recents.RecentsPresenter
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
import eu.kanade.tachiyomi.util.system.launchIO import eu.kanade.tachiyomi.util.system.launchIO
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date import java.util.Date
@ -25,7 +32,8 @@ import kotlin.math.min
class MangaShortcutManager( class MangaShortcutManager(
val preferences: PreferencesHelper = Injekt.get(), val preferences: PreferencesHelper = Injekt.get(),
val db: DatabaseHelper = Injekt.get(), val db: DatabaseHelper = Injekt.get(),
val coverCache: CoverCache = Injekt.get() val coverCache: CoverCache = Injekt.get(),
val sourceManager: SourceManager = Injekt.get()
) { ) {
val context: Context = preferences.context val context: Context = preferences.context
@ -35,54 +43,105 @@ class MangaShortcutManager(
val shortcutManager = context.getSystemService(ShortcutManager::class.java) val shortcutManager = context.getSystemService(ShortcutManager::class.java)
val recentManga = RecentsPresenter.getRecentManga() val recentManga = RecentsPresenter.getRecentManga()
val shortcuts = recentManga.subList( val recentSources = preferences.lastUsedSources().get().mapNotNull {
val splitS = it.split(":")
splitS.first().toLongOrNull()?.let { id ->
sourceManager.getOrStub(id) to splitS[1].toLong()
}
}
var recents = (
recentManga.subList(
0,
min(
recentManga.size,
shortcutManager.maxShortcutCountPerActivity
)
) + recentSources
)
.sortedByDescending { it.second }.map { it.first }
recents = recents.subList(
0, 0,
min( min(
recentManga.size, recentManga.size,
shortcutManager.maxShortcutCountPerActivity shortcutManager.maxShortcutCountPerActivity
) )
).map { manga -> )
val customCoverFile = coverCache.getCustomCoverFile(manga)
val coverFile = if (customCoverFile.exists()) { val shortcuts = recents.mapNotNull { item ->
customCoverFile when (item) {
} else { is Manga -> {
val coverFile = coverCache.getCoverFile(manga) val customCoverFile = coverCache.getCustomCoverFile(item)
if (coverFile.exists()) { val coverFile = if (customCoverFile.exists()) {
if (!manga.favorite) { customCoverFile
coverFile.setLastModified(Date().time) } else {
val coverFile = coverCache.getCoverFile(item)
if (coverFile.exists()) {
if (!item.favorite) {
coverFile.setLastModified(Date().time)
}
coverFile
} else {
null
}
} }
coverFile val bitmap = if (coverFile != null) {
} else { BitmapFactory.decodeFile(coverFile.path)
} else {
null
}
ShortcutInfo.Builder(context, "Manga-${item.id?.toString() ?: item.title}")
.setShortLabel(item.title)
.setLongLabel(item.title)
.setIcon(
if (bitmap != null) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Icon.createWithAdaptiveBitmap(bitmap.toSquare())
} else {
Icon.createWithBitmap(bitmap)
}
else Icon.createWithResource(context, R.drawable.ic_book_24dp)
)
.setIntent(
Intent(
context,
SearchActivity::class.java
).setAction(MainActivity.SHORTCUT_MANGA)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(MangaDetailsController.MANGA_EXTRA, item.id)
)
.build()
}
is Source -> {
val bitmap = (item.icon() as? BitmapDrawable)?.bitmap
ShortcutInfo.Builder(context, "Source-${item.id}")
.setShortLabel(item.name)
.setLongLabel(item.name)
.setIcon(
if (bitmap != null) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Icon.createWithAdaptiveBitmap(bitmap.toSquare())
} else {
Icon.createWithBitmap(bitmap)
}
else Icon.createWithResource(context, R.drawable.ic_extension_update_24dp)
)
.setIntent(
Intent(
context,
SearchActivity::class.java
).setAction(MainActivity.SHORTCUT_SOURCE)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(BrowseSourceController.SOURCE_ID_KEY, item.id)
)
.build()
}
else -> {
null null
} }
} }
val bitmap = if (coverFile != null) {
BitmapFactory.decodeFile(coverFile.path)
} else {
null
}
ShortcutInfo.Builder(context, "Manga-${manga.id?.toString() ?: manga.title}")
.setShortLabel(manga.title)
.setLongLabel(manga.title)
.setIcon(
if (bitmap != null) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Icon.createWithAdaptiveBitmap(bitmap.toSquare())
} else {
Icon.createWithBitmap(bitmap)
}
else Icon.createWithResource(context, R.drawable.ic_book_24dp)
)
.setIntent(
Intent(
context,
SearchActivity::class.java
).setAction(MainActivity.SHORTCUT_MANGA)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(MangaDetailsController.MANGA_EXTRA, manga.id)
)
.build()
} }
Timber.d("Shortcuts: ${shortcuts.joinToString(", ") { it.longLabel ?: "n/a" }}")
shortcutManager.dynamicShortcuts = shortcuts shortcutManager.dynamicShortcuts = shortcuts
} }
} }

Loading…
Cancel
Save