Explorar o código

Unified search: Show error messages, loading anim, click animations. Implement refresh.

Signed-off-by: Álvaro Brey Vilas <alvaro.brey@nextcloud.com>
Álvaro Brey Vilas %!s(int64=3) %!d(string=hai) anos
pai
achega
fac2958788

+ 27 - 11
src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt

@@ -36,6 +36,7 @@ import com.nextcloud.client.network.ClientFactory
 import com.owncloud.android.databinding.ListFragmentBinding
 import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.lib.common.SearchResultEntry
+import com.owncloud.android.lib.common.utils.Log_OC
 import com.owncloud.android.ui.activity.FileDisplayActivity
 import com.owncloud.android.ui.adapter.UnifiedSearchListAdapter
 import com.owncloud.android.ui.asynctasks.GetRemoteFileTask
@@ -43,6 +44,7 @@ import com.owncloud.android.ui.interfaces.UnifiedSearchListInterface
 import com.owncloud.android.ui.unifiedsearch.ProviderID
 import com.owncloud.android.ui.unifiedsearch.UnifiedSearchSection
 import com.owncloud.android.ui.unifiedsearch.UnifiedSearchViewModel
+import com.owncloud.android.utils.DisplayUtils
 import javax.inject.Inject
 
 /**
@@ -73,23 +75,36 @@ class UnifiedSearchFragment : Fragment(), Injectable, UnifiedSearchListInterface
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         vm = ViewModelProvider(this, vmFactory).get(UnifiedSearchViewModel::class.java)
-        vm.searchResults.observe(this, this::onSearchResultChanged)
+        setUpViewModel()
 
-        val query = savedInstanceState?.getString(ARG_QUERY).orEmpty()
-        if (query.isNotBlank()) {
-            vm.startLoading(query)
-            return
+        val query = savedInstanceState?.getString(ARG_QUERY) ?: arguments?.getString(ARG_QUERY)
+        if (!query.isNullOrEmpty()) {
+            vm.setQuery(query)
+            vm.initialQuery()
         }
+    }
 
-        val queryArgument = arguments?.getString(ARG_QUERY).orEmpty()
-        if (queryArgument.isNotBlank()) {
-            vm.startLoading(queryArgument)
+    private fun setUpViewModel() {
+        vm.searchResults.observe(this, this::onSearchResultChanged)
+        vm.isLoading.observe(this) { loading ->
+            binding.swipeContainingList.isRefreshing = loading
+        }
+        vm.error.observe(this) { error ->
+            if (!error.isNullOrEmpty()) {
+                DisplayUtils.showSnackMessage(binding.root, error)
+            }
+        }
+    }
+
+    private fun setUpBinding() {
+        binding.swipeContainingList.setOnRefreshListener {
+            vm.refresh()
         }
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
         _binding = ListFragmentBinding.inflate(inflater, container, false)
-
+        setUpBinding()
         return binding.root
     }
 
@@ -110,7 +125,6 @@ class UnifiedSearchFragment : Fragment(), Injectable, UnifiedSearchListInterface
         binding.listRoot.adapter = adapter
     }
 
-
     override fun onDestroyView() {
         super.onDestroyView()
         _binding = null
@@ -148,6 +162,7 @@ class UnifiedSearchFragment : Fragment(), Injectable, UnifiedSearchListInterface
 
     @VisibleForTesting
     fun onSearchResultChanged(result: List<UnifiedSearchSection>) {
+        Log_OC.d(TAG, "result")
         binding.emptyList.emptyListView.visibility = View.GONE
 
         adapter.setData(result)
@@ -156,10 +171,11 @@ class UnifiedSearchFragment : Fragment(), Injectable, UnifiedSearchListInterface
     @VisibleForTesting
     fun setViewModel(testViewModel: UnifiedSearchViewModel) {
         vm = testViewModel
-        vm.searchResults.observe(this, this::onSearchResultChanged)
+        setUpViewModel()
     }
 
     companion object {
+        private const val TAG = "UnifiedSearchFragment"
         const val ARG_QUERY = "ARG_QUERY"
 
         /**

+ 11 - 4
src/main/java/com/owncloud/android/ui/unifiedsearch/UnifiedSearchViewModel.kt

@@ -97,19 +97,23 @@ class UnifiedSearchViewModel() : ViewModel() {
     }
 
     open fun refresh() {
+        metaResults = mutableMapOf()
         searchResults.value = mutableListOf()
-        startLoading(query.value.orEmpty())
+        initialQuery()
     }
 
     open fun startLoading(query: String) {
         if (!loadingStarted) {
             loadingStarted = true
             this.query.value = query
-            queryAll()
+            initialQuery()
         }
     }
 
-    fun queryAll() {
+    /**
+     * Queries all available providers
+     */
+    fun initialQuery() {
         val queryTerm = query.value.orEmpty()
 
         if (isLoading.value != true && queryTerm.isNotBlank()) {
@@ -161,7 +165,6 @@ class UnifiedSearchViewModel() : ViewModel() {
 
     @Synchronized
     fun onSearchResult(result: UnifiedSearchResult) {
-        isLoading.value = false
 
         if (result.success) {
             val providerMeta = metaResults[result.provider] ?: UnifiedSearchMetadata()
@@ -220,4 +223,8 @@ class UnifiedSearchViewModel() : ViewModel() {
             error.value = "Error showing search result"
         }
     }
+
+    fun setQuery(query: String) {
+        this.query.value = query
+    }
 }

+ 4 - 6
src/main/res/layout/unified_search_footer.xml

@@ -25,20 +25,18 @@
     android:layout_width="match_parent"
     android:layout_height="@dimen/min_list_item_size"
     android:baselineAligned="false"
+    android:foreground="?android:attr/selectableItemBackground"
     android:orientation="horizontal">
 
-    <View
-        android:layout_width="@dimen/standard_list_item_size"
-        android:layout_height="@dimen/standard_list_item_size"
-        android:layout_marginStart="@dimen/zero"
-        android:layout_marginEnd="@dimen/standard_quarter_padding" />
 
     <TextView
         android:layout_width="0dp"
-        android:layout_height="match_parent"
+        android:layout_height="@dimen/standard_list_item_size"
+        android:layout_marginStart="@dimen/standard_list_item_size"
         android:layout_weight="1"
         android:gravity="center_vertical"
         android:orientation="vertical"
+        android:paddingStart="@dimen/standard_quarter_padding"
         android:text="@string/load_more_results"
         android:textColor="@color/secondary_text_color"
         tools:text="Load more results">

+ 1 - 0
src/main/res/layout/unified_search_item.xml

@@ -26,6 +26,7 @@
     android:layout_width="match_parent"
     android:layout_height="@dimen/standard_list_item_size"
     android:baselineAligned="false"
+    android:foreground="?android:attr/selectableItemBackground"
     android:orientation="horizontal">
 
     <androidx.constraintlayout.widget.ConstraintLayout