mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Restore focus on search
This commit is contained in:
parent
3afc4f022b
commit
b30ddab0fc
2 changed files with 73 additions and 29 deletions
|
|
@ -37,13 +37,11 @@ import com.github.damontecres.dolphin.ui.components.StarRating
|
||||||
import com.github.damontecres.dolphin.ui.components.StarRatingPrecision
|
import com.github.damontecres.dolphin.ui.components.StarRatingPrecision
|
||||||
import com.github.damontecres.dolphin.ui.components.TitleValueText
|
import com.github.damontecres.dolphin.ui.components.TitleValueText
|
||||||
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.dolphin.ui.letNotEmpty
|
|
||||||
import com.github.damontecres.dolphin.ui.playOnClickSound
|
import com.github.damontecres.dolphin.ui.playOnClickSound
|
||||||
import com.github.damontecres.dolphin.ui.playSoundOnFocus
|
import com.github.damontecres.dolphin.ui.playSoundOnFocus
|
||||||
import com.github.damontecres.dolphin.ui.roundMinutes
|
import com.github.damontecres.dolphin.ui.roundMinutes
|
||||||
import com.github.damontecres.dolphin.ui.timeRemaining
|
import com.github.damontecres.dolphin.ui.timeRemaining
|
||||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||||
import org.jellyfin.sdk.model.api.PersonKind
|
|
||||||
import org.jellyfin.sdk.model.extensions.ticks
|
import org.jellyfin.sdk.model.extensions.ticks
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -167,7 +165,7 @@ fun MovieDetailsHeader(
|
||||||
TitleValueText(
|
TitleValueText(
|
||||||
stringResource(R.string.video),
|
stringResource(R.string.video),
|
||||||
it,
|
it,
|
||||||
modifier = Modifier,
|
modifier = Modifier.widthIn(max = 200.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
dto.mediaStreams
|
dto.mediaStreams
|
||||||
|
|
@ -183,6 +181,7 @@ fun MovieDetailsHeader(
|
||||||
TitleValueText(
|
TitleValueText(
|
||||||
stringResource(R.string.audio),
|
stringResource(R.string.audio),
|
||||||
it,
|
it,
|
||||||
|
modifier = Modifier.widthIn(max = 200.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,18 +194,18 @@ fun MovieDetailsHeader(
|
||||||
TitleValueText(
|
TitleValueText(
|
||||||
"Subtitles",
|
"Subtitles",
|
||||||
it,
|
it,
|
||||||
modifier = Modifier.widthIn(max = 64.dp),
|
modifier = Modifier.widthIn(max = 120.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO add writers, studio, etc to overview dialog
|
// TODO add writers, studio, etc to overview dialog
|
||||||
dto.people?.firstOrNull { it.type == PersonKind.DIRECTOR }?.name?.let {
|
// dto.people?.firstOrNull { it.type == PersonKind.DIRECTOR }?.name?.let {
|
||||||
TitleValueText(
|
// TitleValueText(
|
||||||
stringResource(R.string.director),
|
// stringResource(R.string.director),
|
||||||
it,
|
// it,
|
||||||
modifier = Modifier.widthIn(max = 80.dp),
|
// modifier = Modifier.widthIn(max = 80.dp),
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
// dto.studios?.letNotEmpty {
|
// dto.studios?.letNotEmpty {
|
||||||
// TitleValueText(
|
// TitleValueText(
|
||||||
// stringResource(R.string.studios),
|
// stringResource(R.string.studios),
|
||||||
|
|
@ -214,13 +213,13 @@ fun MovieDetailsHeader(
|
||||||
// modifier = Modifier.widthIn(max = 80.dp),
|
// modifier = Modifier.widthIn(max = 80.dp),
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
dto.genres?.letNotEmpty {
|
// dto.genres?.letNotEmpty {
|
||||||
TitleValueText(
|
// TitleValueText(
|
||||||
stringResource(R.string.genres),
|
// stringResource(R.string.genres),
|
||||||
it.joinToString(", "),
|
// it.joinToString(", "),
|
||||||
modifier = Modifier.widthIn(max = 80.dp),
|
// modifier = Modifier.widthIn(max = 80.dp),
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ import com.github.damontecres.dolphin.ui.cards.EpisodeCard
|
||||||
import com.github.damontecres.dolphin.ui.cards.ItemRow
|
import com.github.damontecres.dolphin.ui.cards.ItemRow
|
||||||
import com.github.damontecres.dolphin.ui.cards.SeasonCard
|
import com.github.damontecres.dolphin.ui.cards.SeasonCard
|
||||||
import com.github.damontecres.dolphin.ui.components.SearchEditTextBox
|
import com.github.damontecres.dolphin.ui.components.SearchEditTextBox
|
||||||
|
import com.github.damontecres.dolphin.ui.data.RowColumn
|
||||||
|
import com.github.damontecres.dolphin.ui.data.RowColumnSaver
|
||||||
|
import com.github.damontecres.dolphin.ui.ifElse
|
||||||
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||||
import com.github.damontecres.dolphin.ui.tryRequestFocus
|
import com.github.damontecres.dolphin.ui.tryRequestFocus
|
||||||
|
|
@ -58,7 +61,13 @@ class SearchViewModel
|
||||||
val series = MutableLiveData<List<BaseItem?>>(listOf())
|
val series = MutableLiveData<List<BaseItem?>>(listOf())
|
||||||
val episodes = MutableLiveData<List<BaseItem?>>(listOf())
|
val episodes = MutableLiveData<List<BaseItem?>>(listOf())
|
||||||
|
|
||||||
|
private var currentQuery: String? = null
|
||||||
|
|
||||||
fun search(query: String?) {
|
fun search(query: String?) {
|
||||||
|
if (currentQuery == query) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentQuery = query
|
||||||
movies.value = listOf()
|
movies.value = listOf()
|
||||||
series.value = listOf()
|
series.value = listOf()
|
||||||
episodes.value = listOf()
|
episodes.value = listOf()
|
||||||
|
|
@ -117,6 +126,10 @@ class SearchViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const val MOVIE_ROW = 0
|
||||||
|
private const val SERIES_ROW = 1
|
||||||
|
private const val EPISODE_ROW = 2
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SearchPage(
|
fun SearchPage(
|
||||||
userPreferences: UserPreferences,
|
userPreferences: UserPreferences,
|
||||||
|
|
@ -128,16 +141,20 @@ fun SearchPage(
|
||||||
val episodes by viewModel.episodes.observeAsState(listOf())
|
val episodes by viewModel.episodes.observeAsState(listOf())
|
||||||
|
|
||||||
var query by rememberSaveable { mutableStateOf("") }
|
var query by rememberSaveable { mutableStateOf("") }
|
||||||
val searchFocusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
val resultsFocusRequester = remember { FocusRequester() }
|
|
||||||
|
var position by rememberSaveable(stateSaver = RowColumnSaver) {
|
||||||
|
mutableStateOf(
|
||||||
|
RowColumn(-1, -1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(query) {
|
LaunchedEffect(query) {
|
||||||
delay(750L)
|
delay(750L)
|
||||||
viewModel.search(query)
|
viewModel.search(query)
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
// TODO focus on back to results when available
|
focusRequester.tryRequestFocus()
|
||||||
searchFocusRequester.tryRequestFocus()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
|
@ -158,7 +175,11 @@ fun SearchPage(
|
||||||
onSearchClick = {
|
onSearchClick = {
|
||||||
viewModel.search(query)
|
viewModel.search(query)
|
||||||
},
|
},
|
||||||
modifier = Modifier.focusRequester(searchFocusRequester),
|
modifier =
|
||||||
|
Modifier.ifElse(
|
||||||
|
position.row < MOVIE_ROW,
|
||||||
|
Modifier.focusRequester(focusRequester),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,10 +196,18 @@ fun SearchPage(
|
||||||
cardContent = @Composable { index, item, mod, onClick, onLongClick ->
|
cardContent = @Composable { index, item, mod, onClick, onLongClick ->
|
||||||
SeasonCard(
|
SeasonCard(
|
||||||
item = item,
|
item = item,
|
||||||
onClick = onClick,
|
onClick = {
|
||||||
|
position = RowColumn(MOVIE_ROW, index)
|
||||||
|
onClick.invoke()
|
||||||
|
},
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
imageHeight = Cards.height2x3,
|
imageHeight = Cards.height2x3,
|
||||||
modifier = mod,
|
modifier =
|
||||||
|
mod
|
||||||
|
.ifElse(
|
||||||
|
position.row == MOVIE_ROW && position.column == index,
|
||||||
|
Modifier.focusRequester(focusRequester),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -197,10 +226,17 @@ fun SearchPage(
|
||||||
cardContent = @Composable { index, item, mod, onClick, onLongClick ->
|
cardContent = @Composable { index, item, mod, onClick, onLongClick ->
|
||||||
SeasonCard(
|
SeasonCard(
|
||||||
item = item,
|
item = item,
|
||||||
onClick = onClick,
|
onClick = {
|
||||||
|
position = RowColumn(SERIES_ROW, index)
|
||||||
|
onClick.invoke()
|
||||||
|
},
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
imageHeight = Cards.height2x3,
|
imageHeight = Cards.height2x3,
|
||||||
modifier = mod,
|
modifier =
|
||||||
|
mod.ifElse(
|
||||||
|
position.row == SERIES_ROW && position.column == index,
|
||||||
|
Modifier.focusRequester(focusRequester),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -219,10 +255,19 @@ fun SearchPage(
|
||||||
cardContent = @Composable { index, item, mod, onClick, onLongClick ->
|
cardContent = @Composable { index, item, mod, onClick, onLongClick ->
|
||||||
EpisodeCard(
|
EpisodeCard(
|
||||||
item = item,
|
item = item,
|
||||||
onClick = onClick,
|
onClick = {
|
||||||
|
position = RowColumn(EPISODE_ROW, index)
|
||||||
|
onClick.invoke()
|
||||||
|
},
|
||||||
onLongClick = onLongClick,
|
onLongClick = onLongClick,
|
||||||
imageHeight = 140.dp,
|
imageHeight = 140.dp,
|
||||||
modifier = mod.padding(horizontal = 8.dp),
|
modifier =
|
||||||
|
mod
|
||||||
|
.padding(horizontal = 8.dp)
|
||||||
|
.ifElse(
|
||||||
|
position.row == EPISODE_ROW && position.column == index,
|
||||||
|
Modifier.focusRequester(focusRequester),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue