mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-03-31 07:35:55 +00:00
Fixed UI for intro (still missing proper images), Create profile screen and use Condition screen
This commit is contained in:
@@ -161,7 +161,7 @@ fun CreateFirstProfile(chatModel: ChatModel, close: () -> Unit) {
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(MR.images.intro_2),
|
||||
painter = painterResource(MR.images.create_profile),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(200.dp),
|
||||
contentScale = ContentScale.Fit
|
||||
|
||||
@@ -15,7 +15,7 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.BuildConfigCommon
|
||||
@@ -53,8 +53,8 @@ fun ModalData.OnboardingConditionsView() {
|
||||
) {
|
||||
Column(
|
||||
(if (appPlatform.isDesktop) Modifier.width(450.dp).align(Alignment.CenterHorizontally) else Modifier)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING),
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
// Isometric illustration (conditional on USE_BRANDED_IMAGES)
|
||||
@@ -67,7 +67,7 @@ fun ModalData.OnboardingConditionsView() {
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(MR.images.intro_2),
|
||||
painter = painterResource(MR.images.use_conditions),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(200.dp),
|
||||
contentScale = ContentScale.Fit
|
||||
@@ -75,7 +75,6 @@ fun ModalData.OnboardingConditionsView() {
|
||||
}
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
}
|
||||
|
||||
// Title: "Conditions of use" (centered, bold)
|
||||
Text(
|
||||
text = stringResource(MR.strings.conditions_of_use_title),
|
||||
@@ -85,16 +84,14 @@ fun ModalData.OnboardingConditionsView() {
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(DEFAULT_PADDING * 2))
|
||||
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
}
|
||||
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
Column(
|
||||
(if (appPlatform.isDesktop) Modifier.width(450.dp).align(Alignment.CenterHorizontally) else Modifier)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING),
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING),
|
||||
horizontalAlignment = Alignment.Start
|
||||
) {
|
||||
// Body text (left-aligned)
|
||||
@@ -127,7 +124,7 @@ fun ModalData.OnboardingConditionsView() {
|
||||
// Privacy policy link (blue, underlined)
|
||||
Text(
|
||||
stringResource(MR.strings.onboarding_conditions_privacy_policy_and_conditions_of_use),
|
||||
style = TextStyle(fontSize = 17.sp, textDecoration = TextDecoration.Underline),
|
||||
style = TextStyle(fontSize = 17.sp),
|
||||
color = MaterialTheme.colors.primary,
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
@@ -140,11 +137,14 @@ fun ModalData.OnboardingConditionsView() {
|
||||
}
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
Spacer(Modifier.height(DEFAULT_PADDING * 3))
|
||||
|
||||
Column(Modifier.widthIn(max = if (appPlatform.isAndroid) 450.dp else 1000.dp).align(Alignment.CenterHorizontally), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
|
||||
AcceptConditionsButton(enabled = selectedOperatorIds.value.isNotEmpty(), selectedOperatorIds)
|
||||
|
||||
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
// Configure server operators link with icon
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -166,15 +166,15 @@ fun ModalData.OnboardingConditionsView() {
|
||||
fontSize = 16.sp
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
// Server operator icon - using network icon if available, otherwise a simple circle
|
||||
Icon(
|
||||
painterResource(MR.images.ic_info),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colors.secondary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
serverOperators.value.forEach { op ->
|
||||
Image(
|
||||
painterResource(op.logo),
|
||||
contentDescription = op.tradeName,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
}
|
||||
}
|
||||
|
||||
// Configure notifications link with icon
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -196,14 +196,15 @@ fun ModalData.OnboardingConditionsView() {
|
||||
fontSize = 16.sp
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
// Notification icon - using bolt/lightning icon
|
||||
Icon(
|
||||
BoltFilled,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colors.primary,
|
||||
modifier = Modifier.size(16.dp)
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(Modifier.width(DEFAULT_PADDING * 2))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,10 +239,11 @@ fun ModalData.ChooseServerOperators(
|
||||
}
|
||||
|
||||
Spacer(Modifier.weight(1f))
|
||||
Column((
|
||||
if (appPlatform.isDesktop) Modifier.width(600.dp).align(Alignment.CenterHorizontally) else Modifier)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING),
|
||||
Column(
|
||||
(
|
||||
if (appPlatform.isDesktop) Modifier.width(600.dp).align(Alignment.CenterHorizontally) else Modifier)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
serverOperators.value.forEachIndexed { index, srvOperator ->
|
||||
@@ -271,13 +273,14 @@ fun ModalData.ChooseServerOperators(
|
||||
@Composable
|
||||
private fun OperatorCheckView(serverOperator: ServerOperator, selectedOperatorIds: MutableState<Set<Long>>) {
|
||||
val checked = selectedOperatorIds.value.contains(serverOperator.operatorId)
|
||||
TextButton({
|
||||
if (checked) {
|
||||
selectedOperatorIds.value -= serverOperator.operatorId
|
||||
} else {
|
||||
selectedOperatorIds.value += serverOperator.operatorId
|
||||
}
|
||||
},
|
||||
TextButton(
|
||||
{
|
||||
if (checked) {
|
||||
selectedOperatorIds.value -= serverOperator.operatorId
|
||||
} else {
|
||||
selectedOperatorIds.value += serverOperator.operatorId
|
||||
}
|
||||
},
|
||||
border = BorderStroke(1.dp, color = if (checked) MaterialTheme.colors.primary else MaterialTheme.colors.secondary.copy(alpha = 0.5f)),
|
||||
shape = RoundedCornerShape(18.dp)
|
||||
) {
|
||||
@@ -368,7 +371,7 @@ private fun AcceptConditionsButton(
|
||||
}
|
||||
|
||||
private fun continueToNextStep() {
|
||||
appPrefs.onboardingStage.set(if (appPlatform.isAndroid) OnboardingStage.Step4_SetNotificationsMode else OnboardingStage.OnboardingComplete)
|
||||
appPrefs.onboardingStage.set(if (appPlatform.isAndroid) OnboardingStage.Step4_SetNotificationsMode else OnboardingStage.OnboardingComplete)
|
||||
}
|
||||
|
||||
private fun continueToSetNotificationsAfterAccept() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package chat.simplex.common.views.onboarding
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
@@ -8,6 +9,7 @@ import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.BuildConfigCommon
|
||||
import chat.simplex.common.model.ChatModel
|
||||
@@ -42,15 +44,12 @@ private fun IntroCarouselContent(chatModel: ChatModel) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = DEFAULT_PADDING + 8.dp),
|
||||
.padding(top = 100.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
SimpleXLogo(modifier = Modifier.widthIn(max = if (appPlatform.isAndroid) 250.dp else 500.dp))
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(24.dp))
|
||||
|
||||
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
@@ -72,19 +71,22 @@ private fun IntroCarouselContent(chatModel: ChatModel) {
|
||||
}
|
||||
val showButtons = page == 2
|
||||
val introImage = when (page) {
|
||||
0 -> MR.images.intro_2
|
||||
0 -> MR.images.intro_1
|
||||
1 -> MR.images.intro_2
|
||||
else -> MR.images.intro_2
|
||||
else -> MR.images.intro_3
|
||||
}
|
||||
IntroPage(
|
||||
headline = headline,
|
||||
subtitle = subtitle,
|
||||
centralContent = {
|
||||
if (BuildConfigCommon.USE_BRANDED_IMAGES) {
|
||||
Icon(
|
||||
Image(
|
||||
painter = painterResource(introImage),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(200.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.65f)
|
||||
.aspectRatio(1f),
|
||||
contentScale = ContentScale.Fit,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -31,16 +31,16 @@ fun IntroPage(
|
||||
verticalArrangement = Arrangement.Top,
|
||||
) {
|
||||
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(0.5f)
|
||||
.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
centralContent()
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(32.dp))
|
||||
Spacer(Modifier.height(24.dp))
|
||||
|
||||
Text(
|
||||
text = headline,
|
||||
@@ -50,7 +50,7 @@ fun IntroPage(
|
||||
textAlign = TextAlign.Center,
|
||||
lineHeight = 38.sp,
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Spacer(Modifier.height(12.dp))
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.body1,
|
||||
@@ -59,8 +59,9 @@ fun IntroPage(
|
||||
lineHeight = 24.sp,
|
||||
)
|
||||
|
||||
Spacer(Modifier.weight(if (showButtons) 0.5f else 1f))
|
||||
|
||||
if (showButtons && (onCreateProfile != null || onMigrate != null)) {
|
||||
Spacer(Modifier.height(DEFAULT_PADDING * 2))
|
||||
Column(
|
||||
Modifier.widthIn(max = if (appPlatform.isAndroid) 450.dp else 1000.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 246 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 662 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15 10.25H11.52C10.7179 10.2498 9.93692 10.5068 9.29167 10.9832C8.64641 11.4596 8.17092 12.1304 7.935 12.897L3.915 21.961C3.80533 22.3184 3.74971 22.6902 3.75 23.064V30C3.75 30.9946 4.14509 31.9484 4.84835 32.6516C5.55161 33.3549 6.50544 33.75 7.5 33.75H32.5C33.4946 33.75 34.4484 33.3549 35.1517 32.6516C35.8549 31.9484 36.25 30.9946 36.25 30V23.064C36.25 22.6901 36.194 22.3183 36.084 21.961L32.064 12.897C31.8281 12.1306 31.3528 11.4599 30.7077 10.9835C30.0627 10.5071 29.2819 10.25 28.48 10.25H25M3.75 22.5H10.182C10.8784 22.5 11.5611 22.694 12.1534 23.0601C12.7458 23.4262 13.2246 23.9501 13.536 24.573L13.964 25.427C14.2754 26.0499 14.7542 26.5738 15.3466 26.9399C15.9389 27.306 16.6216 27.5 17.318 27.5H22.682C23.3786 27.5002 24.0614 27.3063 24.654 26.9402C25.2466 26.574 25.7255 26.05 26.037 25.427L26.464 24.573C26.7754 23.9501 27.2542 23.4262 27.8466 23.0601C28.439 22.694 29.1216 22.5 29.818 22.5H36.25M20 5V18.75M20 18.75L15 13.75M20 18.75L25 13.75" stroke="#E6A800" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 373 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 799 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 329 KiB |
Reference in New Issue
Block a user