mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	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:
		| @@ -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 | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user