Improve the UI

Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
2025-09-11 20:50:19 +03:00
Unverified
parent 582160e88d
commit 03e718b743
7 changed files with 83 additions and 45 deletions
+1
View File
@@ -13,6 +13,7 @@ plugins {
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
freeCompilerArgs.add("-Xsuppress-warning=NOTHING_TO_INLINE")
}
}
+2 -3
View File
@@ -13,8 +13,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import ru.fromchat.ui.auth.LoginScreen
import ru.fromchat.ui.auth.RegisterScreen
import ru.fromchat.ui.chat.ChatScreen
import ru.fromchat.ui.chat.PublicChatScreen
import ru.fromchat.ui.main.MainScreen
val LocalNavController = compositionLocalOf<NavController> { error("") }
@@ -68,7 +67,7 @@ fun App() {
)
}
composable("chat") { ChatScreen() }
composable("chat") { MainScreen() }
composable("chats/publicChat") {
PublicChatScreen()
@@ -1,4 +1,4 @@
package ru.fromchat.ui.chat
package ru.fromchat.ui
import android.util.Log
import androidx.compose.foundation.background
@@ -69,7 +69,6 @@ import ru.fromchat.api.ApiClient
import ru.fromchat.api.Message
import ru.fromchat.api.WebSocketManager
import ru.fromchat.api.apiRequest
import ru.fromchat.ui.LocalNavController
import kotlin.time.ExperimentalTime
import kotlin.time.Instant
@@ -0,0 +1,52 @@
package ru.fromchat.ui.main
import androidx.compose.foundation.clickable
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ListItem
import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import ru.fromchat.R
import ru.fromchat.ui.LocalNavController
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChatsTab() {
val navController = LocalNavController.current
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
MediumTopAppBar(
title = {
Text(
text = stringResource(R.string.chats),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
},
scrollBehavior = scrollBehavior
)
}
) { innerPadding ->
LazyColumn(contentPadding = innerPadding) {
item {
ListItem(
headlineContent = { Text(stringResource(R.string.public_chat)) },
supportingContent = { Text(stringResource(R.string.chat_last_mesaage)) },
modifier = Modifier.clickable {
navController.navigate("chats/publicChat")
}
)
}
}
}
}
@@ -1,15 +1,16 @@
package ru.fromchat.ui.chat
package ru.fromchat.ui.main
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Chat
import androidx.compose.material.icons.filled.Contacts
import androidx.compose.material.icons.filled.Mail
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
@@ -22,12 +23,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import ru.fromchat.R
import ru.fromchat.ui.LocalNavController
import ru.fromchat.utils.exclude
@Composable
fun ChatScreen() {
fun MainScreen() {
var selectedTab by remember { mutableStateOf("chats") }
val navController = LocalNavController.current
Scaffold(
bottomBar = {
@@ -51,7 +51,8 @@ fun ChatScreen() {
icon = { Icon(Icons.Filled.Mail, contentDescription = null) }
)
}
}
},
contentWindowInsets = WindowInsets.safeDrawing.exclude(WindowInsetsSides.Top)
) { innerPadding ->
Column(
Modifier
@@ -59,15 +60,7 @@ fun ChatScreen() {
.padding(innerPadding)
) {
when (selectedTab) {
"chats" -> {
ListItem(
headlineContent = { Text(stringResource(R.string.public_chat)) },
supportingContent = { Text(stringResource(R.string.chat_last_mesaage)) },
modifier = Modifier.clickable {
navController.navigate("chats/publicChat")
}
)
}
"chats" -> ChatsTab()
"contacts" -> {
Text(stringResource(R.string.coming_soon))
}
@@ -0,0 +1,8 @@
package ru.fromchat.utils
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.exclude
import androidx.compose.foundation.layout.only
inline fun WindowInsets.exclude(sides: WindowInsetsSides) = exclude(this.only(sides))
+9 -23
View File
@@ -1,7 +1,6 @@
@file:Suppress("NOTHING_TO_INLINE")
package ru.fromchat.utils
import android.util.Log
import io.ktor.client.HttpClientConfig
import io.ktor.client.plugins.ClientRequestException
import io.ktor.client.plugins.DefaultRequest
@@ -76,27 +75,14 @@ inline fun HttpClientConfig<*>.logging() = logging {
/**
* Throws if the HTTP response status code is an error (>=400).
* @return The [HttpResponse] if successful.
* @throws ClientRequestException
* @throws ServerResponseException
* @throws ResponseException on error.
* @throws ClientRequestException on 4xx error code.
* @throws ServerResponseException on 5xx error code.
* @throws ResponseException on unknown error code.
*/
suspend fun HttpResponse.failOnError(): HttpResponse {
Log.d("failOnError", "Checking the response code...")
val statusCode = status.value
suspend fun body() = bodyAsText()
Log.d("failOnError", "code: $statusCode")
when (statusCode) {
in 400..499 -> throw ClientRequestException(this, body())
in 500..599 -> throw ServerResponseException(this, body())
suspend fun HttpResponse.failOnError() =
when (status.value) {
in 100..399 -> this
in 400..499 -> throw ClientRequestException(this, bodyAsText())
in 500..599 -> throw ServerResponseException(this, bodyAsText())
else -> throw ResponseException(this, bodyAsText())
}
if (statusCode >= 600) {
throw ResponseException(this, body())
}
Log.d("failOnError", "Success")
return this
}