diff --git a/CHANGES.md b/CHANGES.md index dc4c743bc4..fd141bcdfb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Other changes: Bugfix: - Fix issue on upload error in loop (#587) + - after login, the icon in the top left is a green 'A' for (all communities) rather than my avatar (#267) Translations: - diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/LiveDataObservable.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/LiveDataObservable.kt index a1943bbe1c..9eaeff762e 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/LiveDataObservable.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/LiveDataObservable.kt @@ -20,7 +20,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import io.reactivex.Observable import io.reactivex.android.MainThreadDisposable -import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers private class LiveDataObservable( diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt index f3fb06a45a..d8c254844b 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt @@ -24,6 +24,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.user.model.User +import im.vector.matrix.android.api.util.Optional import io.reactivex.Observable import io.reactivex.Single @@ -45,6 +46,10 @@ class RxSession(private val session: Session) { return session.livePushers().asObservable() } + fun liveUser(userId: String): Observable> { + return session.liveUser(userId).asObservable() + } + fun liveUsers(): Observable> { return session.liveUsers().asObservable() } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt index d3c58edd94..97b02fafea 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/UserService.kt @@ -21,6 +21,7 @@ import androidx.paging.PagedList import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.user.model.User import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.api.util.Optional /** * This interface defines methods to get users. It's implemented at the session level. @@ -47,9 +48,9 @@ interface UserService { /** * Observe a live user from a userId * @param userId the userId to look for. - * @return a Livedata of user with userId + * @return a LiveData of user with userId */ - fun liveUser(userId: String): LiveData + fun liveUser(userId: String): LiveData> /** * Observe a live list of users sorted alphabetically diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Optional.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Optional.kt new file mode 100644 index 0000000000..19fbe2cc88 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Optional.kt @@ -0,0 +1,42 @@ +/* + + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + */ +package im.vector.matrix.android.api.util + +data class Optional constructor(private val value: T?) { + + fun get(): T { + return value!! + } + + fun getOrNull(): T? { + return value + } + + fun getOrElse(fn: () -> T): T { + return value ?: fn() + } + + companion object { + fun from(value: T?): Optional { + return Optional(value) + } + } + +} + +fun T?.toOptional() = Optional(this) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt index 2925997347..40e79d7735 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/DefaultUserService.kt @@ -26,6 +26,8 @@ import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.session.user.model.User import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.api.util.Optional +import im.vector.matrix.android.api.util.toOptional import im.vector.matrix.android.internal.database.RealmLiveData import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.UserEntity @@ -66,7 +68,7 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona return userEntity.asDomain() } - override fun liveUser(userId: String): LiveData { + override fun liveUser(userId: String): LiveData> { val liveRealmData = RealmLiveData(monarchy.realmConfiguration) { realm -> UserEntity.where(realm, userId) } @@ -74,6 +76,7 @@ internal class DefaultUserService @Inject constructor(private val monarchy: Mona results .map { it.asDomain() } .firstOrNull() + .toOptional() } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt index ad39839321..e5f0c5b2d3 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDrawerFragment.kt @@ -51,7 +51,8 @@ class HomeDrawerFragment : VectorBaseFragment() { val groupListFragment = GroupListFragment.newInstance() replaceChildFragment(groupListFragment, R.id.homeDrawerGroupListContainer) } - session.liveUser(session.myUserId).observeK(this) { user -> + session.liveUser(session.myUserId).observeK(this) { optionalUser -> + val user = optionalUser?.getOrNull() if (user != null) { avatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView) homeDrawerUsernameView.text = user.displayName diff --git a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt index 0be22e411e..3f2a2e2958 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/group/GroupListViewModel.kt @@ -33,6 +33,8 @@ import im.vector.riotx.core.extensions.postLiveEvent import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.core.utils.LiveEvent +import io.reactivex.Observable +import io.reactivex.functions.BiFunction const val ALL_COMMUNITIES_GROUP_ID = "ALL_COMMUNITIES_GROUP_ID" @@ -91,20 +93,26 @@ class GroupListViewModel @AssistedInject constructor(@Assisted initialState: Gro } private fun observeGroupSummaries() { - session - .rx() - .liveGroupSummaries() - // Keep only joined groups. Group invitations will be managed later - .map { it.filter { groupSummary -> groupSummary.membership == Membership.JOIN } } - .map { - val myUser = session.getUser(session.myUserId) - val allCommunityGroup = GroupSummary( - groupId = ALL_COMMUNITIES_GROUP_ID, - membership = Membership.JOIN, - displayName = stringProvider.getString(R.string.group_all_communities), - avatarUrl = myUser?.avatarUrl ?: "") - listOf(allCommunityGroup) + it + Observable.combineLatest, List>( + session + .rx() + .liveUser(session.myUserId) + .map { optionalUser -> + GroupSummary( + groupId = ALL_COMMUNITIES_GROUP_ID, + membership = Membership.JOIN, + displayName = stringProvider.getString(R.string.group_all_communities), + avatarUrl = optionalUser.getOrNull()?.avatarUrl ?: "") + }, + session + .rx() + .liveGroupSummaries() + // Keep only joined groups. Group invitations will be managed later + .map { it.filter { groupSummary -> groupSummary.membership == Membership.JOIN } }, + BiFunction { allCommunityGroup, communityGroups -> + listOf(allCommunityGroup) + communityGroups } + ) .execute { async -> val newSelectedGroup = selectedGroup ?: async()?.firstOrNull() copy(asyncGroups = async, selectedGroup = newSelectedGroup)