From 80db00ee2a1bccbeeaf5bc03038d2a72325eb1ea Mon Sep 17 00:00:00 2001 From: AbronStudio Date: Sat, 26 Jul 2025 12:18:06 +0330 Subject: [PATCH] feat(auth): implement platform selection screen with API URL input Add platform selection UI with PepChat and Revolt options Implement clickable platform cards that set the API URL Create custom styled text field for API URL input Add confirm button with localized string resource Fix vertical alignment of placeholder text in text field --- .idea/codeStyles/Project.xml | 35 ++++++++++ .../chat/revolt/activities/MainActivity.kt | 4 +- .../composables/generic/FormTextField.kt | 8 ++- .../screens/login/LoginGreetingScreen.kt | 64 ++++--------------- .../res/drawable/ic_launcher_foreground.xml | 15 +++-- app/src/main/res/values/strings.xml | 1 + 6 files changed, 69 insertions(+), 58 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 7643783a..7f70f7ef 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,5 +1,40 @@ + + + diff --git a/app/src/main/java/chat/revolt/activities/MainActivity.kt b/app/src/main/java/chat/revolt/activities/MainActivity.kt index 153b10c6..64e057d4 100644 --- a/app/src/main/java/chat/revolt/activities/MainActivity.kt +++ b/app/src/main/java/chat/revolt/activities/MainActivity.kt @@ -96,6 +96,7 @@ import chat.revolt.screens.about.AboutScreen import chat.revolt.screens.about.AttributionScreen import chat.revolt.screens.chat.ChatRouterScreen import chat.revolt.screens.chat.views.channel.ChannelScreen +import chat.revolt.screens.chooseplatform.ChoosePlatformScreen import chat.revolt.screens.create.CreateGroupScreen import chat.revolt.screens.labs.LabsRootScreen import chat.revolt.screens.login.LoginGreetingScreen @@ -200,7 +201,7 @@ class MainActivityViewModel @Inject constructor( Log.d("MainActivity", "We can reach Revolt, checking if we're logged in") val token = kvStorage.get("sessionToken") - ?: return@launch startWithDestination("login/greeting") + ?: return@launch startWithDestination("choose-platform") val id = kvStorage.get("sessionId") ?: "" Log.d( @@ -563,6 +564,7 @@ fun AppEntrypoint( ) } + composable("choose-platform") { ChoosePlatformScreen(navController) } composable("login/greeting") { LoginGreetingScreen(navController) } composable("login/login") { LoginScreen(navController) } composable("login/mfa/{mfaTicket}/{allowedAuthTypes}") { backStackEntry -> diff --git a/app/src/main/java/chat/revolt/composables/generic/FormTextField.kt b/app/src/main/java/chat/revolt/composables/generic/FormTextField.kt index 19d1f520..fe4eeeea 100644 --- a/app/src/main/java/chat/revolt/composables/generic/FormTextField.kt +++ b/app/src/main/java/chat/revolt/composables/generic/FormTextField.kt @@ -22,6 +22,9 @@ fun FormTextField( type: KeyboardType = KeyboardType.Text, action: ImeAction = ImeAction.Done, supportingText: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + placeholder: @Composable (() -> Unit)? = null, singleLine: Boolean = true, enabled: Boolean = true ) { @@ -29,11 +32,14 @@ fun FormTextField( value = value, onValueChange = onChange, singleLine = singleLine, + placeholder = placeholder, keyboardOptions = KeyboardOptions(keyboardType = type, imeAction = action), visualTransformation = if (type == KeyboardType.Password) PasswordVisualTransformation() else VisualTransformation.None, label = { Text(label) }, supportingText = supportingText, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, enabled = enabled, modifier = modifier ) -} +} \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/screens/login/LoginGreetingScreen.kt b/app/src/main/java/chat/revolt/screens/login/LoginGreetingScreen.kt index 40433867..0fc711fd 100644 --- a/app/src/main/java/chat/revolt/screens/login/LoginGreetingScreen.kt +++ b/app/src/main/java/chat/revolt/screens/login/LoginGreetingScreen.kt @@ -14,16 +14,13 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawingPadding -import androidx.compose.foundation.layout.width import androidx.compose.material3.Button import androidx.compose.material3.ElevatedButton import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf @@ -31,7 +28,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag @@ -42,12 +38,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController -import chat.revolt.BuildConfig import chat.revolt.R -import chat.revolt.api.REVOLT_MARKETING -import chat.revolt.composables.generic.AnyLink -import chat.revolt.composables.generic.Weblink -import com.chuckerteam.chucker.api.Chucker @OptIn(ExperimentalFoundationApi::class) @Composable @@ -59,7 +50,7 @@ fun LoginGreetingScreen(navController: NavController) { Column( modifier = Modifier .fillMaxSize() - .padding(vertical = 20.dp, horizontal = 0.dp) + .padding(vertical = 20.dp, horizontal = 16.dp) .safeDrawingPadding(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally @@ -71,13 +62,11 @@ fun LoginGreetingScreen(navController: NavController) { horizontalAlignment = Alignment.CenterHorizontally ) { Image( - painter = painterResource(id = R.drawable.revolt_logo_wide), - colorFilter = ColorFilter.tint(LocalContentColor.current), + painter = painterResource(id = R.drawable.onboarding_fly_image), contentDescription = "Revolt Logo", contentScale = ContentScale.Fit, modifier = Modifier - .height(55.dp) - .padding(bottom = 10.dp) + .padding(bottom = 16.dp) .combinedClickable( interactionSource = remember(::MutableInteractionSource), indication = null, @@ -100,7 +89,14 @@ fun LoginGreetingScreen(navController: NavController) { } ) ) + } + Column( + modifier = Modifier + .fillMaxWidth(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { Text( text = stringResource(R.string.login_onboarding_heading), style = MaterialTheme.typography.displaySmall.copy( @@ -109,7 +105,7 @@ fun LoginGreetingScreen(navController: NavController) { textAlign = TextAlign.Center ), modifier = Modifier - .padding(horizontal = 20.dp, vertical = 10.dp) + .padding(bottom = 4.dp) .fillMaxWidth() ) @@ -124,17 +120,12 @@ fun LoginGreetingScreen(navController: NavController) { fontWeight = FontWeight.Normal ), modifier = Modifier - .padding(horizontal = 20.dp, vertical = 10.dp) + .padding(horizontal = 20.dp) .fillMaxWidth() ) - } - Column( - modifier = Modifier - .width(200.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { + Spacer(modifier = Modifier.height(32.dp)) + Button( onClick = { navController.navigate("login/login") }, modifier = Modifier @@ -177,33 +168,6 @@ fun LoginGreetingScreen(navController: NavController) { } Spacer(modifier = Modifier.height(40.dp)) - - CompositionLocalProvider( - LocalTextStyle provides LocalTextStyle.current.copy(textAlign = TextAlign.Center) - ) { - Weblink( - text = stringResource(R.string.terms_of_service), - url = "$REVOLT_MARKETING/terms" - ) - Weblink( - text = stringResource(R.string.privacy_policy), - url = "$REVOLT_MARKETING/privacy" - ) - Weblink( - text = stringResource(R.string.community_guidelines), - url = "$REVOLT_MARKETING/aup" - ) - if (BuildConfig.DEBUG) { - AnyLink( - text = "Debug: Chucker", - action = { - Chucker.getLaunchIntent(context).apply { - context.startActivity(this) - } - } - ) - } - } } } } diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 6a29b828..e9c2f2af 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,9 +1,12 @@ + android:width="72dp" + android:height="72dp" + android:viewportWidth="72" + android:viewportHeight="72"> + android:pathData="M32.888,21.721V31.138H26.569V21.721H32.888ZM51.649,21.721V31.138H45.33V21.721H51.649Z" + android:fillColor="#662D91"/> + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1a5b3bf3..bccf2571 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ Cancel Share Let\'s go + Confirm Fetching some info, hang in there… Hold your horses! You\'re doing that too often in a short amount of time.