Extensions presenter now using less rx

This commit is contained in:
Jay 2020-03-24 02:06:29 -04:00
parent fde6506842
commit 66d62f5aa4
5 changed files with 86 additions and 31 deletions

View File

@ -15,7 +15,9 @@ import eu.kanade.tachiyomi.extension.util.ExtensionLoader
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.util.system.launchNow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext
import rx.Observable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -57,12 +59,28 @@ class ExtensionManager(
private set(value) {
field = value
installedExtensionsRelay.call(value)
listener?.extensionsUpdated()
}
private var listener: ExtensionsChangedListener? = null
fun setListener(listener: ExtensionsChangedListener) {
this.listener = listener
}
fun removeListener(listener: ExtensionsChangedListener) {
if (this.listener == listener)
this.listener = null
}
fun getAppIconForSource(source: Source): Drawable? {
val pkgName =
installedExtensions.find { ext -> ext.sources.any { it.id == source.id } }?.pkgName
return if (pkgName != null) context.packageManager.getApplicationIcon(pkgName)
return if (pkgName != null) try {
context.packageManager.getApplicationIcon(pkgName)
} catch (e: Exception) {
null
}
else null
}
@ -79,6 +97,7 @@ class ExtensionManager(
field = value
availableExtensionsRelay.call(value)
updatedInstalledExtensionsStatuses(value)
listener?.extensionsUpdated()
}
/**
@ -93,6 +112,7 @@ class ExtensionManager(
private set(value) {
field = value
untrustedExtensionsRelay.call(value)
listener?.extensionsUpdated()
}
/**
@ -162,6 +182,19 @@ class ExtensionManager(
}
}
/**
* Finds the available extensions in the [api] and updates [availableExtensions].
*/
suspend fun findAvailableExtensionsAsync() {
withContext(Dispatchers.IO) {
availableExtensions = try {
api.findExtensions()
} catch (e: Exception) {
emptyList()
}
}
}
/**
* Sets the update field of the installed extensions with the given [availableExtensions].
*
@ -352,3 +385,7 @@ class ExtensionManager(
return this
}
}
interface ExtensionsChangedListener {
fun extensionsUpdated()
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.catalogue
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.Activity
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.Menu
@ -33,13 +34,13 @@ import eu.kanade.tachiyomi.util.view.applyWindowInsetsForRootController
import eu.kanade.tachiyomi.util.view.scrollViewWith
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import eu.kanade.tachiyomi.widget.preference.SourceLoginDialog
import kotlin.math.max
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.catalogue_main_controller.*
import kotlinx.android.synthetic.main.extensions_bottom_sheet.*
import kotlinx.android.synthetic.main.main_activity.*
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.math.max
/**
* This controller shows and manages the different catalogues enabled by the user.
@ -180,7 +181,6 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
fun showExtensions() {
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
ext_bottom_sheet.fetchOnlineExtensionsIfNeeded()
}
fun toggleExtensions() {
@ -188,7 +188,6 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
} else {
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
ext_bottom_sheet.fetchOnlineExtensionsIfNeeded()
}
}
@ -209,10 +208,15 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
super.onChangeStarted(handler, type)
if (!type.isPush && handler is SettingsSourcesFadeChangeHandler) {
ext_bottom_sheet.updateExtTitle()
presenter.updateSources()
ext_bottom_sheet.presenter.refreshExtensions()
}
}
override fun onActivityResumed(activity: Activity) {
super.onActivityResumed(activity)
ext_bottom_sheet.presenter.refreshExtensions()
}
/**
* Called when login dialog is closed, refreshes the adapter.
*

View File

@ -5,17 +5,16 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.extension.ExtensionsChangedListener
import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep
import eu.kanade.tachiyomi.util.system.LocaleHelper
import java.util.concurrent.TimeUnit
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -25,36 +24,51 @@ typealias ExtensionTuple =
/**
* Presenter of [ExtensionBottomSheet].
*/
open class ExtensionBottomPresenter(
class ExtensionBottomPresenter(
private val bottomSheet: ExtensionBottomSheet,
private val extensionManager: ExtensionManager = Injekt.get(),
private val preferences: PreferencesHelper = Injekt.get()
) : CoroutineScope {
override var coroutineContext: CoroutineContext = Job() + Dispatchers.Default
) : ExtensionsChangedListener {
private var scope = CoroutineScope(Job() + Dispatchers.Default)
private var extensions = emptyList<ExtensionItem>()
private var currentDownloads = hashMapOf<String, InstallStep>()
fun onCreate() {
// extensionManager.findAvailableExtensions()
bindToExtensionsObservable()
scope.launch {
extensionManager.findAvailableExtensionsAsync()
extensions = toItems(
Triple(
extensionManager.installedExtensions,
extensionManager.untrustedExtensions,
extensionManager.availableExtensions
)
)
withContext(Dispatchers.Main) { bottomSheet.setExtensions(extensions) }
extensionManager.setListener(this@ExtensionBottomPresenter)
}
}
private fun bindToExtensionsObservable(): Subscription {
val installedObservable = extensionManager.getInstalledExtensionsObservable()
val untrustedObservable = extensionManager.getUntrustedExtensionsObservable()
val availableObservable = extensionManager.getAvailableExtensionsObservable()
.startWith(emptyList<Extension.Available>())
fun onDestroy() {
extensionManager.removeListener(this)
}
return Observable.combineLatest(installedObservable, untrustedObservable, availableObservable) { installed, untrusted, available -> Triple(installed, untrusted, available) }
.debounce(100, TimeUnit.MILLISECONDS)
.map(::toItems)
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
bottomSheet.setExtensions(extensions)
}
fun refreshExtensions() {
scope.launch {
extensions = toItems(
Triple(
extensionManager.installedExtensions,
extensionManager.untrustedExtensions,
extensionManager.availableExtensions
)
)
withContext(Dispatchers.Main) { bottomSheet.setExtensions(extensions) }
}
}
override fun extensionsUpdated() {
refreshExtensions()
}
@Synchronized

View File

@ -33,7 +33,7 @@ ExtensionAdapter.OnButtonClickListener,
var sheetBehavior: BottomSheetBehavior<*>? = null
private lateinit var autoCheckItem: AutoCheckItem
var shouldCallApi = true
var shouldCallApi = false
/**
* Adapter containing the list of manga from the catalogue.
@ -54,6 +54,7 @@ ExtensionAdapter.OnButtonClickListener,
// Create recycler and set adapter.
ext_recycler.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context)
ext_recycler.adapter = adapter
ext_recycler.setHasFixedSize(true)
ext_recycler.addItemDecoration(ExtensionDividerItemDecoration(context))
ext_recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
this.controller = controller
@ -146,7 +147,6 @@ ExtensionAdapter.OnButtonClickListener,
}
fun setExtensions(extensions: List<ExtensionItem>) {
// ext_swipe_refresh?.isRefreshing = false
this.extensions = extensions
controller.presenter.updateSources()
drawExtensions()

View File

@ -34,11 +34,11 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor
import kotlin.math.abs
import kotlin.math.min
import kotlinx.android.synthetic.main.main_activity.*
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.math.abs
import kotlin.math.min
/**
* Returns coordinates of view.