summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorsaber safavi <saber.safavi@codic.se>2023-06-28 16:23:05 +0200
committersaber safavi <saber.safavi@codic.se>2023-07-06 12:26:00 +0200
commite25edb6afb9d5869ee593b46a14018cc55d0dbec (patch)
tree9c031787ba1bc4a33babf1a9c99ecbce5278636d /android
parentcc940e2ea9cd9034a99ff1857beccac3cde6e6f6 (diff)
downloadmullvadvpn-e25edb6afb9d5869ee593b46a14018cc55d0dbec.tar.xz
mullvadvpn-e25edb6afb9d5869ee593b46a14018cc55d0dbec.zip
Add collapsible toolbar component with dynamic body height
Diffstat (limited to 'android')
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingToolbarScaffold.kt88
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt4
4 files changed, 94 insertions, 7 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingToolbarScaffold.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingToolbarScaffold.kt
new file mode 100644
index 0000000000..f4b81826bc
--- /dev/null
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingToolbarScaffold.kt
@@ -0,0 +1,88 @@
+package net.mullvad.mullvadvpn.compose.component
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.BoxWithConstraints
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.unit.dp
+import com.google.accompanist.systemuicontroller.rememberSystemUiController
+import me.onebone.toolbar.CollapsingToolbarScaffold
+import me.onebone.toolbar.CollapsingToolbarScaffoldScope
+import me.onebone.toolbar.CollapsingToolbarScaffoldState
+import me.onebone.toolbar.CollapsingToolbarScope
+import me.onebone.toolbar.ExperimentalToolbarApi
+import me.onebone.toolbar.ScrollStrategy
+
+@OptIn(ExperimentalToolbarApi::class)
+@Composable
+fun CollapsingToolbarScaffold(
+ backgroundColor: Color,
+ state: CollapsingToolbarScaffoldState,
+ modifier: Modifier = Modifier,
+ scrollStrategy: ScrollStrategy = ScrollStrategy.ExitUntilCollapsed,
+ isEnabledWhenCollapsable: Boolean = true,
+ toolbarModifier: Modifier = Modifier,
+ toolbar: @Composable CollapsingToolbarScope.() -> Unit,
+ body: @Composable CollapsingToolbarScaffoldScope.() -> Unit,
+) {
+ val dynamic = remember { mutableStateOf(0.dp) }
+ val systemUiController = rememberSystemUiController()
+ systemUiController.setStatusBarColor(backgroundColor)
+ systemUiController.setNavigationBarColor(backgroundColor)
+
+ var isCollapsable by remember { mutableStateOf(false) }
+
+ LaunchedEffect(isCollapsable) {
+ if (!isCollapsable) {
+ state.toolbarState.expand()
+ }
+ }
+ val totalHeights = remember { mutableStateOf(0.dp) }
+ val localDensity = LocalDensity.current
+
+ CollapsingToolbarScaffold(
+ modifier =
+ modifier
+ .background(backgroundColor)
+ .fillMaxWidth()
+ .fillMaxHeight()
+ .onGloballyPositioned { coordinates ->
+ totalHeights.value = with(localDensity) { coordinates.size.height.toDp() }
+ },
+ state = state,
+ scrollStrategy = scrollStrategy,
+ toolbarModifier =
+ toolbarModifier.onGloballyPositioned { coordinates ->
+ with(localDensity) {
+ dynamic.value = totalHeights.value - coordinates.size.height.toDp()
+ }
+ },
+ enabled = isEnabledWhenCollapsable && isCollapsable,
+ toolbar = { toolbar() }
+ ) {
+ var bodyHeight by remember { mutableStateOf(0) }
+
+ BoxWithConstraints(
+ modifier =
+ Modifier.height(dynamic.value).onGloballyPositioned { bodyHeight = it.size.height }
+ ) {
+ val minMaxToolbarHeightDiff =
+ with(state) { toolbarState.maxHeight - toolbarState.minHeight }
+ val isContentHigherThanCollapseThreshold =
+ with(localDensity) { bodyHeight >= maxHeight.toPx() - minMaxToolbarHeightDiff }
+ isCollapsable = isContentHigherThanCollapseThreshold
+ body()
+ }
+ }
+}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt
index 6dd3435e64..0af698e61c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt
@@ -23,7 +23,7 @@ import me.onebone.toolbar.ScrollStrategy
import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.cell.RelayLocationCell
-import net.mullvad.mullvadvpn.compose.component.CollapsableAwareToolbarScaffold
+import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold
import net.mullvad.mullvadvpn.compose.component.CollapsingTopBar
import net.mullvad.mullvadvpn.compose.constant.ContentType
import net.mullvad.mullvadvpn.compose.state.SelectLocationUiState
@@ -54,7 +54,7 @@ fun SelectLocationScreen(
val state = rememberCollapsingToolbarScaffoldState()
val progress = state.toolbarState.progress
LaunchedEffect(Unit) { uiCloseAction.collect { onBackClick() } }
- CollapsableAwareToolbarScaffold(
+ CollapsingToolbarScaffold(
backgroundColor = MaterialTheme.colorScheme.background,
modifier = Modifier.fillMaxSize(),
state = state,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt
index e624170479..a690ba3ae1 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt
@@ -26,7 +26,7 @@ import net.mullvad.mullvadvpn.applist.AppData
import net.mullvad.mullvadvpn.compose.cell.BaseCell
import net.mullvad.mullvadvpn.compose.cell.HeaderSwitchComposeCell
import net.mullvad.mullvadvpn.compose.cell.SplitTunnelingCell
-import net.mullvad.mullvadvpn.compose.component.CollapsableAwareToolbarScaffold
+import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold
import net.mullvad.mullvadvpn.compose.component.CollapsingTopBar
import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar
import net.mullvad.mullvadvpn.compose.constant.CommonContentKey
@@ -36,7 +36,6 @@ import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider
import net.mullvad.mullvadvpn.compose.state.SplitTunnelingUiState
import net.mullvad.mullvadvpn.compose.theme.AppTheme
import net.mullvad.mullvadvpn.compose.theme.Dimens
-import org.koin.androidx.compose.get
@Preview
@Composable
@@ -86,7 +85,7 @@ fun SplitTunnelingScreen(
val progress = state.toolbarState.progress
val lazyListState = rememberLazyListState()
- CollapsableAwareToolbarScaffold(
+ CollapsingToolbarScaffold(
backgroundColor = MaterialTheme.colorScheme.background,
modifier = Modifier.fillMaxSize(),
state = state,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
index 735c9464dc..bc44670940 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
@@ -53,7 +53,7 @@ import net.mullvad.mullvadvpn.compose.cell.InformationComposeCell
import net.mullvad.mullvadvpn.compose.cell.MtuComposeCell
import net.mullvad.mullvadvpn.compose.cell.NormalSwitchComposeCell
import net.mullvad.mullvadvpn.compose.cell.SelectableCell
-import net.mullvad.mullvadvpn.compose.component.CollapsableAwareToolbarScaffold
+import net.mullvad.mullvadvpn.compose.component.CollapsingToolbarScaffold
import net.mullvad.mullvadvpn.compose.component.CollapsingTopBar
import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar
import net.mullvad.mullvadvpn.compose.dialog.ContentBlockersInfoDialog
@@ -211,7 +211,7 @@ fun VpnSettingsScreen(
val state = rememberCollapsingToolbarScaffoldState()
val progress = state.toolbarState.progress
- CollapsableAwareToolbarScaffold(
+ CollapsingToolbarScaffold(
backgroundColor = MaterialTheme.colorScheme.background,
modifier = Modifier.fillMaxSize(),
state = state,