diff --git a/app/src/main/java/com/getcode/CodeApp.kt b/app/src/main/java/com/getcode/CodeApp.kt index ce9299a41..00b70cb09 100644 --- a/app/src/main/java/com/getcode/CodeApp.kt +++ b/app/src/main/java/com/getcode/CodeApp.kt @@ -4,6 +4,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.ExperimentalMaterialApi @@ -16,6 +17,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.stack.StackEvent import cafe.adriel.voyager.navigator.CurrentScreen import cafe.adriel.voyager.navigator.Navigator @@ -33,6 +35,7 @@ import com.getcode.theme.CodeTheme import com.getcode.theme.LocalCodeColors import com.getcode.util.getActivity import com.getcode.util.getActivityScopedViewModel +import com.getcode.util.measured import com.getcode.view.components.AuthCheck import com.getcode.view.components.BottomBarContainer import com.getcode.view.components.CodeScaffold @@ -63,29 +66,38 @@ fun CodeApp() { codeNavigator.screensNavigator = navigator } + var topBarHeight by remember { + mutableStateOf(0.dp) + } val (isVisibleTopBar, isVisibleBackButton) = appState.isVisibleTopBar if (isVisibleTopBar && appState.currentTitle.isNotBlank()) { TitleBar( + modifier = Modifier.measured { topBarHeight = it.height }, title = appState.currentTitle, backButton = isVisibleBackButton, onBackIconClicked = appState::upPress ) + } else { + topBarHeight = 0.dp } - Box( - modifier = Modifier - .padding(innerPaddingModifier) - ) { - when (navigator.lastEvent) { - StackEvent.Push, - StackEvent.Pop -> { - when (navigator.lastItem) { - is LoginScreen, is MainRoot -> CrossfadeTransition(navigator = navigator) - else -> SlideTransition(navigator = navigator) + CompositionLocalProvider(value = LocalTopBarPadding provides PaddingValues(top = topBarHeight)) { + Box( + modifier = Modifier + .padding(innerPaddingModifier) + ) { + when (navigator.lastEvent) { + StackEvent.Push, + StackEvent.Pop -> { + when (navigator.lastItem) { + is LoginScreen, is MainRoot -> CrossfadeTransition(navigator = navigator) + else -> SlideTransition(navigator = navigator) + } } + + StackEvent.Idle, + StackEvent.Replace -> CurrentScreen() } - StackEvent.Idle, - StackEvent.Replace -> CurrentScreen() } } diff --git a/app/src/main/java/com/getcode/CodeAppState.kt b/app/src/main/java/com/getcode/CodeAppState.kt index 7540ad42c..39045ecc2 100644 --- a/app/src/main/java/com/getcode/CodeAppState.kt +++ b/app/src/main/java/com/getcode/CodeAppState.kt @@ -12,15 +12,11 @@ import com.getcode.manager.TopBarManager import com.getcode.navigation.core.CodeNavigator import com.getcode.navigation.core.LocalCodeNavigator import com.getcode.navigation.screens.AccessKeyLoginScreen -import com.getcode.navigation.screens.AccessKeyScreen -import com.getcode.navigation.screens.LoginPhoneConfirmationScreen import com.getcode.navigation.screens.LoginPhoneVerificationScreen import com.getcode.navigation.screens.LoginScreen import com.getcode.navigation.screens.NamedScreen -import com.getcode.navigation.screens.PermissionRequestScreen import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import timber.log.Timber /** * Remembers and creates an instance of [CodeAppState] diff --git a/app/src/main/java/com/getcode/Locals.kt b/app/src/main/java/com/getcode/Locals.kt index e19942f81..4a120764b 100644 --- a/app/src/main/java/com/getcode/Locals.kt +++ b/app/src/main/java/com/getcode/Locals.kt @@ -1,5 +1,6 @@ package com.getcode +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.staticCompositionLocalOf import com.getcode.analytics.AnalyticsService @@ -15,3 +16,4 @@ val LocalNetworkObserver: ProvidableCompositionLocal = staticCompositionLocalOf { null } val LocalCurrencyUtils: ProvidableCompositionLocal = staticCompositionLocalOf { null } val LocalDeeplinks: ProvidableCompositionLocal = staticCompositionLocalOf { null } +val LocalTopBarPadding: ProvidableCompositionLocal = staticCompositionLocalOf { PaddingValues() } diff --git a/app/src/main/java/com/getcode/navigation/screens/Modals.kt b/app/src/main/java/com/getcode/navigation/screens/Modals.kt index 2feec7a15..15909b4a8 100644 --- a/app/src/main/java/com/getcode/navigation/screens/Modals.kt +++ b/app/src/main/java/com/getcode/navigation/screens/Modals.kt @@ -25,9 +25,8 @@ import cafe.adriel.voyager.core.screen.uniqueScreenKey import com.getcode.navigation.core.CodeNavigator import com.getcode.navigation.core.LocalCodeNavigator import com.getcode.theme.CodeTheme -import com.getcode.theme.sheetHeight -import com.getcode.util.keyboardAsState import com.getcode.view.components.SheetTitle +import com.getcode.view.components.keyboardAsState import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -79,7 +78,7 @@ internal fun Screen.ModalContainer( Column( modifier = Modifier .fillMaxWidth() - .fillMaxHeight(sheetHeight) + .fillMaxHeight(CodeTheme.dimens.modalHeightRatio) ) { val lastItem by remember(navigator.lastModalItem) { derivedStateOf { navigator.lastModalItem } @@ -93,13 +92,16 @@ internal fun Screen.ModalContainer( derivedStateOf { closeButton(lastItem) } } + val keyboardVisible by keyboardAsState() val keyboardController = LocalSoftwareKeyboardController.current val composeScope = rememberCoroutineScope() val hideSheet = { composeScope.launch { - keyboardController?.hide() - delay(500) + if (keyboardVisible) { + keyboardController?.hide() + delay(500) + } navigator.hide() } } diff --git a/app/src/main/java/com/getcode/navigation/screens/PhoneCountrySelection.kt b/app/src/main/java/com/getcode/navigation/screens/PhoneCountrySelection.kt index 2b64d92b9..f53b6d814 100644 --- a/app/src/main/java/com/getcode/navigation/screens/PhoneCountrySelection.kt +++ b/app/src/main/java/com/getcode/navigation/screens/PhoneCountrySelection.kt @@ -57,7 +57,7 @@ private fun PhoneCountrySelection( modifier = Modifier .align(Alignment.CenterVertically) .padding(start = CodeTheme.dimens.inset) - .size(CodeTheme.dimens.staticGrid.x5) + .size(CodeTheme.dimens.grid.x5) .clip(CodeTheme.shapes.large), painter = painterResource(id = resId), contentDescription = "" diff --git a/app/src/main/java/com/getcode/theme/Dimens.kt b/app/src/main/java/com/getcode/theme/Dimens.kt index d5e6e2196..ae955726c 100644 --- a/app/src/main/java/com/getcode/theme/Dimens.kt +++ b/app/src/main/java/com/getcode/theme/Dimens.kt @@ -10,7 +10,6 @@ import androidx.compose.ui.unit.dp import com.getcode.BuildConfig val topBarHeight = 56.dp -const val sheetHeight = 0.9f internal val LocalDimens = staticCompositionLocalOf { error("No Dimensions provided") @@ -166,6 +165,7 @@ class Dimensions( val none: Dp = 0.dp, val border: Dp = 1.dp, val thickBorder: Dp = 2.dp, + val modalHeightRatio: Float = 0.94f, val inset: Dp, val screenWidth: Dp = Dp.Unspecified, val screenHeight: Dp = Dp.Unspecified, diff --git a/app/src/main/java/com/getcode/theme/Shape.kt b/app/src/main/java/com/getcode/theme/Shape.kt index 21945a627..1e51e94b3 100644 --- a/app/src/main/java/com/getcode/theme/Shape.kt +++ b/app/src/main/java/com/getcode/theme/Shape.kt @@ -24,5 +24,5 @@ val Shapes.xxl: CornerBasedShape @Composable get() = RoundedCornerShape(25.dp) @Composable -fun Shapes.receipt(step: Dp = CodeTheme.dimens.staticGrid.x2) = TriangleCutShape(step) +fun Shapes.receipt(step: Dp = CodeTheme.dimens.grid.x2) = TriangleCutShape(step) diff --git a/app/src/main/java/com/getcode/view/components/CodeKeyPad.kt b/app/src/main/java/com/getcode/view/components/CodeKeyPad.kt index b9527ffef..2c4768c19 100644 --- a/app/src/main/java/com/getcode/view/components/CodeKeyPad.kt +++ b/app/src/main/java/com/getcode/view/components/CodeKeyPad.kt @@ -59,13 +59,13 @@ fun CodeKeyPad( modifier = Modifier .widthIn(min = 100.dp) .then(modifier), - horizontalArrangement = Arrangement.spacedBy(CodeTheme.dimens.staticGrid.x1), + horizontalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x1), verticalAlignment = Alignment.Bottom ) { for (column in 1..3) { Column( modifier = Modifier.weight(1f), - verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.staticGrid.x1) + verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x1) ) { for (row in 1..4) { val number = (row - 1) * 3 + column diff --git a/app/src/main/java/com/getcode/view/components/OtpBox.kt b/app/src/main/java/com/getcode/view/components/OtpBox.kt index 738eeaaa1..edd2b4ed2 100644 --- a/app/src/main/java/com/getcode/view/components/OtpBox.kt +++ b/app/src/main/java/com/getcode/view/components/OtpBox.kt @@ -26,15 +26,15 @@ fun OtpBox( ) { val height = when (CodeTheme.dimens.heightWindowSizeClass) { - WindowSizeClass.COMPACT -> CodeTheme.dimens.staticGrid.x9 - else -> CodeTheme.dimens.staticGrid.x11 + WindowSizeClass.COMPACT -> CodeTheme.dimens.grid.x9 + else -> CodeTheme.dimens.grid.x11 } Box( modifier = modifier .padding(CodeTheme.dimens.grid.x1) .height(height) - .width(CodeTheme.dimens.staticGrid.x7) + .width(CodeTheme.dimens.grid.x7) .clip(CodeTheme.shapes.small) .rememberedClickable(onClick = onClick) .border( diff --git a/app/src/main/java/com/getcode/view/login/AccessKey.kt b/app/src/main/java/com/getcode/view/login/AccessKey.kt index 3589c64c8..a47c0fae2 100644 --- a/app/src/main/java/com/getcode/view/login/AccessKey.kt +++ b/app/src/main/java/com/getcode/view/login/AccessKey.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -47,6 +48,7 @@ import androidx.compose.ui.zIndex import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension import androidx.hilt.navigation.compose.hiltViewModel +import com.getcode.LocalTopBarPadding import com.getcode.R import com.getcode.manager.BottomBarManager import com.getcode.manager.TopBarManager @@ -57,6 +59,7 @@ import com.getcode.theme.CodeTheme import com.getcode.theme.White import com.getcode.util.IntentUtils import com.getcode.util.addIf +import com.getcode.util.debugBounds import com.getcode.util.measured import com.getcode.util.swallowClicks import com.getcode.view.components.AccessKeySelectionContainer @@ -135,10 +138,6 @@ fun AccessKey( words = dataState.words.joinToString(" ") ) - var textHeight by remember { - mutableStateOf(0.dp) - } - AccessKeySelectionContainer( modifier = Modifier .fillMaxSize() @@ -154,7 +153,8 @@ fun AccessKey( modifier = Modifier .fillMaxSize() .padding(horizontal = CodeTheme.dimens.inset) - .padding(vertical = CodeTheme.dimens.grid.x4), + .padding(vertical = CodeTheme.dimens.grid.x4) + .measured { buttonHeight = it.height }, ) { Column(modifier = Modifier .align(Alignment.BottomCenter) @@ -199,25 +199,36 @@ fun AccessKey( modifier = Modifier .align(Alignment.TopCenter) .fillMaxHeight() - .padding(bottom = buttonHeight) - , - verticalArrangement = Arrangement.Center, + .padding(LocalTopBarPadding.current) + .padding(bottom = buttonHeight + CodeTheme.dimens.grid.x4), horizontalAlignment = Alignment.CenterHorizontally ) { - AnimatedVisibility( - visibleState = isAccessKeyVisible, - enter = fadeIn(animationSpec = tween(300, 0)), - exit = fadeOut(animationSpec = tween(300, 0)) + Column( + modifier = Modifier + // highly specific aspect ratio from iOS :) + .aspectRatio(0.607f, matchHeightConstraintsFirst = true) + .fillMaxWidth() + .weight(1f), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally ) { - dataState.accessKeyCroppedBitmap?.let { bitmap -> - Image( - modifier = Modifier - .fillMaxWidth() - .weight(1f) - .scale(selectionState.scale.value), - bitmap = bitmap.asImageBitmap(), - contentDescription = dataState.wordsFormatted, - ) + AnimatedVisibility( + visibleState = isAccessKeyVisible, + enter = fadeIn(animationSpec = tween(300, 0)), + exit = fadeOut(animationSpec = tween(300, 0)) + ) { + dataState.accessKeyCroppedBitmap?.let { bitmap -> + Image( + modifier = Modifier + .aspectRatio(0.607f, matchHeightConstraintsFirst = true) + .fillMaxWidth() + .weight(1f) + .scale(selectionState.scale.value), + bitmap = bitmap.asImageBitmap(), + contentScale = ContentScale.Crop, + contentDescription = dataState.wordsFormatted, + ) + } } } diff --git a/app/src/main/java/com/getcode/view/main/account/BackupKey.kt b/app/src/main/java/com/getcode/view/main/account/BackupKey.kt index 8e77e0346..5987fa007 100644 --- a/app/src/main/java/com/getcode/view/main/account/BackupKey.kt +++ b/app/src/main/java/com/getcode/view/main/account/BackupKey.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -56,6 +57,7 @@ import com.getcode.theme.BrandLight import com.getcode.theme.CodeTheme import com.getcode.theme.White import com.getcode.util.IntentUtils +import com.getcode.util.debugBounds import com.getcode.util.measured import com.getcode.util.rememberedClickable import com.getcode.util.rememberedLongClickable @@ -140,22 +142,19 @@ fun BackupKey( ) { Cloudy( modifier = Modifier - .fillMaxSize() - .padding(vertical = CodeTheme.dimens.grid.x4), + .fillMaxSize(), enabled = selectionState.shown ) { Box( modifier = Modifier .fillMaxSize() - .padding( - horizontal = CodeTheme.dimens.inset, - vertical = CodeTheme.dimens.grid.x4 - ) + .padding(horizontal = CodeTheme.dimens.inset,) + .padding(vertical = CodeTheme.dimens.grid.x4), ) { Text( modifier = Modifier .align(Alignment.TopCenter) - .padding(vertical = CodeTheme.dimens.grid.x2) + .padding(bottom = CodeTheme.dimens.grid.x2) .measured { textHeight = it.height }, style = CodeTheme.typography.body2.copy(textAlign = TextAlign.Center), color = BrandLight, @@ -166,7 +165,7 @@ fun BackupKey( Column( modifier = Modifier .align(Alignment.BottomCenter) - .measured { buttonHeight = it.height } + .measured { buttonHeight = it.height }, ) { CodeButton( modifier = Modifier.fillMaxWidth(), @@ -184,7 +183,10 @@ fun BackupKey( Column( modifier = Modifier .align(Alignment.TopCenter) + // highly specific aspect ratio from iOS :) + .aspectRatio(0.607f, matchHeightConstraintsFirst = true) .fillMaxHeight() + .padding(vertical = CodeTheme.dimens.grid.x4) .padding(top = textHeight) .padding(bottom = buttonHeight), verticalArrangement = Arrangement.Center, diff --git a/app/src/main/java/com/getcode/view/main/invites/InvitesSheet.kt b/app/src/main/java/com/getcode/view/main/invites/InvitesSheet.kt index 13cbf30cc..632fbf30a 100644 --- a/app/src/main/java/com/getcode/view/main/invites/InvitesSheet.kt +++ b/app/src/main/java/com/getcode/view/main/invites/InvitesSheet.kt @@ -10,7 +10,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel import com.getcode.R import com.getcode.theme.CodeTheme -import com.getcode.theme.sheetHeight import com.getcode.view.components.PermissionCheck import com.getcode.view.components.SheetTitle import com.getcode.view.components.getPermissionLauncher @@ -38,7 +37,7 @@ fun InvitesSheet(upPress: () -> Unit = {}) { Box( modifier = Modifier .fillMaxWidth() - .fillMaxHeight(sheetHeight) + .fillMaxHeight(CodeTheme.dimens.modalHeightRatio) .padding(horizontal = CodeTheme.dimens.inset) ) { Column {