diff --git a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/OnboardingFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/OnboardingFragment.kt index db158000b0..4b9a387e48 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/OnboardingFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/OnboardingFragment.kt @@ -332,7 +332,8 @@ class OnboardingFragment : Fragment() { Mnemonic( mnemonicColorPalette = mnemonicColorPalette, space = spaceId, - startingObject = startingObjectId + startingObject = startingObjectId, + navController = navController ) } else { Box( @@ -377,12 +378,13 @@ class OnboardingFragment : Fragment() { BackHandler { onBackClicked() } } composable( - route = "${OnboardingNavigation.setEmail}?$ONBOARDING_NAME_PARAM={$ONBOARDING_NAME_PARAM}", + route = "${OnboardingNavigation.setEmail}?$ONBOARDING_SPACE_PARAM={$ONBOARDING_SPACE_PARAM}&$ONBOARDING_STARTING_OBJECT_PARAM={$ONBOARDING_STARTING_OBJECT_PARAM}", arguments = listOf( - navArgument(ONBOARDING_NAME_PARAM) { + navArgument(ONBOARDING_SPACE_PARAM) { type = NavType.StringType }, + navArgument(ONBOARDING_STARTING_OBJECT_PARAM) { type = NavType.StringType - defaultValue = "" - nullable = false + nullable = true + defaultValue = null } ), enterTransition = { @@ -393,6 +395,8 @@ class OnboardingFragment : Fragment() { } ) { val focus = LocalFocusManager.current + val spaceId = it.arguments?.getString(ONBOARDING_SPACE_PARAM) + val startingObjectId = it.arguments?.getString(ONBOARDING_STARTING_OBJECT_PARAM) val onBackClicked : () -> Unit = { val lastDestination = navController.currentBackStackEntry if (lastDestination?.destination?.route?.startsWith(OnboardingNavigation.setEmail) == true) { @@ -404,10 +408,23 @@ class OnboardingFragment : Fragment() { } currentPage.value = OnboardingPage.SET_EMAIL backButtonCallback.value = onBackClicked - AddEmail( - navController = navController, - onBackClicked = onBackClicked - ) + if (!spaceId.isNullOrEmpty()) { + AddEmail( + space = spaceId, + startingObject = startingObjectId, + onBackClicked = onBackClicked + ) + } else { + Box( + modifier = Modifier.fillMaxSize() + ) { + Text( + text = stringResource(R.string.onboarding_error_while_creating_account_space_is_missing), + modifier = Modifier.align(Alignment.Center), + textAlign = TextAlign.Center + ) + } + } BackHandler { onBackClicked() } } } @@ -586,17 +603,14 @@ class OnboardingFragment : Fragment() { ) } is OnboardingSetProfileNameViewModel.Navigation.GoBack -> { - // + // do nothing } - is OnboardingSetProfileNameViewModel.Navigation.NavigateToAddEmailScreen -> { - if (keyboardInsets.getBottom(density) > 0) { - focusManager.clearFocus(force = true) - delay(KEYBOARD_HIDE_DELAY) - } - navController.navigate( - route = "${OnboardingNavigation.setEmail}?$ONBOARDING_NAME_PARAM=${command.name}", - ) + is OnboardingSetProfileNameViewModel.Navigation.OpenStartingObject -> { + //do nothing + } + OnboardingSetProfileNameViewModel.Navigation.OpenVault -> { + //do nothing } } } @@ -615,7 +629,8 @@ class OnboardingFragment : Fragment() { private fun Mnemonic( mnemonicColorPalette: List, space: Id, - startingObject: Id? + startingObject: Id?, + navController: NavHostController ) { val component = componentManager().onboardingMnemonicComponent val vm = daggerViewModel { component.get().getViewModel() } @@ -667,6 +682,13 @@ class OnboardingFragment : Fragment() { Timber.e(it, "Error while navigation to vault") } } + is OnboardingMnemonicViewModel.Command.NavigateToAddEmailScreen -> { + val startingObject = command.startingObject + val space = command.space + navController.navigate( + route = "${OnboardingNavigation.setEmail}?$ONBOARDING_SPACE_PARAM=$space&$ONBOARDING_STARTING_OBJECT_PARAM=$startingObject" + ) + } } } } @@ -776,7 +798,8 @@ class OnboardingFragment : Fragment() { @Composable private fun AddEmail( - navController: NavHostController, + space: Id, + startingObject: Id?, onBackClicked: () -> Unit ) { val component = componentManager().onboardingSoulCreationComponent @@ -786,11 +809,10 @@ class OnboardingFragment : Fragment() { val keyboardInsets = WindowInsets.ime val density = LocalDensity.current - val name = navController.currentBackStackEntry?.arguments?.getString(ONBOARDING_NAME_PARAM) ?: "" - SetEmailWrapper( viewModel = vm, - name = name, + startingObject = startingObject, + space = space, onBackClicked = onBackClicked ) @@ -798,25 +820,45 @@ class OnboardingFragment : Fragment() { vm.navigation.collect { command -> when (command) { is OnboardingSetProfileNameViewModel.Navigation.NavigateToMnemonic -> { - if (keyboardInsets.getBottom(density) > 0) { - focusManager.clearFocus(force = true) - delay(KEYBOARD_HIDE_DELAY) - } - val space = command.space - val startingObject = command.startingObject - navController.navigate( - route = buildString { - append("${OnboardingNavigation.mnemonic}?$ONBOARDING_SPACE_PARAM=${space.id}") - startingObject?.let { append("&$ONBOARDING_STARTING_OBJECT_PARAM=${it}") } - } - ) + //do nothing } is OnboardingSetProfileNameViewModel.Navigation.GoBack -> { // } - is OnboardingSetProfileNameViewModel.Navigation.NavigateToAddEmailScreen -> { - //do nothing + is OnboardingSetProfileNameViewModel.Navigation.OpenStartingObject -> { + runCatching { + findNavController().navigate( + R.id.actionOpenVault, + VaultFragment.args(deepLink) + ) + findNavController().navigate( + R.id.actionOpenSpaceFromVault, + HomeScreenFragment.args( + space = command.space.id, + deeplink = null + ) + ) + findNavController().navigate( + R.id.objectNavigation, + EditorFragment.args( + ctx = command.startingObject, + space = command.space.id, + ) + ) + }.onFailure { + Timber.e(it, "Error while navigation to vault") + } + } + OnboardingSetProfileNameViewModel.Navigation.OpenVault -> { + runCatching { + findNavController().navigate( + R.id.actionOpenVault, + VaultFragment.args(deepLink) + ) + }.onFailure { + Timber.e(it, "Error while navigation to vault") + } } } } @@ -873,7 +915,7 @@ class OnboardingFragment : Fragment() { private const val ONBOARDING_SPACE_PARAM = "space" private const val ONBOARDING_STARTING_OBJECT_PARAM = "startingObject" - private const val ONBOARDING_NAME_PARAM = "name" + private const val ONBOARDING_NAME_PARAM = "startingObject" } } diff --git a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/OnboardingAuthScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/OnboardingAuthScreen.kt index 4eaca07f05..edf32f2848 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/OnboardingAuthScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/OnboardingAuthScreen.kt @@ -20,11 +20,15 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.withStyle +import androidx.compose.ui.tooling.preview.Devices.PIXEL_7 import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.em import androidx.compose.ui.unit.sp import com.anytypeio.anytype.R import com.anytypeio.anytype.core_ui.ColorButtonInversion @@ -36,9 +40,15 @@ import com.anytypeio.anytype.core_ui.views.HeadlineOnBoardingTitle import com.anytypeio.anytype.core_ui.views.OnBoardingButtonPrimary import com.anytypeio.anytype.core_ui.views.OnBoardingButtonSecondary import com.anytypeio.anytype.core_ui.views.TextOnBoardingDescription +import com.anytypeio.anytype.core_ui.views.fontRiccioneRegular import com.anytypeio.anytype.presentation.onboarding.OnboardingStartViewModel -@Preview +@Preview( + showBackground = true, + backgroundColor = 0xFF000000, + showSystemUi = true, + device = PIXEL_7 +) @Composable fun AuthScreenPreview() { AuthScreen( @@ -77,7 +87,7 @@ fun AuthScreen( Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center) { Title(modifier = Modifier.align(Alignment.CenterHorizontally)) Subtitle(modifier = Modifier) - Description() + //Description() Spacer(modifier = Modifier.height(72.dp)) } Column( @@ -108,7 +118,7 @@ fun AuthScreen( @Composable fun Title(modifier: Modifier = Modifier) { Image( - painter = painterResource(id = R.drawable.ic_local_first_internet) , + painter = painterResource(id = R.drawable.ic_local_first_internet), contentDescription = "Everything app logo", modifier = modifier ) @@ -126,12 +136,14 @@ fun Subtitle(modifier: Modifier = Modifier) { Text( text = stringResource(id = R.string.onboarding_auth_subtitle), textAlign = TextAlign.Center, - style = HeadlineOnBoardingTitle - .copy( - color = OnboardingSubtitleColor, - fontSize = 43.sp, - lineHeight = 37.5.sp - ) + color = OnboardingSubtitleColor, + style = TextStyle( + fontFamily = fontRiccioneRegular, + fontWeight = FontWeight.W400, + fontSize = 44.sp, + lineHeight = 44.sp, + letterSpacing = (-0.05).em + ) ) } } diff --git a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingEmailScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingEmailScreen.kt index d034904c77..aa595343b9 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingEmailScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingEmailScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextFieldDefaults 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 @@ -29,6 +30,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource @@ -39,6 +41,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.anytypeio.anytype.R +import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_ui.common.DefaultPreviews import com.anytypeio.anytype.core_ui.foundation.noRippleClickable import com.anytypeio.anytype.core_ui.views.ButtonSize @@ -55,19 +58,22 @@ import kotlin.text.isNotEmpty @Composable fun SetEmailWrapper( viewModel: OnboardingSetProfileNameViewModel, - name: String, + startingObject: String?, + space: Id, onBackClicked: () -> Unit, ) { OnboardingEmailScreen( onContinueClicked = { email -> viewModel.onEmailContinueClicked( - name = name, + space = space, + startingObject = startingObject, email = email ) }, onSkipClicked = { viewModel.onEmailSkippedClicked( - name = name, + space = space, + startingObject = startingObject ) }, isLoading = viewModel.state @@ -87,8 +93,13 @@ fun OnboardingEmailScreen( var innerValue by remember { mutableStateOf(TextFieldValue()) } var isError by remember { mutableStateOf(false) } val focusRequester = remember { FocusRequester() } + val focusManager = LocalFocusManager.current val keyboardController = LocalSoftwareKeyboardController.current + LaunchedEffect(Unit) { + focusRequester.requestFocus() + } + fun isValidEmail(email: String): Boolean { return Patterns.EMAIL_ADDRESS.matcher(email).matches() } @@ -96,7 +107,7 @@ fun OnboardingEmailScreen( fun validateAndSubmit() { if (isValidEmail(innerValue.text)) { isError = false - focusRequester.freeFocus() + focusManager.clearFocus() keyboardController?.hide() onContinueClicked(innerValue.text) } else { @@ -108,11 +119,10 @@ fun OnboardingEmailScreen( modifier = Modifier .windowInsetsPadding(WindowInsets.navigationBars) .imePadding() - //.background(color = colorResource(id = R.color.black)) .fillMaxSize() ) { Column { - Spacer(modifier = Modifier.height(148.dp)) + Spacer(modifier = Modifier.height(140.dp)) Text( modifier = Modifier .fillMaxWidth() @@ -148,7 +158,7 @@ fun OnboardingEmailScreen( Text( text = stringResource(id = R.string.onboarding_enter_email), style = PreviewTitle1Regular, - color = colorResource(id = R.color.text_tertiary) + color = Color(0xFF646464) ) }, textStyle = PreviewTitle1Regular.copy( @@ -216,9 +226,9 @@ fun OnboardingEmailScreen( OnBoardingButtonSecondary( text = stringResource(id = R.string.onboarding_button_skip), onClick = { - onSkipClicked().also { - focusRequester.freeFocus() - } + focusManager.clearFocus() + keyboardController?.hide() + onSkipClicked() }, textColor = colorResource(id = R.color.text_white), size = ButtonSize.Large, diff --git a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingMnemonicPhraseScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingMnemonicPhraseScreen.kt index cb8dc378b7..31a83d343f 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingMnemonicPhraseScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingMnemonicPhraseScreen.kt @@ -2,16 +2,21 @@ package com.anytypeio.anytype.ui.onboarding.screens.signup import android.os.Build import android.os.Build.VERSION_CODES +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Text import androidx.compose.material3.ExperimentalMaterial3Api @@ -22,13 +27,15 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment -import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Modifier import androidx.compose.ui.draw.blur import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Devices.PIXEL_7 import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -36,16 +43,14 @@ import com.anytypeio.anytype.R import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_ui.ColorBackgroundField import com.anytypeio.anytype.core_ui.ColorButtonRegular -import com.anytypeio.anytype.core_ui.OnBoardingTextPrimaryColor -import com.anytypeio.anytype.core_ui.OnBoardingTextSecondaryColor import com.anytypeio.anytype.core_ui.extensions.conditional import com.anytypeio.anytype.core_ui.foundation.noRippleClickable -import com.anytypeio.anytype.core_ui.views.BodyRegular +import com.anytypeio.anytype.core_ui.views.ButtonMedium import com.anytypeio.anytype.core_ui.views.ButtonSize -import com.anytypeio.anytype.core_ui.views.HeadlineHeading -import com.anytypeio.anytype.core_ui.views.HeadlineOnBoardingDescription +import com.anytypeio.anytype.core_ui.views.HeadlineTitleSemibold import com.anytypeio.anytype.core_ui.views.OnBoardingButtonPrimary import com.anytypeio.anytype.core_ui.views.OnBoardingButtonSecondary +import com.anytypeio.anytype.core_ui.views.UXBody import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingMnemonicViewModel import com.anytypeio.anytype.ui.onboarding.MnemonicPhraseWidget import com.anytypeio.anytype.ui.onboarding.MnemonicStub @@ -81,8 +86,12 @@ fun MnemonicPhraseScreenWrapper( } - -@Preview +@Preview( + showBackground = true, + backgroundColor = 0xFF000000, + showSystemUi = true, + device = PIXEL_7 +) @Composable fun PreviewMnemonicPhraseScreen() { val fakeMnemonic = "One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve" @@ -96,7 +105,12 @@ fun PreviewMnemonicPhraseScreen() { ) } -@Preview +@Preview( + showBackground = true, + backgroundColor = 0xFF000000, + showSystemUi = true, + device = PIXEL_7 +) @Composable fun PreviewMnemonicPhraseScreen2() { val fakeMnemonic = "One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve" @@ -125,25 +139,28 @@ fun MnemonicPhraseScreen( Column( modifier = Modifier .fillMaxSize() - .padding(horizontal = 16.dp), - verticalArrangement = Arrangement.Top + .padding(horizontal = 20.dp), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally ) { Spacer(modifier = Modifier.height(148.dp)) MnemonicTitle() MnemonicDescription() - ReadMoreButton(showWhatIsRecoveryPhraseDialog) + Spacer(modifier = Modifier.height(31.dp)) MnemonicPhrase( state = state, copyMnemonicToClipboard = copyMnemonicToClipboard, mnemonicColorPalette = mnemonicColorPalette ) + ReadMoreButton(showWhatIsRecoveryPhraseDialog) } MnemonicButtons( modifier = Modifier.align(Alignment.BottomCenter), - openMnemonic = reviewMnemonic, + reviewMnemonic = reviewMnemonic, onCheckLaterClicked = onCheckLaterClicked, onGoToAppClicked = onGoToAppClicked, - state = state + state = state, + copyMnemonicToClipboard = copyMnemonicToClipboard ) } if (showWhatIsRecoveryPhraseDialog.value) { @@ -165,22 +182,27 @@ fun MnemonicPhraseScreen( } @Composable -private fun ReadMoreButton(showWhatIsRecoveryPhraseDialog: MutableState) { - Box( +private fun ColumnScope.ReadMoreButton(showWhatIsRecoveryPhraseDialog: MutableState) { + Row( modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp, bottom = 16.dp) + .wrapContentWidth() + .padding(top = 16.dp) .height(24.dp) .noRippleClickable { showWhatIsRecoveryPhraseDialog.value = true - } + }, + verticalAlignment = Alignment.CenterVertically, ) { + Image( + modifier = Modifier.wrapContentSize(), + painter = painterResource(id = R.drawable.ic_plus_18), + contentDescription = "Read more about recovery phrase", + ) Text( text = stringResource(id = R.string.onboarding_mnemonic_read_more), - style = BodyRegular.copy( - color = Color(0xFFDBDAD4) - ), - modifier = Modifier.align(Alignment.Center) + style = ButtonMedium, + color = Color(0xFF909090), + modifier = Modifier.padding(start = 8.dp), ) } } @@ -188,8 +210,9 @@ private fun ReadMoreButton(showWhatIsRecoveryPhraseDialog: MutableState @Composable fun MnemonicButtons( modifier: Modifier = Modifier, - openMnemonic: () -> Unit, + reviewMnemonic: () -> Unit, onCheckLaterClicked: () -> Unit, + copyMnemonicToClipboard: (String) -> Unit, onGoToAppClicked: () -> Unit, state: OnboardingMnemonicViewModel.State ) { @@ -205,6 +228,7 @@ fun MnemonicButtons( size = ButtonSize.Large ) } + else -> { OnBoardingButtonPrimary( text = stringResource(id = R.string.onboarding_tap_to_reveal), @@ -212,8 +236,13 @@ fun MnemonicButtons( .fillMaxWidth() .padding(horizontal = 16.dp), onClick = { - openMnemonic.invoke() - }, size = ButtonSize.Large + reviewMnemonic.invoke().also { + if (state is OnboardingMnemonicViewModel.State.Mnemonic) { + copyMnemonicToClipboard.invoke(state.mnemonicPhrase) + } + } + }, + size = ButtonSize.Large ) OnBoardingButtonSecondary( text = stringResource(id = R.string.onboarding_key_not_now), @@ -248,9 +277,8 @@ fun MnemonicTitle() { Text( modifier = Modifier, text = stringResource(R.string.onboarding_this_is_your_key_title), - style = HeadlineHeading.copy( - color = OnBoardingTextPrimaryColor - ), + style = HeadlineTitleSemibold, + color = colorResource(id = R.color.text_white), textAlign = TextAlign.Center ) } @@ -273,8 +301,7 @@ fun MnemonicPhrase( Box( modifier = Modifier .fillMaxWidth() - .padding(bottom = 16.dp) - .background(color = ColorBackgroundField, shape = RoundedCornerShape(24.dp)) + .background(color = ColorBackgroundField, shape = RoundedCornerShape(16.dp)) .wrapContentHeight() ) { if (Build.VERSION.SDK_INT <= VERSION_CODES.R && state is OnboardingMnemonicViewModel.State.Mnemonic) { @@ -298,19 +325,6 @@ fun MnemonicPhrase( ) } } - if (state is OnboardingMnemonicViewModel.State.MnemonicOpened) { - OnBoardingButtonSecondary( - text = stringResource(id = R.string.onboarding_key_copy), - modifier = Modifier - .align(CenterHorizontally) - .padding(bottom = 12.dp), - onClick = { - copyMnemonicToClipboard.invoke(state.mnemonicPhrase) - }, - size = ButtonSize.SmallSecondary, - textColor = ColorButtonRegular - ) - } } } @@ -322,16 +336,15 @@ fun MnemonicDescription() { Box( modifier = Modifier .fillMaxWidth() - .padding(horizontal = 24.dp) + .padding(horizontal = 20.dp) .wrapContentHeight(), contentAlignment = Alignment.Center ) { Text( text = stringResource(id = R.string.onboarding_key_description), - style = HeadlineOnBoardingDescription.copy( - color = OnBoardingTextSecondaryColor, - textAlign = TextAlign.Center - ) + textAlign = TextAlign.Center, + style = UXBody, + color = colorResource(id = R.color.text_white) ) } } \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingSetProfileNameScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingSetProfileNameScreen.kt index 720951e8cb..163ac7b49e 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingSetProfileNameScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/onboarding/screens/signup/OnboardingSetProfileNameScreen.kt @@ -4,40 +4,55 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.material.Text +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Devices.PIXEL_7 import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.anytypeio.anytype.R import com.anytypeio.anytype.core_models.Name -import com.anytypeio.anytype.core_ui.OnBoardingTextPrimaryColor -import com.anytypeio.anytype.core_ui.OnBoardingTextSecondaryColor import com.anytypeio.anytype.core_ui.foundation.noRippleClickable import com.anytypeio.anytype.core_ui.views.ButtonSize -import com.anytypeio.anytype.core_ui.views.HeadlineHeading -import com.anytypeio.anytype.core_ui.views.HeadlineOnBoardingDescription +import com.anytypeio.anytype.core_ui.views.Caption1Regular +import com.anytypeio.anytype.core_ui.views.HeadlineTitleSemibold import com.anytypeio.anytype.core_ui.views.OnBoardingButtonPrimary +import com.anytypeio.anytype.core_ui.views.PreviewTitle1Regular +import com.anytypeio.anytype.core_ui.views.UXBody import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingSetProfileNameViewModel -import com.anytypeio.anytype.ui.onboarding.OnboardingInput @Composable @@ -46,7 +61,7 @@ fun SetProfileNameWrapper( onBackClicked: () -> Unit, ) { val name = remember { mutableStateOf("") } - + SetProfileNameScreen( onNextClicked = { inputName -> name.value = inputName @@ -67,45 +82,117 @@ private fun SetProfileNameScreen( onBackClicked: () -> Unit, isLoading: Boolean ) { - val text = remember { mutableStateOf("") } - val focus = LocalFocusManager.current + var innerValue by remember { mutableStateOf(TextFieldValue()) } + val focusRequester = remember { FocusRequester() } + val keyboardController = LocalSoftwareKeyboardController.current + val focusManager = LocalFocusManager.current + var isError by remember { mutableStateOf(false) } + + LaunchedEffect(Unit) { + focusRequester.requestFocus() + } + + fun validateAndSubmit() { + if (innerValue.text.isNotEmpty()) { + isError = false + focusManager.clearFocus() + keyboardController?.hide() + onNextClicked(innerValue.text) + } else { + isError = true + focusManager.clearFocus() + keyboardController?.hide() + } + } Box( - modifier = Modifier.fillMaxSize() + modifier = Modifier + .windowInsetsPadding(WindowInsets.navigationBars) + .imePadding() + .fillMaxSize() ) { Column { Spacer( - modifier = Modifier.height(148.dp) + modifier = Modifier.height(140.dp) ) SetProfileNameTitle(modifier = Modifier.padding(bottom = 12.dp)) SetProfileNameDescription() - Spacer(modifier = Modifier.height(16.dp)) - SetProfileNameInput( - text = text, - onKeyboardActionDoneClicked = { onNextClicked(text.value) } + Spacer(modifier = Modifier.height(32.dp)) + OutlinedTextField( + value = innerValue, + onValueChange = { input -> + innerValue = input + isError = false + }, + shape = RoundedCornerShape(size = 16.dp), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + .focusRequester(focusRequester), + placeholder = { + Text( + text = stringResource(id = R.string.onboarding_your_name), + style = PreviewTitle1Regular, + color = Color(0xFF646464) + ) + }, + supportingText = { + if (isError) { + Text( + text = stringResource(id = R.string.onboarding_name_error), + color = colorResource(id = R.color.palette_system_red), + style = Caption1Regular + ) + } + }, + textStyle = PreviewTitle1Regular.copy( + color = Color(0xFFC2C2C2) + ), + singleLine = true, + colors = TextFieldDefaults.colors( + disabledTextColor = colorResource(id = R.color.text_primary), + cursorColor = Color(0xFFC2C2C2), + focusedContainerColor = Color(0xFF212121), + unfocusedContainerColor = Color(0xFF212121), + errorContainerColor = Color(0xFF212121), + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + errorIndicatorColor = Color.Transparent + ), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), + keyboardActions = KeyboardActions { + validateAndSubmit() + } ) - Spacer(modifier = Modifier.height(16.dp)) + Spacer(modifier = Modifier.height(32.dp)) } Image( modifier = Modifier .align(Alignment.TopStart) .padding(top = 16.dp, start = 9.dp) .noRippleClickable { - focus.clearFocus() + focusManager.clearFocus() onBackClicked() }, painter = painterResource(id = R.drawable.ic_back_onboarding_32), contentDescription = stringResource(R.string.content_description_back_button_icon) ) - SetProfileNameNextButton( + OnBoardingButtonPrimary( + text = stringResource(id = R.string.onboarding_button_continue), + onClick = { + validateAndSubmit() + }, + size = ButtonSize.Large, modifier = Modifier - .align(Alignment.BottomCenter) .fillMaxWidth() - .padding(start = 20.dp, end = 20.dp, bottom = 12.dp) - , - onNextClicked = onNextClicked, - text = text, - isLoading = isLoading + .padding( + start = 20.dp, + end = 20.dp, + bottom = 20.dp + ) + .align(Alignment.BottomCenter), + isLoading = isLoading, + enabled = innerValue.text.isNotEmpty() ) } } @@ -122,90 +209,36 @@ fun SetProfileNameTitle(modifier: Modifier) { Text( modifier = Modifier, text = stringResource(R.string.onboarding_set_your_name_title), - style = HeadlineHeading.copy( - color = OnBoardingTextPrimaryColor - ) + style = HeadlineTitleSemibold, + color = colorResource(id = R.color.text_white) ) } } -@Composable -fun SetProfileNameInput( - text: MutableState, - onKeyboardActionDoneClicked: () -> Unit -) { - Box( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight(), - contentAlignment = Alignment.Center - ) { - val focus = LocalFocusManager.current - val focusRequester = FocusRequester() - OnboardingInput( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .focusRequester(focusRequester) - , - text = text, - placeholder = stringResource(id = R.string.onboarding_your_name), - keyboardActions = KeyboardActions( - onDone = { - focus.clearFocus() - onKeyboardActionDoneClicked() - } - ) - ) - LaunchedEffect(Unit) { - focusRequester.requestFocus() - } - } -} - @Composable fun SetProfileNameDescription() { Box( modifier = Modifier .fillMaxWidth() - .padding(horizontal = 48.dp) + .padding(horizontal = 20.dp) .wrapContentHeight(), contentAlignment = Alignment.Center ) { Text( text = stringResource(id = R.string.onboarding_soul_creation_description), - style = HeadlineOnBoardingDescription.copy( - color = OnBoardingTextSecondaryColor, - textAlign = TextAlign.Center - ) + style = UXBody, + color = colorResource(id = R.color.text_white), + textAlign = TextAlign.Center ) } } -@Composable -fun SetProfileNameNextButton( - modifier: Modifier, - onNextClicked: (Name) -> Unit, - text: MutableState, - isLoading: Boolean -) { - val focus = LocalFocusManager.current - Box(modifier = modifier) { - OnBoardingButtonPrimary( - text = stringResource(id = R.string.done), - onClick = { - onNextClicked(text.value).also { - focus.clearFocus(force = true) - } - }, - size = ButtonSize.Large, - modifier = modifier, - isLoading = isLoading - ) - } -} - -@Preview +@Preview( + showBackground = true, + backgroundColor = 0xFF000000, + showSystemUi = true, + device = PIXEL_7 +) @Composable private fun SetProfileNameScreenPreview() { SetProfileNameScreen( diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/views/OnBoardingDesignSystemButtons.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/views/OnBoardingDesignSystemButtons.kt index fc2ce7138c..db6b54717a 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/views/OnBoardingDesignSystemButtons.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/views/OnBoardingDesignSystemButtons.kt @@ -76,7 +76,7 @@ fun OnBoardingButtonPrimary( Box() { Text( text = if (isLoading) "" else text, - style = size.textStyle + style = ButtonMedium ) if (isLoading) { val loadingAlpha by animateFloatAsState(targetValue = 1f) diff --git a/core-ui/src/main/res/drawable/ic_local_first_internet.xml b/core-ui/src/main/res/drawable/ic_local_first_internet.xml index ef3ce23355..796e14ed31 100644 --- a/core-ui/src/main/res/drawable/ic_local_first_internet.xml +++ b/core-ui/src/main/res/drawable/ic_local_first_internet.xml @@ -1,9 +1,9 @@ + android:width="340dp" + android:height="83dp" + android:viewportWidth="340" + android:viewportHeight="83"> + android:pathData="M24.93,10H22.25C22.06,9.01 21.7,8.09 21.18,7.24C20.66,6.39 20.02,5.65 19.24,5.01C18.47,4.38 17.59,3.89 16.6,3.54C15.62,3.19 14.55,3.01 13.41,3.01C11.57,3.01 9.89,3.49 8.38,4.45C6.87,5.4 5.66,6.81 4.75,8.66C3.86,10.51 3.41,12.77 3.41,15.45C3.41,18.15 3.86,20.43 4.75,22.27C5.66,24.12 6.87,25.52 8.38,26.48C9.89,27.42 11.57,27.9 13.41,27.9C14.55,27.9 15.62,27.72 16.6,27.37C17.59,27.02 18.47,26.53 19.24,25.91C20.02,25.27 20.66,24.53 21.18,23.68C21.7,22.83 22.06,21.9 22.25,20.91H24.93C24.69,22.24 24.24,23.49 23.59,24.64C22.95,25.79 22.12,26.79 21.12,27.66C20.12,28.52 18.98,29.19 17.68,29.67C16.38,30.16 14.96,30.4 13.41,30.4C10.96,30.4 8.79,29.79 6.9,28.57C5.01,27.33 3.52,25.6 2.44,23.37C1.37,21.13 0.83,18.49 0.83,15.45C0.83,12.41 1.37,9.78 2.44,7.54C3.52,5.31 5.01,3.58 6.9,2.36C8.79,1.13 10.96,0.51 13.41,0.51C14.96,0.51 16.38,0.75 17.68,1.24C18.98,1.71 20.12,2.38 21.12,3.25C22.12,4.11 22.95,5.12 23.59,6.26C24.24,7.41 24.69,8.66 24.93,10ZM28.64,30V8.18H31.1V11.53H31.28C31.72,10.44 32.47,9.55 33.55,8.88C34.64,8.2 35.87,7.86 37.25,7.86C37.46,7.86 37.69,7.86 37.94,7.87C38.2,7.88 38.41,7.89 38.58,7.9V10.47C38.47,10.45 38.27,10.42 37.99,10.38C37.7,10.35 37.39,10.33 37.06,10.33C35.93,10.33 34.91,10.57 34.02,11.05C33.14,11.52 32.45,12.18 31.93,13.03C31.42,13.87 31.17,14.83 31.17,15.91V30H28.64ZM49.05,30.45C47.02,30.45 45.26,29.98 43.77,29.03C42.28,28.08 41.13,26.76 40.32,25.07C39.51,23.38 39.11,21.43 39.11,19.22C39.11,17.02 39.51,15.07 40.32,13.37C41.13,11.65 42.25,10.31 43.68,9.35C45.12,8.37 46.79,7.88 48.67,7.88C49.85,7.88 50.99,8.1 52.09,8.54C53.19,8.96 54.18,9.62 55.05,10.51C55.93,11.39 56.62,12.5 57.14,13.85C57.65,15.18 57.9,16.77 57.9,18.59V19.84H40.86V17.61H55.32C55.32,16.21 55.03,14.95 54.47,13.84C53.91,12.71 53.13,11.82 52.12,11.16C51.13,10.51 49.98,10.18 48.67,10.18C47.29,10.18 46.07,10.55 45.02,11.29C43.97,12.03 43.14,13.01 42.55,14.22C41.96,15.43 41.66,16.76 41.65,18.2V19.53C41.65,21.26 41.95,22.78 42.55,24.08C43.15,25.36 44.01,26.36 45.12,27.07C46.23,27.78 47.54,28.14 49.05,28.14C50.09,28.14 50.99,27.98 51.77,27.66C52.55,27.33 53.21,26.9 53.74,26.36C54.28,25.81 54.69,25.21 54.96,24.56L57.36,25.34C57.03,26.26 56.49,27.11 55.73,27.88C54.98,28.66 54.04,29.28 52.92,29.76C51.8,30.22 50.51,30.45 49.05,30.45ZM67.57,30.5C66.25,30.5 65.05,30.24 63.96,29.73C62.87,29.21 62.01,28.46 61.36,27.49C60.72,26.5 60.4,25.31 60.4,23.91C60.4,22.83 60.6,21.92 61.01,21.18C61.41,20.44 61.99,19.83 62.74,19.36C63.49,18.89 64.37,18.51 65.4,18.24C66.42,17.96 67.54,17.75 68.78,17.6C70,17.45 71.03,17.32 71.87,17.2C72.72,17.09 73.37,16.91 73.82,16.66C74.26,16.42 74.49,16.02 74.49,15.47V14.96C74.49,13.47 74.04,12.3 73.15,11.45C72.27,10.59 71,10.16 69.34,10.16C67.77,10.16 66.49,10.5 65.49,11.19C64.51,11.88 63.82,12.7 63.42,13.64L61.02,12.77C61.51,11.58 62.19,10.63 63.07,9.91C63.94,9.2 64.91,8.68 65.99,8.37C67.07,8.04 68.17,7.88 69.27,7.88C70.11,7.88 70.97,7.99 71.87,8.21C72.78,8.43 73.62,8.81 74.4,9.35C75.18,9.88 75.81,10.62 76.29,11.58C76.77,12.52 77.01,13.73 77.01,15.18V30H74.49V26.55H74.33C74.03,27.19 73.58,27.82 72.98,28.42C72.38,29.03 71.64,29.53 70.74,29.91C69.84,30.3 68.78,30.5 67.57,30.5ZM67.91,28.18C69.25,28.18 70.42,27.88 71.4,27.29C72.39,26.69 73.15,25.9 73.68,24.91C74.22,23.92 74.49,22.83 74.49,21.63V18.48C74.3,18.66 73.98,18.82 73.53,18.96C73.1,19.11 72.59,19.23 72.01,19.35C71.45,19.45 70.88,19.54 70.31,19.62C69.74,19.69 69.23,19.76 68.78,19.82C67.54,19.97 66.49,20.2 65.62,20.53C64.75,20.85 64.08,21.29 63.62,21.86C63.16,22.42 62.92,23.14 62.92,24.02C62.92,25.35 63.4,26.37 64.34,27.1C65.29,27.82 66.48,28.18 67.91,28.18ZM90.33,8.18V10.38H79.92V8.18H90.33ZM83.18,2.95H85.72V24.3C85.72,25.21 85.87,25.93 86.19,26.45C86.5,26.96 86.91,27.32 87.41,27.54C87.91,27.75 88.44,27.86 89.01,27.86C89.34,27.86 89.63,27.84 89.87,27.8C90.1,27.75 90.31,27.7 90.49,27.66L91.03,29.94C90.78,30.04 90.48,30.12 90.12,30.2C89.76,30.28 89.32,30.33 88.79,30.33C87.86,30.33 86.96,30.12 86.1,29.72C85.25,29.31 84.55,28.7 84,27.9C83.45,27.09 83.18,26.09 83.18,24.9V2.95ZM102.66,30.45C100.63,30.45 98.87,29.98 97.38,29.03C95.89,28.08 94.74,26.76 93.93,25.07C93.12,23.38 92.72,21.43 92.72,19.22C92.72,17.02 93.12,15.07 93.93,13.37C94.74,11.65 95.86,10.31 97.29,9.35C98.73,8.37 100.39,7.88 102.28,7.88C103.46,7.88 104.6,8.1 105.7,8.54C106.8,8.96 107.79,9.62 108.66,10.51C109.54,11.39 110.23,12.5 110.75,13.85C111.26,15.18 111.51,16.77 111.51,18.59V19.84H94.47V17.61H108.93C108.93,16.21 108.64,14.95 108.07,13.84C107.52,12.71 106.74,11.82 105.73,11.16C104.74,10.51 103.59,10.18 102.28,10.18C100.9,10.18 99.68,10.55 98.63,11.29C97.58,12.03 96.75,13.01 96.16,14.22C95.57,15.43 95.27,16.76 95.26,18.2V19.53C95.26,21.26 95.56,22.78 96.16,24.08C96.76,25.36 97.62,26.36 98.73,27.07C99.84,27.78 101.15,28.14 102.66,28.14C103.69,28.14 104.6,27.98 105.38,27.66C106.16,27.33 106.82,26.9 107.35,26.36C107.89,25.81 108.3,25.21 108.57,24.56L110.97,25.34C110.64,26.26 110.1,27.11 109.34,27.88C108.59,28.66 107.65,29.28 106.53,29.76C105.41,30.22 104.12,30.45 102.66,30.45ZM132.12,30.4C130.33,30.4 128.77,30.05 127.43,29.36C126.1,28.66 125.06,27.71 124.32,26.51C123.58,25.3 123.21,23.94 123.21,22.43C123.21,21.33 123.43,20.34 123.88,19.46C124.33,18.57 124.99,17.73 125.84,16.93C126.69,16.13 127.72,15.29 128.94,14.43L133.15,11.29C134.16,10.57 134.92,9.87 135.44,9.18C135.97,8.48 136.24,7.62 136.24,6.61C136.24,5.63 135.87,4.76 135.13,3.99C134.4,3.21 133.45,2.83 132.29,2.83C131.47,2.83 130.74,3.03 130.1,3.44C129.47,3.84 128.96,4.38 128.58,5.03C128.21,5.67 128.03,6.35 128.03,7.06C128.03,7.72 128.2,8.39 128.54,9.06C128.88,9.73 129.34,10.43 129.92,11.16C130.49,11.89 131.14,12.7 131.85,13.58L145.14,30H142.08L130.49,15.78C129.51,14.59 128.64,13.52 127.89,12.59C127.13,11.64 126.53,10.73 126.1,9.86C125.66,8.98 125.44,8.04 125.44,7.03C125.44,5.79 125.73,4.69 126.31,3.72C126.89,2.75 127.68,1.98 128.7,1.42C129.72,0.86 130.89,0.58 132.2,0.58C133.55,0.58 134.71,0.86 135.7,1.41C136.69,1.96 137.46,2.68 138,3.59C138.55,4.5 138.82,5.51 138.82,6.61C138.82,7.92 138.48,9.09 137.8,10.1C137.13,11.11 136.15,12.11 134.86,13.08L129.58,17.03C128.13,18.12 127.13,19.13 126.59,20.06C126.05,20.98 125.78,21.78 125.78,22.43C125.78,23.45 126.05,24.39 126.58,25.26C127.11,26.12 127.84,26.81 128.78,27.33C129.73,27.85 130.81,28.12 132.03,28.13C133.24,28.12 134.39,27.87 135.46,27.4C136.53,26.92 137.48,26.23 138.33,25.34C139.18,24.45 139.86,23.39 140.37,22.14C140.89,20.9 141.2,19.52 141.28,18L143.74,18.03C143.7,19.59 143.49,20.91 143.1,22C142.72,23.08 142.28,23.97 141.79,24.67C141.3,25.37 140.87,25.94 140.5,26.36C140.4,26.51 140.29,26.65 140.19,26.79C140.08,26.93 139.97,27.07 139.86,27.22C138.91,28.26 137.73,29.05 136.32,29.59C134.92,30.13 133.52,30.4 132.12,30.4ZM164.95,30.45C163,30.45 161.3,29.97 159.85,28.99C158.41,28.02 157.29,26.68 156.5,24.99C155.7,23.29 155.31,21.36 155.31,19.19C155.31,17 155.71,15.06 156.51,13.35C157.33,11.65 158.45,10.31 159.89,9.35C161.33,8.37 163.01,7.88 164.91,7.88C166.37,7.88 167.69,8.17 168.87,8.74C170.05,9.29 171.03,10.09 171.8,11.11C172.57,12.12 173.06,13.3 173.26,14.66H170.7C170.44,13.43 169.8,12.38 168.79,11.51C167.78,10.63 166.5,10.18 164.95,10.18C163.56,10.18 162.33,10.56 161.26,11.32C160.19,12.07 159.35,13.12 158.74,14.46C158.15,15.8 157.85,17.34 157.85,19.11C157.85,20.88 158.14,22.44 158.73,23.81C159.32,25.16 160.14,26.22 161.2,26.99C162.27,27.76 163.52,28.14 164.95,28.14C165.92,28.14 166.8,27.96 167.59,27.6C168.4,27.23 169.07,26.71 169.61,26.04C170.16,25.36 170.53,24.56 170.72,23.64H173.27C173.09,24.95 172.62,26.13 171.87,27.16C171.13,28.18 170.17,28.99 168.99,29.57C167.81,30.16 166.47,30.45 164.95,30.45ZM185.17,30.45C183.29,30.45 181.62,29.98 180.17,29.02C178.73,28.06 177.61,26.74 176.79,25.06C175.98,23.36 175.57,21.41 175.57,19.19C175.57,16.96 175.98,14.99 176.79,13.3C177.61,11.59 178.73,10.27 180.17,9.32C181.62,8.36 183.29,7.88 185.17,7.88C187.06,7.88 188.72,8.36 190.16,9.32C191.6,10.27 192.73,11.6 193.54,13.3C194.36,14.99 194.78,16.96 194.78,19.19C194.78,21.41 194.37,23.36 193.55,25.06C192.74,26.74 191.61,28.06 190.16,29.02C188.72,29.98 187.06,30.45 185.17,30.45ZM185.17,28.14C186.69,28.14 187.97,27.73 189.02,26.92C190.07,26.1 190.87,25.02 191.41,23.66C191.96,22.31 192.23,20.82 192.23,19.19C192.23,17.56 191.96,16.07 191.41,14.7C190.87,13.34 190.07,12.24 189.02,11.42C187.97,10.6 186.69,10.18 185.17,10.18C183.67,10.18 182.38,10.6 181.32,11.42C180.27,12.24 179.47,13.34 178.92,14.7C178.38,16.07 178.11,17.56 178.11,19.19C178.11,20.82 178.38,22.31 178.92,23.66C179.47,25.02 180.27,26.1 181.32,26.92C182.38,27.73 183.66,28.14 185.17,28.14ZM200.85,0.91V30H198.33V0.91H200.85ZM208.07,0.91V30H205.54V0.91H208.07ZM218.86,30.5C217.54,30.5 216.34,30.24 215.25,29.73C214.16,29.21 213.29,28.46 212.65,27.49C212.01,26.5 211.68,25.31 211.68,23.91C211.68,22.83 211.89,21.92 212.29,21.18C212.7,20.44 213.28,19.83 214.03,19.36C214.78,18.89 215.66,18.51 216.68,18.24C217.71,17.96 218.83,17.75 220.07,17.6C221.29,17.45 222.32,17.32 223.16,17.2C224.01,17.09 224.66,16.91 225.11,16.66C225.55,16.42 225.77,16.02 225.77,15.47V14.96C225.77,13.47 225.33,12.3 224.44,11.45C223.56,10.59 222.29,10.16 220.63,10.16C219.06,10.16 217.78,10.5 216.78,11.19C215.8,11.88 215.11,12.7 214.71,13.64L212.31,12.77C212.8,11.58 213.48,10.63 214.35,9.91C215.23,9.2 216.2,8.68 217.28,8.37C218.36,8.04 219.45,7.88 220.56,7.88C221.4,7.88 222.26,7.99 223.16,8.21C224.07,8.43 224.91,8.81 225.69,9.35C226.47,9.88 227.1,10.62 227.58,11.58C228.06,12.52 228.3,13.73 228.3,15.18V30H225.77V26.55H225.62C225.32,27.19 224.87,27.82 224.27,28.42C223.67,29.03 222.93,29.53 222.02,29.91C221.13,30.3 220.07,30.5 218.86,30.5ZM219.2,28.18C220.54,28.18 221.71,27.88 222.69,27.29C223.68,26.69 224.43,25.9 224.97,24.91C225.51,23.92 225.77,22.83 225.77,21.63V18.48C225.59,18.66 225.27,18.82 224.82,18.96C224.39,19.11 223.88,19.23 223.3,19.35C222.74,19.45 222.17,19.54 221.6,19.62C221.03,19.69 220.52,19.76 220.07,19.82C218.83,19.97 217.78,20.2 216.91,20.53C216.04,20.85 215.37,21.29 214.91,21.86C214.45,22.42 214.21,23.14 214.21,24.02C214.21,25.35 214.69,26.37 215.63,27.1C216.58,27.82 217.77,28.18 219.2,28.18ZM233.55,30V0.91H236.1V12.34H236.32C236.61,11.69 237.02,11.02 237.55,10.33C238.09,9.64 238.79,9.06 239.66,8.59C240.54,8.12 241.65,7.88 242.99,7.88C244.78,7.88 246.35,8.36 247.7,9.3C249.06,10.24 250.11,11.56 250.87,13.25C251.63,14.94 252.01,16.9 252.01,19.15C252.01,21.4 251.63,23.38 250.87,25.07C250.12,26.77 249.07,28.09 247.72,29.03C246.37,29.98 244.81,30.45 243.03,30.45C241.7,30.45 240.6,30.22 239.71,29.74C238.82,29.27 238.12,28.69 237.57,28C237.04,27.3 236.62,26.61 236.32,25.95H236.01V30H233.55ZM236.05,19.11C236.05,20.87 236.32,22.43 236.84,23.79C237.37,25.15 238.12,26.21 239.11,26.99C240.1,27.76 241.31,28.14 242.72,28.14C244.17,28.14 245.39,27.74 246.4,26.95C247.4,26.14 248.16,25.06 248.68,23.69C249.2,22.33 249.46,20.8 249.46,19.11C249.46,17.43 249.2,15.92 248.68,14.57C248.17,13.23 247.41,12.16 246.41,11.38C245.41,10.58 244.18,10.18 242.72,10.18C241.3,10.18 240.09,10.57 239.1,11.34C238.11,12.09 237.36,13.14 236.84,14.49C236.32,15.82 236.05,17.36 236.05,19.11ZM264.04,30.45C262.16,30.45 260.49,29.98 259.04,29.02C257.6,28.06 256.48,26.74 255.66,25.06C254.85,23.36 254.44,21.41 254.44,19.19C254.44,16.96 254.85,14.99 255.66,13.3C256.48,11.59 257.6,10.27 259.04,9.32C260.49,8.36 262.16,7.88 264.04,7.88C265.92,7.88 267.59,8.36 269.03,9.32C270.47,10.27 271.59,11.6 272.41,13.3C273.23,14.99 273.64,16.96 273.64,19.19C273.64,21.41 273.24,23.36 272.42,25.06C271.61,26.74 270.48,28.06 269.03,29.02C267.59,29.98 265.92,30.45 264.04,30.45ZM264.04,28.14C265.56,28.14 266.84,27.73 267.89,26.92C268.94,26.1 269.74,25.02 270.28,23.66C270.83,22.31 271.1,20.82 271.1,19.19C271.1,17.56 270.83,16.07 270.28,14.7C269.74,13.34 268.94,12.24 267.89,11.42C266.84,10.6 265.56,10.18 264.04,10.18C262.54,10.18 261.25,10.6 260.19,11.42C259.14,12.24 258.34,13.34 257.79,14.7C257.25,16.07 256.98,17.56 256.98,19.19C256.98,20.82 257.25,22.31 257.79,23.66C258.34,25.02 259.14,26.1 260.19,26.92C261.24,27.73 262.53,28.14 264.04,28.14ZM277.19,30V8.18H279.65V11.53H279.84C280.27,10.44 281.03,9.55 282.11,8.88C283.2,8.2 284.43,7.86 285.8,7.86C286.01,7.86 286.24,7.86 286.5,7.87C286.75,7.88 286.97,7.89 287.14,7.9V10.47C287.02,10.45 286.82,10.42 286.54,10.38C286.26,10.35 285.95,10.33 285.62,10.33C284.48,10.33 283.47,10.57 282.58,11.05C281.7,11.52 281,12.18 280.49,13.03C279.98,13.87 279.72,14.83 279.72,15.91V30H277.19ZM295.55,30.5C294.23,30.5 293.03,30.24 291.94,29.73C290.85,29.21 289.98,28.46 289.34,27.49C288.69,26.5 288.37,25.31 288.37,23.91C288.37,22.83 288.58,21.92 288.98,21.18C289.39,20.44 289.97,19.83 290.72,19.36C291.46,18.89 292.35,18.51 293.37,18.24C294.39,17.96 295.52,17.75 296.75,17.6C297.97,17.45 299.01,17.32 299.85,17.2C300.7,17.09 301.35,16.91 301.8,16.66C302.24,16.42 302.46,16.02 302.46,15.47V14.96C302.46,13.47 302.02,12.3 301.13,11.45C300.25,10.59 298.98,10.16 297.32,10.16C295.75,10.16 294.47,10.5 293.47,11.19C292.49,11.88 291.8,12.7 291.4,13.64L289,12.77C289.49,11.58 290.17,10.63 291.04,9.91C291.91,9.2 292.89,8.68 293.97,8.37C295.05,8.04 296.14,7.88 297.25,7.88C298.08,7.88 298.95,7.99 299.85,8.21C300.76,8.43 301.6,8.81 302.38,9.35C303.15,9.88 303.78,10.62 304.27,11.58C304.75,12.52 304.99,13.73 304.99,15.18V30H302.46V26.55H302.31C302,27.19 301.55,27.82 300.96,28.42C300.36,29.03 299.61,29.53 298.71,29.91C297.81,30.3 296.76,30.5 295.55,30.5ZM295.89,28.18C297.23,28.18 298.39,27.88 299.38,27.29C300.36,26.69 301.12,25.9 301.65,24.91C302.19,23.92 302.46,22.83 302.46,21.63V18.48C302.27,18.66 301.96,18.82 301.51,18.96C301.08,19.11 300.57,19.23 299.99,19.35C299.42,19.45 298.86,19.54 298.29,19.62C297.72,19.69 297.21,19.76 296.75,19.82C295.52,19.97 294.47,20.2 293.6,20.53C292.73,20.85 292.06,21.29 291.6,21.86C291.13,22.42 290.9,23.14 290.9,24.02C290.9,25.35 291.37,26.37 292.32,27.1C293.27,27.82 294.46,28.18 295.89,28.18ZM318.31,8.18V10.38H307.9V8.18H318.31ZM311.15,2.95H313.69V24.3C313.69,25.21 313.85,25.93 314.16,26.45C314.48,26.96 314.88,27.32 315.39,27.54C315.89,27.75 316.42,27.86 316.99,27.86C317.32,27.86 317.61,27.84 317.84,27.8C318.08,27.75 318.29,27.7 318.47,27.66L319.01,29.94C318.76,30.04 318.46,30.12 318.1,30.2C317.74,30.28 317.29,30.33 316.76,30.33C315.83,30.33 314.94,30.12 314.08,29.72C313.23,29.31 312.52,28.7 311.98,27.9C311.43,27.09 311.15,26.09 311.15,24.9V2.95ZM330.64,30.45C328.6,30.45 326.84,29.98 325.36,29.03C323.87,28.08 322.72,26.76 321.9,25.07C321.1,23.38 320.7,21.43 320.7,19.22C320.7,17.02 321.1,15.07 321.9,13.37C322.72,11.65 323.84,10.31 325.27,9.35C326.71,8.37 328.37,7.88 330.26,7.88C331.44,7.88 332.58,8.1 333.68,8.54C334.78,8.96 335.76,9.62 336.63,10.51C337.52,11.39 338.21,12.5 338.72,13.85C339.23,15.18 339.49,16.77 339.49,18.59V19.84H322.44V17.61H336.9C336.9,16.21 336.62,14.95 336.05,13.84C335.49,12.71 334.71,11.82 333.71,11.16C332.71,10.51 331.56,10.18 330.26,10.18C328.87,10.18 327.66,10.55 326.61,11.29C325.55,12.03 324.73,13.01 324.13,14.22C323.55,15.43 323.25,16.76 323.24,18.2V19.53C323.24,21.26 323.54,22.78 324.13,24.08C324.74,25.36 325.6,26.36 326.7,27.07C327.81,27.78 329.12,28.14 330.64,28.14C331.67,28.14 332.58,27.98 333.35,27.66C334.14,27.33 334.8,26.9 335.33,26.36C335.87,25.81 336.27,25.21 336.55,24.56L338.95,25.34C338.62,26.26 338.07,27.11 337.32,27.88C336.57,28.66 335.63,29.28 334.5,29.76C333.39,30.22 332.1,30.45 330.64,30.45ZM17.14,74V52.18H19.68V74H17.14ZM18.43,48.43C17.91,48.43 17.47,48.26 17.1,47.91C16.73,47.55 16.54,47.12 16.54,46.61C16.54,46.11 16.73,45.69 17.1,45.34C17.47,44.98 17.91,44.8 18.43,44.8C18.95,44.8 19.4,44.98 19.77,45.34C20.14,45.69 20.32,46.11 20.32,46.61C20.32,47.12 20.14,47.55 19.77,47.91C19.4,48.26 18.95,48.43 18.43,48.43ZM26.9,60.36V74H24.37V52.18H26.83V55.61H27.05C27.57,54.49 28.36,53.59 29.44,52.92C30.53,52.24 31.87,51.9 33.47,51.9C34.94,51.9 36.23,52.21 37.34,52.82C38.46,53.43 39.32,54.32 39.94,55.51C40.56,56.69 40.88,58.14 40.88,59.87V74H38.35V60.02C38.35,58.23 37.84,56.82 36.84,55.78C35.85,54.73 34.51,54.21 32.84,54.21C31.69,54.21 30.67,54.46 29.78,54.95C28.89,55.44 28.19,56.15 27.66,57.08C27.15,58 26.9,59.09 26.9,60.36ZM69.44,56.97L67.13,57.62C66.9,56.97 66.58,56.38 66.16,55.85C65.74,55.32 65.2,54.89 64.53,54.58C63.86,54.27 63.04,54.11 62.06,54.11C60.58,54.11 59.37,54.46 58.42,55.16C57.47,55.87 57,56.77 57,57.88C57,58.82 57.32,59.58 57.97,60.16C58.62,60.74 59.62,61.2 60.98,61.54L64.27,62.35C66.1,62.8 67.47,63.5 68.38,64.47C69.3,65.43 69.75,66.65 69.75,68.11C69.75,69.34 69.41,70.43 68.73,71.39C68.05,72.34 67.1,73.1 65.88,73.64C64.67,74.18 63.26,74.45 61.66,74.45C59.53,74.45 57.77,73.98 56.39,73.02C55.01,72.05 54.12,70.66 53.73,68.84L56.16,68.25C56.47,69.54 57.08,70.52 57.99,71.19C58.91,71.85 60.12,72.18 61.62,72.18C63.29,72.18 64.63,71.81 65.64,71.06C66.64,70.3 67.14,69.36 67.14,68.22C67.14,67.34 66.85,66.6 66.26,66C65.67,65.4 64.78,64.95 63.59,64.67L60.02,63.82C58.13,63.36 56.73,62.64 55.82,61.66C54.91,60.67 54.46,59.45 54.46,57.99C54.46,56.79 54.78,55.73 55.44,54.82C56.09,53.91 56.99,53.19 58.14,52.66C59.28,52.14 60.59,51.88 62.06,51.88C64.05,51.88 65.65,52.34 66.84,53.25C68.05,54.15 68.91,55.39 69.44,56.97ZM73.29,82.18V52.18H75.75V56.34H76.05C76.35,55.69 76.77,55.02 77.3,54.34C77.83,53.65 78.53,53.07 79.4,52.59C80.28,52.12 81.39,51.88 82.72,51.88C84.52,51.88 86.09,52.36 87.44,53.3C88.79,54.24 89.84,55.56 90.59,57.25C91.35,58.94 91.73,60.9 91.73,63.15C91.73,65.4 91.35,67.38 90.59,69.07C89.84,70.77 88.79,72.09 87.44,73.03C86.09,73.98 84.53,74.45 82.75,74.45C81.44,74.45 80.33,74.22 79.44,73.74C78.56,73.27 77.85,72.69 77.3,72C76.76,71.3 76.34,70.61 76.05,69.95H75.82V82.18H73.29ZM75.79,63.11C75.79,64.87 76.05,66.43 76.57,67.79C77.1,69.15 77.86,70.21 78.85,70.99C79.84,71.76 81.04,72.14 82.45,72.14C83.9,72.14 85.12,71.74 86.12,70.95C87.12,70.14 87.88,69.06 88.4,67.69C88.94,66.33 89.2,64.8 89.2,63.11C89.2,61.43 88.94,59.92 88.42,58.57C87.91,57.23 87.15,56.16 86.15,55.38C85.14,54.58 83.91,54.18 82.45,54.18C81.03,54.18 79.83,54.57 78.83,55.34C77.84,56.09 77.08,57.14 76.56,58.49C76.05,59.82 75.79,61.36 75.79,63.11ZM101.37,74.5C100.05,74.5 98.85,74.24 97.76,73.73C96.67,73.21 95.81,72.46 95.16,71.49C94.52,70.5 94.2,69.31 94.2,67.91C94.2,66.83 94.4,65.92 94.81,65.18C95.21,64.44 95.79,63.83 96.54,63.36C97.29,62.89 98.17,62.51 99.2,62.24C100.22,61.96 101.35,61.75 102.58,61.6C103.8,61.45 104.83,61.32 105.67,61.2C106.53,61.09 107.17,60.91 107.62,60.66C108.06,60.42 108.29,60.02 108.29,59.47V58.96C108.29,57.47 107.84,56.3 106.95,55.45C106.07,54.59 104.8,54.16 103.14,54.16C101.57,54.16 100.29,54.5 99.3,55.19C98.31,55.88 97.62,56.7 97.22,57.64L94.82,56.77C95.31,55.58 96,54.63 96.87,53.91C97.74,53.2 98.71,52.68 99.79,52.37C100.87,52.04 101.97,51.88 103.07,51.88C103.91,51.88 104.77,51.99 105.67,52.21C106.58,52.43 107.43,52.81 108.2,53.35C108.98,53.88 109.61,54.62 110.09,55.58C110.57,56.52 110.82,57.73 110.82,59.18V74H108.29V70.55H108.13C107.83,71.19 107.38,71.82 106.78,72.42C106.18,73.03 105.44,73.53 104.54,73.91C103.64,74.3 102.58,74.5 101.37,74.5ZM101.71,72.18C103.06,72.18 104.22,71.88 105.21,71.29C106.19,70.69 106.95,69.9 107.48,68.91C108.02,67.92 108.29,66.83 108.29,65.63V62.48C108.1,62.66 107.78,62.82 107.33,62.96C106.9,63.11 106.39,63.23 105.82,63.35C105.25,63.45 104.68,63.54 104.11,63.62C103.54,63.69 103.03,63.76 102.58,63.82C101.35,63.97 100.29,64.2 99.42,64.53C98.55,64.85 97.88,65.29 97.42,65.86C96.96,66.42 96.72,67.14 96.72,68.02C96.72,69.35 97.2,70.37 98.14,71.1C99.09,71.82 100.28,72.18 101.71,72.18ZM124.06,74.45C122.11,74.45 120.41,73.97 118.96,72.99C117.53,72.02 116.41,70.68 115.61,68.99C114.82,67.29 114.42,65.36 114.42,63.19C114.42,61 114.82,59.06 115.63,57.35C116.44,55.65 117.57,54.31 119.01,53.35C120.45,52.37 122.12,51.88 124.02,51.88C125.48,51.88 126.8,52.17 127.98,52.74C129.17,53.29 130.14,54.09 130.91,55.11C131.69,56.12 132.18,57.3 132.37,58.66H129.82C129.55,57.43 128.91,56.38 127.9,55.51C126.89,54.63 125.62,54.18 124.06,54.18C122.67,54.18 121.44,54.56 120.37,55.32C119.3,56.07 118.46,57.12 117.86,58.46C117.26,59.8 116.96,61.34 116.96,63.11C116.96,64.88 117.25,66.44 117.84,67.81C118.43,69.16 119.25,70.22 120.31,70.99C121.38,71.76 122.63,72.14 124.06,72.14C125.03,72.14 125.91,71.96 126.71,71.6C127.51,71.23 128.18,70.71 128.72,70.04C129.27,69.36 129.64,68.56 129.83,67.64H132.39C132.2,68.95 131.73,70.13 130.98,71.16C130.24,72.18 129.28,72.99 128.1,73.57C126.92,74.16 125.58,74.45 124.06,74.45ZM144.63,74.45C142.59,74.45 140.83,73.98 139.34,73.03C137.86,72.08 136.71,70.76 135.89,69.07C135.09,67.38 134.68,65.43 134.68,63.22C134.68,61.02 135.09,59.07 135.89,57.37C136.71,55.65 137.83,54.31 139.26,53.35C140.7,52.37 142.36,51.88 144.24,51.88C145.43,51.88 146.57,52.1 147.67,52.54C148.77,52.96 149.75,53.62 150.62,54.51C151.5,55.39 152.2,56.5 152.71,57.85C153.22,59.18 153.48,60.77 153.48,62.59V63.84H136.43V61.61H150.89C150.89,60.21 150.61,58.95 150.04,57.84C149.48,56.71 148.7,55.82 147.7,55.16C146.7,54.51 145.55,54.18 144.24,54.18C142.86,54.18 141.65,54.55 140.59,55.29C139.54,56.03 138.72,57.01 138.12,58.22C137.54,59.43 137.24,60.76 137.23,62.2V63.53C137.23,65.26 137.53,66.78 138.12,68.08C138.73,69.36 139.59,70.36 140.69,71.07C141.8,71.78 143.11,72.14 144.63,72.14C145.66,72.14 146.56,71.98 147.34,71.66C148.13,71.33 148.79,70.9 149.32,70.36C149.85,69.81 150.26,69.21 150.54,68.56L152.94,69.34C152.61,70.26 152.06,71.11 151.3,71.88C150.56,72.66 149.62,73.29 148.49,73.76C147.37,74.22 146.09,74.45 144.63,74.45ZM171.71,56.97L169.39,57.62C169.16,56.97 168.84,56.38 168.43,55.85C168.01,55.32 167.47,54.89 166.79,54.58C166.13,54.27 165.31,54.11 164.32,54.11C162.84,54.11 161.63,54.46 160.68,55.16C159.74,55.87 159.26,56.77 159.26,57.88C159.26,58.82 159.59,59.58 160.23,60.16C160.88,60.74 161.89,61.2 163.24,61.54L166.54,62.35C168.37,62.8 169.73,63.5 170.64,64.47C171.56,65.43 172.02,66.65 172.02,68.11C172.02,69.34 171.68,70.43 171,71.39C170.32,72.34 169.36,73.1 168.14,73.64C166.93,74.18 165.52,74.45 163.92,74.45C161.79,74.45 160.04,73.98 158.65,73.02C157.27,72.05 156.39,70.66 156,68.84L158.43,68.25C158.74,69.54 159.35,70.52 160.26,71.19C161.18,71.85 162.38,72.18 163.88,72.18C165.56,72.18 166.9,71.81 167.9,71.06C168.9,70.3 169.41,69.36 169.41,68.22C169.41,67.34 169.11,66.6 168.53,66C167.94,65.4 167.05,64.95 165.86,64.67L162.29,63.82C160.4,63.36 158.99,62.64 158.09,61.66C157.18,60.67 156.72,59.45 156.72,57.99C156.72,56.79 157.05,55.73 157.7,54.82C158.36,53.91 159.26,53.19 160.4,52.66C161.55,52.14 162.85,51.88 164.32,51.88C166.32,51.88 167.91,52.34 169.11,53.25C170.31,54.15 171.18,55.39 171.71,56.97ZM186.57,82.18C186.07,82.18 185.6,82.13 185.16,82.04C184.73,81.95 184.38,81.84 184.13,81.73L184.81,79.5C185.67,79.76 186.44,79.86 187.11,79.78C187.78,79.71 188.38,79.41 188.9,78.87C189.42,78.34 189.88,77.53 190.29,76.43L191.09,74.21L183.06,52.18H185.8L192.28,70.66H192.48L198.96,52.18H201.7L192.46,77.45C192.07,78.5 191.6,79.38 191.03,80.08C190.46,80.79 189.8,81.32 189.05,81.66C188.32,82.01 187.49,82.18 186.57,82.18ZM212.34,74.45C210.46,74.45 208.79,73.98 207.34,73.02C205.9,72.06 204.77,70.74 203.96,69.06C203.15,67.36 202.74,65.41 202.74,63.19C202.74,60.96 203.15,58.99 203.96,57.3C204.77,55.59 205.9,54.27 207.34,53.32C208.79,52.36 210.46,51.88 212.34,51.88C214.23,51.88 215.89,52.36 217.33,53.32C218.77,54.27 219.89,55.6 220.71,57.3C221.53,58.99 221.94,60.96 221.94,63.19C221.94,65.41 221.54,67.36 220.72,69.06C219.91,70.74 218.78,72.06 217.33,73.02C215.89,73.98 214.23,74.45 212.34,74.45ZM212.34,72.14C213.86,72.14 215.14,71.73 216.19,70.92C217.24,70.1 218.04,69.02 218.58,67.66C219.13,66.31 219.4,64.82 219.4,63.19C219.4,61.56 219.13,60.07 218.58,58.7C218.04,57.34 217.24,56.24 216.19,55.42C215.14,54.6 213.86,54.18 212.34,54.18C210.84,54.18 209.55,54.6 208.49,55.42C207.44,56.24 206.64,57.34 206.09,58.7C205.55,60.07 205.28,61.56 205.28,63.19C205.28,64.82 205.55,66.31 206.09,67.66C206.64,69.02 207.44,70.1 208.49,70.92C209.54,71.73 210.83,72.14 212.34,72.14ZM239.36,65.66V52.18H241.89V74H239.36V70.38H239.16C238.65,71.5 237.84,72.43 236.73,73.18C235.62,73.91 234.27,74.28 232.67,74.28C231.28,74.28 230.04,73.98 228.96,73.38C227.88,72.76 227.03,71.86 226.42,70.68C225.8,69.49 225.49,68.04 225.49,66.32V52.18H228.02V66.16C228.02,67.86 228.52,69.24 229.53,70.28C230.53,71.31 231.82,71.83 233.39,71.83C234.38,71.83 235.32,71.59 236.23,71.12C237.14,70.64 237.89,69.95 238.48,69.04C239.06,68.12 239.36,67 239.36,65.66ZM264.31,74.45C262.43,74.45 260.76,73.98 259.31,73.02C257.87,72.06 256.74,70.74 255.93,69.06C255.12,67.36 254.71,65.41 254.71,63.19C254.71,60.96 255.12,58.99 255.93,57.3C256.74,55.59 257.87,54.27 259.31,53.32C260.76,52.36 262.43,51.88 264.31,51.88C266.2,51.88 267.86,52.36 269.3,53.32C270.74,54.27 271.86,55.6 272.68,57.3C273.5,58.99 273.91,60.96 273.91,63.19C273.91,65.41 273.51,67.36 272.69,69.06C271.88,70.74 270.74,72.06 269.3,73.02C267.86,73.98 266.2,74.45 264.31,74.45ZM264.31,72.14C265.83,72.14 267.11,71.73 268.16,70.92C269.21,70.1 270.01,69.02 270.55,67.66C271.1,66.31 271.37,64.82 271.37,63.19C271.37,61.56 271.1,60.07 270.55,58.7C270.01,57.34 269.21,56.24 268.16,55.42C267.11,54.6 265.83,54.18 264.31,54.18C262.8,54.18 261.52,54.6 260.46,55.42C259.41,56.24 258.61,57.34 258.06,58.7C257.52,60.07 257.25,61.56 257.25,63.19C257.25,64.82 257.52,66.31 258.06,67.66C258.61,69.02 259.41,70.1 260.46,70.92C261.51,71.73 262.8,72.14 264.31,72.14ZM281.57,74L274.97,52.18H277.64L282.82,70.18H283L288.16,52.18H290.84L295.95,70.14H296.15L301.32,52.18H303.99L297.4,74H294.79L289.62,56.12H289.35L284.18,74H281.57ZM309.44,60.36V74H306.91V52.18H309.37V55.61H309.59C310.1,54.49 310.9,53.59 311.98,52.92C313.07,52.24 314.41,51.9 316.01,51.9C317.48,51.9 318.77,52.21 319.88,52.82C320.99,53.43 321.86,54.32 322.48,55.51C323.1,56.69 323.41,58.14 323.41,59.87V74H320.89V60.02C320.89,58.23 320.38,56.82 319.38,55.78C318.39,54.73 317.05,54.21 315.37,54.21C314.23,54.21 313.21,54.46 312.32,54.95C311.43,55.44 310.73,56.15 310.2,57.08C309.69,58 309.44,59.09 309.44,60.36ZM330.09,74.21C329.53,74.21 329.05,74.01 328.64,73.62C328.24,73.21 328.04,72.73 328.04,72.17C328.04,71.6 328.24,71.12 328.64,70.72C329.05,70.32 329.53,70.12 330.09,70.12C330.66,70.12 331.14,70.32 331.54,70.72C331.94,71.12 332.14,71.6 332.14,72.17C332.14,72.54 332.04,72.88 331.85,73.19C331.67,73.5 331.42,73.75 331.11,73.94C330.81,74.12 330.47,74.21 330.09,74.21Z" + android:fillColor="#F3F3F3"/> diff --git a/core-ui/src/main/res/drawable/ic_plus_18.xml b/core-ui/src/main/res/drawable/ic_plus_18.xml new file mode 100644 index 0000000000..bd677db2da --- /dev/null +++ b/core-ui/src/main/res/drawable/ic_plus_18.xml @@ -0,0 +1,9 @@ + + + diff --git a/localization/src/main/res/values/strings.xml b/localization/src/main/res/values/strings.xml index ecd55eeb26..36419e39f3 100644 --- a/localization/src/main/res/values/strings.xml +++ b/localization/src/main/res/values/strings.xml @@ -1111,24 +1111,24 @@ the everything app - for those\nwho celebrate\ntrust & autonomy + Encrypted, offline\n& open Create & collaborate in spaces you own. Encrypted, offline & open. "By continuing you agree to " Terms\u00A0of\u00A0Use " and " Privacy\u00A0Policy I am new here - Enter my Vault - Already have a Key + Next + I already have a key Get my Key Enter your invite code If you don\'t have one just go to anytype.io\nand sign up to the waiting list. This is your Void It is an encrypted location for everything you create. Everything is stored on your device, and backed up to the distributed network. This is your Key - It gives you full ownership over your vault. + It replaces login and password. Keep it safe — you control your data. You can find this Key later in app settings. Show my Key - Tap to Reveal + Reveal and copy Skip Not now Copy to clipboard @@ -1138,9 +1138,9 @@ OR Entering the Void Your Key can\'t be empty - Your name + Type your name - Read more about Key + Read more You can find this key later in app settings What is the Key? It is represented by a recovery phrase – 12 random words from which your vault is magically generated on this device. @@ -2050,5 +2050,6 @@ Please provide specific details of your needs here. Continue Skip Incorrect email + Enter name \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingMnemonicViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingMnemonicViewModel.kt index 50297e454c..4023248ca9 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingMnemonicViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingMnemonicViewModel.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.viewModelScope import com.anytypeio.anytype.analytics.base.Analytics import com.anytypeio.anytype.analytics.base.EventsDictionary import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.NetworkModeConfig import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.domain.auth.interactor.GetMnemonic import com.anytypeio.anytype.domain.config.ConfigStorage @@ -57,24 +58,35 @@ class OnboardingMnemonicViewModel @Inject constructor( type = EventsDictionary.ClickOnboardingButton.CHECK_LATER, step = EventsDictionary.ScreenOnboardingStep.PHRASE ) - viewModelScope.launch { - val config = configStorage.getOrNull() - if (config != null) { - analytics.sendOpenAccountEvent( - analytics = config.analytics - ) - } else { - Timber.w("config was missing before the end of onboarding") - } - if (!startingObject.isNullOrEmpty()) { + if (shouldShowEmail()) { + viewModelScope.launch { commands.emit( - Command.OpenStartingObject( - space = SpaceId(space), - startingObject = startingObject + Command.NavigateToAddEmailScreen( + startingObject = startingObject, + space = space ) ) - } else { - commands.emit(Command.OpenVault) + } + } else { + viewModelScope.launch { + val config = configStorage.getOrNull() + if (config != null) { + analytics.sendOpenAccountEvent( + analytics = config.analytics + ) + } else { + Timber.w("config was missing before the end of onboarding") + } + if (!startingObject.isNullOrEmpty()) { + commands.emit( + Command.OpenStartingObject( + space = SpaceId(space), + startingObject = startingObject + ) + ) + } else { + commands.emit(Command.OpenVault) + } } } } @@ -83,28 +95,44 @@ class OnboardingMnemonicViewModel @Inject constructor( space: Id, startingObject: Id?, ) { - viewModelScope.launch { - val config = configStorage.getOrNull() - if (config != null) { - analytics.sendOpenAccountEvent( - analytics = config.analytics - ) - } else { - Timber.w("config was missing before the end of onboarding") - } - if (!startingObject.isNullOrEmpty()) { + if (shouldShowEmail()) { + viewModelScope.launch { commands.emit( - Command.OpenStartingObject( - space = SpaceId(space), - startingObject = startingObject + Command.NavigateToAddEmailScreen( + startingObject = startingObject, + space = space ) ) - } else { - commands.emit(Command.OpenVault) + } + } else { + viewModelScope.launch { + val config = configStorage.getOrNull() + if (config != null) { + analytics.sendOpenAccountEvent( + analytics = config.analytics + ) + } else { + Timber.w("config was missing before the end of onboarding") + } + if (!startingObject.isNullOrEmpty()) { + commands.emit( + Command.OpenStartingObject( + space = SpaceId(space), + startingObject = startingObject + ) + ) + } else { + commands.emit(Command.OpenVault) + } } } } + private fun shouldShowEmail(): Boolean { + //todo: update with Local Only config + return true + } + private suspend fun proceedWithMnemonicPhrase() { getMnemonic.invoke(Unit).proceed( failure = { e -> Timber.e(e, "Error while getting mnemonic") }, @@ -145,5 +173,9 @@ class OnboardingMnemonicViewModel @Inject constructor( val space: SpaceId, val startingObject: Id ) : Command() + data class NavigateToAddEmailScreen( + val startingObject: String?, + val space: String + ) : Command() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingSetProfileNameViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingSetProfileNameViewModel.kt index e6da606b8f..51236188eb 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingSetProfileNameViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/onboarding/signup/OnboardingSetProfileNameViewModel.kt @@ -28,6 +28,8 @@ import com.anytypeio.anytype.presentation.BuildConfig import com.anytypeio.anytype.presentation.common.BaseViewModel import com.anytypeio.anytype.presentation.extension.proceedWithAccountEvent import com.anytypeio.anytype.presentation.extension.sendAnalyticsOnboardingScreenEvent +import com.anytypeio.anytype.presentation.extension.sendOpenAccountEvent +import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingSetProfileNameViewModel.Navigation.OpenStartingObject import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import javax.inject.Inject import kotlinx.coroutines.delay @@ -71,11 +73,7 @@ class OnboardingSetProfileNameViewModel @Inject constructor( ) { if (state.value !is ScreenState.Loading) { viewModelScope.launch { - navigation.emit( - Navigation.NavigateToAddEmailScreen( - name = name - ) - ) + proceedWithCreatingWallet(name) } } else { sendToast(LOADING_MSG) @@ -256,27 +254,54 @@ class OnboardingSetProfileNameViewModel @Inject constructor( //region Email screen fun onEmailContinueClicked( email: String, - name: String, + space: Id, + startingObject: String? ) { - proceedWithSettingEmail(email = email) - if (state.value !is ScreenState.Loading) { - proceedWithCreatingWallet( - name = name - ) - } else { + if (state.value is ScreenState.Loading) { sendToast(LOADING_MSG) + return } + state.value = ScreenState.Loading + proceedWithSettingEmail(email = email) + proceedWithNavigation(space, startingObject) } fun onEmailSkippedClicked( - name: String + space: Id, + startingObject: String? ) { - if (state.value !is ScreenState.Loading) { - proceedWithCreatingWallet( - name = name + if (state.value is ScreenState.Loading) { + sendToast(LOADING_MSG) + return + } + state.value = ScreenState.Loading + proceedWithNavigation(space, startingObject) + } + + private fun proceedWithNavigation(space: Id, startingObject: String?) { + viewModelScope.launch { + sendOpenAccountAnalytics() + if (!startingObject.isNullOrEmpty()) { + navigation.emit( + OpenStartingObject( + space = SpaceId(space), + startingObject = startingObject + ) + ) + } else { + navigation.emit(Navigation.OpenVault) + } + } + } + + private suspend fun sendOpenAccountAnalytics() { + val config = configStorage.getOrNull() + if (config != null) { + analytics.sendOpenAccountEvent( + analytics = config.analytics ) } else { - sendToast(LOADING_MSG) + Timber.w("config was missing before the end of onboarding") } } @@ -288,12 +313,12 @@ class OnboardingSetProfileNameViewModel @Inject constructor( ) viewModelScope.launch { setMembershipEmail.async(params).fold( - onSuccess = { Timber.d("Email set") }, + onSuccess = { Timber.d("Email set successfully") }, onFailure = { error -> + Timber.e(error, "Error setting email") if (BuildConfig.DEBUG) { - sendToast("Error setting email") + sendToast("Error setting email: ${error.message}") } - Timber.e("Error setting email: $error") } ) } @@ -348,10 +373,12 @@ class OnboardingSetProfileNameViewModel @Inject constructor( sealed class Navigation { data class NavigateToMnemonic(val space: SpaceId, val startingObject: Id?): Navigation() - data class NavigateToAddEmailScreen( - val name: String - ) : Navigation() data object GoBack: Navigation() + data class OpenStartingObject( + val space: SpaceId, + val startingObject: Id + ) : Navigation() + data object OpenVault : Navigation() } sealed class ScreenState {