128 lines
5.1 KiB
Kotlin
128 lines
5.1 KiB
Kotlin
package chats.presentation.chat_list
|
||
|
||
import androidx.compose.foundation.layout.*
|
||
import androidx.compose.foundation.lazy.LazyColumn
|
||
import androidx.compose.foundation.lazy.items
|
||
import androidx.compose.foundation.lazy.LazyRow
|
||
import androidx.compose.material3.*
|
||
import androidx.compose.runtime.Composable
|
||
import androidx.compose.runtime.collectAsState
|
||
import androidx.compose.runtime.getValue
|
||
import androidx.compose.ui.Alignment
|
||
import androidx.compose.ui.Modifier
|
||
import androidx.compose.ui.graphics.Color
|
||
import androidx.compose.ui.res.stringResource
|
||
import androidx.compose.ui.text.font.FontWeight
|
||
import androidx.compose.ui.unit.dp
|
||
import chats.presentation.components.ChatItem
|
||
import stories.presentation.StoryViewModel
|
||
import stories.presentation.components.StoryThumbnail
|
||
import ru.knot.messager.R
|
||
|
||
@Composable
|
||
fun HorizontalDividerComponent(
|
||
modifier: Modifier = Modifier,
|
||
thickness: androidx.compose.ui.unit.Dp = 1.dp,
|
||
color: androidx.compose.ui.graphics.Color = MaterialTheme.colorScheme.outlineVariant
|
||
) {
|
||
androidx.compose.material3.Divider(
|
||
modifier = modifier,
|
||
thickness = thickness,
|
||
color = color
|
||
)
|
||
}
|
||
|
||
@OptIn(ExperimentalMaterial3Api::class)
|
||
@Composable
|
||
fun ChatListScreen(
|
||
viewModel: ChatListViewModel,
|
||
storyViewModel: StoryViewModel,
|
||
onChatClick: (String) -> Unit,
|
||
onStoryClick: (Int) -> Unit
|
||
) {
|
||
val state by viewModel.state.collectAsState()
|
||
val storyState by storyViewModel.state.collectAsState()
|
||
|
||
androidx.compose.runtime.LaunchedEffect(Unit) {
|
||
viewModel.loadChats()
|
||
}
|
||
|
||
Scaffold(
|
||
topBar = {
|
||
TopAppBar(
|
||
title = { Text(stringResource(R.string.chats_title), fontWeight = FontWeight.Bold) },
|
||
colors = TopAppBarDefaults.topAppBarColors(
|
||
containerColor = Color.Transparent,
|
||
titleContentColor = Color.White
|
||
)
|
||
)
|
||
}
|
||
) { paddingValues ->
|
||
Box(
|
||
modifier = Modifier
|
||
.fillMaxSize()
|
||
.padding(paddingValues)
|
||
) {
|
||
if (state.isLoading && state.chats.isEmpty()) {
|
||
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
||
} else {
|
||
LazyColumn {
|
||
// Ряд историй сверху списка чатов
|
||
item {
|
||
if (state.isStoriesEnabled && storyState.storyGroups.isNotEmpty()) {
|
||
LazyRow(
|
||
modifier = Modifier
|
||
.fillMaxWidth()
|
||
.padding(vertical = 8.dp),
|
||
contentPadding = PaddingValues(horizontal = 8.dp)
|
||
) {
|
||
items(storyState.storyGroups.size) { index ->
|
||
val group = storyState.storyGroups[index]
|
||
StoryThumbnail(
|
||
username = group.username,
|
||
avatarUrl = group.avatar,
|
||
hasUnseen = true, // В идеале проверяем по статусам
|
||
onClick = { onStoryClick(index) }
|
||
)
|
||
}
|
||
}
|
||
HorizontalDividerComponent(
|
||
thickness = 0.5.dp,
|
||
color = MaterialTheme.colorScheme.outlineVariant
|
||
)
|
||
}
|
||
}
|
||
|
||
if (state.error != null && state.chats.isEmpty()) {
|
||
item {
|
||
Text(
|
||
text = "${stringResource(R.string.error_occurred)}: ${state.error}",
|
||
color = MaterialTheme.colorScheme.error,
|
||
modifier = Modifier.padding(16.dp)
|
||
)
|
||
}
|
||
} else if (state.chats.isEmpty() && !state.isLoading) {
|
||
item {
|
||
Box(modifier = Modifier.fillParentMaxSize()) {
|
||
Text(
|
||
text = stringResource(R.string.no_chats_found),
|
||
modifier = Modifier.align(Alignment.Center)
|
||
)
|
||
}
|
||
}
|
||
} else {
|
||
items(state.chats) { chat ->
|
||
ChatItem(chat = chat, onClick = onChatClick)
|
||
HorizontalDividerComponent(
|
||
modifier = Modifier.padding(horizontal = 16.dp),
|
||
thickness = 0.5.dp,
|
||
color = MaterialTheme.colorScheme.outlineVariant
|
||
)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|