Remove custom presenter class

This commit is contained in:
len
2017-01-08 20:56:42 +01:00
parent 72f8c4d5e2
commit 96a39f5c54
6 changed files with 79 additions and 599 deletions
@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.manga.info.ChapterCountEvent
import eu.kanade.tachiyomi.ui.manga.info.MangaFavoriteEvent
import eu.kanade.tachiyomi.util.SharedData
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
import rx.Observable
import rx.Subscription
import uy.kohesive.injekt.injectLazy
@@ -44,10 +45,10 @@ class MangaPresenter : BasePresenter<MangaActivity>() {
}
fun setMangaEvent(event: MangaEvent) {
if (isUnsubscribed(mangaSubscription)) {
if (mangaSubscription.isNullOrUnsubscribed()) {
manga = event.manga
mangaSubscription = Observable.just(manga)
.subscribeLatestCache({ view, manga -> view.onSetManga(manga) })
.subscribeLatestCache(MangaActivity::onSetManga)
}
}
@@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.os.Bundle
import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
@@ -15,11 +16,12 @@ import eu.kanade.tachiyomi.ui.manga.MangaEvent
import eu.kanade.tachiyomi.ui.manga.info.ChapterCountEvent
import eu.kanade.tachiyomi.ui.manga.info.MangaFavoriteEvent
import eu.kanade.tachiyomi.util.SharedData
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
import eu.kanade.tachiyomi.util.syncChaptersWithSource
import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import rx.subjects.PublishSubject
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
@@ -69,8 +71,8 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() {
/**
* Subject of list of chapters to allow updating the view without going to DB.
*/
val chaptersSubject: PublishSubject<List<ChapterModel>>
by lazy { PublishSubject.create<List<ChapterModel>>() }
val chaptersRelay: PublishRelay<List<ChapterModel>>
by lazy { PublishRelay.create<List<ChapterModel>>() }
/**
* Whether the chapter list has been requested to the source.
@@ -78,56 +80,33 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() {
var hasRequested = false
private set
companion object {
/**
* Id of the restartable which sends a filtered and ordered list of chapters to the view.
*/
private const val GET_CHAPTERS = 1
/**
* Subscription to retrieve the new list of chapters from the source.
*/
private var fetchChaptersSubscription: Subscription? = null
/**
* Id of the restartable which requests an updated list of chapters to the source.
*/
private const val FETCH_CHAPTERS = 2
/**
* Id of the restartable which listens for download status changes.
*/
private const val CHAPTER_STATUS_CHANGES = 3
}
/**
* Subscription to observe download status changes.
*/
private var observeDownloadsSubscription: Subscription? = null
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
startableLatestCache(GET_CHAPTERS,
// On each subject emission, apply filters and sort then update the view.
{ chaptersSubject
.flatMap { applyChapterFilters(it) }
.observeOn(AndroidSchedulers.mainThread())
}, ChaptersFragment::onNextChapters)
startableFirst(FETCH_CHAPTERS,
{ getRemoteChaptersObservable() },
{ view, result -> view.onFetchChaptersDone() },
ChaptersFragment::onFetchChaptersError)
startableLatestCache(CHAPTER_STATUS_CHANGES,
{ getChapterStatusObservable() },
ChaptersFragment::onChapterStatusChange,
{ view, error -> Timber.e(error) })
// Find the active manga from the shared data or return.
manga = SharedData.get(MangaEvent::class.java)?.manga ?: return
source = sourceManager.get(manga.source)!!
Observable.just(manga)
.subscribeLatestCache(ChaptersFragment::onNextManga)
// Find the source for this manga.
source = sourceManager.get(manga.source)!!
// Prepare the publish subject.
start(GET_CHAPTERS)
// Prepare the relay.
chaptersRelay.flatMap { applyChapterFilters(it) }
.observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache(ChaptersFragment::onNextChapters,
{ view, error -> Timber.e(error) })
// Add the subscription that retrieves the chapters from the database, keeps subscribed to
// changes, and sends the list of chapters to the publish subject.
// changes, and sends the list of chapters to the relay.
add(db.getChapters(manga).asRxObservable()
.map { chapters ->
// Convert every chapter to a model.
@@ -141,12 +120,22 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() {
this.chapters = chapters
// Listen for download status changes
start(CHAPTER_STATUS_CHANGES)
observeDownloads()
// Emit the number of chapters to the info tab.
SharedData.get(ChapterCountEvent::class.java)?.emit(chapters.size)
}
.subscribe { chaptersSubject.onNext(it) })
.subscribe { chaptersRelay.call(it) })
}
private fun observeDownloads() {
observeDownloadsSubscription?.let { remove(it) }
observeDownloadsSubscription = downloadManager.queue.getStatusObservable()
.observeOn(AndroidSchedulers.mainThread())
.filter { download -> download.manga.id == manga.id }
.doOnNext { onDownloadStatusChange(it) }
.subscribeLatestCache(ChaptersFragment::onChapterStatusChange,
{ view, error -> Timber.e(error) })
}
/**
@@ -186,34 +175,24 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() {
*/
fun fetchChaptersFromSource() {
hasRequested = true
start(FETCH_CHAPTERS)
if (!fetchChaptersSubscription.isNullOrUnsubscribed()) return
fetchChaptersSubscription = Observable.defer { source.fetchChapterList(manga) }
.subscribeOn(Schedulers.io())
.map { syncChaptersWithSource(db, it, manga, source) }
.observeOn(AndroidSchedulers.mainThread())
.subscribeFirst({ view, chapters ->
view.onFetchChaptersDone()
}, ChaptersFragment::onFetchChaptersError)
}
/**
* Updates the UI after applying the filters.
*/
private fun refreshChapters() {
chaptersSubject.onNext(chapters)
chaptersRelay.call(chapters)
}
/**
* Returns an observable that updates the chapter list with the latest from the source.
*/
fun getRemoteChaptersObservable(): Observable<Pair<List<Chapter>, List<Chapter>>> =
Observable.defer { source.fetchChapterList(manga) }
.subscribeOn(Schedulers.io())
.map { syncChaptersWithSource(db, it, manga, source) }
.observeOn(AndroidSchedulers.mainThread())
/**
* Returns an observable that listens to download queue status changes.
*/
fun getChapterStatusObservable(): Observable<Download> =
downloadManager.queue.getStatusObservable()
.observeOn(AndroidSchedulers.mainThread())
.filter { download -> download.manga.id == manga.id }
.doOnNext { onDownloadStatusChange(it) }
/**
* Applies the view filters to the list of chapters obtained from the database.
* @param chapters the list of chapters from the database
@@ -224,7 +203,7 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() {
if (onlyUnread()) {
observable = observable.filter { !it.read }
}
if (onlyRead()) {
else if (onlyRead()) {
observable = observable.filter { it.read }
}
if (onlyDownloaded()) {
@@ -9,7 +9,9 @@ import eu.kanade.tachiyomi.data.source.SourceManager
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.manga.MangaEvent
import eu.kanade.tachiyomi.util.SharedData
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import uy.kohesive.injekt.injectLazy
@@ -49,32 +51,21 @@ class MangaInfoPresenter : BasePresenter<MangaInfoFragment>() {
val coverCache: CoverCache by injectLazy()
/**
* The id of the restartable.
* Subscription to send the manga to the view.
*/
private val GET_MANGA = 1
private var viewMangaSubcription: Subscription? = null
/**
* The id of the restartable.
* Subscription to update the manga from the source.
*/
private val FETCH_MANGA_INFO = 2
private var fetchMangaSubscription: Subscription? = null
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
// Notify the view a manga is available or has changed.
startableLatestCache(GET_MANGA,
{ Observable.just(manga) },
{ view, manga -> view.onNextManga(manga, source) })
// Fetch manga info from source.
startableFirst(FETCH_MANGA_INFO,
{ fetchMangaObs() },
{ view, manga -> view.onFetchMangaDone() },
{ view, error -> view.onFetchMangaError() })
manga = SharedData.get(MangaEvent::class.java)?.manga ?: return
source = sourceManager.get(manga.source)!!
refreshManga()
sendMangaToView()
// Update chapter count
SharedData.get(ChapterCountEvent::class.java)?.observable
@@ -88,30 +79,34 @@ class MangaInfoPresenter : BasePresenter<MangaInfoFragment>() {
}
/**
* Fetch manga information from source.
* Sends the active manga to the view.
*/
fun fetchMangaFromSource() {
if (isUnsubscribed(FETCH_MANGA_INFO)) {
start(FETCH_MANGA_INFO)
}
fun sendMangaToView() {
viewMangaSubcription?.let { remove(it) }
viewMangaSubcription = Observable.just(manga)
.subscribeLatestCache({ view, manga -> view.onNextManga(manga, source) })
}
/**
* Fetch manga information from source.
*
* @return manga information.
*/
private fun fetchMangaObs(): Observable<Manga> {
return Observable.defer { source.fetchMangaDetails(manga) }
.flatMap { networkManga ->
fun fetchMangaFromSource() {
if (!fetchMangaSubscription.isNullOrUnsubscribed()) return
fetchMangaSubscription = Observable.defer { source.fetchMangaDetails(manga) }
.map { networkManga ->
manga.copyFrom(networkManga)
manga.initialized = true
db.insertManga(manga).executeAsBlocking()
Observable.just<Manga>(manga)
manga
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext { refreshManga() }
.doOnNext { sendMangaToView() }
.subscribeFirst({ view, manga ->
view.onFetchMangaDone()
}, { view, error ->
view.onFetchMangaError()
})
}
/**
@@ -123,19 +118,14 @@ class MangaInfoPresenter : BasePresenter<MangaInfoFragment>() {
coverCache.deleteFromCache(manga.thumbnail_url)
}
db.insertManga(manga).executeAsBlocking()
refreshManga()
sendMangaToView()
}
private fun setFavorite(favorite:Boolean){
if (manga.favorite == favorite)
private fun setFavorite(favorite: Boolean) {
if (manga.favorite == favorite) {
return
}
toggleFavorite()
}
/**
* Refresh MangaInfo view.
*/
private fun refreshManga() {
start(GET_MANGA)
}
}