diff options
| author | David Göransson <david.goransson@mullvad.net> | 2025-09-02 11:25:10 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson@mullvad.net> | 2025-09-02 11:25:10 +0200 |
| commit | 51621e6faf71b83937b115b1b281eb9aa9816679 (patch) | |
| tree | 8504f0c90c0b23c7bb591056bfd51e2ef7ee5186 /android | |
| parent | eb6671a1d7801f8e10411fbd022679066249ed39 (diff) | |
| parent | aa0b4882bec6a3bd87228b5e538eeb37ead9af7a (diff) | |
| download | mullvadvpn-51621e6faf71b83937b115b1b281eb9aa9816679.tar.xz mullvadvpn-51621e6faf71b83937b115b1b281eb9aa9816679.zip | |
Merge branch 'rework-map-lifecycle'
Diffstat (limited to 'android')
5 files changed, 85 insertions, 31 deletions
diff --git a/android/gradle/verification-metadata.keys.xml b/android/gradle/verification-metadata.keys.xml index 81b1e8649f..c26fed8ba7 100644 --- a/android/gradle/verification-metadata.keys.xml +++ b/android/gradle/verification-metadata.keys.xml @@ -251,6 +251,9 @@ </artifact> </component> <component group="androidx.activity" name="activity-compose" version="1.7.0"> + <artifact name="activity-compose-1.7.0.aar"> + <sha256 value="caa72885d1ce7979c1d6c59a8b255c6097b770780d4d4da95d56979a348646cd" origin="Generated by Gradle" reason="Artifact is not signed"/> + </artifact> <artifact name="activity-compose-1.7.0.module"> <sha256 value="f7a29bcba338575dcf89a553cff9cfad3f140340eaf2b56fd0193244da602c0a" origin="Generated by Gradle" reason="Artifact is not signed"/> </artifact> @@ -350,6 +353,11 @@ <sha256 value="2bfc54475c047131913361f56d0f7f019c6e5bee53eeb0eb7d94a7c499a05227" origin="Generated by Gradle" reason="Artifact is not signed"/> </artifact> </component> + <component group="androidx.compose.animation" name="animation-core" version="1.0.0"> + <artifact name="animation-core-1.0.0.module"> + <sha256 value="2e3502f0deaf56b098b0412075fcc3e7c2d85b95ae9bf4230ec92c2a9008f842" origin="Generated by Gradle" reason="Artifact is not signed"/> + </artifact> + </component> <component group="androidx.compose.animation" name="animation-core" version="1.2.1"> <artifact name="animation-core-1.2.1.module"> <sha256 value="9083ac53ad162f4167ecfb895469943504f4cd6a624e612936a5209144c5b6bf" origin="Generated by Gradle" reason="Artifact is not signed"/> diff --git a/android/gradle/verification-metadata.xml b/android/gradle/verification-metadata.xml index 052a7dbabb..2a76827fe1 100644 --- a/android/gradle/verification-metadata.xml +++ b/android/gradle/verification-metadata.xml @@ -92,6 +92,9 @@ </artifact> </component> <component group="androidx.activity" name="activity-compose" version="1.7.0"> + <artifact name="activity-compose-1.7.0.aar"> + <sha256 value="caa72885d1ce7979c1d6c59a8b255c6097b770780d4d4da95d56979a348646cd" origin="Generated by Gradle"/> + </artifact> <artifact name="activity-compose-1.7.0.module"> <sha256 value="f7a29bcba338575dcf89a553cff9cfad3f140340eaf2b56fd0193244da602c0a" origin="Generated by Gradle"/> </artifact> @@ -431,6 +434,11 @@ <sha256 value="788eeac00159aaedd97f685067cf2c87cbf114c21746732653970e3055231322" origin="Generated by Gradle"/> </artifact> </component> + <component group="androidx.compose.animation" name="animation-core" version="1.0.0"> + <artifact name="animation-core-1.0.0.module"> + <sha256 value="2e3502f0deaf56b098b0412075fcc3e7c2d85b95ae9bf4230ec92c2a9008f842" origin="Generated by Gradle"/> + </artifact> + </component> <component group="androidx.compose.animation" name="animation-core" version="1.2.1"> <artifact name="animation-core-1.2.1.module"> <sha256 value="9083ac53ad162f4167ecfb895469943504f4cd6a624e612936a5209144c5b6bf" origin="Generated by Gradle"/> diff --git a/android/lib/map/build.gradle.kts b/android/lib/map/build.gradle.kts index 347adb4d31..bc43c56bce 100644 --- a/android/lib/map/build.gradle.kts +++ b/android/lib/map/build.gradle.kts @@ -43,5 +43,8 @@ dependencies { implementation(libs.androidx.lifecycle.runtime) implementation(libs.compose.ui) implementation(libs.compose.foundation) + // UI tooling + implementation(libs.compose.ui.tooling.preview) + debugImplementation(libs.compose.ui.tooling) implementation(libs.kermit) } diff --git a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt index 05b8d59701..2e7627c962 100644 --- a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt +++ b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt @@ -1,12 +1,15 @@ package net.mullvad.mullvadvpn.lib.map +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.viewinterop.AndroidView -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.compose.LocalLifecycleOwner import net.mullvad.mullvadvpn.lib.map.data.CameraPosition import net.mullvad.mullvadvpn.lib.map.data.GlobeColors @@ -14,6 +17,40 @@ import net.mullvad.mullvadvpn.lib.map.data.MapViewState import net.mullvad.mullvadvpn.lib.map.data.Marker import net.mullvad.mullvadvpn.lib.map.internal.MapGLSurfaceView import net.mullvad.mullvadvpn.lib.model.LatLong +import net.mullvad.mullvadvpn.lib.model.Latitude +import net.mullvad.mullvadvpn.lib.model.Longitude + +@Preview +@Composable +fun MapPreview() { + val infinite = rememberInfiniteTransition() + val spin = + infinite.animateFloat( + 0f, + 360f, + infiniteRepeatable(animation = tween(30000, easing = LinearEasing)), + ) + + Map( + modifier = Modifier, + cameraLocation = + CameraPosition( + LatLong(Latitude(0f), Longitude.fromFloat(spin.value)), + 2f, + verticalBias = 0.5f, + ), + markers = emptyList(), + globeColors = + GlobeColors( + // Green + landColor = Color(0xFF26513C), + // Blue + oceanColor = Color(0xFF161E50), + // Darker green + contourColor = Color(0xFF1B3626), + ), + ) +} @Composable fun Map( @@ -51,33 +88,15 @@ fun AnimatedMap( @Composable internal fun Map(modifier: Modifier = Modifier, mapViewState: MapViewState) { - var view: MapGLSurfaceView? = remember { null } - val lifeCycleState = LocalLifecycleOwner.current.lifecycle - DisposableEffect(key1 = lifeCycleState) { - val observer = LifecycleEventObserver { _, event -> - when (event) { - Lifecycle.Event.ON_RESUME -> { - view?.onResume() - } - Lifecycle.Event.ON_PAUSE -> { - view?.onPause() - } - else -> {} - } - } - lifeCycleState.addObserver(observer) - - onDispose { - lifeCycleState.removeObserver(observer) - view?.onPause() - view = null - } - } - - AndroidView(modifier = modifier, factory = { MapGLSurfaceView(it) }) { glSurfaceView -> - view = glSurfaceView - glSurfaceView.setData(mapViewState) - } + AndroidView( + modifier = modifier, + factory = { MapGLSurfaceView(it) }, + update = { glSurfaceView -> + glSurfaceView.lifecycle = lifeCycleState + glSurfaceView.setData(mapViewState) + }, + onRelease = { it.lifecycle = null }, + ) } diff --git a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt index 19dd085524..32b8cfe8e3 100644 --- a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt +++ b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt @@ -2,12 +2,28 @@ package net.mullvad.mullvadvpn.lib.map.internal import android.content.Context import android.opengl.GLSurfaceView +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver import net.mullvad.mullvadvpn.lib.map.BuildConfig import net.mullvad.mullvadvpn.lib.map.data.MapViewState internal class MapGLSurfaceView(context: Context) : GLSurfaceView(context) { private val renderer: MapGLRenderer + var lifecycle: Lifecycle? = null + set(value) { + field?.removeObserver(observer) + value?.addObserver(observer) + field = value + } + + private val observer = LifecycleEventObserver { source, event -> + when (event) { + Lifecycle.Event.ON_RESUME -> onResume() + Lifecycle.Event.ON_PAUSE -> onPause() + else -> {} + } + } init { // Create an OpenGL ES 2.0 context |
