Last active
July 20, 2025 10:51
-
-
Save raspberrypisig/97898f5f837847bc732e339a89aa3388 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SearchViewModel @Inject constructor( | |
private val searchUseCase: dagger.Lazy<SearchUseCase>, | |
private val wordsUseCase: GetWordsUseCase, | |
) : ViewModel() { | |
data class UiState( | |
val isLoading: Boolean = true, | |
val words: List<String> = emptyList() | |
) | |
val state: StateFlow<UiState> = flow { | |
emit(UiState(isLoading = true)) | |
val words = wordsUseCase.invoke() | |
emit(UiState(isLoading = false, words = words)) | |
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), UiState()) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val originalStateFlow: StateFlow<Int> = MutableStateFlow(1) | |
val transformedStateFlow: StateFlow<String> = originalStateFlow | |
.map { value -> "Value: $value" } | |
.stateIn( | |
scope = CoroutineScope(Dispatchers.Default), // Or a suitable scope | |
started = SharingStarted.Lazily, | |
initialValue = "Value: ${originalStateFlow.value}" // Initial value for the new StateFlow | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---------- Domain ---------- | |
class GetArticleUseCase @Inject constructor( | |
private val repo: ArticleRepository | |
) { | |
operator fun invoke(id: String): Flow<Article> = repo.observe(id) | |
} | |
class PublishArticleUseCase @Inject constructor( | |
private val repo: ArticleRepository | |
) { | |
suspend operator fun invoke(article: Article) { repo.publish(article) } | |
} | |
// ---------- ViewModel ---------- | |
@HiltViewModel | |
class ArticleViewModel @Inject constructor( | |
private val getArticle: GetArticleUseCase, | |
private val publishArticle: PublishArticleUseCase | |
) : ViewModel() { | |
val uiState: StateFlow<ArticleUiState> = | |
getArticle(articleId) | |
.map { it.toUiState() } | |
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), ArticleUiState.Loading) | |
fun publish() { | |
viewModelScope.launch { | |
publishArticle(uiState.value.toArticle()) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SearchViewModel @Inject constructor( | |
private val searchUseCase: dagger.Lazy<SearchUseCase>, | |
) : ViewModel() { | |
private val searchQuery = MutableStateFlow("") | |
val uiState: LiveData<SearchUiState> = searchQuery | |
.debounce(DEBOUNCE_TIME_IN_MILLIS) | |
.asLiveData() | |
.switchMap(::createUiState) | |
private fun createUiState(query: @JvmSuppressWildcards String) = liveData { | |
Timber.d("collectLatest(), query:[%s]", query) | |
if (query.isEmpty()) { | |
emit(SearchUiState.Idle) | |
return@liveData | |
} | |
try { | |
emit(SearchUiState.Loading) | |
val photos = searchUseCase.get().invoke(query) | |
if (photos.isEmpty()) { | |
emit(SearchUiState.EmptyResult) | |
} else { | |
emit(SearchUiState.Success(photos)) | |
} | |
} catch (e: Exception) { | |
emit(SearchUiState.Error(e)) | |
} | |
} | |
fun onQueryChanged(query: String?) { | |
query ?: return | |
searchQuery.value = query | |
} | |
sealed class SearchUiState { | |
data object Loading : SearchUiState() | |
data object Idle : SearchUiState() | |
data class Success(val photos: List<FlickrPhoto>) : SearchUiState() | |
data object EmptyResult : SearchUiState() | |
data class Error(val exception: Throwable) : SearchUiState() | |
} | |
companion object { | |
private const val DEBOUNCE_TIME_IN_MILLIS = 300L | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment