Skip to content

Commit

Permalink
Implement DoB and Full Name in wallet activation
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandarIlic committed Feb 21, 2024
1 parent 8b62916 commit f331ecc
Show file tree
Hide file tree
Showing 14 changed files with 317 additions and 136 deletions.
4 changes: 1 addition & 3 deletions app/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@
<ID>LongMethod:ThreadScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable fun ThreadScreen( state: ThreadContract.UiState, onClose: () -&gt; Unit, onPostClick: (String) -&gt; Unit, onPostReplyClick: (String) -&gt; Unit, onPostQuoteClick: (String) -&gt; Unit, onProfileClick: (String) -&gt; Unit, onHashtagClick: (String) -&gt; Unit, onMediaClick: (String, String) -&gt; Unit, onGoToWallet: () -&gt; Unit, onReplyInNoteEditor: (String, Uri?, String) -&gt; Unit, eventPublisher: (ThreadContract.UiEvent) -&gt; Unit, )</ID>
<ID>LongMethod:TransactionEditor.kt$@Composable private fun TransactionHeaderColumn( modifier: Modifier, uiMode: UiMode, state: CreateTransactionContract.UiState, keyboardVisible: Boolean, onAmountClick: () -&gt; Unit, )</ID>
<ID>LongMethod:TransactionEditor.kt$@ExperimentalMaterial3Api @ExperimentalComposeUiApi @Composable fun TransactionEditor( modifier: Modifier, state: CreateTransactionContract.UiState, paddingValues: PaddingValues, eventPublisher: (CreateTransactionContract.UiEvent) -&gt; Unit, onCancelClick: () -&gt; Unit, )</ID>
<ID>LongMethod:WalletActivationScreen.kt$@ExperimentalComposeUiApi @Composable private fun WalletActivationDataInput( data: WalletActivationData, working: Boolean, error: Throwable?, onErrorDismiss: () -&gt; Unit, onDataChanged: (WalletActivationData) -&gt; Unit, onActivationCodeRequest: (WalletActivationData) -&gt; Unit, isKeyboardVisible: Boolean, )</ID>
<ID>LongMethod:WalletActivationScreen.kt$@ExperimentalComposeUiApi @Composable private fun WalletCodeActivationInput( working: Boolean, error: Throwable?, email: String, onCodeChanged: () -&gt; Unit, onCodeConfirmation: (String) -&gt; Unit, isKeyboardVisible: Boolean, )</ID>
<ID>LongMethod:WalletActivationScreen.kt$@Suppress("MagicNumber") @OptIn(ExperimentalMaterial3Api::class) @ExperimentalComposeUiApi @Composable private fun WalletActivationDataInput( data: WalletActivationData, working: Boolean, error: Throwable?, onErrorDismiss: () -&gt; Unit, onDataChanged: (WalletActivationData) -&gt; Unit, onActivationCodeRequest: (WalletActivationData) -&gt; Unit, )</ID>
<ID>LongMethod:WalletDashboardScreen.kt$@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @Composable fun WalletDashboardScreen( state: WalletDashboardContract.UiState, onPrimaryDestinationChanged: (PrimalTopLevelDestination) -&gt; Unit, onDrawerDestinationClick: (DrawerScreenDestination) -&gt; Unit, onWalletActivateClick: () -&gt; Unit, onProfileClick: (String) -&gt; Unit, onTransactionClick: (String) -&gt; Unit, onSendClick: () -&gt; Unit, onScanClick: () -&gt; Unit, onReceiveClick: () -&gt; Unit, eventPublisher: (UiEvent) -&gt; Unit, )</ID>
<ID>LongMethod:WalletSettingsScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable fun WalletSettingsScreen( state: WalletSettingsContract.UiState, onClose: () -&gt; Unit, onEditProfileClick: () -&gt; Unit, eventPublisher: (UiEvent) -&gt; Unit, )</ID>
<ID>LongMethod:WelcomeScreen.kt$@Composable fun WelcomeScreen(onSignInClick: () -&gt; Unit, onCreateAccountClick: () -&gt; Unit)</ID>
Expand Down Expand Up @@ -130,8 +130,6 @@
<ID>MagicNumber:Timestamps.kt$60</ID>
<ID>MagicNumber:Timestamps.kt$7</ID>
<ID>MagicNumber:ValidationUtils.kt$32</ID>
<ID>MagicNumber:WalletActivationScreen.kt$0.25f</ID>
<ID>MagicNumber:WalletActivationScreen.kt$0.75f</ID>
<ID>MagicNumber:WalletDashboardScreen.kt$0.42f</ID>
<ID>MagicNumber:WelcomeScreen.kt$0.4f</ID>
<ID>MagicNumber:WelcomeScreen.kt$0.6f</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,20 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.primal.android.R
import net.primal.android.core.compose.PrimalClickableText
import net.primal.android.core.compose.ToSAndPrivacyPolicyText
import net.primal.android.core.compose.button.PrimalCallToActionButton
import net.primal.android.core.compose.fadingBottomEdge
import net.primal.android.core.ext.openUriSafely
import net.primal.android.theme.AppTheme
import net.primal.android.theme.PrimalTheme
import net.primal.android.theme.domain.PrimalTheme

@Composable
fun WelcomeScreen(onSignInClick: () -> Unit, onCreateAccountClick: () -> Unit) {
val localUriHandler = LocalUriHandler.current

Surface(
modifier = Modifier
.systemBarsPadding()
Expand Down Expand Up @@ -92,7 +85,10 @@ fun WelcomeScreen(onSignInClick: () -> Unit, onCreateAccountClick: () -> Unit) {
horizontalAlignment = Alignment.CenterHorizontally,
) {
PrimalCallToActionButton(
modifier = Modifier.widthIn(0.dp, 420.dp).fillMaxWidth().padding(horizontal = 32.dp),
modifier = Modifier
.widthIn(0.dp, 420.dp)
.fillMaxWidth()
.padding(horizontal = 32.dp),
title = stringResource(id = R.string.welcome_create_account_button_title),
subtitle = if (maxHeight > MIN_HEIGHT_FOR_SUBTITLE) {
stringResource(id = R.string.welcome_create_account_button_subtitle)
Expand All @@ -105,7 +101,10 @@ fun WelcomeScreen(onSignInClick: () -> Unit, onCreateAccountClick: () -> Unit) {
Spacer(modifier = Modifier.height(16.dp))

PrimalCallToActionButton(
modifier = Modifier.widthIn(0.dp, 420.dp).fillMaxWidth().padding(horizontal = 32.dp),
modifier = Modifier
.widthIn(0.dp, 420.dp)
.fillMaxWidth()
.padding(horizontal = 32.dp),
title = stringResource(id = R.string.welcome_sign_in_button_title),
subtitle = if (maxHeight > MIN_HEIGHT_FOR_SUBTITLE) {
stringResource(id = R.string.welcome_sign_in_button_subtitle)
Expand All @@ -117,14 +116,12 @@ fun WelcomeScreen(onSignInClick: () -> Unit, onCreateAccountClick: () -> Unit) {

Spacer(modifier = Modifier.height(16.dp))

TermsAndServiceHint(
ToSAndPrivacyPolicyText(
modifier = Modifier
.widthIn(0.dp, 360.dp)
.fillMaxWidth()
.padding(horizontal = 80.dp),
onTosClick = {
localUriHandler.openUriSafely(TOS_URL)
},
.padding(horizontal = 32.dp),
tosPrefix = stringResource(id = R.string.welcome_tos_prefix),
)
}
}
Expand All @@ -134,44 +131,6 @@ fun WelcomeScreen(onSignInClick: () -> Unit, onCreateAccountClick: () -> Unit) {

private const val MIN_HEIGHT_FOR_SUBTITLE = 500

private const val TOS_ANNOTATION_TAG = "TosAnnotationTag"
private const val TOS_URL = "https://www.primal.net/terms"

@Composable
fun TermsAndServiceHint(modifier: Modifier = Modifier, onTosClick: () -> Unit) {
val tosHint = stringResource(id = R.string.welcome_tos_hint)
val tosLink = stringResource(id = R.string.welcome_tos_hint_highlighted_word)
val annotatedString = buildAnnotatedString {
append(tosHint)

val startIndex = tosHint.indexOf(tosLink)
if (startIndex >= 0) {
val endIndex = startIndex + tosLink.length
addStyle(
style = SpanStyle(color = AppTheme.colorScheme.primary),
start = startIndex,
end = endIndex,
)
addStringAnnotation(
tag = TOS_ANNOTATION_TAG,
annotation = tosLink,
start = startIndex,
end = endIndex,
)
}
}

PrimalClickableText(
modifier = modifier,
text = annotatedString,
style = AppTheme.typography.bodySmall.copy(
color = AppTheme.extraColorScheme.onSurfaceVariantAlt3,
textAlign = TextAlign.Center,
),
onClick = { _, _ -> onTosClick() },
)
}

@Preview
@Composable
fun PreviewWelcomeScreen() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package net.primal.android.core.compose

import androidx.compose.foundation.layout.padding
import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerColors
import androidx.compose.material3.DatePickerDefaults
import androidx.compose.material3.DatePickerFormatter
import androidx.compose.material3.DatePickerState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import net.primal.android.theme.AppTheme

@ExperimentalMaterial3Api
@Composable
fun DatePickerModalBottomSheet(
state: DatePickerState,
dateFormatter: DatePickerFormatter = remember { DatePickerFormatter() },
dateValidator: (Long) -> Boolean = { true },
showModeToggle: Boolean = true,
colors: DatePickerColors = DatePickerDefaults.colors(
selectedDayContainerColor = AppTheme.colorScheme.primary,
),
onDismissRequest: () -> Unit,
) {
ModalBottomSheet(
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
containerColor = AppTheme.colorScheme.surface,
tonalElevation = 0.dp,
onDismissRequest = onDismissRequest,
) {
DatePicker(
state = state,
modifier = Modifier.padding(bottom = 16.dp),
dateFormatter = dateFormatter,
dateValidator = dateValidator,
showModeToggle = showModeToggle,
colors = colors,
)
}
}
63 changes: 63 additions & 0 deletions app/src/main/kotlin/net/primal/android/core/compose/ToS.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package net.primal.android.core.compose

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import net.primal.android.R
import net.primal.android.core.ext.openUriSafely
import net.primal.android.theme.AppTheme

private const val TOS_ANNOTATION_TAG = "TosAnnotationTag"
private const val PRIVACY_ANNOTATION_TAG = "PrivacyAnnotationTag"

private const val PRIMAL_TOS_URL = "https://www.primal.net/terms"
private const val PRIMAL_PRIVACY_POLICY_URL = "https://www.primal.net/privacy"

@Composable
fun ToSAndPrivacyPolicyText(modifier: Modifier = Modifier, tosPrefix: String) {
val linkSpanStyle = SpanStyle(color = AppTheme.colorScheme.primary)
val annotatedString = buildAnnotatedString {
append(tosPrefix)
append("\n")

pushStringAnnotation(TOS_ANNOTATION_TAG, "tos")
withStyle(style = linkSpanStyle) {
append(stringResource(id = R.string.legal_tos_hint_highlighted_word))
}
pop()

append(" and ")
pushStringAnnotation(PRIVACY_ANNOTATION_TAG, "privacy")
withStyle(style = linkSpanStyle) {
append(stringResource(id = R.string.legal_privacy_policy_hint_highlighted_word))
}
append(".")
pop()
}

val localUriHandler = LocalUriHandler.current
PrimalClickableText(
modifier = modifier,
text = annotatedString,
style = AppTheme.typography.bodySmall.copy(
color = AppTheme.extraColorScheme.onSurfaceVariantAlt3,
textAlign = TextAlign.Center,
),
onClick = { position, offset ->
annotatedString.getStringAnnotations(
start = position,
end = position,
).firstOrNull()?.let { annotation ->
when (annotation.tag) {
TOS_ANNOTATION_TAG -> localUriHandler.openUriSafely(PRIMAL_TOS_URL)
PRIVACY_ANNOTATION_TAG -> localUriHandler.openUriSafely(PRIMAL_PRIVACY_POLICY_URL)
}
}
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package net.primal.android.wallet.activation
import net.primal.android.wallet.activation.regions.Region

data class WalletActivationData(
val name: String = "",
val firstName: String = "",
val lastName: String = "",
val email: String = "",
val dateOfBirth: Long? = null,
val country: Region? = null,
val state: Region? = null,
)
Loading

0 comments on commit f331ecc

Please sign in to comment.