Clean up base classes

Should be able to throw away some of the search controller stuff after Global Search is migrated
This commit is contained in:
arkon 2022-09-18 17:22:54 -04:00
parent 7ec822503a
commit 0225711f6f
11 changed files with 42 additions and 137 deletions

View file

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.base.controller
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
@ -75,60 +74,10 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) : Contro
}
fun setTitle(title: String? = null) {
var parentController = parentController
while (parentController != null) {
if (parentController is BaseController<*> && parentController.getTitle() != null) {
return
}
parentController = parentController.parentController
}
(activity as? AppCompatActivity)?.supportActionBar?.title = title ?: getTitle()
}
private fun Controller.instance(): String {
return "${javaClass.simpleName}@${Integer.toHexString(hashCode())}"
}
/**
* Workaround for buggy menu item layout after expanding/collapsing an expandable item like a SearchView.
* This method should be removed when fixed upstream.
* Issue link: https://issuetracker.google.com/issues/37657375
*/
var expandActionViewFromInteraction = false
fun MenuItem.fixExpand(onExpand: ((MenuItem) -> Boolean)? = null, onCollapse: ((MenuItem) -> Boolean)? = null) {
setOnActionExpandListener(
object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
return onExpand?.invoke(item) ?: true
}
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
activity?.invalidateOptionsMenu()
return onCollapse?.invoke(item) ?: true
}
},
)
if (expandActionViewFromInteraction) {
expandActionViewFromInteraction = false
expandActionView()
}
}
/**
* Workaround for menu items not disappearing when expanding an expandable item like a SearchView.
* [expandActionViewFromInteraction] should be set to true in [onOptionsItemSelected] when the expandable item is selected
* This method should be called as part of [MenuItem.OnActionExpandListener.onMenuItemActionExpand]
*/
open fun invalidateMenuOnExpand(): Boolean {
return if (expandActionViewFromInteraction) {
activity?.invalidateOptionsMenu()
false
} else {
true
}
}
}

View file

@ -9,7 +9,7 @@ import nucleus.presenter.Presenter
@Suppress("LeakingThis")
abstract class NucleusController<VB : ViewBinding, P : Presenter<*>>(val bundle: Bundle? = null) :
RxController<VB>(bundle),
BaseController<VB>(bundle),
PresenterFactory<P> {
private val delegate = NucleusConductorDelegate(this)

View file

@ -1,31 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.os.Bundle
import android.view.View
import androidx.annotation.CallSuper
import androidx.viewbinding.ViewBinding
import rx.Observable
import rx.Subscription
import rx.subscriptions.CompositeSubscription
abstract class RxController<VB : ViewBinding>(bundle: Bundle? = null) : BaseController<VB>(bundle) {
private var untilDestroySubscriptions = CompositeSubscription()
@CallSuper
override fun onViewCreated(view: View) {
if (untilDestroySubscriptions.isUnsubscribed) {
untilDestroySubscriptions = CompositeSubscription()
}
}
@CallSuper
override fun onDestroyView(view: View) {
super.onDestroyView(view)
untilDestroySubscriptions.unsubscribe()
}
fun <T> Observable<T>.subscribeUntilDestroy(onNext: (T) -> Unit): Subscription {
return subscribe(onNext).also { untilDestroySubscriptions.add(it) }
}
}

View file

@ -6,7 +6,6 @@ import android.text.style.CharacterStyle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.annotation.StringRes
import androidx.appcompat.widget.SearchView
import androidx.core.text.getSpans
import androidx.core.widget.doAfterTextChanged
@ -43,10 +42,7 @@ abstract class SearchableNucleusController<VB : ViewBinding, P : BasePresenter<*
inflater: MenuInflater,
menuId: Int,
searchItemId: Int,
@StringRes queryHint: Int? = null,
restoreCurrentQuery: Boolean = true,
) {
// Inflate menu
inflater.inflate(menuId, menu)
// Initialize search option.
@ -93,21 +89,6 @@ abstract class SearchableNucleusController<VB : ViewBinding, P : BasePresenter<*
searchItem.expandActionView()
searchView.setQuery(nonSubmittedQuery, false)
onSearchViewQueryTextChange(nonSubmittedQuery)
} else {
if (queryHint != null) {
searchView.queryHint = applicationContext?.getString(queryHint)
}
if (restoreCurrentQuery) {
// Restoring a query the user had submitted
if (query.isNotBlank()) {
searchItem.expandActionView()
searchView.setQuery(query, true)
searchView.clearFocus()
onSearchViewQueryTextChange(query)
onSearchViewQueryTextSubmit(query)
}
}
}
// Workaround for weird behavior where searchView gets empty text change despite
@ -190,12 +171,40 @@ abstract class SearchableNucleusController<VB : ViewBinding, P : BasePresenter<*
protected open fun onSearchMenuItemActionCollapse(item: MenuItem?) {
}
/**
* Workaround for buggy menu item layout after expanding/collapsing an expandable item like a SearchView.
* This method should be removed when fixed upstream.
* Issue link: https://issuetracker.google.com/issues/37657375
*/
private var expandActionViewFromInteraction = false
private fun MenuItem.fixExpand(onExpand: ((MenuItem) -> Boolean)? = null, onCollapse: ((MenuItem) -> Boolean)? = null) {
setOnActionExpandListener(
object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
return onExpand?.invoke(item) ?: true
}
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
activity?.invalidateOptionsMenu()
return onCollapse?.invoke(item) ?: true
}
},
)
if (expandActionViewFromInteraction) {
expandActionViewFromInteraction = false
expandActionView()
}
}
/**
* During the conversion to SearchableNucleusController (after which I plan to merge its code
* into BaseController) this addresses an issue where the searchView.onTextFocus event is not
* triggered
*/
override fun invalidateMenuOnExpand(): Boolean {
private fun invalidateMenuOnExpand(): Boolean {
return if (expandActionViewFromInteraction) {
activity?.invalidateOptionsMenu()
setCurrentSearchViewState(SearchViewState.FOCUSED) // we are technically focused here

View file

@ -40,15 +40,6 @@ open class BasePresenter<V> : RxPresenter<V>() {
fun <T> Preference<T>.asState() = PreferenceMutableState(this, presenterScope)
/**
* Subscribes an observable with [deliverFirst] and adds it to the presenter's lifecycle
* subscription list.
*
* @param onNext function to execute when the observable emits an item.
* @param onError function to execute when the observable throws an error.
*/
fun <T> Observable<T>.subscribeFirst(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit) = { _, _ -> }) = compose(deliverFirst<T>()).subscribe(split(onNext, onError)).apply { add(this) }
/**
* Subscribes an observable with [deliverLatestCache] and adds it to the presenter's lifecycle
* subscription list.

View file

@ -92,8 +92,6 @@ open class GlobalSearchController(
inflater,
R.menu.global_search,
R.id.action_search,
null,
false, // the onMenuItemActionExpand will handle this
)
optionsMenuSearchItem = menu.findItem(R.id.action_search)

View file

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.more
import androidx.compose.runtime.Composable
import eu.kanade.presentation.more.MoreScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.controller.FullComposeController
import eu.kanade.tachiyomi.ui.base.controller.RootController
import eu.kanade.tachiyomi.ui.base.controller.pushController
@ -15,8 +14,6 @@ class MoreController :
FullComposeController<MorePresenter>(),
RootController {
override fun getTitle() = resources?.getString(R.string.label_more)
override fun createPresenter() = MorePresenter()
@Composable

View file

@ -879,6 +879,15 @@ class ReaderPresenter(
}
}
/**
* Subscribes an observable with [deliverFirst] and adds it to the presenter's lifecycle
* subscription list.
*
* @param onNext function to execute when the observable emits an item.
* @param onError function to execute when the observable throws an error.
*/
private fun <T> Observable<T>.subscribeFirst(onNext: (ReaderActivity, T) -> Unit, onError: ((ReaderActivity, Throwable) -> Unit) = { _, _ -> }) = compose(deliverFirst<T>()).subscribe(split(onNext, onError)).apply { add(this) }
companion object {
// Safe theoretical max filename size is 255 bytes and 1 char = 2-4 bytes (UTF-8)
private const val MAX_FILE_NAME_BYTES = 250

View file

@ -21,7 +21,6 @@ import com.bluelinelabs.conductor.ControllerChangeType
import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.util.system.getResourceColor
import kotlinx.coroutines.CoroutineScope
@ -114,20 +113,8 @@ abstract class SettingsController : PreferenceController() {
}
}
open fun getTitle(): String? {
return preferenceScreen?.title?.toString()
}
private fun setTitle() {
var parentController = parentController
while (parentController != null) {
if (parentController is BaseController<*> && parentController.getTitle() != null) {
return
}
parentController = parentController.parentController
}
(activity as? AppCompatActivity)?.supportActionBar?.title = getTitle()
(activity as? AppCompatActivity)?.supportActionBar?.title = preferenceScreen?.title?.toString()
}
inline fun <T> Preference.visibleIf(preference: eu.kanade.tachiyomi.core.preference.Preference<T>, crossinline block: (T) -> Boolean) {

View file

@ -43,9 +43,8 @@ object DiskUtil {
/**
* Returns the root folders of all the available external storages.
*/
fun getExternalStorages(context: Context): Collection<File> {
val directories = mutableSetOf<File>()
directories += ContextCompat.getExternalFilesDirs(context, null)
fun getExternalStorages(context: Context): List<File> {
return ContextCompat.getExternalFilesDirs(context, null)
.filterNotNull()
.mapNotNull {
val file = File(it.absolutePath.substringBefore("/Android/"))
@ -56,8 +55,6 @@ object DiskUtil {
null
}
}
return directories
}
/**

View file

@ -27,5 +27,4 @@ class SecurityPreferences(
INCOGNITO(R.string.pref_incognito_mode),
NEVER(R.string.lock_never),
}
}