feat(ui): add HistoryScreen and HistoryViewModel

This commit is contained in:
nk
2026-06-01 13:04:35 +03:00
parent b2af81c070
commit d3cec3bba2
2 changed files with 102 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
package com.radiola.ui.history
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.radiola.ui.components.EmptyState
import com.radiola.ui.components.SearchBar
import com.radiola.ui.components.TrackListItem
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HistoryScreen(
modifier: Modifier = Modifier,
viewModel: HistoryViewModel = hiltViewModel()
) {
val history by viewModel.history.collectAsState()
val searchQuery by viewModel.searchQuery.collectAsState()
Scaffold(
topBar = {
TopAppBar(
title = { Text("История") },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.background
)
)
}
) { padding ->
Column(
modifier = modifier
.fillMaxSize()
.padding(padding)
) {
SearchBar(
query = searchQuery,
onQueryChange = viewModel::onSearchQueryChange,
placeholder = "Поиск в истории...",
modifier = Modifier.padding(16.dp)
)
if (history.isEmpty()) {
EmptyState(message = "История пуста", modifier = Modifier.fillMaxSize())
} else {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(vertical = 8.dp)
) {
items(history) { track ->
TrackListItem(
track = track,
onClick = { /* TODO: open deeplink bottom sheet */ }
)
Divider(color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f))
}
}
}
}
}
}

View File

@@ -0,0 +1,39 @@
package com.radiola.ui.history
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.radiola.domain.model.Track
import com.radiola.domain.repository.TrackHistoryRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class HistoryViewModel @Inject constructor(
private val trackHistoryRepository: TrackHistoryRepository
) : ViewModel() {
private val _searchQuery = MutableStateFlow("")
val searchQuery: StateFlow<String> = _searchQuery.asStateFlow()
val history: StateFlow<List<Track>> = combine(
trackHistoryRepository.getHistory(),
_searchQuery
) { tracks, query ->
if (query.isBlank()) tracks else tracks.filter {
it.artist.contains(query, ignoreCase = true) ||
it.song.contains(query, ignoreCase = true)
}
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
fun onSearchQueryChange(query: String) {
_searchQuery.value = query
}
fun removeTrack(track: Track) {
viewModelScope.launch {
trackHistoryRepository.removeTrack(track)
}
}
}