mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Add music to search
This commit is contained in:
parent
18e3268638
commit
6471b198b2
1 changed files with 114 additions and 26 deletions
|
|
@ -51,6 +51,7 @@ import com.github.damontecres.wholphin.data.model.SeerrItemType
|
|||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
import com.github.damontecres.wholphin.services.SeerrService
|
||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||
import com.github.damontecres.wholphin.ui.Cards
|
||||
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||
import com.github.damontecres.wholphin.ui.cards.DiscoverItemCard
|
||||
|
|
@ -76,6 +77,8 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
|
|
@ -100,10 +103,15 @@ class SearchViewModel
|
|||
val series = MutableLiveData<SearchResult>(SearchResult.NoQuery)
|
||||
val episodes = MutableLiveData<SearchResult>(SearchResult.NoQuery)
|
||||
val collections = MutableLiveData<SearchResult>(SearchResult.NoQuery)
|
||||
val albums = MutableLiveData<SearchResult>(SearchResult.NoQuery)
|
||||
val artists = MutableLiveData<SearchResult>(SearchResult.NoQuery)
|
||||
val songs = MutableLiveData<SearchResult>(SearchResult.NoQuery)
|
||||
val seerrResults = MutableLiveData<SearchResult>(SearchResult.NoQuery)
|
||||
|
||||
private var currentQuery: String? = null
|
||||
|
||||
private val semaphore = Semaphore(4)
|
||||
|
||||
fun search(query: String?) {
|
||||
if (currentQuery == query) {
|
||||
return
|
||||
|
|
@ -117,6 +125,9 @@ class SearchViewModel
|
|||
searchInternal(query, BaseItemKind.MOVIE, movies)
|
||||
searchInternal(query, BaseItemKind.SERIES, series)
|
||||
searchInternal(query, BaseItemKind.EPISODE, episodes)
|
||||
searchInternal(query, BaseItemKind.MUSIC_ALBUM, albums)
|
||||
searchInternal(query, BaseItemKind.MUSIC_ARTIST, artists)
|
||||
searchInternal(query, BaseItemKind.AUDIO, songs)
|
||||
searchInternal(query, BaseItemKind.BOX_SET, collections)
|
||||
searchSeerr(query)
|
||||
} else {
|
||||
|
|
@ -135,19 +146,21 @@ class SearchViewModel
|
|||
) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
try {
|
||||
val request =
|
||||
GetItemsRequest(
|
||||
searchTerm = query,
|
||||
recursive = true,
|
||||
includeItemTypes = listOf(type),
|
||||
fields = SlimItemFields,
|
||||
limit = 25,
|
||||
)
|
||||
val pager =
|
||||
ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope)
|
||||
pager.init()
|
||||
withContext(Dispatchers.Main) {
|
||||
target.value = SearchResult.Success(pager)
|
||||
semaphore.withPermit {
|
||||
val request =
|
||||
GetItemsRequest(
|
||||
searchTerm = query,
|
||||
recursive = true,
|
||||
includeItemTypes = listOf(type),
|
||||
fields = SlimItemFields,
|
||||
limit = 25,
|
||||
)
|
||||
val pager =
|
||||
ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope)
|
||||
pager.init()
|
||||
withContext(Dispatchers.Main) {
|
||||
target.value = SearchResult.Success(pager)
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Exception searching for $type")
|
||||
|
|
@ -202,10 +215,13 @@ sealed interface SearchResult {
|
|||
|
||||
private const val SEARCH_ROW = 0
|
||||
private const val MOVIE_ROW = SEARCH_ROW + 1
|
||||
private const val COLLECTION_ROW = MOVIE_ROW + 1
|
||||
private const val SERIES_ROW = COLLECTION_ROW + 1
|
||||
private const val SERIES_ROW = MOVIE_ROW + 1
|
||||
private const val EPISODE_ROW = SERIES_ROW + 1
|
||||
private const val SEERR_ROW = EPISODE_ROW + 1
|
||||
private const val ALBUM_ROW = EPISODE_ROW + 1
|
||||
private const val ARTIST_ROW = ALBUM_ROW + 1
|
||||
private const val SONG_ROW = ARTIST_ROW + 1
|
||||
private const val COLLECTION_ROW = SONG_ROW + 1
|
||||
private const val SEERR_ROW = COLLECTION_ROW + 1
|
||||
|
||||
/** Delay for focus to settle after voice search dialog dismisses. */
|
||||
private const val VOICE_RESULT_FOCUS_DELAY_MS = 350L
|
||||
|
|
@ -223,6 +239,9 @@ fun SearchPage(
|
|||
val collections by viewModel.collections.observeAsState(SearchResult.NoQuery)
|
||||
val series by viewModel.series.observeAsState(SearchResult.NoQuery)
|
||||
val episodes by viewModel.episodes.observeAsState(SearchResult.NoQuery)
|
||||
val albums by viewModel.albums.observeAsState(SearchResult.NoQuery)
|
||||
val artists by viewModel.artists.observeAsState(SearchResult.NoQuery)
|
||||
val songs by viewModel.songs.observeAsState(SearchResult.NoQuery)
|
||||
val seerrResults by viewModel.seerrResults.observeAsState(SearchResult.NoQuery)
|
||||
|
||||
// val query = rememberTextFieldState()
|
||||
|
|
@ -367,16 +386,6 @@ fun SearchPage(
|
|||
onClickPosition = { position = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
searchResultRow(
|
||||
title = context.getString(R.string.collections),
|
||||
result = collections,
|
||||
rowIndex = COLLECTION_ROW,
|
||||
position = position,
|
||||
focusRequester = focusRequesters[COLLECTION_ROW],
|
||||
onClickItem = onClickItem,
|
||||
onClickPosition = { position = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
searchResultRow(
|
||||
title = context.getString(R.string.tv_shows),
|
||||
result = series,
|
||||
|
|
@ -409,6 +418,85 @@ fun SearchPage(
|
|||
)
|
||||
},
|
||||
)
|
||||
searchResultRow(
|
||||
title = context.getString(R.string.albums),
|
||||
result = albums,
|
||||
rowIndex = ALBUM_ROW,
|
||||
position = position,
|
||||
focusRequester = focusRequesters[ALBUM_ROW],
|
||||
onClickItem = onClickItem,
|
||||
onClickPosition = { position = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
cardContent = { index, item, mod, onClick, onLongClick ->
|
||||
SeasonCard(
|
||||
item = item,
|
||||
onClick = {
|
||||
position = RowColumn(ALBUM_ROW, index)
|
||||
onClick.invoke()
|
||||
},
|
||||
onLongClick = onLongClick,
|
||||
imageHeight = Cards.heightEpisode,
|
||||
aspectRatio = AspectRatios.SQUARE,
|
||||
modifier = mod,
|
||||
)
|
||||
},
|
||||
)
|
||||
searchResultRow(
|
||||
title = context.getString(R.string.artists),
|
||||
result = artists,
|
||||
rowIndex = COLLECTION_ROW,
|
||||
position = position,
|
||||
focusRequester = focusRequesters[COLLECTION_ROW],
|
||||
onClickItem = onClickItem,
|
||||
onClickPosition = { position = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
cardContent = { index, item, mod, onClick, onLongClick ->
|
||||
SeasonCard(
|
||||
item = item,
|
||||
onClick = {
|
||||
position = RowColumn(ALBUM_ROW, index)
|
||||
onClick.invoke()
|
||||
},
|
||||
onLongClick = onLongClick,
|
||||
imageHeight = Cards.heightEpisode,
|
||||
aspectRatio = AspectRatios.SQUARE,
|
||||
modifier = mod,
|
||||
)
|
||||
},
|
||||
)
|
||||
searchResultRow(
|
||||
title = context.getString(R.string.songs),
|
||||
result = songs,
|
||||
rowIndex = SONG_ROW,
|
||||
position = position,
|
||||
focusRequester = focusRequesters[SONG_ROW],
|
||||
onClickItem = onClickItem,
|
||||
onClickPosition = { position = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
cardContent = { index, item, mod, onClick, onLongClick ->
|
||||
SeasonCard(
|
||||
item = item,
|
||||
onClick = {
|
||||
position = RowColumn(ALBUM_ROW, index)
|
||||
onClick.invoke()
|
||||
},
|
||||
onLongClick = onLongClick,
|
||||
imageHeight = Cards.heightEpisode,
|
||||
aspectRatio = AspectRatios.SQUARE,
|
||||
modifier = mod,
|
||||
)
|
||||
},
|
||||
)
|
||||
searchResultRow(
|
||||
title = context.getString(R.string.collections),
|
||||
result = collections,
|
||||
rowIndex = COLLECTION_ROW,
|
||||
position = position,
|
||||
focusRequester = focusRequesters[COLLECTION_ROW],
|
||||
onClickItem = onClickItem,
|
||||
onClickPosition = { position = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
searchResultRow(
|
||||
title = context.getString(R.string.discover),
|
||||
result = seerrResults,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue