From 9bf484cf1e8f3ab1379e5814248500b7d6818b21 Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoit.marty@gmail.com>
Date: Thu, 12 Sep 2019 16:38:45 +0200
Subject: [PATCH 1/4] Create a Failure to handle cancellation, and use it to
 ignore cancellation on room search

---
 .../java/im/vector/matrix/android/api/failure/Failure.kt    | 1 +
 .../im/vector/matrix/android/internal/network/Request.kt    | 2 ++
 .../riotx/features/roomdirectory/RoomDirectoryViewModel.kt  | 6 ++++++
 3 files changed, 9 insertions(+)

diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt
index 152adb0665..26170a288f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/Failure.kt
@@ -31,6 +31,7 @@ import java.io.IOException
  */
 sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) {
     data class Unknown(val throwable: Throwable? = null) : Failure(throwable)
+    data class Cancelled(val throwable: Throwable? = null) : Failure(throwable)
     data class NetworkConnection(val ioException: IOException? = null) : Failure(ioException)
     data class ServerError(val error: MatrixError, val httpCode: Int) : Failure(RuntimeException(error.toString()))
     // When server send an error, but it cannot be interpreted as a MatrixError
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt
index 4be2d4a27f..ede9e823bf 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt
@@ -22,6 +22,7 @@ import im.vector.matrix.android.api.failure.ConsentNotGivenError
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.failure.MatrixError
 import im.vector.matrix.android.internal.di.MoshiProvider
+import kotlinx.coroutines.CancellationException
 import okhttp3.ResponseBody
 import org.greenrobot.eventbus.EventBus
 import retrofit2.Call
@@ -49,6 +50,7 @@ internal class Request<DATA> {
                 is IOException              -> Failure.NetworkConnection(exception)
                 is Failure.ServerError,
                 is Failure.OtherServerError -> exception
+                is CancellationException    -> Failure.Cancelled(exception)
                 else                        -> Failure.Unknown(exception)
             }
         }
diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt
index bf36fb265d..89af5330ca 100644
--- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt
@@ -22,6 +22,7 @@ import com.airbnb.mvrx.*
 import com.squareup.inject.assisted.Assisted
 import com.squareup.inject.assisted.AssistedInject
 import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.room.model.Membership
 import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
@@ -176,6 +177,11 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState:
                     }
 
                     override fun onFailure(failure: Throwable) {
+                        if (failure is Failure.Cancelled) {
+                            // Ignore, another request should be already started
+                            return
+                        }
+
                         currentTask = null
 
                         setState {

From 3739e50d466d8e38ced20b64d2dfb8385ee4e253 Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoit@matrix.org>
Date: Thu, 12 Sep 2019 16:59:00 +0200
Subject: [PATCH 2/4] Better error message for timeout

---
 .../java/im/vector/riotx/core/error/ErrorFormatter.kt    | 9 ++++++++-
 vector/src/main/res/values/strings_riotX.xml             | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt
index bb7892e109..8987b0260a 100644
--- a/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt
+++ b/vector/src/main/java/im/vector/riotx/core/error/ErrorFormatter.kt
@@ -20,6 +20,7 @@ import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.failure.MatrixError
 import im.vector.riotx.R
 import im.vector.riotx.core.resources.StringProvider
+import java.net.SocketTimeoutException
 import javax.inject.Inject
 
 class ErrorFormatter @Inject constructor(val stringProvider: StringProvider) {
@@ -33,7 +34,13 @@ class ErrorFormatter @Inject constructor(val stringProvider: StringProvider) {
     fun toHumanReadable(throwable: Throwable?): String {
         return when (throwable) {
             null                         -> null
-            is Failure.NetworkConnection -> stringProvider.getString(R.string.error_no_network)
+            is Failure.NetworkConnection -> {
+                if (throwable.ioException is SocketTimeoutException) {
+                    stringProvider.getString(R.string.error_network_timeout)
+                } else {
+                    stringProvider.getString(R.string.error_no_network)
+                }
+            }
             is Failure.ServerError       -> {
                 if (throwable.error.code == MatrixError.M_CONSENT_NOT_GIVEN) {
                     // Special case for terms and conditions
diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml
index e02de69806..f2ac7817be 100644
--- a/vector/src/main/res/values/strings_riotX.xml
+++ b/vector/src/main/res/values/strings_riotX.xml
@@ -11,5 +11,6 @@
     <!-- This one is already defined in Riot, but not yet synced-->
     <string name="error_user_already_logged_in">It looks like you’re trying to connect to another homeserver. Do you want to sign out?</string>
 
+    <string name="error_network_timeout">Looks like the server is taking to long to respond, this can be caused by either poor connectivity or an error with our servers. Please try again in a while.</string>
 
 </resources>
\ No newline at end of file

From b3d649a4d9a63ca3e08b4fde520f13599bca6293 Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoit.marty@gmail.com>
Date: Tue, 17 Sep 2019 14:55:19 +0200
Subject: [PATCH 3/4] Fix characters erased from the Search field when the
 result are coming (#545)

---
 CHANGES.md                                            |  2 +-
 .../features/roomdirectory/PublicRoomsFragment.kt     | 11 ++++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index f8561a0fe4..de38ef4cef 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,7 +11,7 @@ Other changes:
  -
 
 Bugfix:
- -
+ - Fix characters erased from the Search field when the result are coming (#545)
 
 Translations:
  -
diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt
index 32cd673273..2dfef5536f 100644
--- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/PublicRoomsFragment.kt
@@ -143,10 +143,15 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback
         viewModel.loadMore()
     }
 
+    var initialValueSet = false
+
     override fun invalidate() = withState(viewModel) { state ->
-        if (publicRoomsFilter.query.toString() != state.currentFilter) {
-            // For initial filter
-            publicRoomsFilter.setQuery(state.currentFilter, false)
+        if (!initialValueSet) {
+            initialValueSet = true
+            if (publicRoomsFilter.query.toString() != state.currentFilter) {
+                // For initial filter
+                publicRoomsFilter.setQuery(state.currentFilter, false)
+            }
         }
 
         // Populate list with Epoxy

From ed93f4a6c16ab5c173738e94b0b682b2ef50221a Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoit@matrix.org>
Date: Thu, 12 Sep 2019 17:17:54 +0200
Subject: [PATCH 4/4] Cancel any request properly

---
 .../riotx/features/roomdirectory/RoomDirectoryViewModel.kt   | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt
index 89af5330ca..456ea23834 100644
--- a/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/roomdirectory/RoomDirectoryViewModel.kt
@@ -226,4 +226,9 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState:
         })
     }
 
+    override fun onCleared() {
+        super.onCleared()
+
+        currentTask?.cancel()
+    }
 }
\ No newline at end of file