-
Notifications
You must be signed in to change notification settings - Fork 23
/
MjImagesViewModel.kt
117 lines (100 loc) · 3.53 KB
/
MjImagesViewModel.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package ui
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import domain.model.MjImages
import domain.model.State
import domain.usecase.MjImagesFetchUseCase
import domain.usecase.MjImagesUseCase
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import midjourneyimagescomposemultiplatform.shared.generated.resources.Res
import midjourneyimagescomposemultiplatform.shared.generated.resources.failed_fetch_message
import org.jetbrains.compose.resources.getString
class MjImagesViewModel(
private val fetchUseCase: MjImagesFetchUseCase,
private val useCase: MjImagesUseCase,
) : ViewModel() {
private val _state = MutableStateFlow(State.LOADING)
val state: StateFlow<State> = _state.asStateFlow()
private val _images = MutableStateFlow(MjImages())
val images: StateFlow<MjImages> = _images.asStateFlow()
private val _useDarkTheme: MutableStateFlow<Boolean> = MutableStateFlow(false)
val useDarkTheme: StateFlow<Boolean> = _useDarkTheme.asStateFlow()
private val _dialogPreviewUrl: MutableStateFlow<String> = MutableStateFlow("")
val dialogPreviewUrl: StateFlow<String> = _dialogPreviewUrl.asStateFlow()
private val _snackMessage: MutableSharedFlow<String> = MutableSharedFlow()
val snackMessage: SharedFlow<String> = _snackMessage.asSharedFlow()
init {
checkTheme()
fetchImages()
}
fun loadMore() {
with(_images.value) {
if (currentPage < totalPages) {
fetchImages(currentPage + 1)
}
}
}
fun refreshImages() {
_images.value = MjImages()
fetchImages()
}
private fun fetchImages(
page: Int = 1,
) {
fetchUseCase
.getImages(page)
.onStart { _state.value = State.LOADING }
.onEach { images ->
if (_images.value.images.isEmpty() && images.isEmpty()) {
_state.value = State.EMPTY
} else {
_state.value = State.CONTENT
_images.value += images
}
}.catch {
it.printStackTrace()
if (_images.value.isEmpty()) {
_state.value = State.ERROR
} else {
_snackMessage.emit(getString(Res.string.failed_fetch_message))
}
}
.launchIn(viewModelScope)
}
suspend fun isEligibleToShowSnackBar(): Boolean =
useCase.isEligibleToShowSnackMessage()
suspend fun setSnackMessageShown() {
useCase.setSnackMessageShown()
}
fun setDarkMode(isEnabled: Boolean) {
viewModelScope.launch {
_useDarkTheme.emit(isEnabled)
useCase.setDarkMode(isEnabled)
}
}
private fun checkTheme() {
viewModelScope.launch {
_useDarkTheme.emit(useCase.isDarkModeEnabled())
}
}
fun showPreviewDialog(hqImageUrl: String) {
viewModelScope.launch {
_dialogPreviewUrl.emit(hqImageUrl)
}
}
fun dismissPreviewDialog() {
viewModelScope.launch {
_dialogPreviewUrl.emit("")
}
}
}