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:
parent
7ec822503a
commit
0225711f6f
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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) }
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,5 +27,4 @@ class SecurityPreferences(
|
||||
INCOGNITO(R.string.pref_incognito_mode),
|
||||
NEVER(R.string.lock_never),
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user