fix: say sign in is not available yet, instead of offering a flow alpha cannot finish
The sign in screen asked for an nsec or npub, walked through a confirmation step and reported an error when the sign in failed. None of that can succeed while the app is in alpha testing, so the screen is now the notice and nothing else, centred in the window because the message is the only thing on it. The screen no longer reads any state, so it takes no arguments and the navigation host stops handing it the repository. SignInToProfileViewModel, SignInToProfileUIState and SignInToProfileFormState are left where they are. Nothing references them now, but they are the implementation to restore when sign in ships, rather than something to write again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -195,6 +195,7 @@
|
||||
<string name="shared_key">Shared key</string>
|
||||
<string name="sign">Sign</string>
|
||||
<string name="sign_in">Sign in</string>
|
||||
<string name="sign_in_is_not_yet_available_while_mantra_is">Sign in is not yet available while Mantra is in alpha testing.</string>
|
||||
<string name="sign_in_to_nsec">Sign in to nsec</string>
|
||||
<string name="sign_in_to_torch_via_nsec_or_remote_signer">Sign in to Mantra via nsec, or remote signer</string>
|
||||
<string name="sign_in_with_an_npub">Sign in with an npub</string>
|
||||
|
||||
@@ -2,273 +2,42 @@ package press.mantra.compose.ui.composable
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Create
|
||||
import androidx.compose.material.icons.filled.NavigateNext
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LoadingIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NSec
|
||||
import press.mantra.compose.ui.theme.spacing
|
||||
import mantra.composeapp.generated.resources.Res
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import mantra.composeapp.generated.resources.be_sure_to_keep_this_nsec_safe
|
||||
import mantra.composeapp.generated.resources.enter_the_nsec_or_npub_read_only_that_you
|
||||
import mantra.composeapp.generated.resources.next
|
||||
import mantra.composeapp.generated.resources.nsec_npub_nip_05_static_address
|
||||
import mantra.composeapp.generated.resources.sign_in
|
||||
import mantra.composeapp.generated.resources.sign_in_to_nsec
|
||||
import mantra.composeapp.generated.resources.sign_in_with_an_npub
|
||||
import mantra.composeapp.generated.resources.something_went_wrong_and_we_were_unable_to
|
||||
import mantra.composeapp.generated.resources.this_will_give_you_read_only_access_to_the
|
||||
import mantra.composeapp.generated.resources.this_will_give_you_write_access_to_the
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import mantra.composeapp.generated.resources.sign_in_is_not_yet_available_while_mantra_is
|
||||
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
|
||||
import press.mantra.compose.ui.theme.readableContent
|
||||
import press.mantra.compose.ui.theme.ConformancePreviews
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
// The message is the whole screen while sign in is held back, so it is centred in
|
||||
// the window rather than given the leading edge the readable column normally keeps.
|
||||
@Composable
|
||||
fun SignInToProfileScreen(
|
||||
initialSignInToProfileUIState: press.mantra.compose.ui.view.state.SignInToProfileUIState = press.mantra.compose.ui.view.state.SignInToProfileUIState.InputPrompt,
|
||||
nostrRepository: press.mantra.compose.repository.NostrRepository
|
||||
) {
|
||||
val signInToProfileViewModel: press.mantra.compose.ui.view.model.SignInToProfileViewModel = viewModel (
|
||||
factory = press.mantra.compose.ui.view.model.SignInToProfileViewModel.factory(
|
||||
initialSignInToProfileUIState,
|
||||
nostrRepository
|
||||
)
|
||||
)
|
||||
// imePadding: this screen has a text field, and without it the software
|
||||
// keyboard covers whatever is being typed into.
|
||||
Scaffold(
|
||||
snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
|
||||
modifier = Modifier.imePadding()) { innerPadding ->
|
||||
fun SignInToProfileScreen() {
|
||||
Scaffold(snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) }) { innerPadding ->
|
||||
Column(
|
||||
modifier = Modifier.padding(innerPadding)
|
||||
modifier = Modifier.fillMaxSize().padding(innerPadding)
|
||||
.readableContent()
|
||||
.padding(MaterialTheme.spacing.screenMargin),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
MaterialTheme.spacing.space125
|
||||
),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
|
||||
) {
|
||||
|
||||
when (val signInToProfileUIState = signInToProfileViewModel.signInToProfileUIState.value) {
|
||||
is press.mantra.compose.ui.view.state.SignInToProfileUIState.InputPrompt -> {
|
||||
Text(
|
||||
stringResource(Res.string.sign_in),
|
||||
style = MaterialTheme.typography.headlineSmall
|
||||
)
|
||||
|
||||
TextField(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
state = signInToProfileViewModel.signInToProfileFormState.textFieldForm.textFieldState,
|
||||
isError = signInToProfileViewModel.signInToProfileFormState.textFieldForm.errorMessage.value != null,
|
||||
supportingText = signInToProfileViewModel.signInToProfileFormState.textFieldForm.errorMessage.value?.let {
|
||||
{
|
||||
Text(
|
||||
text = it,
|
||||
modifier = Modifier.padding(
|
||||
bottom = MaterialTheme.spacing.compactPadding
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Password,
|
||||
imeAction = ImeAction.Done
|
||||
),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(Res.string.nsec_npub_nip_05_static_address),
|
||||
maxLines = 1,
|
||||
)
|
||||
},
|
||||
placeholder = {
|
||||
Text(
|
||||
text = stringResource(Res.string.enter_the_nsec_or_npub_read_only_that_you),
|
||||
maxLines = 1,
|
||||
)
|
||||
},
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
Icons.Default.Create,
|
||||
contentDescription = "Write note"
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
signInToProfileViewModel.signInToProfileUIState.value = signInToProfileViewModel.validateCredential().let { credentialEntity ->
|
||||
when (credentialEntity) {
|
||||
is NSec -> {
|
||||
press.mantra.compose.ui.view.state.SignInToProfileUIState.ConfirmNsecSignIn(
|
||||
nsec = signInToProfileViewModel.signInToProfileFormState.textFieldForm.textFieldState.text.toString(),
|
||||
hexKey = credentialEntity.hex
|
||||
)
|
||||
}
|
||||
is NPub -> {
|
||||
press.mantra.compose.ui.view.state.SignInToProfileUIState.ConfirmNpubSignIn(
|
||||
npub = signInToProfileViewModel.signInToProfileFormState.textFieldForm.textFieldState.text.toString(),
|
||||
hexKey = credentialEntity.hex
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
press.mantra.compose.ui.view.state.SignInToProfileUIState.Error
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
) {
|
||||
Text(
|
||||
stringResource(Res.string.next)
|
||||
)
|
||||
Icon(
|
||||
Icons.Default.NavigateNext,
|
||||
contentDescription = "Next"
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
is press.mantra.compose.ui.view.state.SignInToProfileUIState.ConfirmNpubSignIn-> {
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(Res.string.sign_in_with_an_npub),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
Text(
|
||||
text = signInToProfileUIState.npub,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Text(
|
||||
text = signInToProfileUIState.hexKey,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(4f)
|
||||
)
|
||||
|
||||
|
||||
|
||||
Text(
|
||||
text = stringResource(Res.string.this_will_give_you_read_only_access_to_the),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
if (signInToProfileViewModel.isActionPending.value) {
|
||||
LoadingIndicator(
|
||||
modifier = Modifier
|
||||
)
|
||||
} else {
|
||||
Button(
|
||||
onClick = {
|
||||
signInToProfileViewModel.signInToAccount()
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.sign_in)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is press.mantra.compose.ui.view.state.SignInToProfileUIState.ConfirmNsecSignIn-> {
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(Res.string.sign_in_to_nsec),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(Res.string.be_sure_to_keep_this_nsec_safe),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(4f)
|
||||
)
|
||||
|
||||
|
||||
|
||||
Text(
|
||||
text = stringResource(Res.string.this_will_give_you_write_access_to_the),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
if (signInToProfileViewModel.isActionPending.value) {
|
||||
LoadingIndicator(
|
||||
modifier = Modifier
|
||||
)
|
||||
} else {
|
||||
Button(
|
||||
onClick = {
|
||||
signInToProfileViewModel.signInToAccount()
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.sign_in)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is press.mantra.compose.ui.view.state.SignInToProfileUIState.Error -> {
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(Res.string.something_went_wrong_and_we_were_unable_to),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = stringResource(Res.string.sign_in_is_not_yet_available_while_mantra_is),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,20 +49,7 @@ private fun SignInToProfileScreenPreview() {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
SignInToProfileScreen(
|
||||
initialSignInToProfileUIState =
|
||||
press.mantra.compose.ui.view.state.SignInToProfileUIState.InputPrompt,
|
||||
// SignInToProfileUIState.Error,
|
||||
// SignInToProfileUIState.ConfirmNpubSignIn(
|
||||
// npub = "npub1uh366qnj68a7atvwgwdy4569xd6v5jtferftapqztwjwlzh9553q47pqsx",
|
||||
// hexKey = "e5e3ad0272d1fbeead8e439a4ad3453374ca4969c8d2be84025ba4ef8ae5a522"
|
||||
// ),
|
||||
// SignInToProfileUIState.ConfirmNsecSignIn(
|
||||
// nsec = "nsecthingsaretobekeptsecret",
|
||||
// hexKey = "e5e3ad0272d1fbeead8e439a4ad3453374ca4969c8d2be84025ba4ef8ae5a522"
|
||||
// ),
|
||||
nostrRepository = press.mantra.compose.repository.NostrRepository.NO_OP_NOSTR_REPOSITORY
|
||||
)
|
||||
SignInToProfileScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,9 +628,7 @@ fun MantraNavHost(
|
||||
)
|
||||
}
|
||||
composable<SignInRoute> {
|
||||
SignInToProfileScreen(
|
||||
nostrRepository = databaseNostrRepository
|
||||
)
|
||||
SignInToProfileScreen()
|
||||
}
|
||||
composable<UnsignedProfileRoute> { backStackEntry ->
|
||||
backStackEntry.toRoute<UnsignedProfileRoute>()
|
||||
|
||||
Reference in New Issue
Block a user