mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-3629 Onboarding | Flow update (#2397)
This commit is contained in:
parent
a30d949792
commit
63ee890a0b
11 changed files with 443 additions and 264 deletions
|
@ -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<Color>,
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<Boolean>) {
|
||||
Box(
|
||||
private fun ColumnScope.ReadMoreButton(showWhatIsRecoveryPhraseDialog: MutableState<Boolean>) {
|
||||
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<Boolean>
|
|||
@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)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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<String>,
|
||||
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<String>,
|
||||
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(
|
||||
|
|
|
@ -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)
|
||||
|
|
File diff suppressed because one or more lines are too long
9
core-ui/src/main/res/drawable/ic_plus_18.xml
Normal file
9
core-ui/src/main/res/drawable/ic_plus_18.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="18"
|
||||
android:viewportHeight="18">
|
||||
<path
|
||||
android:pathData="M9,17.474C7.832,17.474 6.737,17.252 5.713,16.81C4.689,16.372 3.79,15.766 3.015,14.992C2.24,14.211 1.632,13.312 1.189,12.294C0.752,11.27 0.533,10.175 0.533,9.007C0.533,7.839 0.752,6.743 1.189,5.72C1.632,4.696 2.24,3.797 3.015,3.022C3.79,2.247 4.689,1.641 5.713,1.204C6.737,0.761 7.832,0.54 9,0.54C10.168,0.54 11.263,0.761 12.287,1.204C13.311,1.641 14.21,2.247 14.985,3.022C15.76,3.797 16.366,4.696 16.803,5.72C17.245,6.743 17.467,7.839 17.467,9.007C17.467,10.175 17.245,11.27 16.803,12.294C16.366,13.312 15.76,14.211 14.985,14.992C14.21,15.766 13.311,16.372 12.287,16.81C11.263,17.252 10.168,17.474 9,17.474ZM4.949,9.015C4.949,9.225 5.018,9.397 5.157,9.53C5.295,9.657 5.472,9.721 5.688,9.721H8.286V12.327C8.286,12.543 8.35,12.72 8.477,12.858C8.61,12.991 8.781,13.058 8.992,13.058C9.208,13.058 9.382,12.991 9.515,12.858C9.653,12.72 9.722,12.543 9.722,12.327V9.721H12.329C12.539,9.721 12.713,9.657 12.852,9.53C12.99,9.397 13.059,9.225 13.059,9.015C13.059,8.799 12.99,8.625 12.852,8.492C12.719,8.354 12.544,8.285 12.329,8.285H9.722V5.687C9.722,5.471 9.653,5.294 9.515,5.155C9.382,5.017 9.208,4.948 8.992,4.948C8.781,4.948 8.61,5.017 8.477,5.155C8.35,5.294 8.286,5.471 8.286,5.687V8.285H5.688C5.472,8.285 5.295,8.354 5.157,8.492C5.018,8.625 4.949,8.799 4.949,9.015Z"
|
||||
android:fillColor="@color/glyph_active"/>
|
||||
</vector>
|
|
@ -1111,24 +1111,24 @@
|
|||
<!--region ONBOARDING -->
|
||||
|
||||
<string name="onboarding_auth_title">the everything app</string>
|
||||
<string name="onboarding_auth_subtitle">for those\nwho celebrate\ntrust & autonomy</string>
|
||||
<string name="onboarding_auth_subtitle">Encrypted, offline\n& open</string>
|
||||
<string name="onboarding_auth_description">Create & collaborate in spaces you own. Encrypted, offline & open.</string>
|
||||
<string name="onboarding_terms_and_policy_prefix">"By continuing you agree to "</string>
|
||||
<string name="onboarding_terms_and_policy_terms">Terms\u00A0of\u00A0Use</string>
|
||||
<string name="onboarding_terms_and_policy_infix">" and "</string>
|
||||
<string name="onboarding_terms_and_policy_privacy">Privacy\u00A0Policy</string>
|
||||
<string name="onboarding_new_vault_button_text">I am new here</string>
|
||||
<string name="onboarding_enter_my_vault">Enter my Vault</string>
|
||||
<string name="onboarding_have_key_button_text">Already have a Key</string>
|
||||
<string name="onboarding_enter_my_vault">Next</string>
|
||||
<string name="onboarding_have_key_button_text">I already have a key</string>
|
||||
<string name="onboarding_get_my_key_button_text">Get my Key</string>
|
||||
<string name="onboarding_invite_code_title">Enter your invite code</string>
|
||||
<string name="onboarding_invite_code_description">If you don\'t have one just go to anytype.io\nand sign up to the waiting list.</string>
|
||||
<string name="onboarding_void_title">This is your Void</string>
|
||||
<string name="onboarding_void_description">It is an encrypted location for everything you create. Everything is stored on your device, and backed up to the distributed network.</string>
|
||||
<string name="onboarding_this_is_your_key_title">This is your Key</string>
|
||||
<string name="onboarding_key_description">It gives you full ownership over your vault.</string>
|
||||
<string name="onboarding_key_description">It replaces login and password. Keep it safe — you control your data. You can find this Key later in app settings.</string>
|
||||
<string name="onboarding_show_my_key">Show my Key</string>
|
||||
<string name="onboarding_tap_to_reveal">Tap to Reveal</string>
|
||||
<string name="onboarding_tap_to_reveal">Reveal and copy</string>
|
||||
<string name="onboarding_key_skip">Skip</string>
|
||||
<string name="onboarding_key_not_now">Not now</string>
|
||||
<string name="onboarding_key_copy">Copy to clipboard</string>
|
||||
|
@ -1138,9 +1138,9 @@
|
|||
<string name="onboarding_login_or">OR</string>
|
||||
<string name="onboarding_entering_void_title">Entering the Void</string>
|
||||
<string name="onboarding_your_key_can_t_be_empty">Your Key can\'t be empty</string>
|
||||
<string name="onboarding_your_name">Your name</string>
|
||||
<string name="onboarding_your_name">Type your name</string>
|
||||
|
||||
<string name="onboarding_mnemonic_read_more">Read more about Key</string>
|
||||
<string name="onboarding_mnemonic_read_more">Read more</string>
|
||||
<string name="onboarding_key_additional_info">You can find this key later in app settings</string>
|
||||
<string name="onboarding_what_is_the_key">What is the Key?</string>
|
||||
<string name="onboarding_recovery_phrase_description">It is represented by a recovery phrase – 12 random words from which your vault is magically generated on this device.</string>
|
||||
|
@ -2050,5 +2050,6 @@ Please provide specific details of your needs here.</string>
|
|||
<string name="onboarding_button_continue">Continue</string>
|
||||
<string name="onboarding_button_skip">Skip</string>
|
||||
<string name="onboarding_email_error">Incorrect email</string>
|
||||
<string name="onboarding_name_error">Enter name</string>
|
||||
|
||||
</resources>
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue