Initial support for external sources

This commit is contained in:
inorichi
2017-01-08 18:12:19 +01:00
committed by GitHub
parent 77d986f213
commit dd56d7c0bb
60 changed files with 1371 additions and 1126 deletions

View File

@@ -14,6 +14,7 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.f2prateek.rx.preferences.Preference
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.source.model.FilterList
import eu.kanade.tachiyomi.data.source.online.LoginSource
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment
@@ -32,7 +33,6 @@ import nucleus.factory.RequiresPresenter
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import rx.subjects.PublishSubject
import timber.log.Timber
import java.util.concurrent.TimeUnit.MILLISECONDS
/**
@@ -104,6 +104,11 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
private val toolbar: Toolbar
get() = (activity as MainActivity).toolbar
/**
* Snackbar containing an error message when a request fails.
*/
private var snack: Snackbar? = null
/**
* Navigation view containing filter items.
*/
@@ -201,8 +206,7 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
} else if (source != presenter.source) {
selectedIndex = position
showProgressBar()
glm.scrollToPositionWithOffset(0, 0)
llm.scrollToPositionWithOffset(0, 0)
adapter.clear()
presenter.setActiveSource(source)
navView?.setFilters(presenter.sourceFilters)
activity.invalidateOptionsMenu()
@@ -233,14 +237,14 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
}
navView.onSearchClicked = {
val allDefault = (0..navView.adapter.items.lastIndex)
.none { navView.adapter.items[it].state != presenter.source.filters[it].state }
presenter.setSourceFilter(if (allDefault) emptyList() else navView.adapter.items)
val allDefault = navView.adapter.items.hasSameState(presenter.source.getFilterList())
showProgressBar()
adapter.clear()
presenter.setSourceFilter(if (allDefault) FilterList() else navView.adapter.items)
}
navView.onResetClicked = {
presenter.appliedFilters = emptyList()
presenter.appliedFilters = FilterList()
val newFilters = presenter.source.getFilterList()
presenter.sourceFilters = newFilters
navView.setFilters(newFilters)
@@ -277,7 +281,7 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
// Setup filters button
menu.findItem(R.id.action_set_filter).apply {
icon.mutate()
if (presenter.source.filters.isEmpty()) {
if (presenter.sourceFilters.isEmpty()) {
isEnabled = false
icon.alpha = 128
} else {
@@ -355,8 +359,7 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
return
showProgressBar()
catalogue_grid.layoutManager.scrollToPosition(0)
catalogue_list.layoutManager.scrollToPosition(0)
adapter.clear()
presenter.restartPager(newQuery)
}
@@ -394,9 +397,11 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
*/
fun onAddPageError(error: Throwable) {
hideProgressBar()
Timber.e(error)
catalogue_view.snack(error.message ?: "", Snackbar.LENGTH_INDEFINITE) {
val message = if (error is NoResultsException) "No results found" else (error.message ?: "")
snack?.dismiss()
snack = catalogue_view.snack(message, Snackbar.LENGTH_INDEFINITE) {
setAction(R.string.action_retry) {
showProgressBar()
presenter.requestNext()
@@ -456,6 +461,8 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
*/
private fun showProgressBar() {
progress.visibility = ProgressBar.VISIBLE
snack?.dismiss()
snack = null
}
/**
@@ -463,6 +470,8 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
*/
private fun showGridProgressBar() {
progress_grid.visibility = ProgressBar.VISIBLE
snack?.dismiss()
snack = null
}
/**

View File

@@ -9,7 +9,8 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.source.online.OnlineSource.Filter
import eu.kanade.tachiyomi.data.source.model.Filter
import eu.kanade.tachiyomi.data.source.model.FilterList
import eu.kanade.tachiyomi.util.dpToPx
import eu.kanade.tachiyomi.util.getResourceColor
import eu.kanade.tachiyomi.util.inflate
@@ -38,14 +39,14 @@ class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs:
reset_btn.setOnClickListener { onResetClicked() }
}
fun setFilters(items: List<Filter<*>>) {
fun setFilters(items: FilterList) {
adapter.items = items
adapter.notifyDataSetChanged()
}
inner class Adapter : RecyclerView.Adapter<Holder>() {
var items: List<Filter<*>> = emptyList()
var items: FilterList = FilterList()
override fun getItemCount(): Int {
return items.size

View File

@@ -1,28 +1,32 @@
package eu.kanade.tachiyomi.ui.catalogue
import eu.kanade.tachiyomi.data.source.CatalogueSource
import eu.kanade.tachiyomi.data.source.model.FilterList
import eu.kanade.tachiyomi.data.source.model.MangasPage
import eu.kanade.tachiyomi.data.source.online.OnlineSource
import eu.kanade.tachiyomi.data.source.online.OnlineSource.Filter
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
open class CataloguePager(val source: OnlineSource, val query: String, val filters: List<Filter<*>>) : Pager() {
open class CataloguePager(val source: CatalogueSource, val query: String, val filters: FilterList) : Pager() {
override fun requestNext(transformer: (Observable<MangasPage>) -> Observable<MangasPage>): Observable<MangasPage> {
val lastPage = lastPage
val page = if (lastPage == null)
MangasPage(1)
else
MangasPage(lastPage.page + 1).apply { url = lastPage.nextPageUrl!! }
override fun requestNext(): Observable<MangasPage> {
val page = currentPage
val observable = if (query.isBlank() && filters.isEmpty())
source.fetchPopularManga(page)
else
source.fetchSearchManga(page, query, filters)
return transformer(observable)
.doOnNext { results.onNext(it) }
.doOnNext { this@CataloguePager.lastPage = it }
return observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext {
if (it.mangas.isNotEmpty()) {
onPageReceived(it)
} else {
throw NoResultsException()
}
}
}
}

View File

@@ -6,12 +6,12 @@ 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.getOrDefault
import eu.kanade.tachiyomi.data.source.CatalogueSource
import eu.kanade.tachiyomi.data.source.Source
import eu.kanade.tachiyomi.data.source.SourceManager
import eu.kanade.tachiyomi.data.source.model.MangasPage
import eu.kanade.tachiyomi.data.source.model.FilterList
import eu.kanade.tachiyomi.data.source.model.SManga
import eu.kanade.tachiyomi.data.source.online.LoginSource
import eu.kanade.tachiyomi.data.source.online.OnlineSource
import eu.kanade.tachiyomi.data.source.online.OnlineSource.Filter
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import rx.Observable
import rx.Subscription
@@ -55,7 +55,7 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
/**
* Active source.
*/
lateinit var source: OnlineSource
lateinit var source: CatalogueSource
private set
/**
@@ -67,12 +67,12 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
/**
* Modifiable list of filters.
*/
var sourceFilters: List<Filter<*>> = emptyList()
var sourceFilters = FilterList()
/**
* List of filters used by the [Pager]. If empty alongside [query], the popular query is used.
*/
var appliedFilters: List<Filter<*>> = emptyList()
var appliedFilters = FilterList()
/**
* Pager containing a list of manga results.
@@ -136,7 +136,7 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
* @param query the query.
* @param filters the current state of the filters (for search mode).
*/
fun restartPager(query: String = this.query, filters: List<Filter<*>> = this.appliedFilters) {
fun restartPager(query: String = this.query, filters: FilterList = this.appliedFilters) {
this.query = query
this.appliedFilters = filters
@@ -145,11 +145,17 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
// Create a new pager.
pager = createPager(query, filters)
val sourceId = source.id
// Prepare the pager.
pagerSubscription?.let { remove(it) }
pagerSubscription = pager.results()
.subscribeReplay({ view, page ->
view.onAddPage(page.page, page.mangas)
.observeOn(Schedulers.io())
.map { it.first to it.second.map { networkToLocalManga(it, sourceId) } }
.doOnNext { initializeMangas(it.second) }
.observeOn(AndroidSchedulers.mainThread())
.subscribeReplay({ view, pair ->
view.onAddPage(pair.first, pair.second)
}, { view, error ->
Timber.e(error)
})
@@ -165,7 +171,7 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
if (!hasNextPage()) return
pageSubscription?.let { remove(it) }
pageSubscription = pager.requestNext { getPageTransformer(it) }
pageSubscription = Observable.defer { pager.requestNext() }
.subscribeFirst({ view, page ->
// Nothing to do when onNext is emitted.
}, CatalogueFragment::onAddPageError)
@@ -175,7 +181,7 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
* Returns true if the last fetched page has a next page.
*/
fun hasNextPage(): Boolean {
return pager.hasNextPage()
return pager.hasNextPage
}
/**
@@ -183,12 +189,12 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
*
* @param source the new active source.
*/
fun setActiveSource(source: OnlineSource) {
fun setActiveSource(source: CatalogueSource) {
prefs.lastUsedCatalogueSource().set(source.id)
this.source = source
sourceFilters = source.getFilterList()
restartPager(query = "", filters = emptyList())
restartPager(query = "", filters = FilterList())
}
/**
@@ -208,7 +214,7 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
initializerSubscription?.let { remove(it) }
initializerSubscription = mangaDetailSubject.observeOn(Schedulers.io())
.flatMap { Observable.from(it) }
.filter { !it.initialized }
.filter { it.thumbnail_url == null && !it.initialized }
.concatMap { getMangaDetailsObservable(it) }
.onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread())
@@ -221,41 +227,21 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
.apply { add(this) }
}
/**
* Returns the function to apply to the observable of the list of manga from the source.
*
* @param observable the observable from the source.
* @return the function to apply.
*/
fun getPageTransformer(observable: Observable<MangasPage>): Observable<MangasPage> {
return observable.subscribeOn(Schedulers.io())
.doOnNext { it.mangas.replace { networkToLocalManga(it) } }
.doOnNext { initializeMangas(it.mangas) }
.observeOn(AndroidSchedulers.mainThread())
}
/**
* Replaces an object in the list with another.
*/
fun <T> MutableList<T>.replace(block: (T) -> T) {
forEachIndexed { i, obj ->
set(i, block(obj))
}
}
/**
* Returns a manga from the database for the given manga from network. It creates a new entry
* if the manga is not yet in the database.
*
* @param networkManga the manga from network.
* @param sManga the manga from the source.
* @return a manga from the database.
*/
private fun networkToLocalManga(networkManga: Manga): Manga {
var localManga = db.getManga(networkManga.url, source.id).executeAsBlocking()
private fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
var localManga = db.getManga(sManga.url, sourceId).executeAsBlocking()
if (localManga == null) {
val result = db.insertManga(networkManga).executeAsBlocking()
networkManga.id = result.insertedId()
localManga = networkManga
val newManga = Manga.create(sManga.url, sManga.title, sourceId)
newManga.copyFrom(sManga)
val result = db.insertManga(newManga).executeAsBlocking()
newManga.id = result.insertedId()
localManga = newManga
}
return localManga
}
@@ -279,6 +265,7 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
return source.fetchMangaDetails(manga)
.flatMap { networkManga ->
manga.copyFrom(networkManga)
manga.initialized = true
db.insertManga(manga).executeAsBlocking()
Observable.just(manga)
}
@@ -290,13 +277,13 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
*
* @return a source.
*/
fun getLastUsedSource(): OnlineSource {
fun getLastUsedSource(): CatalogueSource {
val id = prefs.lastUsedCatalogueSource().get() ?: -1
val source = sourceManager.get(id)
if (!isValidSource(source)) {
return findFirstValidSource()
}
return source as OnlineSource
return source as CatalogueSource
}
/**
@@ -320,14 +307,14 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
*
* @return the index of the first valid source.
*/
fun findFirstValidSource(): OnlineSource {
fun findFirstValidSource(): CatalogueSource {
return sources.first { isValidSource(it) }
}
/**
* Returns a list of enabled sources ordered by language and name.
*/
open protected fun getEnabledSources(): List<OnlineSource> {
open protected fun getEnabledSources(): List<CatalogueSource> {
val languages = prefs.enabledLanguages().getOrDefault()
val hiddenCatalogues = prefs.hiddenCatalogues().getOrDefault()
@@ -336,7 +323,7 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
languages.add("en")
}
return sourceManager.getOnlineSources()
return sourceManager.getCatalogueSources()
.filter { it.lang in languages }
.filterNot { it.id.toString() in hiddenCatalogues }
.sortedBy { "(${it.lang}) ${it.name}" }
@@ -365,13 +352,13 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
/**
* Set the filter states for the current source.
*
* @param filterStates a list of active filters.
* @param filters a list of active filters.
*/
fun setSourceFilter(filters: List<Filter<*>>) {
fun setSourceFilter(filters: FilterList) {
restartPager(filters = filters)
}
open fun createPager(query: String, filters: List<Filter<*>>): Pager {
open fun createPager(query: String, filters: FilterList): Pager {
return CataloguePager(source, query, filters)
}

View File

@@ -0,0 +1,3 @@
package eu.kanade.tachiyomi.ui.catalogue
class NoResultsException : Exception()

View File

@@ -1,25 +1,31 @@
package eu.kanade.tachiyomi.ui.catalogue
import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.tachiyomi.data.source.model.MangasPage
import rx.subjects.PublishSubject
import eu.kanade.tachiyomi.data.source.model.SManga
import rx.Observable
/**
* A general pager for source requests (latest updates, popular, search)
*/
abstract class Pager {
abstract class Pager(var currentPage: Int = 1) {
protected var lastPage: MangasPage? = null
var hasNextPage = true
private set
protected val results = PublishSubject.create<MangasPage>()
protected val results: PublishRelay<Pair<Int, List<SManga>>> = PublishRelay.create()
fun results(): Observable<MangasPage> {
fun results(): Observable<Pair<Int, List<SManga>>> {
return results.asObservable()
}
fun hasNextPage(): Boolean {
return lastPage == null || lastPage?.nextPageUrl != null
abstract fun requestNext(): Observable<MangasPage>
fun onPageReceived(mangasPage: MangasPage) {
val page = currentPage
currentPage++
hasNextPage = mangasPage.hasNextPage && !mangasPage.mangas.isEmpty()
results.call(Pair(page, mangasPage.mangas))
}
abstract fun requestNext(transformer: (Observable<MangasPage>) -> Observable<MangasPage>): Observable<MangasPage>
}

View File

@@ -1,28 +1,22 @@
package eu.kanade.tachiyomi.ui.latest_updates
import eu.kanade.tachiyomi.data.source.CatalogueSource
import eu.kanade.tachiyomi.data.source.model.MangasPage
import eu.kanade.tachiyomi.data.source.online.OnlineSource
import eu.kanade.tachiyomi.ui.catalogue.Pager
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
/**
* LatestUpdatesPager inherited from the general Pager.
*/
class LatestUpdatesPager(val source: OnlineSource): Pager() {
class LatestUpdatesPager(val source: CatalogueSource): Pager() {
override fun requestNext(transformer: (Observable<MangasPage>) -> Observable<MangasPage>): Observable<MangasPage> {
val lastPage = lastPage
val page = if (lastPage == null)
MangasPage(1)
else
MangasPage(lastPage.page + 1).apply { url = lastPage.nextPageUrl!! }
val observable = source.fetchLatestUpdates(page)
return transformer(observable)
.doOnNext { results.onNext(it) }
.doOnNext { this@LatestUpdatesPager.lastPage = it }
override fun requestNext(): Observable<MangasPage> {
return source.fetchLatestUpdates(currentPage)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext { onPageReceived(it) }
}
}

View File

@@ -1,26 +1,26 @@
package eu.kanade.tachiyomi.ui.latest_updates
import eu.kanade.tachiyomi.data.source.CatalogueSource
import eu.kanade.tachiyomi.data.source.Source
import eu.kanade.tachiyomi.data.source.online.OnlineSource
import eu.kanade.tachiyomi.data.source.model.FilterList
import eu.kanade.tachiyomi.ui.catalogue.CataloguePresenter
import eu.kanade.tachiyomi.ui.catalogue.Pager
import eu.kanade.tachiyomi.data.source.online.OnlineSource.Filter
/**
* Presenter of [LatestUpdatesFragment]. Inherit CataloguePresenter.
*/
class LatestUpdatesPresenter : CataloguePresenter() {
override fun createPager(query: String, filters: List<Filter<*>>): Pager {
override fun createPager(query: String, filters: FilterList): Pager {
return LatestUpdatesPager(source)
}
override fun getEnabledSources(): List<OnlineSource> {
override fun getEnabledSources(): List<CatalogueSource> {
return super.getEnabledSources().filter { it.supportsLatest }
}
override fun isValidSource(source: Source?): Boolean {
return super.isValidSource(source) && (source as OnlineSource).supportsLatest
return super.isValidSource(source) && (source as CatalogueSource).supportsLatest
}
}

View File

@@ -125,7 +125,7 @@ class LibraryPresenter : BasePresenter<LibraryFragment>() {
*/
private fun applyFilters(map: Map<Int, List<Manga>>): Map<Int, List<Manga>> {
// Cached list of downloaded manga directories given a source id.
val mangaDirectories = mutableMapOf<Int, Array<UniFile>>()
val mangaDirectories = mutableMapOf<Long, Array<UniFile>>()
// Cached list of downloaded chapter directories for a manga.
val chapterDirectories = mutableMapOf<Long, Boolean>()

View File

@@ -197,7 +197,7 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() {
/**
* Returns an observable that updates the chapter list with the latest from the source.
*/
fun getRemoteChaptersObservable() = source.fetchChapterList(manga)
fun getRemoteChaptersObservable() = Observable.defer { source.fetchChapterList(manga) }
.subscribeOn(Schedulers.io())
.map { syncChaptersWithSource(db, it, manga, source) }
.observeOn(AndroidSchedulers.mainThread())

View File

@@ -15,6 +15,7 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.source.Source
import eu.kanade.tachiyomi.data.source.model.SManga
import eu.kanade.tachiyomi.data.source.online.OnlineSource
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment
import eu.kanade.tachiyomi.ui.manga.MangaActivity
@@ -122,9 +123,9 @@ class MangaInfoFragment : BaseRxFragment<MangaInfoPresenter>() {
// Update status TextView.
manga_status.setText(when (manga.status) {
Manga.ONGOING -> R.string.ongoing
Manga.COMPLETED -> R.string.completed
Manga.LICENSED -> R.string.licensed
SManga.ONGOING -> R.string.ongoing
SManga.COMPLETED -> R.string.completed
SManga.LICENSED -> R.string.licensed
else -> R.string.unknown
})

View File

@@ -99,9 +99,10 @@ class MangaInfoPresenter : BasePresenter<MangaInfoFragment>() {
* @return manga information.
*/
private fun fetchMangaObs(): Observable<Manga> {
return source.fetchMangaDetails(manga)
return Observable.defer { source.fetchMangaDetails(manga) }
.flatMap { networkManga ->
manga.copyFrom(networkManga)
manga.initialized = true
db.insertManga(manga).executeAsBlocking()
Observable.just<Manga>(manga)
}

View File

@@ -4,6 +4,9 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.source.Source
import eu.kanade.tachiyomi.data.source.model.Page
import eu.kanade.tachiyomi.data.source.online.OnlineSource
import eu.kanade.tachiyomi.data.source.online.fetchImageFromCacheThenNet
import eu.kanade.tachiyomi.data.source.online.fetchPageListFromCacheThenNet
import eu.kanade.tachiyomi.util.plusAssign
import rx.Observable
import rx.schedulers.Schedulers
@@ -36,9 +39,11 @@ class ChapterLoader(
}
private fun prepareOnlineReading() {
if (source !is OnlineSource) return
subscriptions += Observable.defer { Observable.just(queue.take().page) }
.filter { it.status == Page.QUEUE }
.concatMap { source.fetchImage(it) }
.concatMap { source.fetchImageFromCacheThenNet(it) }
.repeat()
.subscribeOn(Schedulers.io())
.subscribe({
@@ -57,6 +62,10 @@ class ChapterLoader(
Observable.just(chapter.pages!!)
}
.doOnNext { pages ->
if (pages.isEmpty()) {
throw Exception("Page list is empty")
}
// Now that the number of pages is known, fix the requested page if the last one
// was requested.
if (chapter.requestedPage == -1) {
@@ -76,8 +85,8 @@ class ChapterLoader(
// Fetch the page list from disk.
downloadManager.buildPageList(source, manga, chapter)
} else {
// Fetch the page list from cache or fallback to network
source.fetchPageList(chapter)
(source as? OnlineSource)?.fetchPageListFromCacheThenNet(chapter)
?: source.fetchPageList(chapter)
}
}
.doOnNext { pages ->
@@ -111,6 +120,8 @@ class ChapterLoader(
queue.offer(PriorityPage(page, 2))
}
private data class PriorityPage(val page: Page, val priority: Int): Comparable<PriorityPage> {
companion object {

View File

@@ -372,7 +372,9 @@ class ReaderPresenter : BasePresenter<ReaderActivity>() {
Observable.fromCallable {
// Cache current page list progress for online chapters to allow a faster reopen
if (!chapter.isDownloaded) {
source.let { if (it is OnlineSource) it.savePageList(chapter, pages) }
source.let {
if (it is OnlineSource) chapterCache.putPageListToCache(chapter, pages)
}
}
try {

View File

@@ -130,7 +130,7 @@ class RecentChaptersPresenter : BasePresenter<RecentChaptersFragment>() {
*/
private fun setDownloadedChapters(chapters: List<RecentChapter>) {
// Cached list of downloaded manga directories.
val mangaDirectories = mutableMapOf<Int, Array<UniFile>>()
val mangaDirectories = mutableMapOf<Long, Array<UniFile>>()
// Cached list of downloaded chapter directories for a manga.
val chapterDirectories = mutableMapOf<Long, Array<UniFile>>()

View File

@@ -123,13 +123,14 @@ class SettingsSourcesFragment : SettingsFragment() {
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == SOURCE_CHANGE_REQUEST) {
val pref = findPreference(getSourceKey(resultCode)) as? LoginCheckBoxPreference
if (requestCode == SOURCE_CHANGE_REQUEST && data != null) {
val sourceId = data.getLongExtra("key", -1L)
val pref = findPreference(getSourceKey(sourceId)) as? LoginCheckBoxPreference
pref?.notifyChanged()
}
}
private fun getSourceKey(sourceId: Int): String {
private fun getSourceKey(sourceId: Long): String {
return "source_$sourceId"
}

View File

@@ -81,8 +81,9 @@ class SettingsTrackingFragment : SettingsFragment() {
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == SYNC_CHANGE_REQUEST) {
updatePreference(resultCode)
if (requestCode == SYNC_CHANGE_REQUEST && data != null) {
val serviceId = data.getIntExtra("key", -1)
updatePreference(serviceId)
}
}