summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2025-07-15 10:31:30 +0200
committerDavid Göransson <david.goransson@mullvad.net>2025-07-17 11:17:09 +0200
commit00bba9cdbdfcb7719b1e89ede22d30896bd827df (patch)
tree7025723afdb1b7a853a063a64c9d056a721202b6
parent176f0a8569e6c0d99d0ff5b79d88a69ad1183880 (diff)
downloadmullvadvpn-00bba9cdbdfcb7719b1e89ede22d30896bd827df.tar.xz
mullvadvpn-00bba9cdbdfcb7719b1e89ede22d30896bd827df.zip
Fix focus on notification close
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt1
-rw-r--r--android/lib/tv/src/main/kotlin/net/mullvad/mullvadvpn/lib/tv/NotificationBannerTv.kt3
-rw-r--r--android/lib/ui/component/src/main/kotlin/net/mullvad/mullvadvpn/lib/ui/component/AnimatedNotificationBanner.kt21
4 files changed, 27 insertions, 2 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt
index 1605b83cdb..2279e47407 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import java.time.Duration
@@ -68,6 +69,7 @@ fun NotificationBanner(
modifier: Modifier = Modifier,
notification: InAppNotification?,
isPlayBuild: Boolean,
+ contentFocusRequester: FocusRequester = FocusRequester(),
openAppListing: () -> Unit,
onClickShowAccount: () -> Unit,
onClickShowChangelog: () -> Unit,
@@ -81,6 +83,7 @@ fun NotificationBanner(
notification = notification,
isPlayBuild = isPlayBuild,
openAppListing = openAppListing,
+ contentFocusRequester = contentFocusRequester,
onClickShowAccount = onClickShowAccount,
onClickShowChangelog = onClickShowChangelog,
onClickDismissChangelog = onClickDismissChangelog,
@@ -94,6 +97,7 @@ fun NotificationBanner(
notification = notification,
isPlayBuild = isPlayBuild,
openAppListing = openAppListing,
+ contentFocusRequester = contentFocusRequester,
onClickShowAccount = onClickShowAccount,
onClickShowChangelog = onClickShowChangelog,
onClickDismissChangelog = onClickDismissChangelog,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
index 82d6736c99..88a4c30922 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
@@ -450,6 +450,7 @@ private fun Content(
modifier = Modifier.align(Alignment.TopCenter),
notification = state.inAppNotification,
isPlayBuild = state.isPlayBuild,
+ contentFocusRequester = focusRequester,
openAppListing = onOpenAppListing,
onClickShowAccount = onManageAccountClick,
onClickShowChangelog = onChangelogClick,
diff --git a/android/lib/tv/src/main/kotlin/net/mullvad/mullvadvpn/lib/tv/NotificationBannerTv.kt b/android/lib/tv/src/main/kotlin/net/mullvad/mullvadvpn/lib/tv/NotificationBannerTv.kt
index 8868938a12..8208e5f6ec 100644
--- a/android/lib/tv/src/main/kotlin/net/mullvad/mullvadvpn/lib/tv/NotificationBannerTv.kt
+++ b/android/lib/tv/src/main/kotlin/net/mullvad/mullvadvpn/lib/tv/NotificationBannerTv.kt
@@ -6,6 +6,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.mullvad.mullvadvpn.lib.model.InAppNotification
@@ -36,6 +37,7 @@ fun NotificationBannerTv(
notification: InAppNotification?,
isPlayBuild: Boolean,
openAppListing: () -> Unit,
+ contentFocusRequester: FocusRequester = FocusRequester(),
onClickShowAccount: () -> Unit,
onClickShowChangelog: () -> Unit,
onClickDismissChangelog: () -> Unit,
@@ -58,6 +60,7 @@ fun NotificationBannerTv(
notification = notification,
isPlayBuild = isPlayBuild,
openAppListing = openAppListing,
+ contentFocusRequester = contentFocusRequester,
onClickShowAccount = onClickShowAccount,
onClickShowChangelog = onClickShowChangelog,
onClickDismissChangelog = onClickDismissChangelog,
diff --git a/android/lib/ui/component/src/main/kotlin/net/mullvad/mullvadvpn/lib/ui/component/AnimatedNotificationBanner.kt b/android/lib/ui/component/src/main/kotlin/net/mullvad/mullvadvpn/lib/ui/component/AnimatedNotificationBanner.kt
index 4a9bdf1769..8889a37399 100644
--- a/android/lib/ui/component/src/main/kotlin/net/mullvad/mullvadvpn/lib/ui/component/AnimatedNotificationBanner.kt
+++ b/android/lib/ui/component/src/main/kotlin/net/mullvad/mullvadvpn/lib/ui/component/AnimatedNotificationBanner.kt
@@ -16,8 +16,13 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
@@ -41,6 +46,7 @@ fun AnimatedNotificationBanner(
notification: InAppNotification?,
isPlayBuild: Boolean,
openAppListing: () -> Unit,
+ contentFocusRequester: FocusRequester,
onClickShowAccount: () -> Unit,
onClickShowChangelog: () -> Unit,
onClickDismissChangelog: () -> Unit,
@@ -49,9 +55,20 @@ fun AnimatedNotificationBanner(
) {
// Fix for animating to invisible state
val previous = rememberPrevious(current = notification, shouldUpdate = { _, _ -> true })
+
+ val isVisible = notification != null
+
+ val isNotificationDismissed = !isVisible && previous != null
+ val notificationHasFocus = remember { mutableStateOf(false) }
+ LaunchedEffect(isNotificationDismissed) {
+ // If the notification is dismissed, we want to reset the previous notification
+ if (isNotificationDismissed && notificationHasFocus.value) {
+ contentFocusRequester.requestFocus()
+ }
+ }
AnimatedVisibility(
- modifier = modifier,
- visible = notification != null,
+ modifier = modifier.onFocusChanged { notificationHasFocus.value = it.hasFocus },
+ visible = isVisible,
enter = slideInVertically(initialOffsetY = { -it }),
exit = slideOutVertically(targetOffsetY = { -it }),
) {