Let element enterprise be able to configure id for mapTiler. (#4446)
* Let element enterprise configure the ids for maptiler service. * Disable location sharing and location viewer is the service is not available. * Fix compilation issue on connected test * Do not allow to reload the map if the mapId is not available. * Update screenshots * Rename file. * Better to inject a string provider here, so we can unit test DefaultLocationService. --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
parent
60f1c9500f
commit
2fd1c21df0
24 changed files with 198 additions and 36 deletions
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector 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.features.location.api
|
||||
|
||||
interface LocationService {
|
||||
fun isServiceAvailable(): Boolean
|
||||
}
|
||||
|
|
@ -103,6 +103,7 @@ fun StaticMapView(
|
|||
} else {
|
||||
StaticMapPlaceholder(
|
||||
showProgress = collectedState.value.isLoading(),
|
||||
canReload = builder.isServiceAvailable(),
|
||||
contentDescription = contentDescription,
|
||||
width = maxWidth,
|
||||
height = maxHeight,
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ internal class MapTilerStaticMapUrlBuilder(
|
|||
// to keep the perceived content size constant at the expense of sharpness.
|
||||
return "$MAPTILER_BASE_URL/$mapId/static/$lon,$lat,$finalZoom/${finalWidth}x${finalHeight}$scale.webp?key=$apiKey&attribution=bottomleft"
|
||||
}
|
||||
|
||||
override fun isServiceAvailable() = apiKey.isNotEmpty()
|
||||
}
|
||||
|
||||
private fun coerceWidthAndHeight(width: Int, height: Int, is2x: Boolean): Pair<Int, Int> {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ package io.element.android.features.location.api.internal
|
|||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -18,7 +20,6 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
|
|
@ -28,12 +29,12 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
|||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.BooleanProvider
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
internal fun StaticMapPlaceholder(
|
||||
showProgress: Boolean,
|
||||
canReload: Boolean,
|
||||
contentDescription: String?,
|
||||
width: Dp,
|
||||
height: Dp,
|
||||
|
|
@ -54,7 +55,7 @@ internal fun StaticMapPlaceholder(
|
|||
)
|
||||
if (showProgress) {
|
||||
CircularProgressIndicator()
|
||||
} else {
|
||||
} else if (canReload) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
|
|
@ -70,14 +71,24 @@ internal fun StaticMapPlaceholder(
|
|||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun StaticMapPlaceholderPreview(
|
||||
@PreviewParameter(BooleanProvider::class) values: Boolean
|
||||
) = ElementPreview {
|
||||
StaticMapPlaceholder(
|
||||
showProgress = values,
|
||||
contentDescription = null,
|
||||
width = 400.dp,
|
||||
height = 400.dp,
|
||||
onLoadMapClick = {},
|
||||
)
|
||||
internal fun StaticMapPlaceholderPreview() = ElementPreview {
|
||||
Column(
|
||||
modifier = Modifier.padding(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
listOf(
|
||||
true to false,
|
||||
false to true,
|
||||
false to false,
|
||||
).forEach { (showProgress, canReload) ->
|
||||
StaticMapPlaceholder(
|
||||
showProgress = showProgress,
|
||||
canReload = canReload,
|
||||
contentDescription = null,
|
||||
width = 400.dp,
|
||||
height = 200.dp,
|
||||
onLoadMapClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ interface StaticMapUrlBuilder {
|
|||
height: Int,
|
||||
density: Float,
|
||||
): String
|
||||
|
||||
fun isServiceAvailable(): Boolean
|
||||
}
|
||||
|
||||
fun StaticMapUrlBuilder(context: Context): StaticMapUrlBuilder = MapTilerStaticMapUrlBuilder(context = context)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,21 @@ class MapTilerStaticMapUrlBuilderTest {
|
|||
darkMapId = "aDarkMapId",
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `isServiceAvailable returns true if api key is not empty`() {
|
||||
assertThat(builder.isServiceAvailable()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isServiceAvailable returns false if api key is empty`() {
|
||||
val builderWithoutKey = MapTilerStaticMapUrlBuilder(
|
||||
apiKey = "",
|
||||
lightMapId = "aLightMapId",
|
||||
darkMapId = "aDarkMapId",
|
||||
)
|
||||
assertThat(builderWithoutKey.isServiceAvailable()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `static map 1x density`() {
|
||||
assertThat(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue