Limiting search to settings menu only, localized breadcrumb string, and code cleanup after code review.

This commit is contained in:
mpm11011 2020-08-30 16:35:15 -04:00
parent f10fe8bf02
commit d53719b79e
9 changed files with 46 additions and 151 deletions

View file

@ -273,11 +273,9 @@ dependencies {
testImplementation "org.robolectric:shadows-multidex:$robolectric_version" testImplementation "org.robolectric:shadows-multidex:$robolectric_version"
testImplementation "org.robolectric:shadows-play-services:$robolectric_version" testImplementation "org.robolectric:shadows-play-services:$robolectric_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$BuildPluginsVersion.KOTLIN"
implementation "org.jetbrains.kotlin:kotlin-reflect:$BuildPluginsVersion.KOTLIN" implementation "org.jetbrains.kotlin:kotlin-reflect:$BuildPluginsVersion.KOTLIN"
final coroutines_version = '1.3.9' final coroutines_version = '1.3.9'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

View file

@ -2,9 +2,6 @@ package eu.kanade.tachiyomi.ui.more
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Menu
import android.view.MenuInflater
import androidx.appcompat.widget.SearchView
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -18,7 +15,6 @@ import eu.kanade.tachiyomi.ui.category.CategoryController
import eu.kanade.tachiyomi.ui.download.DownloadController import eu.kanade.tachiyomi.ui.download.DownloadController
import eu.kanade.tachiyomi.ui.setting.SettingsController import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.ui.setting.SettingsMainController import eu.kanade.tachiyomi.ui.setting.SettingsMainController
import eu.kanade.tachiyomi.ui.setting.settingssearch.SettingsSearchController
import eu.kanade.tachiyomi.util.preference.add import eu.kanade.tachiyomi.util.preference.add
import eu.kanade.tachiyomi.util.preference.iconRes import eu.kanade.tachiyomi.util.preference.iconRes
import eu.kanade.tachiyomi.util.preference.iconTint import eu.kanade.tachiyomi.util.preference.iconTint
@ -30,11 +26,6 @@ import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.openInBrowser import eu.kanade.tachiyomi.util.system.openInBrowser
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.appcompat.QueryTextEvent
import reactivecircus.flowbinding.appcompat.queryTextEvents
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -149,33 +140,6 @@ class MoreController :
} }
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
// Inflate menu
inflater.inflate(R.menu.settings_main, menu)
// Initialize search option.
val searchItem = menu.findItem(R.id.action_search)
val searchView = searchItem.actionView as SearchView
searchView.maxWidth = Int.MAX_VALUE
// Change hint to show global search.
searchView.queryHint = applicationContext?.getString(R.string.action_search_settings)
// Create query listener which opens the global search view.
searchView.queryTextEvents()
.filterIsInstance<QueryTextEvent.QueryChanged>()
.onEach {
performSettingsSearch(it.queryText.toString())
}
.launchIn(scope)
}
private fun performSettingsSearch(query: String) {
router.pushController(
SettingsSearchController(query).withFadeTransaction()
)
}
companion object { companion object {
private const val URL_HELP = "https://tachiyomi.org/help/" private const val URL_HELP = "https://tachiyomi.org/help/"
} }

View file

@ -115,7 +115,7 @@ class SettingsMainController : SettingsController() {
private fun performSettingsSearch(query: String) { private fun performSettingsSearch(query: String) {
router.pushController( router.pushController(
SettingsSearchController(query).withFadeTransaction() SettingsSearchController().withFadeTransaction()
) )
} }
} }

View file

@ -64,9 +64,8 @@ class SettingsSearchAdapter(val controller: SettingsSearchController) :
*/ */
private fun restoreHolderState(holder: RecyclerView.ViewHolder) { private fun restoreHolderState(holder: RecyclerView.ViewHolder) {
val key = "holder_${holder.bindingAdapterPosition}" val key = "holder_${holder.bindingAdapterPosition}"
val holderState = bundle.getSparseParcelableArray<Parcelable>(key) bundle.getSparseParcelableArray<Parcelable>(key)?.let {
if (holderState != null) { holder.itemView.restoreHierarchyState(it)
holder.itemView.restoreHierarchyState(holderState)
bundle.remove(key) bundle.remove(key)
} }
} }

View file

@ -17,13 +17,10 @@ import eu.kanade.tachiyomi.ui.setting.SettingsController
/** /**
* This controller shows and manages the different search result in settings search. * This controller shows and manages the different search result in settings search.
* This controller should only handle UI actions, IO actions should be done by [SettingsSearchPresenter] * [SettingsSearchAdapter.OnTitleClickListener] called when preference is clicked in settings search
* [SettingsSearchAdapter.WhatListener] called when preference is clicked in settings search
*/ */
open class SettingsSearchController( class SettingsSearchController :
protected val initialQuery: String? = null, NucleusController<SettingsSearchControllerBinding, SettingsSearchPresenter>(),
protected val extensionFilter: String? = null
) : NucleusController<SettingsSearchControllerBinding, SettingsSearchPresenter>(),
SettingsSearchAdapter.OnTitleClickListener { SettingsSearchAdapter.OnTitleClickListener {
/** /**
@ -57,7 +54,7 @@ open class SettingsSearchController(
* @return instance of [SettingsSearchPresenter] * @return instance of [SettingsSearchPresenter]
*/ */
override fun createPresenter(): SettingsSearchPresenter { override fun createPresenter(): SettingsSearchPresenter {
return SettingsSearchPresenter(initialQuery, extensionFilter) return SettingsSearchPresenter()
} }
/** /**
@ -108,11 +105,6 @@ open class SettingsSearchController(
}) })
} }
/**
* Called when the view is created
*
* @param view view of controller
*/
override fun onViewCreated(view: View) { override fun onViewCreated(view: View) {
super.onViewCreated(view) super.onViewCreated(view)
@ -138,44 +130,14 @@ open class SettingsSearchController(
adapter?.onRestoreInstanceState(savedViewState) adapter?.onRestoreInstanceState(savedViewState)
} }
/**
* Returns the view holder for the given preference.
*
* @param pref used to find holder containing source
* @return the holder of the preference or null if it's not bound.
*/
// private fun getHolder(pref: Preference): SettingsSearchHolder? {
// val adapter = adapter ?: return null
//
// adapter.allBoundViewHolders.forEach { holder ->
// val item = adapter.getItem(holder.bindingAdapterPosition)
// if (item != null && pref.key == item.pref.key) {
// return holder as SettingsSearchHolder
// }
// }
//
// return null
// }
/** /**
* returns a list of `SettingsSearchItem` to be shown as search results * returns a list of `SettingsSearchItem` to be shown as search results
*/ */
fun getResultSet(query: String? = null): List<SettingsSearchItem> { fun getResultSet(query: String? = null): List<SettingsSearchItem> {
val list = mutableListOf<SettingsSearchItem>() val list = mutableListOf<SettingsSearchItem>()
if (query.isNullOrBlank()) { if (!query.isNullOrBlank()) {
SettingsSearchHelper.prefSearchResultList.forEach { SettingsSearchHelper.getFilteredResults(query)
list.add(SettingsSearchItem(it, null))
}
} else {
SettingsSearchHelper.prefSearchResultList
.filter {
val inTitle = it.title.contains(query, true)
val inSummary = it.summary.contains(query, true)
val inBreadcrumb = it.breadcrumb.contains(query, true)
return@filter inTitle || inSummary || inBreadcrumb
}
.forEach { .forEach {
list.add(SettingsSearchItem(it, null)) list.add(SettingsSearchItem(it, null))
} }
@ -197,6 +159,6 @@ open class SettingsSearchController(
* Opens a catalogue with the given search. * Opens a catalogue with the given search.
*/ */
override fun onTitleClick(ctrl: SettingsController) { override fun onTitleClick(ctrl: SettingsController) {
router.replaceTopController(ctrl.withFadeTransaction()) router.pushController(ctrl.withFadeTransaction())
} }
} }

View file

@ -2,11 +2,11 @@ package eu.kanade.tachiyomi.ui.setting.settingssearch
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.res.Resources
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceCategory import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceGroup import androidx.preference.PreferenceGroup
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import eu.kanade.tachiyomi.ui.more.AboutController
import eu.kanade.tachiyomi.ui.setting.SettingsAdvancedController import eu.kanade.tachiyomi.ui.setting.SettingsAdvancedController
import eu.kanade.tachiyomi.ui.setting.SettingsBackupController import eu.kanade.tachiyomi.ui.setting.SettingsBackupController
import eu.kanade.tachiyomi.ui.setting.SettingsBrowseController import eu.kanade.tachiyomi.ui.setting.SettingsBrowseController
@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.ui.setting.SettingsParentalControlsController
import eu.kanade.tachiyomi.ui.setting.SettingsReaderController import eu.kanade.tachiyomi.ui.setting.SettingsReaderController
import eu.kanade.tachiyomi.ui.setting.SettingsSecurityController import eu.kanade.tachiyomi.ui.setting.SettingsSecurityController
import eu.kanade.tachiyomi.ui.setting.SettingsTrackingController import eu.kanade.tachiyomi.ui.setting.SettingsTrackingController
import eu.kanade.tachiyomi.util.system.isLTR
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance import kotlin.reflect.full.createInstance
@ -38,8 +39,7 @@ object SettingsSearchHelper {
SettingsParentalControlsController::class, SettingsParentalControlsController::class,
SettingsReaderController::class, SettingsReaderController::class,
SettingsSecurityController::class, SettingsSecurityController::class,
SettingsTrackingController::class, SettingsTrackingController::class
AboutController::class
) )
/** /**
@ -63,13 +63,23 @@ object SettingsSearchHelper {
} }
} }
fun getFilteredResults(query: String): List<SettingsSearchResult> {
return prefSearchResultList.filter {
val inTitle = it.title.contains(query, true)
val inSummary = it.summary.contains(query, true)
val inBreadcrumb = it.breadcrumb.contains(query, true)
return@filter inTitle || inSummary || inBreadcrumb
}
}
/** /**
* Extracts the data needed from a `Preference` to create a `SettingsSearchResult`, and then adds it to `prefSearchResultList` * Extracts the data needed from a `Preference` to create a `SettingsSearchResult`, and then adds it to `prefSearchResultList`
*/ */
private fun getSettingSearchResult(ctrl: SettingsController, pref: Preference, breadcrumbs: String = "") { private fun getSettingSearchResult(ctrl: SettingsController, pref: Preference, breadcrumbs: String = "") {
when (pref) { when (pref) {
is PreferenceGroup -> { is PreferenceGroup -> {
val breadcrumbsStr = breadcrumbs + " > ${pref.title}" val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
for (x in 0 until pref.preferenceCount) { for (x in 0 until pref.preferenceCount) {
val subPref = pref.getPreference(x) val subPref = pref.getPreference(x)
@ -77,7 +87,7 @@ object SettingsSearchHelper {
} }
} }
is PreferenceCategory -> { is PreferenceCategory -> {
val breadcrumbsStr = breadcrumbs + " > ${pref.title}" val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
for (x in 0 until pref.preferenceCount) { for (x in 0 until pref.preferenceCount) {
val subPref = pref.getPreference(x) val subPref = pref.getPreference(x)
@ -88,7 +98,7 @@ object SettingsSearchHelper {
// Is an actual preference // Is an actual preference
val title = pref.title.toString() val title = pref.title.toString()
val summary = if (pref.summary != null) pref.summary.toString() else "" val summary = if (pref.summary != null) pref.summary.toString() else ""
val breadcrumbsStr = breadcrumbs + " > ${pref.title}" val breadcrumbsStr = addLocalizedBreadcrumb(breadcrumbs, "${pref.title}")
prefSearchResultList.add( prefSearchResultList.add(
SettingsSearchResult( SettingsSearchResult(
@ -103,6 +113,16 @@ object SettingsSearchHelper {
} }
} }
private fun addLocalizedBreadcrumb(path: String, node: String): String {
return if (Resources.getSystem().isLTR) {
// This locale reads left to right.
"$path > $node"
} else {
// This locale reads right to left.
"$node < $path"
}
}
data class SettingsSearchResult( data class SettingsSearchResult(
val key: String?, val key: String?,
val title: String, val title: String,

View file

@ -3,7 +3,10 @@ package eu.kanade.tachiyomi.ui.setting.settingssearch
import android.view.View import android.view.View
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import kotlin.reflect.full.createInstance import kotlin.reflect.full.createInstance
import kotlinx.android.synthetic.main.settings_search_controller_card.* import kotlinx.android.synthetic.main.settings_search_controller_card.search_result_pref_breadcrumb
import kotlinx.android.synthetic.main.settings_search_controller_card.search_result_pref_summary
import kotlinx.android.synthetic.main.settings_search_controller_card.search_result_pref_title
import kotlinx.android.synthetic.main.settings_search_controller_card.title_wrapper
/** /**
* Holder that binds the [SettingsSearchItem] containing catalogue cards. * Holder that binds the [SettingsSearchItem] containing catalogue cards.

View file

@ -16,11 +16,6 @@ import eu.kanade.tachiyomi.R
class SettingsSearchItem(val settingsSearchResult: SettingsSearchHelper.SettingsSearchResult, val results: List<SettingsSearchItem>?) : class SettingsSearchItem(val settingsSearchResult: SettingsSearchHelper.SettingsSearchResult, val results: List<SettingsSearchItem>?) :
AbstractFlexibleItem<SettingsSearchHolder>() { AbstractFlexibleItem<SettingsSearchHolder>() {
/**
* Set view.
*
* @return id of view
*/
override fun getLayoutRes(): Int { override fun getLayoutRes(): Int {
return R.layout.settings_search_controller_card return R.layout.settings_search_controller_card
} }
@ -34,9 +29,6 @@ class SettingsSearchItem(val settingsSearchResult: SettingsSearchHelper.Settings
return SettingsSearchHolder(view, adapter as SettingsSearchAdapter) return SettingsSearchHolder(view, adapter as SettingsSearchAdapter)
} }
/**
* Bind item to view.
*/
override fun bindViewHolder( override fun bindViewHolder(
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
holder: SettingsSearchHolder, holder: SettingsSearchHolder,
@ -46,11 +38,6 @@ class SettingsSearchItem(val settingsSearchResult: SettingsSearchHelper.Settings
holder.bind(this) holder.bind(this)
} }
/**
* Used to check if two items are equal.
*
* @return items are equal?
*/
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other is SettingsSearchItem) { if (other is SettingsSearchItem) {
return settingsSearchResult == settingsSearchResult return settingsSearchResult == settingsSearchResult
@ -58,11 +45,6 @@ class SettingsSearchItem(val settingsSearchResult: SettingsSearchHelper.Settings
return false return false
} }
/**
* Return hash code of item.
*
* @return hashcode
*/
override fun hashCode(): Int { override fun hashCode(): Int {
return settingsSearchResult.hashCode() return settingsSearchResult.hashCode()
} }

View file

@ -3,30 +3,16 @@ package eu.kanade.tachiyomi.ui.setting.settingssearch
import android.os.Bundle import android.os.Bundle
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
import rx.Subscription
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
/** /**
* Presenter of [SettingsSearchController] * Presenter of [SettingsSearchController]
* Function calls should be done from here. UI calls should be done from the controller. * Function calls should be done from here. UI calls should be done from the controller.
*
* @param sourceManager manages the different sources.
* @param db manages the database calls.
* @param preferences manages the preference calls.
*/ */
open class SettingsSearchPresenter( open class SettingsSearchPresenter : BasePresenter<SettingsSearchController>() {
val initialQuery: String? = "",
val initialExtensionFilter: String? = null,
val sourceManager: SourceManager = Injekt.get(),
val db: DatabaseHelper = Injekt.get(),
val preferences: PreferencesHelper = Injekt.get()
) : BasePresenter<SettingsSearchController>() {
/** /**
* Query from the view. * Query from the view.
@ -34,36 +20,17 @@ open class SettingsSearchPresenter(
var query = "" var query = ""
private set private set
/** val sourceManager: SourceManager = Injekt.get()
* Fetches the different sources by user settings. val db: DatabaseHelper = Injekt.get()
*/ val preferences: PreferencesHelper = Injekt.get()
private var fetchSourcesSubscription: Subscription? = null
/**
* Subscription for fetching images of manga.
*/
private var fetchImageSubscription: Subscription? = null
private val extensionManager by injectLazy<ExtensionManager>()
private var extensionFilter: String? = null
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
query = savedState?.getString(SettingsSearchPresenter::query.name) ?: "" // TODO - Some way to restore previous query?
extensionFilter = savedState?.getString(SettingsSearchPresenter::extensionFilter.name)
?: initialExtensionFilter
}
override fun onDestroy() {
fetchSourcesSubscription?.unsubscribe()
fetchImageSubscription?.unsubscribe()
super.onDestroy()
} }
override fun onSave(state: Bundle) { override fun onSave(state: Bundle) {
state.putString(BrowseSourcePresenter::query.name, query) state.putString(SettingsSearchPresenter::query.name, query)
state.putString(SettingsSearchPresenter::extensionFilter.name, extensionFilter)
super.onSave(state) super.onSave(state)
} }
} }