mirror of
https://github.com/fromchat-messenger/app.git
synced 2026-09-22 19:15:05 +03:00
@@ -13,6 +13,7 @@ plugins {
|
|||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
jvmTarget.set(JvmTarget.JVM_11)
|
jvmTarget.set(JvmTarget.JVM_11)
|
||||||
|
freeCompilerArgs.add("-Xsuppress-warning=NOTHING_TO_INLINE")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ import androidx.navigation.compose.composable
|
|||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import ru.fromchat.ui.auth.LoginScreen
|
import ru.fromchat.ui.auth.LoginScreen
|
||||||
import ru.fromchat.ui.auth.RegisterScreen
|
import ru.fromchat.ui.auth.RegisterScreen
|
||||||
import ru.fromchat.ui.chat.ChatScreen
|
import ru.fromchat.ui.main.MainScreen
|
||||||
import ru.fromchat.ui.chat.PublicChatScreen
|
|
||||||
|
|
||||||
val LocalNavController = compositionLocalOf<NavController> { error("") }
|
val LocalNavController = compositionLocalOf<NavController> { error("") }
|
||||||
|
|
||||||
@@ -68,7 +67,7 @@ fun App() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable("chat") { ChatScreen() }
|
composable("chat") { MainScreen() }
|
||||||
|
|
||||||
composable("chats/publicChat") {
|
composable("chats/publicChat") {
|
||||||
PublicChatScreen()
|
PublicChatScreen()
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,4 @@
|
|||||||
package ru.fromchat.ui.chat
|
package ru.fromchat.ui
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -69,7 +69,6 @@ import ru.fromchat.api.ApiClient
|
|||||||
import ru.fromchat.api.Message
|
import ru.fromchat.api.Message
|
||||||
import ru.fromchat.api.WebSocketManager
|
import ru.fromchat.api.WebSocketManager
|
||||||
import ru.fromchat.api.apiRequest
|
import ru.fromchat.api.apiRequest
|
||||||
import ru.fromchat.ui.LocalNavController
|
|
||||||
import kotlin.time.ExperimentalTime
|
import kotlin.time.ExperimentalTime
|
||||||
import kotlin.time.Instant
|
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")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-16
@@ -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.Column
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.safeDrawing
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.Chat
|
import androidx.compose.material.icons.automirrored.filled.Chat
|
||||||
import androidx.compose.material.icons.filled.Contacts
|
import androidx.compose.material.icons.filled.Contacts
|
||||||
import androidx.compose.material.icons.filled.Mail
|
import androidx.compose.material.icons.filled.Mail
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
|
||||||
import androidx.compose.material3.NavigationBar
|
import androidx.compose.material3.NavigationBar
|
||||||
import androidx.compose.material3.NavigationBarItem
|
import androidx.compose.material3.NavigationBarItem
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
@@ -22,12 +23,11 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import ru.fromchat.R
|
import ru.fromchat.R
|
||||||
import ru.fromchat.ui.LocalNavController
|
import ru.fromchat.utils.exclude
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChatScreen() {
|
fun MainScreen() {
|
||||||
var selectedTab by remember { mutableStateOf("chats") }
|
var selectedTab by remember { mutableStateOf("chats") }
|
||||||
val navController = LocalNavController.current
|
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
@@ -51,7 +51,8 @@ fun ChatScreen() {
|
|||||||
icon = { Icon(Icons.Filled.Mail, contentDescription = null) }
|
icon = { Icon(Icons.Filled.Mail, contentDescription = null) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
contentWindowInsets = WindowInsets.safeDrawing.exclude(WindowInsetsSides.Top)
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
@@ -59,15 +60,7 @@ fun ChatScreen() {
|
|||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
) {
|
) {
|
||||||
when (selectedTab) {
|
when (selectedTab) {
|
||||||
"chats" -> {
|
"chats" -> ChatsTab()
|
||||||
ListItem(
|
|
||||||
headlineContent = { Text(stringResource(R.string.public_chat)) },
|
|
||||||
supportingContent = { Text(stringResource(R.string.chat_last_mesaage)) },
|
|
||||||
modifier = Modifier.clickable {
|
|
||||||
navController.navigate("chats/publicChat")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
"contacts" -> {
|
"contacts" -> {
|
||||||
Text(stringResource(R.string.coming_soon))
|
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))
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
@file:Suppress("NOTHING_TO_INLINE")
|
@file:Suppress("NOTHING_TO_INLINE")
|
||||||
package ru.fromchat.utils
|
package ru.fromchat.utils
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import io.ktor.client.HttpClientConfig
|
import io.ktor.client.HttpClientConfig
|
||||||
import io.ktor.client.plugins.ClientRequestException
|
import io.ktor.client.plugins.ClientRequestException
|
||||||
import io.ktor.client.plugins.DefaultRequest
|
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).
|
* Throws if the HTTP response status code is an error (>=400).
|
||||||
* @return The [HttpResponse] if successful.
|
* @return The [HttpResponse] if successful.
|
||||||
* @throws ClientRequestException
|
* @throws ClientRequestException on 4xx error code.
|
||||||
* @throws ServerResponseException
|
* @throws ServerResponseException on 5xx error code.
|
||||||
* @throws ResponseException on error.
|
* @throws ResponseException on unknown error code.
|
||||||
*/
|
*/
|
||||||
suspend fun HttpResponse.failOnError(): HttpResponse {
|
suspend fun HttpResponse.failOnError() =
|
||||||
Log.d("failOnError", "Checking the response code...")
|
when (status.value) {
|
||||||
val statusCode = status.value
|
in 100..399 -> this
|
||||||
suspend fun body() = bodyAsText()
|
in 400..499 -> throw ClientRequestException(this, bodyAsText())
|
||||||
|
in 500..599 -> throw ServerResponseException(this, bodyAsText())
|
||||||
Log.d("failOnError", "code: $statusCode")
|
else -> throw ResponseException(this, bodyAsText())
|
||||||
|
|
||||||
when (statusCode) {
|
|
||||||
in 400..499 -> throw ClientRequestException(this, body())
|
|
||||||
in 500..599 -> throw ServerResponseException(this, body())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statusCode >= 600) {
|
|
||||||
throw ResponseException(this, body())
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("failOnError", "Success")
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user