mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-10 04:55:06 +01:00
Library presenter no longer using oberserables
This lagged sorting for D&D so time to get rid of it
This commit is contained in:
parent
362c39056b
commit
5d31737c68
@ -13,7 +13,10 @@ class LibraryManga : MangaImpl() {
|
|||||||
fun mangaType(): Int {
|
fun mangaType(): Int {
|
||||||
val sourceManager:SourceManager by injectLazy()
|
val sourceManager:SourceManager by injectLazy()
|
||||||
return if (currentGenres()?.split(",")?.any
|
return if (currentGenres()?.split(",")?.any
|
||||||
{ tag -> tag.trim().toLowerCase(Locale.getDefault()) == "long strip" } == true ||
|
{ tag ->
|
||||||
|
val trimmedTag = tag.trim().toLowerCase(Locale.getDefault())
|
||||||
|
trimmedTag == "long strip" || trimmedTag == "manwha"
|
||||||
|
} == true ||
|
||||||
sourceManager.getOrStub(source).name.contains("webtoon", true))
|
sourceManager.getOrStub(source).name.contains("webtoon", true))
|
||||||
MANWHA
|
MANWHA
|
||||||
else MANGA
|
else MANGA
|
||||||
|
@ -22,6 +22,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
|||||||
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||||
|
import eu.kanade.tachiyomi.data.download.DownloadServiceListener
|
||||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateRanker.rankingScheme
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateRanker.rankingScheme
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
|
||||||
@ -52,6 +53,7 @@ import rx.schedulers.Schedulers
|
|||||||
import timber.log.Timber
|
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 uy.kohesive.injekt.injectLazy
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -233,6 +235,16 @@ class LibraryUpdateService(
|
|||||||
val categoryId = intent.getIntExtra(KEY_CATEGORY, -1)
|
val categoryId = intent.getIntExtra(KEY_CATEGORY, -1)
|
||||||
return getMangaToUpdate(categoryId, target)
|
return getMangaToUpdate(categoryId, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var listener:LibraryServiceListener? = null
|
||||||
|
|
||||||
|
fun setListener(listener: LibraryServiceListener) {
|
||||||
|
this.listener = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListener() {
|
||||||
|
listener = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -353,9 +365,11 @@ class LibraryUpdateService(
|
|||||||
val fetchedChapters = try { source.fetchChapterList(manga).toBlocking().single() }
|
val fetchedChapters = try { source.fetchChapterList(manga).toBlocking().single() }
|
||||||
catch(e: java.lang.Exception) {
|
catch(e: java.lang.Exception) {
|
||||||
failedUpdates.add(manga)
|
failedUpdates.add(manga)
|
||||||
emptyList<SChapter>() }
|
emptyList<SChapter>()
|
||||||
|
}
|
||||||
if (fetchedChapters.isNotEmpty()) {
|
if (fetchedChapters.isNotEmpty()) {
|
||||||
val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source).first
|
val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source).first
|
||||||
|
listener?.updatedManga(manga)
|
||||||
if (newChapters.isNotEmpty()) {
|
if (newChapters.isNotEmpty()) {
|
||||||
if (downloadNew && (categoriesToDownload.isEmpty() || manga.category in categoriesToDownload)) {
|
if (downloadNew && (categoriesToDownload.isEmpty() || manga.category in categoriesToDownload)) {
|
||||||
downloadChapters(manga, newChapters.sortedBy { it.chapter_number })
|
downloadChapters(manga, newChapters.sortedBy { it.chapter_number })
|
||||||
@ -592,5 +606,8 @@ class LibraryUpdateService(
|
|||||||
intent.action = MainActivity.SHORTCUT_RECENTLY_UPDATED
|
intent.action = MainActivity.SHORTCUT_RECENTLY_UPDATED
|
||||||
return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LibraryServiceListener {
|
||||||
|
fun updatedManga(manga: LibraryManga)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) :
|
|||||||
|
|
||||||
//background = VectorDrawableCompat.create(resources!!, R.drawable.button_bg_transparent, null)
|
//background = VectorDrawableCompat.create(resources!!, R.drawable.button_bg_transparent, null)
|
||||||
setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_text_state))
|
setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_text_state))
|
||||||
backgroundTintList = ContextCompat.getColorStateList(context, R.drawable.button_bg_transparent)
|
backgroundTintList = ContextCompat.getColorStateList(context, R.color.button_bg)
|
||||||
|
|
||||||
val extension = item.extension
|
val extension = item.extension
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
|||||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import kotlinx.android.synthetic.main.library_category.view.*
|
import kotlinx.android.synthetic.main.library_category.view.*
|
||||||
|
import kotlinx.android.synthetic.main.library_controller.*
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import rx.subscriptions.CompositeSubscription
|
import rx.subscriptions.CompositeSubscription
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
@ -128,7 +129,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
swipe_refresh.setOnRefreshListener {
|
swipe_refresh.setOnRefreshListener {
|
||||||
val inQueue = LibraryUpdateService.categoryInQueue(category.id)
|
val inQueue = LibraryUpdateService.categoryInQueue(category.id)
|
||||||
controller.snack?.dismiss()
|
controller.snack?.dismiss()
|
||||||
controller.snack = snack(
|
controller.snack = controller.snackbar_layout.snack(
|
||||||
resources.getString(
|
resources.getString(
|
||||||
when {
|
when {
|
||||||
inQueue -> R.string.category_already_in_queue
|
inQueue -> R.string.category_already_in_queue
|
||||||
|
@ -37,6 +37,8 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadServiceListener
|
import eu.kanade.tachiyomi.data.download.DownloadServiceListener
|
||||||
|
import eu.kanade.tachiyomi.data.library.LibraryServiceListener
|
||||||
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
@ -79,7 +81,8 @@ class LibraryController(
|
|||||||
ActionMode.Callback,
|
ActionMode.Callback,
|
||||||
ChangeMangaCategoriesDialog.Listener,
|
ChangeMangaCategoriesDialog.Listener,
|
||||||
MigrationInterface,
|
MigrationInterface,
|
||||||
DownloadServiceListener {
|
DownloadServiceListener,
|
||||||
|
LibraryServiceListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Position of the active category.
|
* Position of the active category.
|
||||||
@ -273,15 +276,17 @@ class LibraryController(
|
|||||||
super.onChangeStarted(handler, type)
|
super.onChangeStarted(handler, type)
|
||||||
if (type.isEnter) {
|
if (type.isEnter) {
|
||||||
activity?.tabs?.setupWithViewPager(library_pager)
|
activity?.tabs?.setupWithViewPager(library_pager)
|
||||||
presenter.subscribeLibrary()
|
presenter.getLibrary()
|
||||||
DownloadService.addListener(this)
|
DownloadService.addListener(this)
|
||||||
DownloadService.callListeners()
|
DownloadService.callListeners()
|
||||||
|
LibraryUpdateService.setListener(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
adapter?.onDestroy()
|
adapter?.onDestroy()
|
||||||
DownloadService.removeListener(this)
|
DownloadService.removeListener(this)
|
||||||
|
LibraryUpdateService.removeListener()
|
||||||
adapter = null
|
adapter = null
|
||||||
actionMode = null
|
actionMode = null
|
||||||
tabsVisibilitySubscription?.unsubscribe()
|
tabsVisibilitySubscription?.unsubscribe()
|
||||||
@ -298,6 +303,11 @@ class LibraryController(
|
|||||||
bottom_sheet.adjustTitleMargin(downloading)
|
bottom_sheet.adjustTitleMargin(downloading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun updatedManga(manga: LibraryManga) {
|
||||||
|
presenter.updateManga(manga)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDetach(view: View) {
|
override fun onDetach(view: View) {
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
snack?.dismiss()
|
snack?.dismiss()
|
||||||
@ -347,9 +357,9 @@ class LibraryController(
|
|||||||
tabsVisibilitySubscription?.unsubscribe()
|
tabsVisibilitySubscription?.unsubscribe()
|
||||||
tabsVisibilitySubscription = tabsVisibilityRelay.subscribe { visible ->
|
tabsVisibilitySubscription = tabsVisibilityRelay.subscribe { visible ->
|
||||||
val tabAnimator = (activity as? MainActivity)?.tabAnimator ?: return@subscribe
|
val tabAnimator = (activity as? MainActivity)?.tabAnimator ?: return@subscribe
|
||||||
if (visible && tabAnimator.getHeight() == 0) {
|
if (visible) {
|
||||||
tabAnimator.expand()
|
tabAnimator.expand()
|
||||||
} else if (!visible && tabAnimator.getHeight() != 0) {
|
} else if (!visible) {
|
||||||
tabAnimator.collapse()
|
tabAnimator.collapse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -746,7 +756,7 @@ class LibraryController(
|
|||||||
presenter.removeMangaFromLibrary(mangas)
|
presenter.removeMangaFromLibrary(mangas)
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
snack?.dismiss()
|
snack?.dismiss()
|
||||||
snack = pager_layout?.snack(activity?.getString(R.string.manga_removed_library) ?: "", Snackbar
|
snack = snackbar_layout?.snack(activity?.getString(R.string.manga_removed_library) ?: "", Snackbar
|
||||||
.LENGTH_INDEFINITE) {
|
.LENGTH_INDEFINITE) {
|
||||||
var undoing = false
|
var undoing = false
|
||||||
setAction(R.string.action_undo) {
|
setAction(R.string.action_undo) {
|
||||||
|
@ -33,10 +33,16 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
|||||||
import eu.kanade.tachiyomi.util.lang.combineLatest
|
import eu.kanade.tachiyomi.util.lang.combineLatest
|
||||||
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed
|
||||||
import eu.kanade.tachiyomi.util.lang.removeArticles
|
import eu.kanade.tachiyomi.util.lang.removeArticles
|
||||||
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_EXCLUDE
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_EXCLUDE
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_IGNORE
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_IGNORE
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_INCLUDE
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_INCLUDE
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_REALLY_EXCLUDE
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_REALLY_EXCLUDE
|
||||||
|
import kotlinx.coroutines.CoroutineStart
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
@ -80,36 +86,21 @@ class LibraryPresenter(
|
|||||||
var allCategories: List<Category> = emptyList()
|
var allCategories: List<Category> = emptyList()
|
||||||
private set
|
private set
|
||||||
/**
|
/**
|
||||||
* Relay used to apply the UI filters to the last emission of the library.
|
* List of all manga to update the
|
||||||
*/
|
*/
|
||||||
private val filterTriggerRelay = BehaviorRelay.create(Unit)
|
private var rawMangaMap:LibraryMap? = null
|
||||||
|
|
||||||
/**
|
private var currentMangaMap:LibraryMap? = null
|
||||||
* Relay used to apply the UI update to the last emission of the library.
|
|
||||||
*/
|
|
||||||
private val downloadTriggerRelay = BehaviorRelay.create(Unit)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Relay used to apply the selected sorting method to the last emission of the library.
|
|
||||||
*/
|
|
||||||
private val sortTriggerRelay = BehaviorRelay.create(Unit)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Library subscription.
|
|
||||||
*/
|
|
||||||
private var librarySubscription: Subscription? = null
|
|
||||||
|
|
||||||
private var lastCategoryId:Int? = null
|
|
||||||
|
|
||||||
override fun onCreate(savedState: Bundle?) {
|
override fun onCreate(savedState: Bundle?) {
|
||||||
super.onCreate(savedState)
|
super.onCreate(savedState)
|
||||||
subscribeLibrary()
|
getLibrary()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribes to library if needed.
|
* Subscribes to library if needed.
|
||||||
*/
|
*/
|
||||||
fun subscribeLibrary() {
|
/* fun subscribeLibrary() {
|
||||||
if (librarySubscription.isNullOrUnsubscribed()) {
|
if (librarySubscription.isNullOrUnsubscribed()) {
|
||||||
librarySubscription = getLibraryObservable()
|
librarySubscription = getLibraryObservable()
|
||||||
.combineLatest(downloadTriggerRelay.observeOn(Schedulers.io())) {
|
.combineLatest(downloadTriggerRelay.observeOn(Schedulers.io())) {
|
||||||
@ -126,6 +117,22 @@ class LibraryPresenter(
|
|||||||
view.onNextLibraryUpdate(categories, mangaMap)
|
view.onNextLibraryUpdate(categories, mangaMap)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
fun getLibrary() {
|
||||||
|
launchUI {
|
||||||
|
val mangaMap = withContext(Dispatchers.IO) {
|
||||||
|
val library = getLibraryFromDB()
|
||||||
|
library.apply { setDownloadCount(library.mangaMap) }
|
||||||
|
rawMangaMap = library.mangaMap
|
||||||
|
var mangaMap = library.mangaMap
|
||||||
|
mangaMap = applyFilters(mangaMap)
|
||||||
|
mangaMap = applySort(mangaMap)
|
||||||
|
mangaMap
|
||||||
|
}
|
||||||
|
currentMangaMap = mangaMap
|
||||||
|
view?.onNextLibraryUpdate(categories, mangaMap)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,7 +235,6 @@ class LibraryPresenter(
|
|||||||
val catSorted = applySort(mapOf(catId to categoryManga), catId)
|
val catSorted = applySort(mapOf(catId to categoryManga), catId)
|
||||||
val mutableMap = map.toMutableMap()
|
val mutableMap = map.toMutableMap()
|
||||||
mutableMap[catId] = catSorted.values.first()
|
mutableMap[catId] = catSorted.values.first()
|
||||||
lastCategoryId = null
|
|
||||||
return mutableMap
|
return mutableMap
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,8 +295,6 @@ class LibraryPresenter(
|
|||||||
* @param map the map to sort.
|
* @param map the map to sort.
|
||||||
*/
|
*/
|
||||||
private fun applySort(map: LibraryMap): LibraryMap {
|
private fun applySort(map: LibraryMap): LibraryMap {
|
||||||
if (lastCategoryId != null) return applyCatSort(map, lastCategoryId)
|
|
||||||
|
|
||||||
val sortingMode = preferences.librarySortingMode().getOrDefault()
|
val sortingMode = preferences.librarySortingMode().getOrDefault()
|
||||||
|
|
||||||
val lastReadManga by lazy {
|
val lastReadManga by lazy {
|
||||||
@ -408,7 +412,34 @@ class LibraryPresenter(
|
|||||||
*
|
*
|
||||||
* @return an observable of the categories and its manga.
|
* @return an observable of the categories and its manga.
|
||||||
*/
|
*/
|
||||||
private fun getLibraryObservable(): Observable<Library> {
|
private fun getLibraryFromDB(): Library {
|
||||||
|
val categories = db.getCategories().executeAsBlocking().toMutableList()
|
||||||
|
val libraryAsList = preferences.libraryAsList()
|
||||||
|
val showCategories = preferences.showCategories().getOrDefault()
|
||||||
|
var libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||||
|
if (!showCategories)
|
||||||
|
libraryManga = libraryManga.distinctBy { it.id }
|
||||||
|
val libraryMap = libraryManga.map { manga ->
|
||||||
|
LibraryItem(manga, libraryAsList)
|
||||||
|
}.groupBy {
|
||||||
|
if (showCategories) it.manga.category else 0
|
||||||
|
}
|
||||||
|
if (libraryMap.containsKey(0))
|
||||||
|
categories.add(0, createDefaultCategory())
|
||||||
|
|
||||||
|
this.allCategories = categories
|
||||||
|
this.categories = if (!preferences.showCategories().getOrDefault())
|
||||||
|
arrayListOf(createDefaultCategory())
|
||||||
|
else categories
|
||||||
|
return Library(this.categories, libraryMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the categories and all its manga from the database.
|
||||||
|
*
|
||||||
|
* @return an observable of the categories and its manga.
|
||||||
|
*/
|
||||||
|
/*private fun getLibraryObservable(): Observable<Library> {
|
||||||
return Observable.combineLatest(getCategoriesObservable(), getLibraryMangasObservable()) { dbCategories, libraryManga ->
|
return Observable.combineLatest(getCategoriesObservable(), getLibraryMangasObservable()) { dbCategories, libraryManga ->
|
||||||
val categories = if (libraryManga.containsKey(0))
|
val categories = if (libraryManga.containsKey(0))
|
||||||
arrayListOf(createDefaultCategory()) + dbCategories
|
arrayListOf(createDefaultCategory()) + dbCategories
|
||||||
@ -420,7 +451,7 @@ class LibraryPresenter(
|
|||||||
else categories
|
else categories
|
||||||
Library(this.categories, libraryManga)
|
Library(this.categories, libraryManga)
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private fun createDefaultCategory(): Category {
|
private fun createDefaultCategory(): Category {
|
||||||
val default = Category.createDefault(context)
|
val default = Category.createDefault(context)
|
||||||
@ -429,7 +460,7 @@ class LibraryPresenter(
|
|||||||
else default.mangaOrder = defOrder.split("/").mapNotNull { it.toLongOrNull() }
|
else default.mangaOrder = defOrder.split("/").mapNotNull { it.toLongOrNull() }
|
||||||
return default
|
return default
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
/**
|
/**
|
||||||
* Get the categories from the database.
|
* Get the categories from the database.
|
||||||
*
|
*
|
||||||
@ -458,36 +489,60 @@ class LibraryPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* Requests the library to be filtered.
|
* Requests the library to be filtered.
|
||||||
*/
|
*/
|
||||||
fun requestFilterUpdate() {
|
fun requestFilterUpdate() {
|
||||||
filterTriggerRelay.call(Unit)
|
launchUI {
|
||||||
|
var mangaMap = rawMangaMap ?: return@launchUI
|
||||||
|
mangaMap = withContext(Dispatchers.IO) { applyFilters(mangaMap) }
|
||||||
|
mangaMap = withContext(Dispatchers.IO) { applySort(mangaMap) }
|
||||||
|
currentMangaMap = mangaMap
|
||||||
|
view?.onNextLibraryUpdate(categories, mangaMap)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests the library to have download badges added.
|
* Requests the library to have download badges added.
|
||||||
*/
|
*/
|
||||||
fun requestDownloadBadgesUpdate() {
|
fun requestDownloadBadgesUpdate() {
|
||||||
downloadTriggerRelay.call(Unit)
|
//getLibrary()
|
||||||
|
launchUI {
|
||||||
|
val mangaMap = rawMangaMap ?: return@launchUI
|
||||||
|
withContext(Dispatchers.IO) { setDownloadCount(mangaMap) }
|
||||||
|
rawMangaMap = mangaMap
|
||||||
|
val current = currentMangaMap ?: return@launchUI
|
||||||
|
withContext(Dispatchers.IO) { setDownloadCount(current) }
|
||||||
|
currentMangaMap = current
|
||||||
|
view?.onNextLibraryUpdate(categories, current)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests the library to be sorted.
|
* Requests the library to be sorted.
|
||||||
*/
|
*/
|
||||||
fun requestSortUpdate() {
|
fun requestSortUpdate() {
|
||||||
sortTriggerRelay.call(Unit)
|
launchUI {
|
||||||
|
var mangaMap = currentMangaMap ?: return@launchUI
|
||||||
|
mangaMap = withContext(Dispatchers.IO) { applySort(mangaMap) }
|
||||||
|
currentMangaMap = mangaMap
|
||||||
|
view?.onNextLibraryUpdate(categories, mangaMap)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requestCatSortUpdate(catId: Int) {
|
fun requestCatSortUpdate(catId: Int) {
|
||||||
lastCategoryId = catId
|
launchUI {
|
||||||
sortTriggerRelay.call(Unit)
|
var mangaMap = currentMangaMap ?: return@launchUI
|
||||||
|
mangaMap = withContext(Dispatchers.IO) { applyCatSort(mangaMap, catId) }
|
||||||
|
currentMangaMap = mangaMap
|
||||||
|
view?.onNextLibraryUpdate(categories, mangaMap)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requestFullUpdate() {
|
fun requestFullUpdate() {
|
||||||
librarySubscription?.unsubscribe()
|
//librarySubscription?.unsubscribe()
|
||||||
subscribeLibrary()
|
getLibrary()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -495,7 +550,7 @@ class LibraryPresenter(
|
|||||||
*/
|
*/
|
||||||
fun onOpenManga() {
|
fun onOpenManga() {
|
||||||
// Avoid further db updates for the library when it's not needed
|
// Avoid further db updates for the library when it's not needed
|
||||||
librarySubscription?.let { remove(it) }
|
//librarySubscription?.let { remove(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -517,18 +572,19 @@ class LibraryPresenter(
|
|||||||
* @param deleteChapters whether to also delete downloaded chapters.
|
* @param deleteChapters whether to also delete downloaded chapters.
|
||||||
*/
|
*/
|
||||||
fun removeMangaFromLibrary(mangas: List<Manga>) {
|
fun removeMangaFromLibrary(mangas: List<Manga>) {
|
||||||
// Create a set of the list
|
|
||||||
val mangaToDelete = mangas.distinctBy { it.id }
|
|
||||||
mangaToDelete.forEach { it.favorite = false }
|
|
||||||
|
|
||||||
Observable.fromCallable { db.insertMangas(mangaToDelete).executeAsBlocking() }
|
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
||||||
.onErrorResumeNext { Observable.empty() }
|
// Create a set of the list
|
||||||
.subscribeOn(Schedulers.io())
|
val mangaToDelete = mangas.distinctBy { it.id }
|
||||||
.subscribe()
|
mangaToDelete.forEach { it.favorite = false }
|
||||||
|
|
||||||
|
db.insertMangas(mangaToDelete).executeAsBlocking()
|
||||||
|
getLibrary()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun confirmDeletion(mangas: List<Manga>) {
|
fun confirmDeletion(mangas: List<Manga>) {
|
||||||
Observable.fromCallable {
|
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
||||||
val mangaToDelete = mangas.distinctBy { it.id }
|
val mangaToDelete = mangas.distinctBy { it.id }
|
||||||
mangaToDelete.forEach { manga ->
|
mangaToDelete.forEach { manga ->
|
||||||
db.resetMangaInfo(manga).executeAsBlocking()
|
db.resetMangaInfo(manga).executeAsBlocking()
|
||||||
@ -537,18 +593,44 @@ class LibraryPresenter(
|
|||||||
if (source != null)
|
if (source != null)
|
||||||
downloadManager.deleteManga(manga, source)
|
downloadManager.deleteManga(manga, source)
|
||||||
}
|
}
|
||||||
}.subscribeOn(Schedulers.io()).subscribe()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateManga(manga: LibraryManga) {
|
||||||
|
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
||||||
|
val rawMap = rawMangaMap ?: return@launch
|
||||||
|
val currentMap = currentMangaMap ?: return@launch
|
||||||
|
rawMap.apply {
|
||||||
|
forEach {
|
||||||
|
it.value.forEach { item ->
|
||||||
|
if (item.manga.id == manga.id)
|
||||||
|
item.manga.unread = manga.unread
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentMap.apply {
|
||||||
|
forEach {
|
||||||
|
it.value.forEach { item ->
|
||||||
|
if (item.manga.id == manga.id)
|
||||||
|
item.manga.unread = manga.unread
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rawMangaMap = rawMap
|
||||||
|
currentMangaMap = currentMap
|
||||||
|
requestSortUpdate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addMangas(mangas: List<Manga>) {
|
fun addMangas(mangas: List<Manga>) {
|
||||||
val mangaToAdd = mangas.distinctBy { it.id }
|
|
||||||
mangaToAdd.forEach { it.favorite = true }
|
|
||||||
|
|
||||||
Observable.fromCallable { db.insertMangas(mangaToAdd).executeAsBlocking() }
|
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
||||||
.onErrorResumeNext { Observable.empty() }
|
val mangaToAdd = mangas.distinctBy { it.id }
|
||||||
.subscribeOn(Schedulers.io())
|
mangaToAdd.forEach { it.favorite = true }
|
||||||
.subscribe()
|
db.insertMangas(mangaToAdd).executeAsBlocking()
|
||||||
mangaToAdd.forEach { db.insertManga(it).executeAsBlocking() }
|
getLibrary()
|
||||||
|
mangaToAdd.forEach { db.insertManga(it).executeAsBlocking() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,8 +28,6 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
|
|||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.inflate
|
import eu.kanade.tachiyomi.util.view.inflate
|
||||||
import eu.kanade.tachiyomi.util.view.marginBottom
|
|
||||||
import eu.kanade.tachiyomi.util.view.marginTop
|
|
||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
import eu.kanade.tachiyomi.util.view.updatePadding
|
import eu.kanade.tachiyomi.util.view.updatePadding
|
||||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
@ -85,21 +83,18 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
}
|
}
|
||||||
|
|
||||||
var onGroupClicked: (Int) -> Unit = { _ -> }
|
var onGroupClicked: (Int) -> Unit = { _ -> }
|
||||||
val recycler = androidx.recyclerview.widget.RecyclerView(context)
|
|
||||||
var pager:View? = null
|
var pager:View? = null
|
||||||
|
|
||||||
fun onCreate(pagerView:View) {
|
fun onCreate(pagerView:View) {
|
||||||
if (context.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
if (context.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
|
|| isTablet()) {
|
||||||
sideLayout.orientation = HORIZONTAL
|
sideLayout.orientation = HORIZONTAL
|
||||||
val marginValue = 10.dpToPx
|
sortingLayout.updateLayoutParams<MarginLayoutParams> {
|
||||||
arrayListOf(sortingLayout).forEach {
|
bottomMargin = 0
|
||||||
it.updateLayoutParams<MarginLayoutParams> {
|
topMargin = 0
|
||||||
bottomMargin = 0
|
|
||||||
topMargin = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sortScrollView.updatePadding(
|
sortScrollView.updatePadding(
|
||||||
bottom = marginValue,
|
bottom = 10.dpToPx,
|
||||||
top = 0
|
top = 0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -116,12 +111,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
}
|
}
|
||||||
|
|
||||||
pager = pagerView
|
pager = pagerView
|
||||||
pager?.setPadding(0, 0, 0, topbar.height)
|
|
||||||
updateTitle()
|
updateTitle()
|
||||||
|
val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2)
|
||||||
|
val coordLayout:View = (pagerView.parent as ViewGroup).findViewById(R.id.snackbar_layout)
|
||||||
sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||||
override fun onSlide(bottomSheet: View, progress: Float) {
|
override fun onSlide(bottomSheet: View, progress: Float) {
|
||||||
updateRootPadding(progress)
|
updateRootPadding(progress)
|
||||||
topbar.alpha = 1 - progress
|
topbar.alpha = 1 - progress
|
||||||
|
shadow.alpha = (1 - progress) * 0.25f
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStateChanged(p0: View, state: Int) {
|
override fun onStateChanged(p0: View, state: Int) {
|
||||||
@ -136,6 +133,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
|
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
|
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
|
||||||
pager?.setPadding(0, 0, 0, topbar.height - height)
|
pager?.setPadding(0, 0, 0, topbar.height - height)
|
||||||
|
coordLayout.setPadding(0, 0, 0, topbar.height)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
updateRootPadding()
|
updateRootPadding()
|
||||||
@ -146,10 +144,20 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
mainSortTextView.setOnClickListener { showMainSortOptions() }
|
mainSortTextView.setOnClickListener { showMainSortOptions() }
|
||||||
catSortTextView.setOnClickListener { showCatSortOptions() }
|
catSortTextView.setOnClickListener { showCatSortOptions() }
|
||||||
clearButton.setOnClickListener { clearFilters() }
|
clearButton.setOnClickListener { clearFilters() }
|
||||||
|
downloadCheckbox.isChecked = preferences.downloadBadge().getOrDefault()
|
||||||
|
downloadCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
preferences.downloadBadge().set(isChecked)
|
||||||
|
onGroupClicked(ACTION_BADGE)
|
||||||
|
}
|
||||||
|
|
||||||
displayGroup.bindToPreference(preferences.libraryAsList())
|
displayGroup.bindToPreference(preferences.libraryAsList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isTablet(): Boolean {
|
||||||
|
return (context.resources.configuration.screenLayout and Configuration
|
||||||
|
.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
|
||||||
|
}
|
||||||
|
|
||||||
fun updateTitle() {
|
fun updateTitle() {
|
||||||
launchUI {
|
launchUI {
|
||||||
val text = withContext(Dispatchers.IO) {
|
val text = withContext(Dispatchers.IO) {
|
||||||
@ -422,7 +430,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
mainSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
mainSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||||
drawable, null, null, null
|
null, null, drawable, null
|
||||||
)
|
)
|
||||||
mainSortTextView.text = withContext(Dispatchers.IO) {
|
mainSortTextView.text = withContext(Dispatchers.IO) {
|
||||||
if (sortId == LibrarySort.DRAG_AND_DROP)
|
if (sortId == LibrarySort.DRAG_AND_DROP)
|
||||||
@ -471,7 +479,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
catSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
catSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||||
drawable, null, null, null
|
null, null, drawable, null
|
||||||
)
|
)
|
||||||
catSortTextView.text = withContext(Dispatchers.IO) {
|
catSortTextView.text = withContext(Dispatchers.IO) {
|
||||||
context.getString(
|
context.getString(
|
||||||
|
@ -178,7 +178,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
}
|
}
|
||||||
nav_view.setCheckedItem(id)
|
nav_view.setCheckedItem(id)
|
||||||
}
|
}
|
||||||
else if (currentRoot?.tag()?.toIntOrNull() == id) {
|
else if (currentRoot.tag()?.toIntOrNull() == id) {
|
||||||
when (id) {
|
when (id) {
|
||||||
R.id.nav_drawer_recents -> {
|
R.id.nav_drawer_recents -> {
|
||||||
if (router.backstack.size > 1) router.popToRoot()
|
if (router.backstack.size > 1) router.popToRoot()
|
||||||
|
9
app/src/main/res/drawable/square_ripple.xml
Normal file
9
app/src/main/res/drawable/square_ripple.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:color="@color/gray_button">
|
||||||
|
<item android:id="@android:id/mask">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/gray_button" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
@ -39,7 +39,6 @@
|
|||||||
android:paddingStart="20dp"
|
android:paddingStart="20dp"
|
||||||
android:paddingTop="10dp"
|
android:paddingTop="10dp"
|
||||||
android:paddingEnd="20dp"
|
android:paddingEnd="20dp"
|
||||||
android:paddingBottom="10dp"
|
|
||||||
android:scrollbars="none">
|
android:scrollbars="none">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -72,10 +71,8 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="6dp"
|
android:layout_marginTop="6dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:paddingStart="30dp"
|
android:paddingStart="23dp"
|
||||||
android:paddingTop="0dp"
|
|
||||||
android:paddingEnd="20dp"
|
android:paddingEnd="20dp"
|
||||||
android:paddingBottom="10dp"
|
|
||||||
android:scrollbars="none">
|
android:scrollbars="none">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -103,8 +100,10 @@
|
|||||||
android:layout_marginEnd="20dp"
|
android:layout_marginEnd="20dp"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:drawablePadding="16dp"
|
android:drawablePadding="16dp"
|
||||||
|
android:background="@drawable/square_ripple"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:padding="5dp"
|
||||||
android:text="srgdg"
|
android:text="srgdg"
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
@ -115,7 +114,9 @@
|
|||||||
android:id="@+id/catSortTextView"
|
android:id="@+id/catSortTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/square_ripple"
|
||||||
android:layout_marginEnd="20dp"
|
android:layout_marginEnd="20dp"
|
||||||
|
android:padding="5dp"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:drawablePadding="16dp"
|
android:drawablePadding="16dp"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
@ -132,6 +133,8 @@
|
|||||||
android:id="@+id/displayLayout"
|
android:id="@+id/displayLayout"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="7dp"
|
||||||
|
android:layout_marginEnd="14dp"
|
||||||
android:baselineAligned="false"
|
android:baselineAligned="false"
|
||||||
android:gravity="center|start"
|
android:gravity="center|start"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
@ -169,6 +172,12 @@
|
|||||||
android:text="@string/action_display_list" />
|
android:text="@string/action_display_list" />
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/downloadCheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/action_display_download_badge"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:id="@+id/snackbar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.EmptyView
|
<eu.kanade.tachiyomi.widget.EmptyView
|
||||||
android:id="@+id/empty_view"
|
android:id="@+id/empty_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
Loading…
Reference in New Issue
Block a user