From 938a14ad1cc75bad0f0fddee17da31cee2c5c3d0 Mon Sep 17 00:00:00 2001 From: Abhijit Valluri Date: Tue, 1 Sep 2020 19:01:15 +0100 Subject: [PATCH] Implement search feature in add-ons page --- .../fenix/addons/AddonsManagementFragment.kt | 78 +++++++++++++++++-- app/src/main/res/menu/addons_menu.xml | 14 ++++ app/src/main/res/values/strings.xml | 2 + 3 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 app/src/main/res/menu/addons_menu.xml diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt index 3fd49bcb8..a28e8de94 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt @@ -6,9 +6,10 @@ package org.mozilla.fenix.addons import android.content.Context import android.os.Bundle -import android.view.Gravity -import android.view.View +import android.view.* import android.view.accessibility.AccessibilityEvent +import android.view.inputmethod.EditorInfo +import androidx.appcompat.widget.SearchView import androidx.core.content.res.ResourcesCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment @@ -23,8 +24,6 @@ import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManagerException -import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment -import mozilla.components.feature.addons.ui.AddonsManagerAdapter import mozilla.components.feature.addons.ui.PermissionsDialogFragment import mozilla.components.feature.addons.ui.translatedName import network.novak.fenix.components.PagedAddonsManagerAdapter @@ -37,6 +36,7 @@ import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.theme.ThemeManager +import java.util.Locale import java.util.concurrent.CancellationException /** @@ -50,12 +50,76 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) */ private var isInstallationInProgress = false private var adapter: PagedAddonsManagerAdapter? = null + private var addons: List? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + setHasOptionsMenu(true) + return super.onCreateView(inflater, container, savedInstanceState) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) bindRecyclerView(view) } + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.addons_menu, menu) + val searchItem = menu.findItem(R.id.search) + val searchView: SearchView = searchItem.actionView as SearchView + searchView.imeOptions = EditorInfo.IME_ACTION_DONE + searchView.queryHint = getString(R.string.addons_search_hint) + + searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + override fun onQueryTextSubmit(query: String): Boolean { + return searchAddons(query.trim()) + } + + override fun onQueryTextChange(newText: String): Boolean { + return searchAddons(newText.trim()) + } + }) + } + + private fun searchAddons(addonNameSubStr: String): Boolean { + if (adapter == null) { + return false + } + + val searchedAddons = arrayListOf() + + addons?.forEach { addon -> + val names = addon.translatableName + names["en-US"]?.let { name -> + if (name.toLowerCase(Locale.ENGLISH).contains(addonNameSubStr.toLowerCase(Locale.ENGLISH))) { + searchedAddons.add(addon) + } + } + } + updateUI(searchedAddons) + + return true + } + + private fun updateUI(searchedAddons: List) { + adapter?.updateAddons(searchedAddons) + + if (searchedAddons.isEmpty()) { + view?.let { view -> + view.add_ons_empty_message.visibility = View.VISIBLE + view.add_ons_list.visibility = View.GONE + } + } else { + view?.let { view -> + view.add_ons_empty_message.visibility = View.GONE + view.add_ons_list.visibility = View.VISIBLE + } + } + } + override fun onResume() { super.onResume() showToolbar(getString(R.string.preferences_addons)) @@ -85,14 +149,14 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) val shouldRefresh = adapter != null lifecycleScope.launch(IO) { try { - val addons = requireContext().components.addonManager.getAddons() + addons = requireContext().components.addonManager.getAddons() lifecycleScope.launch(Dispatchers.Main) { runIfFragmentIsAttached { if (!shouldRefresh) { adapter = PagedAddonsManagerAdapter( requireContext().components.addonCollectionProvider, managementView, - addons, + addons!!, style = createAddonStyle(requireContext()) ) } @@ -102,7 +166,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) recyclerView.adapter = adapter if (shouldRefresh) { - adapter?.updateAddons(addons) + adapter?.updateAddons(addons!!) } } } diff --git a/app/src/main/res/menu/addons_menu.xml b/app/src/main/res/menu/addons_menu.xml new file mode 100644 index 000000000..81cf966cd --- /dev/null +++ b/app/src/main/res/menu/addons_menu.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e8617f459..732dacecd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -324,6 +324,8 @@ External download manager Add-ons + + Search add-ons Notifications