mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Return focus to the tabs if a grid has no results (#676)
## Description Previously, if you clicked on a tab and the resulting grid had no results, the nav drawer would open and focus which is not good. This PR fixes that and instead returns focus back to the tab row. ### Related issues Fixes #543
This commit is contained in:
parent
197265e7f5
commit
d5192abf62
8 changed files with 71 additions and 17 deletions
|
|
@ -86,6 +86,7 @@ import com.github.damontecres.wholphin.ui.playback.scale
|
||||||
import com.github.damontecres.wholphin.ui.rememberInt
|
import com.github.damontecres.wholphin.ui.rememberInt
|
||||||
import com.github.damontecres.wholphin.ui.setValueOnMain
|
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||||
import com.github.damontecres.wholphin.ui.toServerString
|
import com.github.damontecres.wholphin.ui.toServerString
|
||||||
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||||
|
|
@ -525,6 +526,7 @@ fun CollectionFolderGrid(
|
||||||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||||
useSeriesForPrimary: Boolean = true,
|
useSeriesForPrimary: Boolean = true,
|
||||||
filterOptions: List<ItemFilterBy<*>> = DefaultFilterOptions,
|
filterOptions: List<ItemFilterBy<*>> = DefaultFilterOptions,
|
||||||
|
focusRequesterOnEmpty: FocusRequester? = null,
|
||||||
) = CollectionFolderGrid(
|
) = CollectionFolderGrid(
|
||||||
preferences,
|
preferences,
|
||||||
itemId.toServerString(),
|
itemId.toServerString(),
|
||||||
|
|
@ -541,6 +543,7 @@ fun CollectionFolderGrid(
|
||||||
positionCallback = positionCallback,
|
positionCallback = positionCallback,
|
||||||
useSeriesForPrimary = useSeriesForPrimary,
|
useSeriesForPrimary = useSeriesForPrimary,
|
||||||
filterOptions = filterOptions,
|
filterOptions = filterOptions,
|
||||||
|
focusRequesterOnEmpty = focusRequesterOnEmpty,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -560,6 +563,7 @@ fun CollectionFolderGrid(
|
||||||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||||
useSeriesForPrimary: Boolean = true,
|
useSeriesForPrimary: Boolean = true,
|
||||||
filterOptions: List<ItemFilterBy<*>> = DefaultFilterOptions,
|
filterOptions: List<ItemFilterBy<*>> = DefaultFilterOptions,
|
||||||
|
focusRequesterOnEmpty: FocusRequester? = null,
|
||||||
playlistViewModel: AddPlaylistViewModel = hiltViewModel(),
|
playlistViewModel: AddPlaylistViewModel = hiltViewModel(),
|
||||||
viewModel: CollectionFolderViewModel =
|
viewModel: CollectionFolderViewModel =
|
||||||
hiltViewModel<CollectionFolderViewModel, CollectionFolderViewModel.Factory>(
|
hiltViewModel<CollectionFolderViewModel, CollectionFolderViewModel.Factory>(
|
||||||
|
|
@ -615,6 +619,7 @@ fun CollectionFolderGrid(
|
||||||
pager = pager,
|
pager = pager,
|
||||||
sortAndDirection = sortAndDirection!!,
|
sortAndDirection = sortAndDirection!!,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
focusRequesterOnEmpty = focusRequesterOnEmpty,
|
||||||
onClickItem = onClickItem,
|
onClickItem = onClickItem,
|
||||||
onLongClickItem = { position, item ->
|
onLongClickItem = { position, item ->
|
||||||
moreDialog.makePresent(PositionItem(position, item))
|
moreDialog.makePresent(PositionItem(position, item))
|
||||||
|
|
@ -759,6 +764,7 @@ fun CollectionFolderGridContent(
|
||||||
currentFilter: GetItemsFilter = GetItemsFilter(),
|
currentFilter: GetItemsFilter = GetItemsFilter(),
|
||||||
filterOptions: List<ItemFilterBy<*>> = listOf(),
|
filterOptions: List<ItemFilterBy<*>> = listOf(),
|
||||||
onFilterChange: (GetItemsFilter) -> Unit = {},
|
onFilterChange: (GetItemsFilter) -> Unit = {},
|
||||||
|
focusRequesterOnEmpty: FocusRequester? = null,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
|
@ -767,7 +773,11 @@ fun CollectionFolderGridContent(
|
||||||
var viewOptions by remember { mutableStateOf(viewOptions) }
|
var viewOptions by remember { mutableStateOf(viewOptions) }
|
||||||
|
|
||||||
val gridFocusRequester = remember { FocusRequester() }
|
val gridFocusRequester = remember { FocusRequester() }
|
||||||
RequestOrRestoreFocus(gridFocusRequester)
|
if (pager.isNotEmpty()) {
|
||||||
|
RequestOrRestoreFocus(gridFocusRequester)
|
||||||
|
} else {
|
||||||
|
focusRequesterOnEmpty?.tryRequestFocus()
|
||||||
|
}
|
||||||
var backdropImageUrl by remember { mutableStateOf<String?>(null) }
|
var backdropImageUrl by remember { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
var position by rememberInt(initialPosition)
|
var position by rememberInt(initialPosition)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import androidx.compose.ui.focus.FocusDirection
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusProperties
|
import androidx.compose.ui.focus.focusProperties
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRestorer
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.layout.onGloballyPositioned
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
|
|
@ -39,13 +40,16 @@ import androidx.compose.ui.unit.sp
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
||||||
|
import com.github.damontecres.wholphin.ui.ifElse
|
||||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TabRow(
|
fun TabRow(
|
||||||
selectedTabIndex: Int,
|
selectedTabIndex: Int,
|
||||||
tabs: List<String>,
|
tabs: List<String>,
|
||||||
|
focusRequesters: List<FocusRequester>,
|
||||||
onClick: (Int) -> Unit,
|
onClick: (Int) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
|
@ -55,7 +59,6 @@ fun TabRow(
|
||||||
state.animateScrollToItem(selectedTabIndex, -(state.layoutInfo.viewportSize.width / 3.5).toInt())
|
state.animateScrollToItem(selectedTabIndex, -(state.layoutInfo.viewportSize.width / 3.5).toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val focusRequesters = remember(tabs) { List(tabs.size) { FocusRequester() } }
|
|
||||||
var rowHasFocus by remember { mutableStateOf(false) }
|
var rowHasFocus by remember { mutableStateOf(false) }
|
||||||
LazyRow(
|
LazyRow(
|
||||||
state = state,
|
state = state,
|
||||||
|
|
@ -68,6 +71,7 @@ fun TabRow(
|
||||||
onEnter = {
|
onEnter = {
|
||||||
// If entering from left or right, use last or first tab
|
// If entering from left or right, use last or first tab
|
||||||
// Otherwise use the selected tab
|
// Otherwise use the selected tab
|
||||||
|
Timber.v("onEnter requestedFocusDirection=$requestedFocusDirection, selectedTabIndex=$selectedTabIndex")
|
||||||
val focusRequester =
|
val focusRequester =
|
||||||
if (requestedFocusDirection == FocusDirection.Left) {
|
if (requestedFocusDirection == FocusDirection.Left) {
|
||||||
focusRequesters.lastOrNull()
|
focusRequesters.lastOrNull()
|
||||||
|
|
@ -183,6 +187,7 @@ private fun TabRowPreview() {
|
||||||
TabRow(
|
TabRow(
|
||||||
selectedTabIndex = 1,
|
selectedTabIndex = 1,
|
||||||
tabs = listOf("Tab 1", "Tab 2", "Tab 3"),
|
tabs = listOf("Tab 1", "Tab 2", "Tab 3"),
|
||||||
|
focusRequesters = listOf(),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
)
|
)
|
||||||
Tab(
|
Tab(
|
||||||
|
|
|
||||||
|
|
@ -93,14 +93,19 @@ fun CollectionFolderLiveTv(
|
||||||
remember { viewModel.getRememberedTab(preferences, destination.itemId, 0) }
|
remember { viewModel.getRememberedTab(preferences, destination.itemId, 0) }
|
||||||
val folders by viewModel.recordingFolders.observeAsState(listOf())
|
val folders by viewModel.recordingFolders.observeAsState(listOf())
|
||||||
|
|
||||||
|
val tvGuideStr = stringResource(R.string.tv_guide)
|
||||||
|
val tvDvrStr = stringResource(R.string.tv_dvr_schedule)
|
||||||
val tabs =
|
val tabs =
|
||||||
listOf(
|
remember(folders) {
|
||||||
TabId(stringResource(R.string.tv_guide), UUID.randomUUID()),
|
listOf(
|
||||||
TabId(stringResource(R.string.tv_dvr_schedule), UUID.randomUUID()),
|
TabId(tvGuideStr, UUID.randomUUID()),
|
||||||
) + folders
|
TabId(tvDvrStr, UUID.randomUUID()),
|
||||||
|
) + folders
|
||||||
|
}
|
||||||
|
|
||||||
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val tabFocusRequesters = remember(tabs.size) { List(tabs.size) { FocusRequester() } }
|
||||||
|
|
||||||
val firstTabFocusRequester = remember { FocusRequester() }
|
val firstTabFocusRequester = remember { FocusRequester() }
|
||||||
LaunchedEffect(Unit) { firstTabFocusRequester.tryRequestFocus() }
|
LaunchedEffect(Unit) { firstTabFocusRequester.tryRequestFocus() }
|
||||||
|
|
@ -133,6 +138,7 @@ fun CollectionFolderLiveTv(
|
||||||
.focusRequester(firstTabFocusRequester),
|
.focusRequester(firstTabFocusRequester),
|
||||||
tabs = tabs.map { it.title },
|
tabs = tabs.map { it.title },
|
||||||
onClick = { selectedTabIndex = it },
|
onClick = { selectedTabIndex = it },
|
||||||
|
focusRequesters = tabFocusRequesters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
when (selectedTabIndex) {
|
when (selectedTabIndex) {
|
||||||
|
|
@ -150,10 +156,12 @@ fun CollectionFolderLiveTv(
|
||||||
|
|
||||||
1 -> {
|
1 -> {
|
||||||
DvrSchedule(
|
DvrSchedule(
|
||||||
true,
|
requestFocusAfterLoading = true,
|
||||||
Modifier
|
focusRequesterOnEmpty = tabFocusRequesters[1],
|
||||||
.fillMaxSize()
|
modifier =
|
||||||
.focusRequester(focusRequester),
|
Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.focusRequester(focusRequester),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,6 +184,7 @@ fun CollectionFolderLiveTv(
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
defaultViewOptions = ViewOptions(),
|
defaultViewOptions = ViewOptions(),
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ErrorMessage("Invalid tab index $selectedTabIndex", null)
|
ErrorMessage("Invalid tab index $selectedTabIndex", null)
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ fun CollectionFolderMovie(
|
||||||
)
|
)
|
||||||
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val tabFocusRequesters = remember { List(tabs.size) { FocusRequester() } }
|
||||||
|
|
||||||
val firstTabFocusRequester = remember { FocusRequester() }
|
val firstTabFocusRequester = remember { FocusRequester() }
|
||||||
LaunchedEffect(Unit) { firstTabFocusRequester.tryRequestFocus() }
|
LaunchedEffect(Unit) { firstTabFocusRequester.tryRequestFocus() }
|
||||||
|
|
@ -88,6 +89,7 @@ fun CollectionFolderMovie(
|
||||||
.focusRequester(firstTabFocusRequester),
|
.focusRequester(firstTabFocusRequester),
|
||||||
tabs = tabs,
|
tabs = tabs,
|
||||||
onClick = { selectedTabIndex = it },
|
onClick = { selectedTabIndex = it },
|
||||||
|
focusRequesters = tabFocusRequesters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
when (selectedTabIndex) {
|
when (selectedTabIndex) {
|
||||||
|
|
@ -136,6 +138,7 @@ fun CollectionFolderMovie(
|
||||||
showHeader = position < columns
|
showHeader = position < columns
|
||||||
},
|
},
|
||||||
playEnabled = true,
|
playEnabled = true,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,6 +171,7 @@ fun CollectionFolderMovie(
|
||||||
showHeader = position < columns
|
showHeader = position < columns
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ fun CollectionFolderTv(
|
||||||
)
|
)
|
||||||
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val tabFocusRequesters = remember { List(tabs.size) { FocusRequester() } }
|
||||||
|
|
||||||
val firstTabFocusRequester = remember { FocusRequester() }
|
val firstTabFocusRequester = remember { FocusRequester() }
|
||||||
LaunchedEffect(Unit) { firstTabFocusRequester.tryRequestFocus() }
|
LaunchedEffect(Unit) { firstTabFocusRequester.tryRequestFocus() }
|
||||||
|
|
@ -91,6 +92,7 @@ fun CollectionFolderTv(
|
||||||
.focusRequester(firstTabFocusRequester),
|
.focusRequester(firstTabFocusRequester),
|
||||||
tabs = tabs,
|
tabs = tabs,
|
||||||
onClick = { selectedTabIndex = it },
|
onClick = { selectedTabIndex = it },
|
||||||
|
focusRequesters = tabFocusRequesters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
when (selectedTabIndex) {
|
when (selectedTabIndex) {
|
||||||
|
|
@ -138,6 +140,7 @@ fun CollectionFolderTv(
|
||||||
preferencesViewModel.navigationManager.navigateTo(item.destination())
|
preferencesViewModel.navigationManager.navigateTo(item.destination())
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ fun FavoritesPage(
|
||||||
stringResource(R.string.playlists),
|
stringResource(R.string.playlists),
|
||||||
stringResource(R.string.people),
|
stringResource(R.string.people),
|
||||||
)
|
)
|
||||||
|
val tabFocusRequesters = remember { List(tabs.size) { FocusRequester() } }
|
||||||
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
var selectedTabIndex by rememberSaveable { mutableIntStateOf(rememberedTabIndex) }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
|
@ -107,6 +108,7 @@ fun FavoritesPage(
|
||||||
.padding(start = 32.dp, top = 16.dp, bottom = 16.dp),
|
.padding(start = 32.dp, top = 16.dp, bottom = 16.dp),
|
||||||
tabs = tabs,
|
tabs = tabs,
|
||||||
onClick = { selectedTabIndex = it },
|
onClick = { selectedTabIndex = it },
|
||||||
|
focusRequesters = tabFocusRequesters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// TODO playEnabled = true for movies & episodes
|
// TODO playEnabled = true for movies & episodes
|
||||||
|
|
@ -139,6 +141,7 @@ fun FavoritesPage(
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
filterOptions = DefaultForFavoritesFilterOptions,
|
filterOptions = DefaultForFavoritesFilterOptions,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,6 +173,7 @@ fun FavoritesPage(
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
filterOptions = DefaultForFavoritesFilterOptions,
|
filterOptions = DefaultForFavoritesFilterOptions,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,6 +206,7 @@ fun FavoritesPage(
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
filterOptions = DefaultForFavoritesFilterOptions,
|
filterOptions = DefaultForFavoritesFilterOptions,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,6 +238,7 @@ fun FavoritesPage(
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
filterOptions = DefaultForFavoritesFilterOptions,
|
filterOptions = DefaultForFavoritesFilterOptions,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,6 +270,7 @@ fun FavoritesPage(
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
filterOptions = DefaultForFavoritesFilterOptions,
|
filterOptions = DefaultForFavoritesFilterOptions,
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -300,6 +307,7 @@ fun FavoritesPage(
|
||||||
},
|
},
|
||||||
playEnabled = false,
|
playEnabled = false,
|
||||||
filterOptions = listOf(),
|
filterOptions = listOf(),
|
||||||
|
focusRequesterOnEmpty = tabFocusRequesters.getOrNull(selectedTabIndex),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ class DvrScheduleViewModel
|
||||||
@Composable
|
@Composable
|
||||||
fun DvrSchedule(
|
fun DvrSchedule(
|
||||||
requestFocusAfterLoading: Boolean,
|
requestFocusAfterLoading: Boolean,
|
||||||
|
focusRequesterOnEmpty: FocusRequester,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: DvrScheduleViewModel = hiltViewModel(),
|
viewModel: DvrScheduleViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
|
|
@ -138,7 +139,13 @@ fun DvrSchedule(
|
||||||
var showDialog by remember { mutableStateOf<BaseItem?>(null) }
|
var showDialog by remember { mutableStateOf<BaseItem?>(null) }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
if (requestFocusAfterLoading) {
|
if (requestFocusAfterLoading) {
|
||||||
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
|
LaunchedEffect(Unit) {
|
||||||
|
if (active.isNotEmpty() || recordings.isNotEmpty()) {
|
||||||
|
focusRequester.tryRequestFocus()
|
||||||
|
} else {
|
||||||
|
focusRequesterOnEmpty.tryRequestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DvrScheduleContent(
|
DvrScheduleContent(
|
||||||
activeRecordings = active,
|
activeRecordings = active,
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,18 @@ fun SeriesOverviewContent(
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
val scrollConnection = rememberDelayedNestedScroll()
|
val scrollConnection = rememberDelayedNestedScroll()
|
||||||
var requestFocusAfterSeason by remember { mutableStateOf(false) }
|
var requestFocusAfterSeason by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val seasonStr = stringResource(R.string.tv_season)
|
||||||
|
val tabs =
|
||||||
|
remember(seasons) {
|
||||||
|
seasons.mapNotNull {
|
||||||
|
it?.name
|
||||||
|
?: it?.data?.indexNumber?.let { "$seasonStr $it" }
|
||||||
|
?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val focusRequesters = remember(seasons) { List(seasons.size) { FocusRequester() } }
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier =
|
modifier =
|
||||||
modifier
|
modifier
|
||||||
|
|
@ -138,17 +150,13 @@ fun SeriesOverviewContent(
|
||||||
}
|
}
|
||||||
TabRow(
|
TabRow(
|
||||||
selectedTabIndex = selectedTabIndex,
|
selectedTabIndex = selectedTabIndex,
|
||||||
tabs =
|
tabs = tabs,
|
||||||
seasons.mapNotNull {
|
|
||||||
it?.name
|
|
||||||
?: it?.data?.indexNumber?.let { stringResource(R.string.tv_season) + " $it" }
|
|
||||||
?: ""
|
|
||||||
},
|
|
||||||
onClick = {
|
onClick = {
|
||||||
selectedTabIndex = it
|
selectedTabIndex = it
|
||||||
onChangeSeason.invoke(it)
|
onChangeSeason.invoke(it)
|
||||||
requestFocusAfterSeason = true
|
requestFocusAfterSeason = true
|
||||||
},
|
},
|
||||||
|
focusRequesters = focusRequesters,
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.focusRequester(tabRowFocusRequester)
|
.focusRequester(tabRowFocusRequester)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue