feat(ui): add HistoryScreen and HistoryViewModel
This commit is contained in:
63
app/src/main/java/com/radiola/ui/history/HistoryScreen.kt
Normal file
63
app/src/main/java/com/radiola/ui/history/HistoryScreen.kt
Normal 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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
app/src/main/java/com/radiola/ui/history/HistoryViewModel.kt
Normal file
39
app/src/main/java/com/radiola/ui/history/HistoryViewModel.kt
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user