From 7f545079ad4ebb187bfdaa2b042ffe4614017883 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 11 May 2026 14:49:53 +0200 Subject: [PATCH] Prevent user from starting LLS in thread --- .../impl/share/ShareLocationPresenter.kt | 7 ++- .../impl/share/ShareLocationPresenterTest.kt | 44 ++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt index b56f9c7cb3..6c0d2120bc 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenter.kt @@ -171,7 +171,7 @@ class ShareLocationPresenter( dialogState = dialogState, trackUserLocation = trackUserPosition, hasLocationPermission = permissionsState.isAnyGranted, - canShareLiveLocation = isLiveLocationSharingEnabled, + canShareLiveLocation = isLiveLocationSharingEnabled && timelineMode.canShareLiveLocation(), appName = appName, startLiveLocationAction = startLiveLocationAction.value, eventSink = ::handleEvent, @@ -210,4 +210,9 @@ class ShareLocationPresenter( } } +private fun Timeline.Mode.canShareLiveLocation() = when (this) { + is Timeline.Mode.Thread -> false + else -> true +} + private fun generateBody(uri: String): String = "Location was shared at $uri" diff --git a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt index 855deba694..dff5f05ee9 100644 --- a/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt +++ b/features/location/impl/src/test/kotlin/io/element/android/features/location/impl/share/ShareLocationPresenterTest.kt @@ -29,6 +29,7 @@ import io.element.android.features.location.impl.live.LiveLocationStore import io.element.android.features.location.test.FakeActiveLiveLocationShareManager import io.element.android.features.messages.test.FakeMessageComposerContext import io.element.android.libraries.dateformatter.test.FakeDurationFormatter +import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId @@ -40,6 +41,7 @@ import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.A_THREAD_ID import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.core.aBuildMeta @@ -82,13 +84,14 @@ class ShareLocationPresenterTest { private fun TestScope.createShareLocationPresenter( joinedRoom: JoinedRoom = FakeJoinedRoom(), + timelineMode: Timeline.Mode = Timeline.Mode.Live, locationActions: FakeLocationActions = fakeLocationActions, liveLocationShareManager: FakeActiveLiveLocationShareManager = FakeActiveLiveLocationShareManager(), liveLocationStore: LiveLocationStore = createLiveLocationStore(sessionId = joinedRoom.sessionId), ): ShareLocationPresenter = ShareLocationPresenter( permissionsPresenterFactory = { fakePermissionsPresenter }, room = joinedRoom, - timelineMode = Timeline.Mode.Live, + timelineMode = timelineMode, analyticsService = fakeAnalyticsService, messageComposerContext = fakeMessageComposerContext, locationActions = locationActions, @@ -653,6 +656,45 @@ class ShareLocationPresenterTest { cancelAndIgnoreRemainingEvents() } } + + @Test + fun `canShareLiveLocation is false when the feature is disabled`() = runTest { + fakeFeatureFlagService.setFeatureEnabled(FeatureFlags.LiveLocationSharing, false) + val shareLocationPresenter = createShareLocationPresenter( + timelineMode = Timeline.Mode.Live, + ) + shareLocationPresenter.test { + skipItems(1) + val state = awaitItem() + assertThat(state.canShareLiveLocation).isFalse() + } + } + + @Test + fun `canShareLiveLocation is true when the feature is enabled`() = runTest { + fakeFeatureFlagService.setFeatureEnabled(FeatureFlags.LiveLocationSharing, true) + val shareLocationPresenter = createShareLocationPresenter( + timelineMode = Timeline.Mode.Live, + ) + shareLocationPresenter.test { + skipItems(1) + val state = awaitItem() + assertThat(state.canShareLiveLocation).isTrue() + } + } + + @Test + fun `canShareLiveLocation is false in thread timeline`() = runTest { + fakeFeatureFlagService.setFeatureEnabled(FeatureFlags.LiveLocationSharing, true) + val shareLocationPresenter = createShareLocationPresenter( + timelineMode = Timeline.Mode.Thread(A_THREAD_ID), + ) + shareLocationPresenter.test { + skipItems(1) + val state = awaitItem() + assertThat(state.canShareLiveLocation).isFalse() + } + } } private fun createLiveLocationStore(