Загрузка данных
package ru.notesapp.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import ru.notesapp.data.NotesRepository
import ru.notesapp.data.remote.NetworkResult
import ru.notesapp.domain.Note
import ru.notesapp.domain.NoteType
import javax.inject.Inject
@HiltViewModel
class NotesViewModel @Inject constructor(
private val repository: NotesRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<NotesUiState>(NotesUiState.Loading)
val uiState: StateFlow<NotesUiState> = _uiState.asStateFlow()
private val _isRefreshing = MutableStateFlow(false)
val isRefreshing: StateFlow<Boolean> = _isRefreshing.asStateFlow()
private val _snackbarMessage = MutableStateFlow<String?>(null)
val snackbarMessage: StateFlow<String?> = _snackbarMessage.asStateFlow()
private val _searchMode = MutableStateFlow(false)
val searchMode: StateFlow<Boolean> = _searchMode.asStateFlow()
private val _searchQuery = MutableStateFlow("")
val searchQuery: StateFlow<String> = _searchQuery.asStateFlow()
private var notesJob: Job? = null
init {
loadNotes()
}
fun loadNotes() {
notesJob?.cancel()
notesJob = viewModelScope.launch {
_uiState.value = NotesUiState.Loading
repository.observeAll().collect { notes ->
_uiState.value = if (notes.isEmpty()) NotesUiState.Empty
else NotesUiState.Success(notes)
}
}
}
fun refresh() {
viewModelScope.launch {
_isRefreshing.value = true
when (val result = repository.refresh()) {
is NetworkResult.Success -> {
// Берём актуальный список прямо из репозитория — он уже обновлён
val current = repository.observeAll().first()
_snackbarMessage.value = "Обновлено: ${current.size} заметок"
}
is NetworkResult.Error -> {
_snackbarMessage.value = "Ошибка сервера: ${result.code}"
}
is NetworkResult.NetworkError -> {
_snackbarMessage.value = "Нет соединения с интернетом"
}
}
_isRefreshing.value = false
}
}
fun addNote(
title: String,
content: String,
type: NoteType,
imageUrl: String? = null,
) {
viewModelScope.launch {
repository.add(
Note(
id = 0L,
title = title,
content = content,
createdAt = System.currentTimeMillis(),
type = type,
imageUrl = imageUrl,
)
)
}
}
fun updateNote(note: Note) {
viewModelScope.launch {
repository.update(note)
}
}
fun deleteNote(id: Long) {
viewModelScope.launch {
repository.delete(id)
}
}
fun openSearch() {
_searchMode.value = true
}
fun closeSearch() {
_searchMode.value = false
_searchQuery.value = ""
loadNotes()
}
fun searchNotes(query: String) {
_searchQuery.value = query
notesJob?.cancel()
if (query.isBlank()) {
loadNotes()
return
}
notesJob = viewModelScope.launch {
repository.search(query).collect { notes ->
_uiState.value = if (notes.isEmpty()) NotesUiState.Empty
else NotesUiState.Success(notes)
}
}
}
fun clearSnackbarMessage() {
_snackbarMessage.value = null
}
}