From 81b90df90983da0f8e71ed328f6b9fd5d98c64e6 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 16 May 2022 18:01:54 +0200 Subject: [PATCH] Observe the current live location shares in a room --- .../map/GetListOfUserLiveLocationUseCase.kt | 49 ++++------------ .../live/map/LocationLiveMapViewModel.kt | 2 +- .../map/UserLiveLocationViewStateMapper.kt | 56 +++++++++++++++++++ 3 files changed, 69 insertions(+), 38 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/UserLiveLocationViewStateMapper.kt diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCase.kt b/vector/src/main/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCase.kt index 2505ba11a4..ca4f6859ee 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/GetListOfUserLiveLocationUseCase.kt @@ -16,51 +16,26 @@ package im.vector.app.features.location.live.map -import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider -import im.vector.app.features.location.LocationData -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.channels.trySendBlocking +import androidx.lifecycle.asFlow import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.mapLatest import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.getRoom import javax.inject.Inject class GetListOfUserLiveLocationUseCase @Inject constructor( private val session: Session, - private val locationPinProvider: LocationPinProvider + private val userLiveLocationViewStateMapper: UserLiveLocationViewStateMapper, ) { // TODO add unit tests - fun execute(): Flow> { - // TODO get room and call SDK to get the correct flow of locations - - return callbackFlow { - val myUserId = session.myUserId - - locationPinProvider.create(myUserId) { pinDrawable -> - val user1 = UserLiveLocationViewState( - userId = session.myUserId, - pinDrawable = pinDrawable, - locationData = LocationData( - latitude = 48.863447, - longitude = 2.328608, - uncertainty = null - ) - ) - val user2 = UserLiveLocationViewState( - userId = session.myUserId, - pinDrawable = pinDrawable, - locationData = LocationData( - latitude = 48.843816, - longitude = 2.359235, - uncertainty = null - ) - ) - val userLocations = listOf(user1, user2) - trySendBlocking(userLocations) - channel.close() - } - awaitClose() - } + fun execute(roomId: String): Flow> { + return session.getRoom(roomId) + ?.locationSharingService() + ?.getRunningLiveLocationShareSummaries() + ?.asFlow() + ?.mapLatest { it.mapNotNull { summary -> userLiveLocationViewStateMapper.map(summary) } } + ?: emptyFlow() } } diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewModel.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewModel.kt index bd834b4672..73608d35bc 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewModel.kt @@ -40,7 +40,7 @@ class LocationLiveMapViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { - getListOfUserLiveLocationUseCase.execute() + getListOfUserLiveLocationUseCase.execute(initialState.roomId) .onEach { setState { copy(userLocations = it) } } .launchIn(viewModelScope) } diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/UserLiveLocationViewStateMapper.kt b/vector/src/main/java/im/vector/app/features/location/live/map/UserLiveLocationViewStateMapper.kt new file mode 100644 index 0000000000..fb5eb24769 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/map/UserLiveLocationViewStateMapper.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 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.app.features.location.live.map + +import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider +import im.vector.app.features.location.toLocationData +import kotlinx.coroutines.suspendCancellableCoroutine +import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary +import javax.inject.Inject + +// TODO add unit tests +class UserLiveLocationViewStateMapper @Inject constructor( + private val locationPinProvider: LocationPinProvider, +) { + + suspend fun map(liveLocationShareAggregatedSummary: LiveLocationShareAggregatedSummary) = + suspendCancellableCoroutine { continuation -> + val userId = liveLocationShareAggregatedSummary.userId + val locationData = liveLocationShareAggregatedSummary.lastLocationDataContent + ?.getBestLocationInfo() + ?.geoUri + .toLocationData() + + when { + userId.isNullOrEmpty() || locationData == null -> continuation.resume(null) { + // do nothing on cancellation + } + else -> { + locationPinProvider.create(userId) { pinDrawable -> + val viewState = UserLiveLocationViewState( + userId = userId, + pinDrawable = pinDrawable, + locationData = locationData + ) + continuation.resume(viewState) { + // do nothing on cancellation + } + } + } + } + } +}