Добавлен индикатор загрузки и подключен снэкбар

Этот коммит содержится в:
Глеб Иваницкий 2024-08-28 11:53:32 +03:00
родитель d7aefcb03d
Коммит 7d6531af1f
3 изменённых файлов: 149 добавлений и 97 удалений

Просмотреть файл

@ -1,7 +1,10 @@
package ru.csasq.cit_is_bot
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
@ -12,7 +15,9 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
@ -65,22 +70,33 @@ fun App() {
colorScheme = darkScheme,
) {
val navController = rememberNavController()
val snackbarHostState = remember {
SnackbarHostState()
val progressIndicatorState = remember {
mutableStateOf(false)
}
val snackbarHostState = SnackbarHostState()
val floatingActionButtonState = remember {
mutableStateOf<(@Composable () -> Unit)?>(null)
}
Scaffold(
topBar = {
TopAppBar(
title = {
Text(
text = "Сообщения",
Column {
TopAppBar(
title = {
Text(
text = "Сообщения",
overflow = TextOverflow.Ellipsis,
softWrap = false,
)
},
)
when {
progressIndicatorState.value -> LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth(),
)
},
)
}
}
},
bottomBar = {
NavigationBar {
@ -119,12 +135,12 @@ fun App() {
snackbarHost = {
SnackbarHost(
hostState = snackbarHostState,
) {
) { snackbarData ->
Snackbar(
snackbarData = it,
containerColor = MaterialTheme.colorScheme.errorContainer,
contentColor = MaterialTheme.colorScheme.error,
actionColor = MaterialTheme.colorScheme.onErrorContainer,
snackbarData = snackbarData,
// containerColor = MaterialTheme.colorScheme.errorContainer,
// contentColor = MaterialTheme.colorScheme.error,
// actionColor = MaterialTheme.colorScheme.onErrorContainer,
)
}
},
@ -145,6 +161,8 @@ fun App() {
ScenariosScreen(
navController,
paddingValues,
progressIndicatorState,
snackbarHostState,
floatingActionButtonState,
)
}

Просмотреть файл

@ -21,6 +21,7 @@ import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
@ -84,11 +85,15 @@ enum class MessageType(
fun ScenarioDialog(
scenarioDialogState: MutableState<Scenario?>,
client: HttpClient,
onSuccess: () -> Unit,
properties: DialogProperties = DialogProperties(
usePlatformDefaultWidth = false,
),
) {
val coroutine = rememberCoroutineScope()
val progressIndicatorState = remember {
mutableStateOf(false)
}
val nameState = remember {
mutableStateOf(scenarioDialogState.value?.name)
}
@ -119,71 +124,98 @@ fun ScenarioDialog(
modifier = Modifier
.fillMaxSize(),
topBar = {
TopAppBar(
title = {
Text(
text = scenarioDialogState.value?.id?.let {
"Изменить сценарий"
} ?: "Добавить сценарий",
overflow = TextOverflow.Ellipsis,
maxLines = 1,
)
},
navigationIcon = {
IconButton(
onClick = {
scenarioDialogState.value = null
},
) {
Icon(
painter = painterResource(Res.drawable.baseline_close_24),
contentDescription = null,
)
}
},
actions = {
Button(
onClick = {
scenarioDialogState.value?.name = nameState.value!!
coroutine.launch {
val response = client.put("https://cit.csasq.ru/api/scripts") {
contentType(ContentType.Application.Json)
setBody(scenarioDialogState.value)
}
when(response.status) {
HttpStatusCode.Created -> scenarioDialogState.value = null
}
}
},
) {
Column {
TopAppBar(
title = {
Text(
text = "Сохранить",
text = scenarioDialogState.value?.id?.let {
"Изменить сценарий"
} ?: "Добавить сценарий",
overflow = TextOverflow.Ellipsis,
softWrap = false,
)
}
val dropdownMenuState = remember {
mutableStateOf(false)
}
IconButton(
onClick = {
dropdownMenuState.value = true
},
) {
Icon(
painter = painterResource(Res.drawable.baseline_more_vert_24),
contentDescription = null,
)
}
DropdownMenu(
expanded = dropdownMenuState.value,
onDismissRequest = {
dropdownMenuState.value = false
},
) {
scenarioDialogState.value?.let {
},
navigationIcon = {
IconButton(
onClick = {
scenarioDialogState.value = null
},
) {
Icon(
painter = painterResource(Res.drawable.baseline_close_24),
contentDescription = null,
)
}
},
actions = {
Button(
onClick = {
scenarioDialogState.value?.name = nameState.value!!
coroutine.launch {
progressIndicatorState.value = true
val response = client.put("https://cit.csasq.ru/api/scripts") {
contentType(ContentType.Application.Json)
setBody(scenarioDialogState.value)
}
progressIndicatorState.value = false
when (response.status) {
HttpStatusCode.Created -> {
onSuccess()
scenarioDialogState.value = null
}
}
}
},
) {
Text(
text = "Сохранить",
)
}
val dropdownMenuState = remember {
mutableStateOf(false)
}
IconButton(
onClick = {
dropdownMenuState.value = true
},
) {
Icon(
painter = painterResource(Res.drawable.baseline_more_vert_24),
contentDescription = null,
)
}
DropdownMenu(
expanded = dropdownMenuState.value,
onDismissRequest = {
dropdownMenuState.value = false
},
) {
scenarioDialogState.value?.let {
DropdownMenuItem(
text = {
Text(
text = "Удалить",
)
},
onClick = {
dropdownMenuState.value = false
},
)
}
DropdownMenuItem(
text = {
Text(
text = "Удалить",
text = "Сообщить о проблеме",
)
},
onClick = {
dropdownMenuState.value = false
},
)
DropdownMenuItem(
text = {
Text(
text = "Справка",
)
},
onClick = {
@ -191,29 +223,15 @@ fun ScenarioDialog(
},
)
}
DropdownMenuItem(
text = {
Text(
text = "Сообщить о проблеме",
)
},
onClick = {
dropdownMenuState.value = false
},
)
DropdownMenuItem(
text = {
Text(
text = "Справка",
)
},
onClick = {
dropdownMenuState.value = false
},
)
}
},
)
},
)
when {
progressIndicatorState.value -> LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth(),
)
}
}
},
floatingActionButton = {
ExtendedFloatingActionButton(

Просмотреть файл

@ -8,6 +8,8 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@ -15,6 +17,7 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.buildAnnotatedString
@ -46,8 +49,11 @@ data class Scenario(
fun ScenariosScreen(
navController: NavController,
paddingValues: PaddingValues,
progressIndicatorState: MutableState<Boolean>,
snackbarHostState: SnackbarHostState,
floatingActionButtonState: MutableState<(@Composable () -> Unit)?>,
) {
val snackbarCoroutineScope = rememberCoroutineScope()
val verticalScrollState = rememberScrollState()
val floatingActionButtonExpandedState = remember {
mutableStateOf(true)
@ -74,7 +80,9 @@ fun ScenariosScreen(
}
LaunchedEffect(false) {
client.launch {
progressIndicatorState.value = true
val response = client.get("https://cit.csasq.ru/api/scripts")
progressIndicatorState.value = false
when (response.status) {
HttpStatusCode.OK -> scenarioList.addAll(response.body())
}
@ -127,7 +135,7 @@ fun ScenariosScreen(
}
val captionAnnotatedString = buildAnnotatedString {
append(it.time)
append(" \u2022 ")
append(" \u2022 ")
append(it.messageNumber)
}
SwitchButton(
@ -147,6 +155,14 @@ fun ScenariosScreen(
ScenarioDialog(
scenarioDialogState = scenarioDialogState,
client = client,
onSuccess = {
snackbarCoroutineScope.launch {
snackbarHostState.showSnackbar(
message = "Сценарий сохранен",
duration = SnackbarDuration.Short,
)
}
},
)
}
}