mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-22 01:15:54 +03:00
Better error handling Rx call
This commit is contained in:
parent
baef9f5aa7
commit
6146925757
1 changed files with 30 additions and 52 deletions
|
@ -33,7 +33,9 @@ import org.matrix.android.sdk.api.MatrixPatterns
|
|||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.profile.ProfileService
|
||||
import org.matrix.android.sdk.api.session.user.model.User
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.rx.rx
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
@ -57,9 +59,6 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User
|
|||
|
||||
companion object : MvRxViewModelFactory<UserListViewModel, UserListViewState> {
|
||||
|
||||
private val USER_NOT_FOUND_MAP = emptyMap<String, Any>()
|
||||
private val USER_NOT_FOUND = User("")
|
||||
|
||||
override fun create(viewModelContext: ViewModelContext, state: UserListViewState): UserListViewModel? {
|
||||
val factory = when (viewModelContext) {
|
||||
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
|
||||
|
@ -124,65 +123,44 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User
|
|||
}
|
||||
|
||||
currentUserSearchDisposable?.dispose()
|
||||
|
||||
directoryUsersSearch
|
||||
.debounce(300, TimeUnit.MILLISECONDS)
|
||||
.switchMapSingle { search ->
|
||||
val stream = if (search.isBlank()) {
|
||||
Single.just(emptyList())
|
||||
} else if (MatrixPatterns.isUserId(search)) {
|
||||
// If it's a valid user id try to use Profile API
|
||||
// because directory only returns users that are in public rooms or share a room with you, where as
|
||||
// profile will work other federations
|
||||
session.rx().searchUsersDirectory(search, 50, state.excludedUserIds ?: emptySet())
|
||||
.map { users ->
|
||||
users.sortedBy { it.toMatrixItem().firstLetterOfDisplayName() }
|
||||
}
|
||||
.zipWith(
|
||||
session.rx().getProfileInfo(search)
|
||||
// ... not sure how to handle that properly (manage error case in map and return optional)
|
||||
.onErrorReturn { USER_NOT_FOUND_MAP }
|
||||
.map { json ->
|
||||
if (json === USER_NOT_FOUND_MAP) {
|
||||
USER_NOT_FOUND
|
||||
} else {
|
||||
User(
|
||||
userId = search,
|
||||
displayName = json[ProfileService.DISPLAY_NAME_KEY] as? String,
|
||||
avatarUrl = json[ProfileService.AVATAR_URL_KEY] as? String
|
||||
)
|
||||
}
|
||||
},
|
||||
{ t1, t2 ->
|
||||
if (t2 == USER_NOT_FOUND) {
|
||||
t1
|
||||
}
|
||||
// profile result might also be in search results, in this case keep search result
|
||||
else if (t1.indexOfFirst { it.userId == t2.userId } != -1) {
|
||||
t1
|
||||
} else {
|
||||
// put it first
|
||||
listOf(t2) + t1
|
||||
}
|
||||
}
|
||||
)
|
||||
.doOnSubscribe {
|
||||
currentUserSearchDisposable = it
|
||||
}
|
||||
.doOnDispose {
|
||||
currentUserSearchDisposable = null
|
||||
}
|
||||
Single.just(emptyList<User>())
|
||||
} else {
|
||||
session.rx()
|
||||
val searchObservable = session.rx()
|
||||
.searchUsersDirectory(search, 50, state.excludedUserIds ?: emptySet())
|
||||
.map { users ->
|
||||
users.sortedBy { it.toMatrixItem().firstLetterOfDisplayName() }
|
||||
}
|
||||
.doOnSubscribe {
|
||||
currentUserSearchDisposable = it
|
||||
}
|
||||
.doOnDispose {
|
||||
currentUserSearchDisposable = null
|
||||
// If it's a valid user id try to use Profile API
|
||||
// because directory only returns users that are in public rooms or share a room with you, where as
|
||||
// profile will work other federations
|
||||
if (!MatrixPatterns.isUserId(search)) {
|
||||
searchObservable
|
||||
} else {
|
||||
val profileObservable = session.rx().getProfileInfo(search)
|
||||
.map { json ->
|
||||
User(
|
||||
userId = search,
|
||||
displayName = json[ProfileService.DISPLAY_NAME_KEY] as? String,
|
||||
avatarUrl = json[ProfileService.AVATAR_URL_KEY] as? String
|
||||
).toOptional()
|
||||
}
|
||||
.onErrorReturn { Optional.empty() }
|
||||
|
||||
Single.zip(searchObservable, profileObservable, { searchResults, optionalProfile ->
|
||||
val profile = optionalProfile.getOrNull() ?: return@zip searchResults
|
||||
val searchContainsProfile = searchResults.indexOfFirst { it.userId == profile.userId } != -1
|
||||
if (searchContainsProfile) {
|
||||
searchResults
|
||||
} else {
|
||||
listOf(profile) + searchResults
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
stream.toAsync {
|
||||
copy(directoryUsers = it)
|
||||
|
|
Loading…
Reference in a new issue