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