Live location : start collecting live location

This commit is contained in:
ganfra 2026-04-03 18:21:37 +02:00
parent a7e254cc84
commit 4e0165458a
8 changed files with 295 additions and 49 deletions

View file

@ -43,7 +43,7 @@ import io.element.android.libraries.matrix.impl.mapper.map
import io.element.android.libraries.matrix.impl.room.history.map
import io.element.android.libraries.matrix.impl.room.join.map
import io.element.android.libraries.matrix.impl.room.knock.RustKnockRequest
import io.element.android.libraries.matrix.impl.room.location.map
import io.element.android.libraries.matrix.impl.room.location.liveLocationSharesFlow
import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher
import io.element.android.libraries.matrix.impl.roomdirectory.map
import io.element.android.libraries.matrix.impl.timeline.RustTimeline
@ -68,7 +68,6 @@ import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.DateDividerMode
import org.matrix.rustcomponents.sdk.IdentityStatusChangeListener
import org.matrix.rustcomponents.sdk.KnockRequestsListener
import org.matrix.rustcomponents.sdk.LiveLocationShareListener
import org.matrix.rustcomponents.sdk.RoomMessageEventMessageType
import org.matrix.rustcomponents.sdk.RoomSendQueueUpdate
import org.matrix.rustcomponents.sdk.SendQueueListener
@ -504,13 +503,7 @@ class JoinedRustRoom(
}
override fun subscribeToLiveLocationShares(): Flow<List<LiveLocationShare>> {
return mxCallbackFlow {
innerRoom.subscribeToLiveLocationShares(object : LiveLocationShareListener {
override fun call(liveLocationShares: List<org.matrix.rustcomponents.sdk.LiveLocationShare>) {
trySend(liveLocationShares.map { it.map() })
}
})
}
return innerRoom.liveLocationSharesFlow()
}
override suspend fun startLiveLocationShare(durationMillis: Long): Result<Unit> = withContext(roomDispatcher) {

View file

@ -1,21 +0,0 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.room.location
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.location.LiveLocationShare
import org.matrix.rustcomponents.sdk.LiveLocationShare as RustLiveLocationShare
fun RustLiveLocationShare.map(): LiveLocationShare {
return LiveLocationShare(
userId = UserId(userId),
lastGeoUri = lastLocation.location.geoUri,
lastTimestamp = lastLocation.ts.toLong(),
isLive = isLive,
)
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.room.location
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.location.LiveLocationShare
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import org.matrix.rustcomponents.sdk.LiveLocationShare as RustLiveLocationShare
import org.matrix.rustcomponents.sdk.LiveLocationShareListener
import org.matrix.rustcomponents.sdk.LiveLocationShareUpdate
import org.matrix.rustcomponents.sdk.RoomInterface
fun RoomInterface.liveLocationSharesFlow(): Flow<List<LiveLocationShare>> {
fun MutableList<LiveLocationShare>.applyUpdate(update: LiveLocationShareUpdate) {
when (update) {
is LiveLocationShareUpdate.Append -> addAll(update.values.map { it.into() })
is LiveLocationShareUpdate.Clear -> clear()
is LiveLocationShareUpdate.Insert -> add(update.index.toInt(), update.value.into())
is LiveLocationShareUpdate.PopBack -> if (isNotEmpty()) removeAt(lastIndex)
is LiveLocationShareUpdate.PopFront -> if (isNotEmpty()) removeAt(0)
is LiveLocationShareUpdate.PushBack -> add(update.value.into())
is LiveLocationShareUpdate.PushFront -> add(0, update.value.into())
is LiveLocationShareUpdate.Remove -> removeAt(update.index.toInt())
is LiveLocationShareUpdate.Reset -> {
clear()
addAll(update.values.map { it.into() })
}
is LiveLocationShareUpdate.Set -> set(update.index.toInt(), update.value.into())
is LiveLocationShareUpdate.Truncate -> subList(update.length.toInt(), size).clear()
}
}
return mxCallbackFlow {
val shares: MutableList<LiveLocationShare> = ArrayList()
subscribeToLiveLocationShares(object : LiveLocationShareListener {
override fun onUpdate(updates: List<LiveLocationShareUpdate>) {
for (update in updates) {
shares.applyUpdate(update)
}
trySend(shares)
}
})
}.buffer(Channel.UNLIMITED)
}
private fun RustLiveLocationShare.into(): LiveLocationShare {
return LiveLocationShare(
userId = UserId(userId),
lastGeoUri = lastLocation?.location?.geoUri.orEmpty(),
lastTimestamp = lastLocation?.ts?.toLong() ?: 0,
)
}