mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Further improvements to resuming the app (#577)
## Description Fixes issues when the app is resumed, such as after the screensaver is dismissed. For example, if you pause during playback and the screensaver starts, Wholphin will stop playback and go back to the previous page. But with this PR, instead of focus being lost and defaulting to teh nav drawer, focus will restore on the play button or episode card. ### Related issues Related to #552 & https://github.com/damontecres/Wholphin/issues/552#issuecomment-3690614491
This commit is contained in:
parent
bdec72752d
commit
a797bd8267
9 changed files with 127 additions and 94 deletions
|
|
@ -230,7 +230,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
Timber.i("onResume")
|
||||
Timber.d("onResume")
|
||||
lifecycleScope.launchIO {
|
||||
appUpgradeHandler.run()
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
override fun onRestart() {
|
||||
super.onRestart()
|
||||
Timber.i("onRestart")
|
||||
Timber.d("onRestart")
|
||||
viewModel.appStart()
|
||||
// val signInAutomatically =
|
||||
// runBlocking { userPreferencesDataStore.data.firstOrNull()?.signInAutomatically } ?: true
|
||||
|
|
@ -250,35 +250,35 @@ class MainActivity : AppCompatActivity() {
|
|||
// }
|
||||
}
|
||||
|
||||
// override fun onStop() {
|
||||
// super.onStop()
|
||||
// Timber.i("onStop")
|
||||
// }
|
||||
//
|
||||
// override fun onPause() {
|
||||
// super.onPause()
|
||||
// Timber.i("onPause")
|
||||
// }
|
||||
//
|
||||
// override fun onStart() {
|
||||
// super.onStart()
|
||||
// Timber.i("onStart")
|
||||
// }
|
||||
//
|
||||
// override fun onSaveInstanceState(outState: Bundle) {
|
||||
// super.onSaveInstanceState(outState)
|
||||
// Timber.i("onSaveInstanceState")
|
||||
// }
|
||||
//
|
||||
// override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
// super.onRestoreInstanceState(savedInstanceState)
|
||||
// Timber.i("onRestoreInstanceState")
|
||||
// }
|
||||
//
|
||||
// override fun onDestroy() {
|
||||
// super.onDestroy()
|
||||
// Timber.i("onDestroy")
|
||||
// }
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
Timber.d("onStop")
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
Timber.d("onPause")
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
Timber.d("onStart")
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
Timber.d("onSaveInstanceState")
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
Timber.d("onRestoreInstanceState")
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
Timber.d("onDestroy")
|
||||
}
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ import androidx.compose.ui.platform.LocalContext
|
|||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.compose.LifecycleEventEffect
|
||||
import androidx.media3.common.Player
|
||||
import coil3.request.ErrorResult
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
|
|
@ -167,6 +169,26 @@ fun OneTimeLaunchedEffect(runOnceBlock: suspend CoroutineScope.() -> Unit) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls [tryRequestFocus] on the provided [FocusRequester] when this composable launches or resumes
|
||||
*/
|
||||
@Composable
|
||||
fun RequestOrRestoreFocus(
|
||||
focusRequester: FocusRequester?,
|
||||
debugKey: String? = null,
|
||||
) {
|
||||
if (focusRequester != null) {
|
||||
LaunchedEffect(Unit) {
|
||||
debugKey?.let { Timber.v("RequestOrRestoreFocus: %s", it) }
|
||||
focusRequester.tryRequestFocus()
|
||||
}
|
||||
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
|
||||
debugKey?.let { Timber.v("RequestOrRestoreFocus onResume: %s", it) }
|
||||
focusRequester.tryRequestFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Modifier.enableMarquee(focused: Boolean) =
|
||||
if (focused) {
|
||||
basicMarquee(
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import androidx.compose.ui.unit.Dp
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.tv.material3.MaterialTheme
|
||||
import androidx.tv.material3.Text
|
||||
|
|
@ -67,7 +68,7 @@ import com.github.damontecres.wholphin.services.BackdropService
|
|||
import com.github.damontecres.wholphin.services.FavoriteWatchManager
|
||||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||
import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect
|
||||
import com.github.damontecres.wholphin.ui.RequestOrRestoreFocus
|
||||
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||
import com.github.damontecres.wholphin.ui.cards.GridCard
|
||||
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
||||
|
|
@ -85,17 +86,18 @@ import com.github.damontecres.wholphin.ui.playback.scale
|
|||
import com.github.damontecres.wholphin.ui.rememberInt
|
||||
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||
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.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.GetPersonsHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
|
|
@ -114,13 +116,13 @@ import org.jellyfin.sdk.model.serializer.toUUIDOrNull
|
|||
import timber.log.Timber
|
||||
import java.util.TreeSet
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration
|
||||
|
||||
@HiltViewModel
|
||||
@HiltViewModel(assistedFactory = CollectionFolderViewModel.Factory::class)
|
||||
class CollectionFolderViewModel
|
||||
@Inject
|
||||
@AssistedInject
|
||||
constructor(
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
api: ApiClient,
|
||||
@param:ApplicationContext private val context: Context,
|
||||
private val serverRepository: ServerRepository,
|
||||
|
|
@ -128,7 +130,25 @@ class CollectionFolderViewModel
|
|||
private val favoriteWatchManager: FavoriteWatchManager,
|
||||
private val backdropService: BackdropService,
|
||||
val navigationManager: NavigationManager,
|
||||
@Assisted itemId: String,
|
||||
@Assisted initialSortAndDirection: SortAndDirection?,
|
||||
@Assisted("recursive") private val recursive: Boolean,
|
||||
@Assisted private val collectionFilter: CollectionFolderFilter,
|
||||
@Assisted("useSeriesForPrimary") private val useSeriesForPrimary: Boolean,
|
||||
@Assisted defaultViewOptions: ViewOptions,
|
||||
) : ItemViewModel(api) {
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(
|
||||
itemId: String,
|
||||
initialSortAndDirection: SortAndDirection?,
|
||||
@Assisted("recursive") recursive: Boolean,
|
||||
collectionFilter: CollectionFolderFilter,
|
||||
@Assisted("useSeriesForPrimary") useSeriesForPrimary: Boolean,
|
||||
defaultViewOptions: ViewOptions,
|
||||
): CollectionFolderViewModel
|
||||
}
|
||||
|
||||
val loading = MutableLiveData<LoadingState>(LoadingState.Loading)
|
||||
val backgroundLoading = MutableLiveData<LoadingState>(LoadingState.Loading)
|
||||
val pager = MutableLiveData<List<BaseItem?>>(listOf())
|
||||
|
|
@ -136,26 +156,19 @@ class CollectionFolderViewModel
|
|||
val filter = MutableLiveData<GetItemsFilter>(GetItemsFilter())
|
||||
val viewOptions = MutableLiveData<ViewOptions>()
|
||||
|
||||
private var useSeriesForPrimary: Boolean = true
|
||||
private lateinit var collectionFilter: CollectionFolderFilter
|
||||
var position: Int
|
||||
get() = savedStateHandle.get<Int>("position") ?: 0
|
||||
set(value) {
|
||||
savedStateHandle["position"] = value
|
||||
}
|
||||
|
||||
fun init(
|
||||
itemId: String,
|
||||
initialSortAndDirection: SortAndDirection?,
|
||||
recursive: Boolean,
|
||||
collectionFilter: CollectionFolderFilter,
|
||||
useSeriesForPrimary: Boolean,
|
||||
defaultViewOptions: ViewOptions,
|
||||
): Job =
|
||||
init {
|
||||
viewModelScope.launch(
|
||||
LoadingExceptionHandler(
|
||||
loading,
|
||||
context.getString(R.string.error_loading_collection, itemId),
|
||||
) + Dispatchers.IO,
|
||||
) {
|
||||
this@CollectionFolderViewModel.collectionFilter = collectionFilter
|
||||
this@CollectionFolderViewModel.useSeriesForPrimary = useSeriesForPrimary
|
||||
this@CollectionFolderViewModel.itemId = itemId
|
||||
itemId.toUUIDOrNull()?.let {
|
||||
fetchItem(it)
|
||||
}
|
||||
|
|
@ -184,6 +197,7 @@ class CollectionFolderViewModel
|
|||
|
||||
loadResults(true, sortAndDirection, recursive, filterToUse, useSeriesForPrimary)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveLibraryDisplayInfo(
|
||||
newFilter: GetItemsFilter = this.filter.value!!,
|
||||
|
|
@ -537,25 +551,27 @@ fun CollectionFolderGrid(
|
|||
playEnabled: Boolean,
|
||||
defaultViewOptions: ViewOptions,
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: CollectionFolderViewModel = hiltViewModel(key = itemId),
|
||||
playlistViewModel: AddPlaylistViewModel = hiltViewModel(),
|
||||
initialSortAndDirection: SortAndDirection? = null,
|
||||
showTitle: Boolean = true,
|
||||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||
useSeriesForPrimary: Boolean = true,
|
||||
filterOptions: List<ItemFilterBy<*>> = DefaultFilterOptions,
|
||||
playlistViewModel: AddPlaylistViewModel = hiltViewModel(),
|
||||
viewModel: CollectionFolderViewModel =
|
||||
hiltViewModel<CollectionFolderViewModel, CollectionFolderViewModel.Factory>(
|
||||
key = itemId,
|
||||
) {
|
||||
it.create(
|
||||
itemId = itemId,
|
||||
initialSortAndDirection = initialSortAndDirection,
|
||||
recursive = recursive,
|
||||
collectionFilter = initialFilter,
|
||||
useSeriesForPrimary = useSeriesForPrimary,
|
||||
defaultViewOptions = defaultViewOptions,
|
||||
)
|
||||
},
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
OneTimeLaunchedEffect {
|
||||
viewModel.init(
|
||||
itemId,
|
||||
initialSortAndDirection,
|
||||
recursive,
|
||||
initialFilter,
|
||||
useSeriesForPrimary,
|
||||
defaultViewOptions,
|
||||
)
|
||||
}
|
||||
val sortAndDirection by viewModel.sortAndDirection.observeAsState(SortAndDirection.DEFAULT)
|
||||
val filter by viewModel.filter.observeAsState(initialFilter.filter)
|
||||
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
|
||||
|
|
@ -589,6 +605,7 @@ fun CollectionFolderGrid(
|
|||
Box(modifier = modifier) {
|
||||
CollectionFolderGridContent(
|
||||
preferences = preferences,
|
||||
initialPosition = viewModel.position,
|
||||
item = item,
|
||||
title = title,
|
||||
pager = pager,
|
||||
|
|
@ -611,7 +628,10 @@ fun CollectionFolderGrid(
|
|||
},
|
||||
showTitle = showTitle,
|
||||
sortOptions = sortOptions,
|
||||
positionCallback = positionCallback,
|
||||
positionCallback = { columns, position ->
|
||||
viewModel.position = position
|
||||
positionCallback?.invoke(columns, position)
|
||||
},
|
||||
letterPosition = { viewModel.positionOfLetter(it) ?: -1 },
|
||||
viewOptions = viewOptions,
|
||||
defaultViewOptions = defaultViewOptions,
|
||||
|
|
@ -728,6 +748,7 @@ fun CollectionFolderGridContent(
|
|||
onClickPlayAll: (shuffle: Boolean) -> Unit,
|
||||
onClickPlay: (Int, BaseItem) -> Unit,
|
||||
onChangeBackdrop: (BaseItem) -> Unit,
|
||||
initialPosition: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
showTitle: Boolean = true,
|
||||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||
|
|
@ -742,10 +763,10 @@ fun CollectionFolderGridContent(
|
|||
var viewOptions by remember { mutableStateOf(viewOptions) }
|
||||
|
||||
val gridFocusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) { gridFocusRequester.tryRequestFocus() }
|
||||
RequestOrRestoreFocus(gridFocusRequester)
|
||||
var backdropImageUrl by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
var position by rememberInt(0)
|
||||
var position by rememberInt(initialPosition)
|
||||
val focusedItem = pager.getOrNull(position)
|
||||
if (viewOptions.showDetails) {
|
||||
LaunchedEffect(focusedItem) {
|
||||
|
|
@ -861,7 +882,7 @@ fun CollectionFolderGridContent(
|
|||
showJumpButtons = false, // TODO add preference
|
||||
showLetterButtons = sortAndDirection.sort == ItemSortBy.SORT_NAME,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
initialPosition = 0,
|
||||
initialPosition = initialPosition,
|
||||
positionCallback = { columns, newPosition ->
|
||||
showHeader = newPosition < columns
|
||||
position = newPosition
|
||||
|
|
|
|||
|
|
@ -117,12 +117,16 @@ fun <T : CardGridItem> CardGrid(
|
|||
val startPosition = initialPosition.coerceIn(0, (pager.size - 1).coerceAtLeast(0))
|
||||
|
||||
val fractionCacheWindow = LazyLayoutCacheWindow(aheadFraction = 1f, behindFraction = 0.5f)
|
||||
val gridState = rememberLazyGridState(cacheWindow = fractionCacheWindow)
|
||||
var focusedIndex by rememberSaveable { mutableIntStateOf(initialPosition) }
|
||||
val gridState =
|
||||
rememberLazyGridState(
|
||||
cacheWindow = fractionCacheWindow,
|
||||
initialFirstVisibleItemIndex = focusedIndex,
|
||||
)
|
||||
val scope = rememberCoroutineScope()
|
||||
val firstFocus = remember { FocusRequester() }
|
||||
val zeroFocus = remember { FocusRequester() }
|
||||
var previouslyFocusedIndex by rememberSaveable { mutableIntStateOf(0) }
|
||||
var focusedIndex by rememberSaveable { mutableIntStateOf(initialPosition) }
|
||||
|
||||
var alphabetFocus by remember { mutableStateOf(false) }
|
||||
val focusOn = { index: Int ->
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
||||
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
|
||||
|
|
@ -31,6 +30,7 @@ import com.github.damontecres.wholphin.R
|
|||
import com.github.damontecres.wholphin.data.ChosenStreams
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.ui.RequestOrRestoreFocus
|
||||
import com.github.damontecres.wholphin.ui.components.DialogParams
|
||||
import com.github.damontecres.wholphin.ui.components.DialogPopup
|
||||
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
||||
|
|
@ -48,7 +48,6 @@ import com.github.damontecres.wholphin.ui.detail.PlaylistLoadingState
|
|||
import com.github.damontecres.wholphin.ui.detail.buildMoreDialogItems
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.rememberInt
|
||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -291,9 +290,7 @@ fun EpisodeDetailsContent(
|
|||
val resumePosition = dto.userData?.playbackPositionTicks?.ticks ?: Duration.ZERO
|
||||
|
||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequesters.getOrNull(position)?.tryRequestFocus()
|
||||
}
|
||||
RequestOrRestoreFocus(focusRequesters.getOrNull(position))
|
||||
Box(modifier = modifier) {
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
|||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
||||
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
|
||||
|
|
@ -49,6 +48,7 @@ import com.github.damontecres.wholphin.preferences.UserPreferences
|
|||
import com.github.damontecres.wholphin.services.TrailerService
|
||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||
import com.github.damontecres.wholphin.ui.Cards
|
||||
import com.github.damontecres.wholphin.ui.RequestOrRestoreFocus
|
||||
import com.github.damontecres.wholphin.ui.cards.ChapterRow
|
||||
import com.github.damontecres.wholphin.ui.cards.ExtrasRow
|
||||
import com.github.damontecres.wholphin.ui.cards.ItemRow
|
||||
|
|
@ -73,7 +73,6 @@ import com.github.damontecres.wholphin.ui.detail.buildMoreDialogItemsForHome
|
|||
import com.github.damontecres.wholphin.ui.detail.buildMoreDialogItemsForPerson
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.rememberInt
|
||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -391,9 +390,9 @@ fun MovieDetailsContent(
|
|||
val resumePosition = dto.userData?.playbackPositionTicks?.ticks ?: Duration.ZERO
|
||||
|
||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequesters.getOrNull(position)?.tryRequestFocus()
|
||||
}
|
||||
|
||||
RequestOrRestoreFocus(focusRequesters.getOrNull(position))
|
||||
|
||||
Box(modifier = modifier) {
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import androidx.compose.foundation.relocation.bringIntoViewRequester
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.PlayArrow
|
||||
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
|
||||
|
|
@ -46,6 +45,7 @@ import com.github.damontecres.wholphin.data.model.Trailer
|
|||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.services.TrailerService
|
||||
import com.github.damontecres.wholphin.ui.Cards
|
||||
import com.github.damontecres.wholphin.ui.RequestOrRestoreFocus
|
||||
import com.github.damontecres.wholphin.ui.cards.ExtrasRow
|
||||
import com.github.damontecres.wholphin.ui.cards.ItemRow
|
||||
import com.github.damontecres.wholphin.ui.cards.PersonRow
|
||||
|
|
@ -74,7 +74,6 @@ import com.github.damontecres.wholphin.ui.detail.movie.TrailerRow
|
|||
import com.github.damontecres.wholphin.ui.letNotEmpty
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.rememberInt
|
||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -313,9 +312,7 @@ fun SeriesDetailsContent(
|
|||
var position by rememberInt()
|
||||
val focusRequesters = remember { List(SIMILAR_ROW + 1) { FocusRequester() } }
|
||||
val playFocusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequesters.getOrNull(position)?.tryRequestFocus()
|
||||
}
|
||||
RequestOrRestoreFocus(focusRequesters.getOrNull(position))
|
||||
var moreDialog by remember { mutableStateOf<DialogParams?>(null) }
|
||||
|
||||
Box(
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem
|
|||
import com.github.damontecres.wholphin.data.model.Person
|
||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||
import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect
|
||||
import com.github.damontecres.wholphin.ui.RequestOrRestoreFocus
|
||||
import com.github.damontecres.wholphin.ui.cards.BannerCard
|
||||
import com.github.damontecres.wholphin.ui.cards.PersonRow
|
||||
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
||||
|
|
@ -181,13 +181,9 @@ fun SeriesOverviewContent(
|
|||
}
|
||||
|
||||
is EpisodeList.Success -> {
|
||||
val state = rememberLazyListState()
|
||||
OneTimeLaunchedEffect {
|
||||
if (state.firstVisibleItemIndex != position.episodeRowIndex) {
|
||||
state.scrollToItem(position.episodeRowIndex)
|
||||
}
|
||||
firstItemFocusRequester.tryRequestFocus()
|
||||
}
|
||||
val state = rememberLazyListState(position.episodeRowIndex)
|
||||
RequestOrRestoreFocus(firstItemFocusRequester)
|
||||
|
||||
LazyRow(
|
||||
state = state,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import com.github.damontecres.wholphin.data.model.ItemPlayback
|
|||
import com.github.damontecres.wholphin.data.model.Person
|
||||
import com.github.damontecres.wholphin.data.model.Trailer
|
||||
import com.github.damontecres.wholphin.preferences.ThemeSongVolume
|
||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.services.BackdropService
|
||||
import com.github.damontecres.wholphin.services.ExtrasService
|
||||
import com.github.damontecres.wholphin.services.FavoriteWatchManager
|
||||
|
|
@ -98,7 +97,6 @@ class SeriesViewModel
|
|||
): SeriesViewModel
|
||||
}
|
||||
|
||||
private lateinit var prefs: UserPreferences
|
||||
val loading = MutableLiveData<LoadingState>(LoadingState.Loading)
|
||||
val seasons = MutableLiveData<List<BaseItem?>>(listOf())
|
||||
val episodes = MutableLiveData<EpisodeList>(EpisodeList.Loading)
|
||||
|
|
@ -119,7 +117,6 @@ class SeriesViewModel
|
|||
"Error loading series $seriesId",
|
||||
) + Dispatchers.IO,
|
||||
) {
|
||||
this@SeriesViewModel.prefs = userPreferencesService.getCurrent()
|
||||
Timber.v("Start")
|
||||
val item = fetchItem(seriesId)
|
||||
backdropService.submit(item)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue