Clean up base classes

Should be able to throw away some of the search controller stuff after Global Search is migrated

(cherry picked from commit 0225711f6f91417af0ae41d42f81c70c86a572ab)
This commit is contained in:
arkon 2022-09-18 17:22:54 -04:00 committed by Jobobby04
parent 966bd31d61
commit 00bb74f330
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

@ -98,8 +98,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
@ -18,8 +17,6 @@ class MoreController :
FullComposeController<MorePresenter>(),
RootController {
override fun getTitle() = resources?.getString(R.string.label_more)
override fun createPresenter() = MorePresenter()
@Composable

View File

@ -1106,6 +1106,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

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