mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-23 19:26:50 +00:00
feat(search): add Jellyfin-backed search
This commit is contained in:
12
core/src/main/java/hu/bbara/purefin/data/SearchManager.kt
Normal file
12
core/src/main/java/hu/bbara/purefin/data/SearchManager.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
package hu.bbara.purefin.data
|
||||
|
||||
import hu.bbara.purefin.feature.search.SearchResult
|
||||
import hu.bbara.purefin.model.Genre
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface SearchManager {
|
||||
val searchResult : StateFlow<List<SearchResult>>
|
||||
val genres: StateFlow<Set<Genre>>
|
||||
fun setGenres(genres : Set<String>)
|
||||
fun setSearchTerm(searchTerm: String)
|
||||
}
|
||||
@@ -1,65 +1,31 @@
|
||||
package hu.bbara.purefin.feature.search
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import hu.bbara.purefin.data.LocalMediaRepository
|
||||
import hu.bbara.purefin.data.UserSessionRepository
|
||||
import hu.bbara.purefin.image.ArtworkKind
|
||||
import hu.bbara.purefin.image.ImageUrlBuilder
|
||||
import hu.bbara.purefin.data.SearchManager
|
||||
import hu.bbara.purefin.model.MediaKind
|
||||
import hu.bbara.purefin.navigation.MovieDto
|
||||
import hu.bbara.purefin.navigation.NavigationManager
|
||||
import hu.bbara.purefin.navigation.Route
|
||||
import hu.bbara.purefin.navigation.SeriesDto
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
@OptIn(FlowPreview::class)
|
||||
class SearchViewModel @Inject constructor(
|
||||
private val mediaCatalogReader: LocalMediaRepository,
|
||||
private val userSessionRepository: UserSessionRepository,
|
||||
private val searchManager: SearchManager,
|
||||
private val navigationManager: NavigationManager,
|
||||
) : ViewModel() {
|
||||
|
||||
val genres = mediaCatalogReader.genres
|
||||
|
||||
private val _searchResult = MutableStateFlow<List<SearchResult>>(emptyList())
|
||||
val searchResult = _searchResult.asStateFlow()
|
||||
|
||||
private val query = MutableStateFlow("")
|
||||
|
||||
init {
|
||||
combine(
|
||||
query.debounce(300).distinctUntilChanged(),
|
||||
mediaCatalogReader.movies,
|
||||
mediaCatalogReader.series
|
||||
) { currentQuery, movies, series ->
|
||||
val filteredMovies = movies.filter {
|
||||
it.value.title.contains(currentQuery, ignoreCase = true)
|
||||
}
|
||||
val filteredSeries = series.filter {
|
||||
it.value.name.contains(currentQuery, ignoreCase = true)
|
||||
}
|
||||
_searchResult.value = filteredMovies.values.map {
|
||||
SearchResult.create(it, createImageUrl(it.id))
|
||||
} + filteredSeries.values.map {
|
||||
SearchResult.create(it, createImageUrl(it.id))
|
||||
}
|
||||
}.launchIn(viewModelScope)
|
||||
}
|
||||
val genres = searchManager.genres
|
||||
val searchResult = searchManager.searchResult
|
||||
|
||||
fun search(query: String) {
|
||||
this.query.value = query
|
||||
searchManager.setSearchTerm(query)
|
||||
}
|
||||
|
||||
fun setSelectedGenre(genreName: String?) {
|
||||
searchManager.setGenres(genreName?.let { setOf(it) } ?: emptySet())
|
||||
}
|
||||
|
||||
fun onSearchResultSelected(searchResult: SearchResult) {
|
||||
@@ -90,8 +56,4 @@ class SearchViewModel @Inject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun createImageUrl(id: UUID) : String {
|
||||
return ImageUrlBuilder.toImageUrl(userSessionRepository.serverUrl.first(), id,
|
||||
ArtworkKind.PRIMARY)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user