Refactor: Introduce SquareButton and SquareElevatedButton components for consistent button styling

This commit adds two new composable functions, SquareButton and SquareElevatedButton, to standardize button styling across the application. The new components encapsulate the button shape and styling, promoting code reuse and cleaner UI implementation.

- Created SquareButton for standard button functionality with customizable onClick and content.
- Created SquareElevatedButton for elevated button functionality with similar customization options.
- Replaced instances of Button and ElevatedButton in various screens with the new SquareButton and SquareElevatedButton components for consistency and improved maintainability.
This commit is contained in:
AbronStudio 2025-08-09 10:29:40 +03:30
parent bc27106d30
commit bf6546725f
8 changed files with 73 additions and 77 deletions

View File

@ -0,0 +1,51 @@
package chat.revolt.composables.generic
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.Button
import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun SquareButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
content: @Composable () -> Unit
) {
Button(
onClick = onClick,
modifier = modifier,
enabled = enabled,
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) {
content()
}
}
@Composable
fun SquareElevatedButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
ElevatedButton(
onClick = onClick,
modifier = modifier,
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) {
content()
}
}

View File

@ -36,7 +36,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.FloatingActionButton
@ -70,8 +69,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import chat.revolt.R import chat.revolt.R
import chat.revolt.api.RevoltAPI import chat.revolt.api.RevoltAPI
@ -90,6 +89,7 @@ import chat.revolt.api.settings.SyncedSettings
import chat.revolt.composables.generic.GroupIcon import chat.revolt.composables.generic.GroupIcon
import chat.revolt.composables.generic.IconPlaceholder import chat.revolt.composables.generic.IconPlaceholder
import chat.revolt.composables.generic.RemoteImage import chat.revolt.composables.generic.RemoteImage
import chat.revolt.composables.generic.SquareButton
import chat.revolt.composables.generic.UserAvatar import chat.revolt.composables.generic.UserAvatar
import chat.revolt.composables.generic.presenceFromStatus import chat.revolt.composables.generic.presenceFromStatus
import chat.revolt.composables.screens.chat.ChannelIcon import chat.revolt.composables.screens.chat.ChannelIcon
@ -738,16 +738,10 @@ private fun ColumnScope.DirectMessagesChannelListRenderer(
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
Spacer(Modifier.height(16.dp)) Spacer(Modifier.height(16.dp))
Button( SquareButton(
onClick = { onClick = {
onDestinationChanged(ChatRouterDestination.Friends) onDestinationChanged(ChatRouterDestination.Friends)
}, },
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.new_conversation)) Text(text = stringResource(R.string.new_conversation))
} }

View File

@ -13,9 +13,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -37,6 +35,7 @@ import androidx.navigation.NavController
import chat.revolt.R import chat.revolt.R
import chat.revolt.api.ApplicationPlatform import chat.revolt.api.ApplicationPlatform
import chat.revolt.api.RevoltAPI import chat.revolt.api.RevoltAPI
import chat.revolt.composables.generic.SquareButton
@Composable @Composable
fun ChoosePlatformScreen(navController: NavController) { fun ChoosePlatformScreen(navController: NavController) {
@ -191,7 +190,7 @@ fun ChoosePlatformScreen(navController: NavController) {
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 8.dp) .padding(vertical = 8.dp)
) )
Button( SquareButton(
onClick = { onClick = {
if(apiUrlValue.value.isNotEmpty()){ if(apiUrlValue.value.isNotEmpty()){
when(apiUrlValue.value){ when(apiUrlValue.value){
@ -201,7 +200,7 @@ fun ChoosePlatformScreen(navController: NavController) {
ApplicationPlatform.REVOLT.baseUrl -> RevoltAPI.setPlatform( ApplicationPlatform.REVOLT.baseUrl -> RevoltAPI.setPlatform(
ApplicationPlatform.REVOLT ApplicationPlatform.REVOLT
) )
else -> return@Button else -> return@SquareButton
} }
} }
navController.navigate("login/greeting") navController.navigate("login/greeting")
@ -210,12 +209,6 @@ fun ChoosePlatformScreen(navController: NavController) {
.padding(top = 32.dp, bottom = 16.dp) .padding(top = 32.dp, bottom = 16.dp)
.fillMaxWidth() .fillMaxWidth()
.testTag("confirm_platform_button"), .testTag("confirm_platform_button"),
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.confirm)) Text(text = stringResource(R.string.confirm))
} }

View File

@ -14,9 +14,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.Button
import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -36,12 +33,14 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavController import androidx.navigation.NavController
import chat.revolt.R
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import chat.revolt.R
import chat.revolt.composables.generic.SquareButton
import chat.revolt.composables.generic.SquareElevatedButton
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
@ -129,34 +128,22 @@ fun LoginGreetingScreen(navController: NavController) {
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
Button( SquareButton(
onClick = { navController.navigate("login/login") }, onClick = { navController.navigate("login/login") },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.testTag("view_login_page_button"), .testTag("view_login_page_button"),
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.login)) Text(text = stringResource(R.string.login))
} }
Spacer(modifier = Modifier.height(5.dp)) Spacer(modifier = Modifier.height(5.dp))
ElevatedButton( SquareElevatedButton(
onClick = { navController.navigate("register/details") }, onClick = { navController.navigate("register/details") },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.testTag("view_signup_page_button"), .testTag("view_signup_page_button"),
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.signup)) Text(text = stringResource(R.string.signup))
} }

View File

@ -13,10 +13,8 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.text.input.TextObfuscationMode import androidx.compose.foundation.text.input.TextObfuscationMode
import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -58,6 +56,7 @@ import chat.revolt.api.routes.account.EmailPasswordAssessment
import chat.revolt.api.routes.account.negotiateAuthentication import chat.revolt.api.routes.account.negotiateAuthentication
import chat.revolt.api.routes.onboard.needsOnboarding import chat.revolt.api.routes.onboard.needsOnboarding
import chat.revolt.composables.generic.FormTextField import chat.revolt.composables.generic.FormTextField
import chat.revolt.composables.generic.SquareButton
import chat.revolt.composables.generic.Weblink import chat.revolt.composables.generic.Weblink
import chat.revolt.persistence.KVStorage import chat.revolt.persistence.KVStorage
import chat.revolt.ui.theme.FragmentMono import chat.revolt.ui.theme.FragmentMono
@ -337,19 +336,13 @@ fun LoginScreen(navController: NavController, viewModel: LoginViewModel = hiltVi
) )
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
Button( SquareButton(
onClick = { onClick = {
viewModel.doLogin() viewModel.doLogin()
}, },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.testTag("confirm_platform_button"), .testTag("confirm_platform_button"),
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.login)) Text(text = stringResource(R.string.login))
} }

View File

@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.imeNestedScroll
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -35,6 +34,7 @@ import chat.revolt.R
import chat.revolt.api.routes.onboard.OnboardingCompletionBody import chat.revolt.api.routes.onboard.OnboardingCompletionBody
import chat.revolt.api.routes.onboard.completeOnboarding import chat.revolt.api.routes.onboard.completeOnboarding
import chat.revolt.composables.generic.FormTextField import chat.revolt.composables.generic.FormTextField
import chat.revolt.composables.generic.SquareButton
import chat.revolt.persistence.KVStorage import chat.revolt.persistence.KVStorage
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -168,7 +168,7 @@ fun OnboardingScreen(navController: NavController, onOnboardingComplete: () -> U
label = stringResource(R.string.onboarding_username) label = stringResource(R.string.onboarding_username)
) )
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
Button( SquareButton(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
onClick = { onClick = {
coroutineScope.launch { coroutineScope.launch {
@ -176,12 +176,6 @@ fun OnboardingScreen(navController: NavController, onOnboardingComplete: () -> U
} }
}, },
enabled = username.value.isNotBlank(), enabled = username.value.isNotBlank(),
shape = MaterialTheme.shapes.small.copy(
topStart = androidx.compose.foundation.shape.CornerSize(8.dp),
topEnd = androidx.compose.foundation.shape.CornerSize(8.dp),
bottomStart = androidx.compose.foundation.shape.CornerSize(8.dp),
bottomEnd = androidx.compose.foundation.shape.CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.complete_registration)) Text(text = stringResource(R.string.complete_registration))
} }

View File

@ -13,8 +13,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -52,6 +50,7 @@ import chat.revolt.api.routes.account.RegistrationBody
import chat.revolt.api.routes.account.register import chat.revolt.api.routes.account.register
import chat.revolt.api.routes.misc.getRootRoute import chat.revolt.api.routes.misc.getRootRoute
import chat.revolt.composables.generic.FormTextField import chat.revolt.composables.generic.FormTextField
import chat.revolt.composables.generic.SquareButton
import com.hcaptcha.sdk.HCaptcha import com.hcaptcha.sdk.HCaptcha
import com.hcaptcha.sdk.HCaptchaConfig import com.hcaptcha.sdk.HCaptchaConfig
import com.hcaptcha.sdk.HCaptchaSize import com.hcaptcha.sdk.HCaptchaSize
@ -240,7 +239,7 @@ fun RegisterDetailsScreen(
val context = LocalContext.current val context = LocalContext.current
Button( SquareButton(
onClick = { onClick = {
viewModel.initCaptcha(context) { viewModel.initCaptcha(context) {
viewModel.doRegistration(navController) viewModel.doRegistration(navController)
@ -249,12 +248,6 @@ fun RegisterDetailsScreen(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.testTag("setup_continue_button"), .testTag("setup_continue_button"),
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.continue_)) Text(text = stringResource(R.string.continue_))
} }

View File

@ -4,7 +4,6 @@ import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -13,9 +12,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -31,12 +27,13 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.compose.rememberNavController
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import chat.revolt.R import chat.revolt.R
import chat.revolt.composables.generic.SquareButton
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -119,7 +116,7 @@ fun RegisterVerifyScreen(navController: NavController, email: String) {
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
Button( SquareButton(
modifier = Modifier modifier = Modifier
.fillMaxWidth(), .fillMaxWidth(),
onClick = { onClick = {
@ -127,12 +124,6 @@ fun RegisterVerifyScreen(navController: NavController, email: String) {
intent.addCategory(Intent.CATEGORY_APP_EMAIL) intent.addCategory(Intent.CATEGORY_APP_EMAIL)
intentLauncher.launch(intent) intentLauncher.launch(intent)
}, },
shape = MaterialTheme.shapes.small.copy(
topStart = CornerSize(8.dp),
topEnd = CornerSize(8.dp),
bottomStart = CornerSize(8.dp),
bottomEnd = CornerSize(8.dp)
)
) { ) {
Text(text = stringResource(R.string.open_mail_app)) Text(text = stringResource(R.string.open_mail_app))
} }