diff --git a/app/src/main/java/chat/revolt/api/routes/googlesheets/ServerDataRepository.kt b/app/src/main/java/chat/revolt/api/routes/googlesheets/ServerDataRepository.kt index f4f9bb98..7d474c26 100644 --- a/app/src/main/java/chat/revolt/api/routes/googlesheets/ServerDataRepository.kt +++ b/app/src/main/java/chat/revolt/api/routes/googlesheets/ServerDataRepository.kt @@ -29,6 +29,7 @@ class ServerDataRepository { "false" -> false else -> true }, + showColor = rowData["showcolor"] ) } emit(servers) @@ -46,4 +47,5 @@ data class ServerData( val description: String, val inviteCode: String, val disabled: Boolean, + val showColor: String?, ) \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/composables/screens/chat/discover/DiscoverServersList.kt b/app/src/main/java/chat/revolt/composables/screens/chat/discover/DiscoverServersList.kt index 7f97a9b8..7f0146ed 100644 --- a/app/src/main/java/chat/revolt/composables/screens/chat/discover/DiscoverServersList.kt +++ b/app/src/main/java/chat/revolt/composables/screens/chat/discover/DiscoverServersList.kt @@ -17,6 +17,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -27,6 +28,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -34,6 +36,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.core.graphics.toColorInt import androidx.hilt.navigation.compose.hiltViewModel import chat.revolt.R import chat.revolt.api.RevoltAPI @@ -154,6 +157,26 @@ fun ServerItem( onClick: () -> Unit, isProcessing: Boolean = false ) { + // Safely convert the hex string to a Color, or return null if invalid + fun parseColorOrNull(hex: String?): Color? { + return hex?.let { raw -> + val normalized = if (raw.startsWith("#")) raw else "#$raw" + try { + Color(normalized.toColorInt()) + } catch (_: IllegalArgumentException) { + null + } + } + } + + // Determine card colors based on server.showColor + val containerColor = parseColorOrNull(server.showColor) + val cardColors = if (containerColor != null) { + CardDefaults.cardColors(containerColor = containerColor) + } else { + CardDefaults.cardColors() + } + // Calculate alpha values based on disabled state val contentAlpha = if (server.disabled) 0.5f else 1.0f val descriptionAlpha = if (server.disabled) 0.4f else 0.7f @@ -162,7 +185,8 @@ fun ServerItem( modifier = Modifier .fillMaxWidth() .padding(vertical = 8.dp) - .clickable(enabled = !isProcessing) { onClick() } + .clickable(enabled = !isProcessing) { onClick() }, + colors = cardColors, ) { Row( modifier = Modifier @@ -262,7 +286,8 @@ private fun ServerItemPreview() { name = "Revolt Lounge", description = "The official Revolt server. Hang out, chat, and get help with Revolt.", inviteCode = "revolt", - disabled = false + disabled = false, + showColor = null ) ServerItem( server = server, @@ -272,6 +297,26 @@ private fun ServerItemPreview() { ) } +@Preview +@Composable +private fun ColorfulServerItemPreview() { + val server = ServerData( + id = "1", + name = "Revolt Lounge", + description = "The official Revolt server. Hang out, chat, and get help with Revolt.", + inviteCode = "revolt", + disabled = false, + showColor = "#1591ea" + ) + ServerItem( + server = server, + onClick = {}, + isJoined = false, + isProcessing = false + ) +} + + @Preview @Composable private fun JoinedServerItemPreview() { @@ -280,7 +325,8 @@ private fun JoinedServerItemPreview() { name = "Revolt Lounge", description = "The official Revolt server. Hang out, chat, and get help with Revolt.", inviteCode = "revolt", - disabled = false + disabled = false, + showColor = null, ) ServerItem( server = server, diff --git a/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt b/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt index d30ed1ac..7cdf2efb 100644 --- a/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt +++ b/app/src/main/java/chat/revolt/composables/screens/chat/drawer/ChannelSideDrawer.kt @@ -421,18 +421,17 @@ fun ChannelSideDrawer( } Column( Modifier + .clip( + MaterialTheme.shapes.medium.copy( + topStart = CornerSize(24.dp), + ) + ) .background(MaterialTheme.colorScheme.surfaceContainer) .weight(1f) .fillMaxHeight() ) { Box( Modifier - .clip( - MaterialTheme.shapes.medium.copy( - topStart = CornerSize(0.dp), - topEnd = CornerSize(0.dp) - ) - ) .height(serverBannerHeight) ) { if (server?.banner != null) { diff --git a/app/src/main/java/chat/revolt/screens/chat/views/FriendsScreen.kt b/app/src/main/java/chat/revolt/screens/chat/views/FriendsScreen.kt index 5906c657..6b242e69 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/FriendsScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/FriendsScreen.kt @@ -4,7 +4,6 @@ import android.content.Context import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.clickable @@ -12,14 +11,10 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState @@ -100,7 +95,6 @@ import chat.revolt.composables.generic.CountableListHeader import chat.revolt.composables.generic.UserAvatar import chat.revolt.internals.extensions.zero import chat.revolt.markdown.jbm.asHexString -import chat.revolt.screens.chat.LocalIsConnected import io.github.g00fy2.quickie.QRResult import io.github.g00fy2.quickie.ScanQRCode import kotlinx.coroutines.Dispatchers @@ -474,72 +468,61 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean = false, onDrawerCli Scaffold( topBar = { - Column { - AnimatedVisibility(LocalIsConnected.current) { - Spacer( - Modifier - .height( - WindowInsets.statusBars.asPaddingValues() - .calculateTopPadding() - ) + TopAppBar( + title = { + Text( + text = stringResource(R.string.friends), + maxLines = 1, + overflow = TextOverflow.Ellipsis, ) - } - TopAppBar( - title = { - Text( - text = stringResource(R.string.friends), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - navigationIcon = { - if (useDrawer) { - IconButton(onClick = { - onDrawerClicked() - }) { - Icon( - painter = painterResource(R.drawable.icn_menu_24dp), - contentDescription = stringResource(id = R.string.menu) - ) - } - } - }, - actions = { + }, + navigationIcon = { + if (useDrawer) { IconButton(onClick = { - overflowMenuShown = true + onDrawerClicked() }) { Icon( - painter = painterResource(R.drawable.icn_more_vert_24dp), - contentDescription = stringResource(R.string.menu) + painter = painterResource(R.drawable.icn_menu_24dp), + contentDescription = stringResource(id = R.string.menu) ) } - DropdownMenu( - expanded = overflowMenuShown, - onDismissRequest = { - overflowMenuShown = false - } - ) { - DropdownMenuItem( - text = { - Text(stringResource(R.string.friends_deny_all_incoming)) - }, - onClick = { + } + }, + actions = { + IconButton(onClick = { + overflowMenuShown = true + }) { + Icon( + painter = painterResource(R.drawable.icn_more_vert_24dp), + contentDescription = stringResource(R.string.menu) + ) + } + DropdownMenu( + expanded = overflowMenuShown, + onDismissRequest = { + overflowMenuShown = false + } + ) { + DropdownMenuItem( + text = { + Text(stringResource(R.string.friends_deny_all_incoming)) + }, + onClick = { + scope.launch { + overflowMenuShown = false + } + with(Dispatchers.IO) { scope.launch { - overflowMenuShown = false - } - with(Dispatchers.IO) { - scope.launch { - FriendRequests.getIncoming() - .forEach { it.id?.let { id -> unfriendUser(id) } } - } + FriendRequests.getIncoming() + .forEach { it.id?.let { id -> unfriendUser(id) } } } } - ) - } - }, - windowInsets = WindowInsets.zero - ) - } + } + ) + } + }, + windowInsets = WindowInsets.zero + ) }, ) { pv -> Box( diff --git a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt index 1290ec80..8b7eac44 100644 --- a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt @@ -10,11 +10,11 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.LargeTopAppBar import androidx.compose.material3.ListItem import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -67,7 +67,7 @@ fun SettingsScreen( Column( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), ) { - LargeTopAppBar( + TopAppBar( scrollBehavior = scrollBehavior, title = { Text(