Improve UI

Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
2025-09-13 18:56:07 +03:00
Unverified
parent 8d2703a77e
commit be169d0fe9
5 changed files with 147 additions and 100 deletions
+1
View File
@@ -29,6 +29,7 @@
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="NestedLambdaShadowedImplicitParameter" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
+1 -1
View File
@@ -13,7 +13,7 @@ plugins {
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
freeCompilerArgs.add("-Xsuppress-warning=NOTHING_TO_INLINE")
freeCompilerArgs.add("-Xwarning-level=NOTHING_TO_INLINE:disabled")
}
}
@@ -31,8 +31,7 @@ object WebSocketManager {
private val _messages = MutableSharedFlow<WebSocketMessage>(replay = 0, extraBufferCapacity = 64)
val messages = _messages.asSharedFlow()
@Volatile
private var globalHandlers = mutableListOf<((WebSocketMessage) -> Unit)>()
private val globalHandlers = mutableListOf<((WebSocketMessage) -> Unit)>()
fun addGlobalMessageHandler(handler: ((WebSocketMessage) -> Unit)) {
globalHandlers += handler
@@ -1,6 +1,9 @@
package ru.fromchat.ui
import android.util.Log
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -10,6 +13,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
@@ -29,8 +33,10 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.DoneAll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LoadingIndicator
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -51,11 +57,15 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.datetime.TimeZone
import kotlinx.datetime.format
import kotlinx.datetime.toLocalDateTime
@@ -76,7 +86,7 @@ import ru.fromchat.utils.exclude
import kotlin.time.ExperimentalTime
import kotlin.time.Instant
@OptIn(ExperimentalMaterial3Api::class, ExperimentalTime::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalTime::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun PublicChatScreen() {
val navController = LocalNavController.current
@@ -84,8 +94,12 @@ fun PublicChatScreen() {
val scrollState = rememberScrollState()
val messages = remember { mutableStateListOf<Message>() }
var loading by remember { mutableStateOf(true) }
LaunchedEffect(Unit) {
val coroutineContext = coroutineContext
CoroutineScope(Dispatchers.IO).launch {
apiRequest {
ApiClient.getMessages()
}.onSuccess {
@@ -109,7 +123,11 @@ fun PublicChatScreen() {
}
delay(500)
scrollState.animateScrollTo(scrollState.maxValue)
withContext(coroutineContext) {
scrollState.scrollTo(scrollState.maxValue)
}
loading = false
}.join()
}
Scaffold(
@@ -205,6 +223,7 @@ fun PublicChatScreen() {
}
}
) { innerPadding ->
Box(Modifier.fillMaxSize()) {
Column(
Modifier
.padding(innerPadding)
@@ -215,7 +234,8 @@ fun PublicChatScreen() {
text: String,
isAuthor: Boolean,
isRead: Boolean,
timestamp: String
timestamp: String,
username: String
) {
var rowWidth by remember { mutableStateOf(0.dp) }
val density = LocalDensity.current
@@ -225,7 +245,7 @@ fun PublicChatScreen() {
.padding(horizontal = 16.dp, vertical = 4.dp)
.fillMaxWidth()
.onSizeChanged {
rowWidth = with (density) {
rowWidth = with(density) {
it.width.toDp()
}
},
@@ -251,6 +271,14 @@ fun PublicChatScreen() {
.width(IntrinsicSize.Max)
.widthIn(max = rowWidth * 0.80f)
) {
if (!isAuthor) {
Text(
text = username,
fontWeight = FontWeight.W600,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
Text(text)
Row(
verticalAlignment = Alignment.CenterVertically,
@@ -282,9 +310,26 @@ fun PublicChatScreen() {
timestamp = Instant
.parse(it.utcTimestamp)
.toLocalDateTime(TimeZone.currentSystemDefault())
.format(DATETIME_FORMAT)
.format(DATETIME_FORMAT),
username = it.username
)
}
}
AnimatedVisibility(
visible = loading,
enter = EnterTransition.None,
exit = fadeOut()
) {
Box(
Modifier
.background(MaterialTheme.colorScheme.surface)
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
LoadingIndicator(Modifier.size(70.dp))
}
}
}
}
}
+11 -9
View File
@@ -1,6 +1,6 @@
[versions]
agp = "8.12.3"
kotlin = "2.2.10"
kotlin = "2.2.20"
coreKtx = "1.17.0"
junit = "4.13.2"
junitVersion = "1.3.0"
@@ -11,8 +11,10 @@ activityCompose = "1.11.0"
composeBom = "2025.09.00"
materialIconsExtended = "1.7.8"
navigationCompose = "2.9.4"
ktor = "3.2.3"
ktor = "3.3.0"
kotlinxSerializationJson = "1.9.0"
compose = "1.9.1"
material3 = "1.5.0-alpha04"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -23,13 +25,13 @@ androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-co
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "compose" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "compose" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "compose" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview", version.ref = "compose" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version.ref = "compose" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4", version.ref = "compose" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime" }
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }