mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 12:41:50 +01:00
Recent Read Controller is no longer Rx
Unfortunately to fix #72, an rx observer is needed since the reader adds to the db after the recents is back in view
This commit is contained in:
parent
f91e66269f
commit
fb2ab7d765
@ -96,7 +96,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
new
|
||||
}
|
||||
|
||||
adapter = MigrationProcessAdapter(this, view.context)
|
||||
adapter = MigrationProcessAdapter(this)
|
||||
|
||||
recycler.adapter = adapter
|
||||
recycler.layoutManager = LinearLayoutManager(view.context)
|
||||
|
@ -16,8 +16,7 @@ import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class MigrationProcessAdapter(
|
||||
val controller: MigrationListController,
|
||||
context: Context
|
||||
val controller: MigrationListController
|
||||
) : FlexibleAdapter<MigrationProcessItem>(null, controller, true) {
|
||||
|
||||
|
||||
|
@ -1,35 +1,37 @@
|
||||
package eu.kanade.tachiyomi.ui.recently_read
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.catalogue.browse.ProgressItem
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.android.synthetic.main.recently_read_controller.empty_view
|
||||
import kotlinx.android.synthetic.main.recently_read_controller.recycler
|
||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
||||
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
||||
import kotlinx.android.synthetic.main.recently_read_controller.*
|
||||
|
||||
/**
|
||||
* Fragment that shows recently read manga.
|
||||
* Uses R.layout.fragment_recently_read.
|
||||
* UI related actions should be called from here.
|
||||
*/
|
||||
class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
||||
class RecentlyReadController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
FlexibleAdapter.OnUpdateListener,
|
||||
FlexibleAdapter.EndlessScrollListener,
|
||||
RecentlyReadAdapter.OnRemoveClickListener,
|
||||
@ -50,16 +52,17 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
||||
* Endless loading item.
|
||||
*/
|
||||
private var progressItem: ProgressItem? = null
|
||||
private var observeLater:Boolean = false
|
||||
private var query = ""
|
||||
|
||||
private var presenter = RecentlyReadPresenter(this)
|
||||
private var recentItems: MutableList<RecentlyReadItem>? = null
|
||||
|
||||
|
||||
override fun getTitle(): String? {
|
||||
return resources?.getString(R.string.label_recent_manga)
|
||||
}
|
||||
|
||||
override fun createPresenter(): RecentlyReadPresenter {
|
||||
return RecentlyReadPresenter()
|
||||
}
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||
return inflater.inflate(R.layout.recently_read_controller, container, false)
|
||||
}
|
||||
@ -73,38 +76,52 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
||||
super.onViewCreated(view)
|
||||
|
||||
// Initialize adapter
|
||||
recycler.layoutManager = LinearLayoutManager(view.context)
|
||||
adapter = RecentlyReadAdapter(this@RecentlyReadController)
|
||||
recycler.setHasFixedSize(true)
|
||||
adapter = RecentlyReadAdapter(this)
|
||||
recycler.adapter = adapter
|
||||
recycler.layoutManager = LinearLayoutManager(view.context)
|
||||
recycler.setHasFixedSize(true)
|
||||
recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
||||
resetProgressItem()
|
||||
|
||||
if (recentItems != null)
|
||||
adapter?.updateDataSet(recentItems!!.toList())
|
||||
|
||||
launchUI {
|
||||
val manga = presenter.refresh(query)
|
||||
recentItems = manga.toMutableList()
|
||||
adapter?.updateDataSet(manga)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView(view: View) {
|
||||
adapter = null
|
||||
super.onDestroyView(view)
|
||||
override fun onActivityResumed(activity: Activity) {
|
||||
super.onActivityResumed(activity)
|
||||
if (observeLater) {
|
||||
presenter.observe()
|
||||
observeLater = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate adapter with chapters
|
||||
*
|
||||
* @param mangaHistory list of manga history
|
||||
*/
|
||||
fun onNextManga(mangaHistory: List<RecentlyReadItem>, cleanBatch: Boolean = false) {
|
||||
if (adapter?.itemCount ?: 0 == 0 || cleanBatch)
|
||||
fun onNextManga(mangaHistory: List<RecentlyReadItem>) {
|
||||
val adapter = adapter ?: return
|
||||
adapter.updateDataSet(mangaHistory)
|
||||
adapter.onLoadMoreComplete(null)
|
||||
if (recentItems == null)
|
||||
resetProgressItem()
|
||||
if (cleanBatch) adapter?.updateDataSet(mangaHistory)
|
||||
else adapter?.onLoadMoreComplete(mangaHistory)
|
||||
recentItems = mangaHistory.toMutableList()
|
||||
}
|
||||
|
||||
fun onAddPageError(error: Throwable) {
|
||||
fun onAddPageError() {
|
||||
adapter?.onLoadMoreComplete(null)
|
||||
adapter?.endlessTargetCount = 1
|
||||
}
|
||||
|
||||
override fun onUpdateEmptyView(size: Int) {
|
||||
if (size > 0) {
|
||||
empty_view.hide()
|
||||
empty_view?.hide()
|
||||
} else {
|
||||
empty_view.show(R.drawable.ic_glasses_black_128dp, R.string.information_no_recent_manga)
|
||||
}
|
||||
@ -122,17 +139,17 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
||||
override fun onLoadMore(lastPosition: Int, currentPage: Int) {
|
||||
val view = view ?: return
|
||||
if (BackupRestoreService.isRunning(view.context.applicationContext)) {
|
||||
onAddPageError(Throwable())
|
||||
onAddPageError()
|
||||
return
|
||||
}
|
||||
val adapter = adapter ?: return
|
||||
presenter.requestNext(adapter.itemCount, query)
|
||||
presenter.requestNext(query)
|
||||
}
|
||||
|
||||
override fun noMoreLoad(newItemsSize: Int) { }
|
||||
|
||||
override fun onResumeClick(position: Int) {
|
||||
val activity = activity ?: return
|
||||
observeLater = true
|
||||
val (manga, chapter, _) = (adapter?.getItem(position) as? RecentlyReadItem)?.mch ?: return
|
||||
|
||||
val nextChapter = presenter.getNextChapter(chapter, manga)
|
||||
@ -168,17 +185,24 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
||||
inflater.inflate(R.menu.recently_read, menu)
|
||||
val searchItem = menu.findItem(R.id.action_search)
|
||||
val searchView = searchItem.actionView as SearchView
|
||||
searchView.maxWidth = Int.MAX_VALUE
|
||||
if (query.isNotEmpty()) {
|
||||
searchItem.expandActionView()
|
||||
searchView.setQuery(query, true)
|
||||
searchView.clearFocus()
|
||||
}
|
||||
searchView.queryTextChanges().filter { router.backstack.lastOrNull()?.controller() == this }
|
||||
.subscribeUntilDestroy {
|
||||
query = it.toString()
|
||||
presenter.updateList(query)
|
||||
setOnQueryTextChangeListener(searchView) {
|
||||
if (query != it) {
|
||||
query = it ?: return@setOnQueryTextChangeListener false
|
||||
launchUI {
|
||||
resetProgressItem()
|
||||
presenter.lastCount = 25
|
||||
val manga = presenter.refresh(query)
|
||||
recentItems = manga.toMutableList()
|
||||
adapter?.updateDataSet(manga)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
// Fixes problem with the overflow icon showing up in lieu of search
|
||||
searchItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
|
||||
|
@ -6,6 +6,10 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.Dispatcher
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
@ -20,60 +24,47 @@ import java.util.Date
|
||||
* Contains information and data for fragment.
|
||||
* Observable updates should be called from here.
|
||||
*/
|
||||
class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
||||
class RecentlyReadPresenter(private val view: RecentlyReadController) {
|
||||
|
||||
/**
|
||||
* Used to connect to database
|
||||
*/
|
||||
val db: DatabaseHelper by injectLazy()
|
||||
private var readerSubscription:Subscription? = null
|
||||
var lastCount = 25
|
||||
var lastSearch = ""
|
||||
|
||||
override fun onCreate(savedState: Bundle?) {
|
||||
super.onCreate(savedState)
|
||||
|
||||
//pageSubscription?.let { remove(it) }
|
||||
// Used to get a list of recently read manga
|
||||
updateList()
|
||||
}
|
||||
|
||||
fun requestNext(offset: Int, search: String = "") {
|
||||
lastCount = offset
|
||||
fun requestNext(search: String = "") {
|
||||
lastCount += 25
|
||||
lastSearch = search
|
||||
getRecentMangaObservable((offset), search)
|
||||
.subscribeLatestCache({ view, mangas ->
|
||||
view.onNextManga(mangas)
|
||||
}, RecentlyReadController::onAddPageError)
|
||||
updateList(search)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recent manga observable
|
||||
* Get all recent manga up to a point
|
||||
* @return list of history
|
||||
*/
|
||||
private fun getRecentMangaObservable(offset: Int = 0, search: String = ""): Observable<List<RecentlyReadItem>> {
|
||||
private fun getRecentMangaLimit(search: String = ""): List<RecentlyReadItem> {
|
||||
// Set date for recent manga
|
||||
val cal = Calendar.getInstance()
|
||||
cal.time = Date()
|
||||
cal.add(Calendar.YEAR, -50)
|
||||
|
||||
return db.getRecentManga(cal.time, offset, search).asRxObservable()
|
||||
.map { recents -> recents.map(::RecentlyReadItem) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
return db.getRecentMangaLimit(cal.time, lastCount, search).executeAsBlocking()
|
||||
.map(::RecentlyReadItem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recent manga observable
|
||||
* @return list of history
|
||||
*/
|
||||
private fun getRecentMangaLimitObservable(offset: Int = 0, search: String = ""): Observable<List<RecentlyReadItem>> {
|
||||
// Set date for recent manga
|
||||
fun observe() {
|
||||
readerSubscription?.unsubscribe()
|
||||
val cal = Calendar.getInstance()
|
||||
cal.time = Date()
|
||||
cal.add(Calendar.YEAR, -50)
|
||||
|
||||
return db.getRecentMangaLimit(cal.time, lastCount, search).asRxObservable()
|
||||
.map { recents -> recents.map(::RecentlyReadItem) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
readerSubscription = db.getRecentMangaLimit(cal.time, lastCount, "").asRxObservable().map {
|
||||
val items = it.map(::RecentlyReadItem)
|
||||
launchUI {
|
||||
view.onNextManga(items)
|
||||
}
|
||||
}.observeOn(Schedulers.io()).skip(1).take(1).subscribe()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,12 +77,28 @@ class RecentlyReadPresenter : BasePresenter<RecentlyReadController>() {
|
||||
updateList()
|
||||
}
|
||||
|
||||
fun updateList(search: String? = null) {
|
||||
lastSearch = search?:lastSearch
|
||||
getRecentMangaLimitObservable(lastCount, lastSearch).take(1)
|
||||
.subscribeLatestCache({ view, mangas ->
|
||||
view.onNextManga(mangas, true)
|
||||
}, RecentlyReadController::onAddPageError)
|
||||
suspend fun refresh(search: String? = null): List<RecentlyReadItem> {
|
||||
val manga = withContext(Dispatchers.IO) { getRecentMangaLimit(search ?: "") }
|
||||
checkIfNew(manga.size, search)
|
||||
lastSearch = search ?: lastSearch
|
||||
lastCount = manga.size
|
||||
return manga
|
||||
}
|
||||
|
||||
private fun updateList(search: String? = null) {
|
||||
launchUI {
|
||||
val manga = withContext(Dispatchers.IO) { getRecentMangaLimit(search ?: "") }
|
||||
checkIfNew(manga.size, search)
|
||||
lastSearch = search ?: lastSearch
|
||||
lastCount = manga.size
|
||||
view.onNextManga(manga)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIfNew(newCount: Int, newSearch: String?) {
|
||||
if (lastCount > newCount && newSearch == lastSearch) {
|
||||
view.onAddPageError()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,14 +13,12 @@ import android.widget.TextView
|
||||
import androidx.annotation.Px
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.WhichButton
|
||||
import com.afollestad.materialdialogs.actions.getActionButton
|
||||
import com.afollestad.materialdialogs.actions.hasActionButton
|
||||
import com.amulyakhare.textdrawable.TextDrawable
|
||||
import eu.kanade.tachiyomi.R
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import kotlin.math.min
|
||||
@ -199,6 +197,22 @@ data class ViewPaddingState(
|
||||
val end: Int
|
||||
)
|
||||
|
||||
|
||||
fun Controller.setOnQueryTextChangeListener(searchView: SearchView, f: (text: String?) -> Boolean) {
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
if (router.backstack.lastOrNull()?.controller() == this@setOnQueryTextChangeListener) {
|
||||
return f(newText)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@RequiresApi(17)
|
||||
inline fun View.updatePaddingRelative(
|
||||
@Px start: Int = paddingStart,
|
||||
|
@ -1,26 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/frame_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingTop="4dp"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
tools:listitem="@layout/recently_read_item">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
<eu.kanade.tachiyomi.widget.EmptyView
|
||||
android:id="@+id/empty_view"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"/>
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
|
Loading…
Reference in New Issue
Block a user