mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Barebones search page
This commit is contained in:
parent
ca7dd3797a
commit
b0b791f325
2 changed files with 188 additions and 1 deletions
|
|
@ -0,0 +1,181 @@
|
||||||
|
package com.github.damontecres.dolphin.ui.main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||||
|
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||||
|
import com.github.damontecres.dolphin.ui.cards.ItemRow
|
||||||
|
import com.github.damontecres.dolphin.ui.components.EditTextBox
|
||||||
|
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
||||||
|
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||||
|
import com.github.damontecres.dolphin.ui.tryRequestFocus
|
||||||
|
import com.github.damontecres.dolphin.util.ApiRequestPager
|
||||||
|
import com.github.damontecres.dolphin.util.ExceptionHandler
|
||||||
|
import com.github.damontecres.dolphin.util.GetItemsRequestHandler
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
|
import org.jellyfin.sdk.model.api.request.GetItemsRequest
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class SearchViewModel
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
val api: ApiClient,
|
||||||
|
) : ViewModel() {
|
||||||
|
val movies = MutableLiveData<List<BaseItem?>>(listOf())
|
||||||
|
val series = MutableLiveData<List<BaseItem?>>(listOf())
|
||||||
|
val episodes = MutableLiveData<List<BaseItem?>>(listOf())
|
||||||
|
|
||||||
|
fun search(query: String?) {
|
||||||
|
movies.value = listOf()
|
||||||
|
series.value = listOf()
|
||||||
|
episodes.value = listOf()
|
||||||
|
if (query.isNotNullOrBlank()) {
|
||||||
|
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||||
|
val request =
|
||||||
|
GetItemsRequest(
|
||||||
|
searchTerm = query,
|
||||||
|
recursive = true,
|
||||||
|
includeItemTypes = listOf(BaseItemKind.MOVIE),
|
||||||
|
limit = 25,
|
||||||
|
)
|
||||||
|
val pager = ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope)
|
||||||
|
pager.init()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
movies.value = pager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||||
|
val request =
|
||||||
|
GetItemsRequest(
|
||||||
|
searchTerm = query,
|
||||||
|
recursive = true,
|
||||||
|
includeItemTypes = listOf(BaseItemKind.SERIES),
|
||||||
|
limit = 25,
|
||||||
|
)
|
||||||
|
val pager = ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope)
|
||||||
|
pager.init()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
series.value = pager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||||
|
val request =
|
||||||
|
GetItemsRequest(
|
||||||
|
searchTerm = query,
|
||||||
|
recursive = true,
|
||||||
|
includeItemTypes = listOf(BaseItemKind.EPISODE),
|
||||||
|
limit = 25,
|
||||||
|
)
|
||||||
|
val pager = ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope)
|
||||||
|
pager.init()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
episodes.value = pager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getHints(query: String) {
|
||||||
|
// TODO
|
||||||
|
// api.searchApi.getSearchHints()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SearchPage(
|
||||||
|
navigationManager: NavigationManager,
|
||||||
|
userPreferences: UserPreferences,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
viewModel: SearchViewModel = hiltViewModel(),
|
||||||
|
) {
|
||||||
|
val movies by viewModel.movies.observeAsState(listOf())
|
||||||
|
val series by viewModel.series.observeAsState(listOf())
|
||||||
|
val episodes by viewModel.episodes.observeAsState(listOf())
|
||||||
|
|
||||||
|
var query by remember { mutableStateOf("") }
|
||||||
|
val searchFocusRequester = remember { FocusRequester() }
|
||||||
|
val resultsFocusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
LaunchedEffect(query) {
|
||||||
|
delay(750L)
|
||||||
|
viewModel.search(query)
|
||||||
|
}
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
// TODO focus on back to results when available
|
||||||
|
searchFocusRequester.tryRequestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
contentPadding = PaddingValues(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
modifier = modifier,
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
EditTextBox(
|
||||||
|
value = query,
|
||||||
|
onValueChange = {
|
||||||
|
query = it
|
||||||
|
},
|
||||||
|
keyboardActions =
|
||||||
|
KeyboardActions(
|
||||||
|
onSearch = {
|
||||||
|
viewModel.search(query)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
modifier = Modifier.focusRequester(searchFocusRequester),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itemsIndexed(listOf(movies, series, episodes)) { index, items ->
|
||||||
|
if (items.isNotEmpty()) {
|
||||||
|
ItemRow(
|
||||||
|
title =
|
||||||
|
when (index) {
|
||||||
|
0 -> "Movies"
|
||||||
|
1 -> "Series"
|
||||||
|
2 -> "Episodes"
|
||||||
|
else -> ""
|
||||||
|
},
|
||||||
|
items = items,
|
||||||
|
onClickItem = {
|
||||||
|
navigationManager.navigateTo(it.destination())
|
||||||
|
},
|
||||||
|
onLongClickItem = {},
|
||||||
|
modifier = Modifier.focusRequester(resultsFocusRequester),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ import com.github.damontecres.dolphin.ui.detail.VideoDetails
|
||||||
import com.github.damontecres.dolphin.ui.detail.movie.MovieDetails
|
import com.github.damontecres.dolphin.ui.detail.movie.MovieDetails
|
||||||
import com.github.damontecres.dolphin.ui.detail.series.SeriesOverview
|
import com.github.damontecres.dolphin.ui.detail.series.SeriesOverview
|
||||||
import com.github.damontecres.dolphin.ui.main.HomePage
|
import com.github.damontecres.dolphin.ui.main.HomePage
|
||||||
|
import com.github.damontecres.dolphin.ui.main.SearchPage
|
||||||
import com.github.damontecres.dolphin.ui.playback.PlaybackContent
|
import com.github.damontecres.dolphin.ui.playback.PlaybackContent
|
||||||
import com.github.damontecres.dolphin.ui.preferences.PreferenceScreenOption
|
import com.github.damontecres.dolphin.ui.preferences.PreferenceScreenOption
|
||||||
import com.github.damontecres.dolphin.ui.preferences.PreferencesPage
|
import com.github.damontecres.dolphin.ui.preferences.PreferencesPage
|
||||||
|
|
@ -124,7 +125,12 @@ fun DestinationContent(
|
||||||
|
|
||||||
Destination.License -> LicenseInfo(modifier)
|
Destination.License -> LicenseInfo(modifier)
|
||||||
|
|
||||||
Destination.Search -> TODO()
|
Destination.Search ->
|
||||||
|
SearchPage(
|
||||||
|
navigationManager = navigationManager,
|
||||||
|
userPreferences = preferences,
|
||||||
|
modifier = modifier,
|
||||||
|
)
|
||||||
Destination.Setup -> TODO()
|
Destination.Setup -> TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue