mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-11-08 16:28:36 +01:00
Several minor fixes (#1505)
## Description Collecting some minor fixes together: - Adds error handling when submitting a discover/seerr request, previously there was no visual feedback if the request failed - Fix MpvPlayer reporting that it was buffering forever - Fix discover results row on regular search page not being clickable - Fix focus loss when returning to movie details after playback advanced enough to switch the button from Play to Resume - Fix some focus issues when returning to the TV guide page ### Related issues Related to #1503 for MPV Fixes #1500 Fixes #1508 Fixes #1501 ### Testing Emulator & nvidia shield ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
a1b372667b
commit
a0869ca6e4
7 changed files with 103 additions and 66 deletions
|
|
@ -26,6 +26,7 @@ import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
import androidx.compose.material.icons.filled.Refresh
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
|
@ -59,6 +60,7 @@ import com.github.damontecres.wholphin.ui.data.SortAndDirection
|
||||||
import com.github.damontecres.wholphin.ui.ifElse
|
import com.github.damontecres.wholphin.ui.ifElse
|
||||||
import com.github.damontecres.wholphin.ui.theme.PreviewInteractionSource
|
import com.github.damontecres.wholphin.ui.theme.PreviewInteractionSource
|
||||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||||
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import org.jellyfin.sdk.model.api.ItemSortBy
|
import org.jellyfin.sdk.model.api.ItemSortBy
|
||||||
import org.jellyfin.sdk.model.api.SortOrder
|
import org.jellyfin.sdk.model.api.SortOrder
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
@ -85,6 +87,14 @@ fun ExpandablePlayButtons(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val firstFocus = remember { FocusRequester() }
|
val firstFocus = remember { FocusRequester() }
|
||||||
|
val restartInteractionSource = remember { MutableInteractionSource() }
|
||||||
|
val restartButtonFocused by restartInteractionSource.collectIsFocusedAsState()
|
||||||
|
LaunchedEffect(resumePosition) {
|
||||||
|
// Reset focus if the restart button was focuses and it is going to disappear
|
||||||
|
if (restartButtonFocused && resumePosition == Duration.ZERO) {
|
||||||
|
firstFocus.tryRequestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
LazyRow(
|
LazyRow(
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
contentPadding = PaddingValues(8.dp),
|
contentPadding = PaddingValues(8.dp),
|
||||||
|
|
@ -93,19 +103,19 @@ fun ExpandablePlayButtons(
|
||||||
.focusGroup()
|
.focusGroup()
|
||||||
.focusRestorer(firstFocus),
|
.focusRestorer(firstFocus),
|
||||||
) {
|
) {
|
||||||
|
item("play") {
|
||||||
|
ExpandablePlayButton(
|
||||||
|
title = if (resumePosition > Duration.ZERO) R.string.resume else R.string.play,
|
||||||
|
resume = resumePosition,
|
||||||
|
icon = Icons.Default.PlayArrow,
|
||||||
|
onClick = playOnClick,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.onFocusChanged(buttonOnFocusChanged)
|
||||||
|
.focusRequester(firstFocus),
|
||||||
|
)
|
||||||
|
}
|
||||||
if (resumePosition > Duration.ZERO) {
|
if (resumePosition > Duration.ZERO) {
|
||||||
item("play") {
|
|
||||||
ExpandablePlayButton(
|
|
||||||
title = R.string.resume,
|
|
||||||
resume = resumePosition,
|
|
||||||
icon = Icons.Default.PlayArrow,
|
|
||||||
onClick = playOnClick,
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.onFocusChanged(buttonOnFocusChanged)
|
|
||||||
.focusRequester(firstFocus),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
item("restart") {
|
item("restart") {
|
||||||
ExpandablePlayButton(
|
ExpandablePlayButton(
|
||||||
title = R.string.restart,
|
title = R.string.restart,
|
||||||
|
|
@ -114,19 +124,7 @@ fun ExpandablePlayButtons(
|
||||||
onClick = playOnClick,
|
onClick = playOnClick,
|
||||||
modifier = Modifier.onFocusChanged(buttonOnFocusChanged),
|
modifier = Modifier.onFocusChanged(buttonOnFocusChanged),
|
||||||
mirrorIcon = true,
|
mirrorIcon = true,
|
||||||
)
|
interactionSource = restartInteractionSource,
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item("play") {
|
|
||||||
ExpandablePlayButton(
|
|
||||||
title = R.string.play,
|
|
||||||
resume = Duration.ZERO,
|
|
||||||
icon = Icons.Default.PlayArrow,
|
|
||||||
onClick = playOnClick,
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.onFocusChanged(buttonOnFocusChanged)
|
|
||||||
.focusRequester(firstFocus),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ fun CollectionFolderLiveTv(
|
||||||
when (selectedTabIndex) {
|
when (selectedTabIndex) {
|
||||||
0 -> {
|
0 -> {
|
||||||
TvGuideGrid(
|
TvGuideGrid(
|
||||||
|
preferences = preferences,
|
||||||
onRowPosition = {
|
onRowPosition = {
|
||||||
showHeader = it <= 0
|
showHeader = it <= 0
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import com.github.damontecres.wholphin.services.SeerrUserConfig
|
||||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
|
import com.github.damontecres.wholphin.ui.showToast
|
||||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||||
import com.github.damontecres.wholphin.util.successValue
|
import com.github.damontecres.wholphin.util.successValue
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
|
|
@ -168,7 +169,7 @@ class DiscoverMovieViewModel
|
||||||
is4k: Boolean,
|
is4k: Boolean,
|
||||||
) {
|
) {
|
||||||
viewModelScope.launchIO {
|
viewModelScope.launchIO {
|
||||||
val request =
|
try {
|
||||||
seerrService.api.requestApi.requestPost(
|
seerrService.api.requestApi.requestPost(
|
||||||
RequestPostRequest(
|
RequestPostRequest(
|
||||||
is4k = is4k,
|
is4k = is4k,
|
||||||
|
|
@ -176,6 +177,12 @@ class DiscoverMovieViewModel
|
||||||
mediaType = RequestPostRequest.MediaType.MOVIE,
|
mediaType = RequestPostRequest.MediaType.MOVIE,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
} catch (ex: kotlinx.coroutines.CancellationException) {
|
||||||
|
throw ex
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Timber.e(ex, "Error requesting %s", id)
|
||||||
|
showToast(context, "An error occurred")
|
||||||
|
}
|
||||||
fetchAndSetItem().await()
|
fetchAndSetItem().await()
|
||||||
updateCanCancel()
|
updateCanCancel()
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +192,14 @@ class DiscoverMovieViewModel
|
||||||
viewModelScope.launchIO {
|
viewModelScope.launchIO {
|
||||||
state.value.movie.successValue?.mediaInfo?.requests?.firstOrNull()?.let {
|
state.value.movie.successValue?.mediaInfo?.requests?.firstOrNull()?.let {
|
||||||
// TODO handle multiple requests? Or just delete self's request?
|
// TODO handle multiple requests? Or just delete self's request?
|
||||||
seerrService.api.requestApi.requestRequestIdDelete(it.id.toString())
|
try {
|
||||||
|
seerrService.api.requestApi.requestRequestIdDelete(it.id.toString())
|
||||||
|
} catch (ex: kotlinx.coroutines.CancellationException) {
|
||||||
|
throw ex
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Timber.e(ex, "Error requesting %s", id)
|
||||||
|
showToast(context, "An error occurred")
|
||||||
|
}
|
||||||
fetchAndSetItem().await()
|
fetchAndSetItem().await()
|
||||||
updateCanCancel()
|
updateCanCancel()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import com.github.damontecres.wholphin.services.SeerrService
|
||||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
|
import com.github.damontecres.wholphin.ui.showToast
|
||||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||||
import com.github.damontecres.wholphin.util.successValue
|
import com.github.damontecres.wholphin.util.successValue
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
|
|
@ -209,27 +210,34 @@ class DiscoverSeriesViewModel
|
||||||
it.requestedBy?.id ==
|
it.requestedBy?.id ==
|
||||||
seerrServerRepository.currentUserId.first()
|
seerrServerRepository.currentUserId.first()
|
||||||
}
|
}
|
||||||
if (currentRequest != null) {
|
try {
|
||||||
Timber.v("User has pending request, will update")
|
if (currentRequest != null) {
|
||||||
seerrService.api.requestApi.requestRequestIdPut(
|
Timber.v("User has pending request, will update")
|
||||||
requestId = currentRequest.id.toString(),
|
seerrService.api.requestApi.requestRequestIdPut(
|
||||||
requestRequestIdPutRequest =
|
requestId = currentRequest.id.toString(),
|
||||||
RequestRequestIdPutRequest(
|
requestRequestIdPutRequest =
|
||||||
|
RequestRequestIdPutRequest(
|
||||||
|
is4k = is4k,
|
||||||
|
mediaType = RequestRequestIdPutRequest.MediaType.TV,
|
||||||
|
seasons = seasons.toList(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Timber.v("New request for %s seasons", seasons.size)
|
||||||
|
seerrService.api.requestApi.requestPost(
|
||||||
|
RequestPostRequest(
|
||||||
is4k = is4k,
|
is4k = is4k,
|
||||||
mediaType = RequestRequestIdPutRequest.MediaType.TV,
|
mediaId = id,
|
||||||
|
mediaType = RequestPostRequest.MediaType.TV,
|
||||||
seasons = seasons.toList(),
|
seasons = seasons.toList(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
Timber.v("New request for %s seasons", seasons.size)
|
} catch (ex: CancellationException) {
|
||||||
seerrService.api.requestApi.requestPost(
|
throw ex
|
||||||
RequestPostRequest(
|
} catch (ex: Exception) {
|
||||||
is4k = is4k,
|
Timber.e(ex, "Error requesting %s", id)
|
||||||
mediaId = id,
|
showToast(context, "An error occurred")
|
||||||
mediaType = RequestPostRequest.MediaType.TV,
|
|
||||||
seasons = seasons.toList(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchAndSetItem().await()?.let {
|
fetchAndSetItem().await()?.let {
|
||||||
|
|
@ -244,7 +252,15 @@ class DiscoverSeriesViewModel
|
||||||
viewModelScope.launchIO {
|
viewModelScope.launchIO {
|
||||||
state.value.tvSeries.successValue?.mediaInfo?.requests?.firstOrNull()?.let {
|
state.value.tvSeries.successValue?.mediaInfo?.requests?.firstOrNull()?.let {
|
||||||
// TODO handle multiple requests? Or just delete self's request?
|
// TODO handle multiple requests? Or just delete self's request?
|
||||||
seerrService.api.requestApi.requestRequestIdDelete(it.id.toString())
|
try {
|
||||||
|
seerrService.api.requestApi.requestRequestIdDelete(it.id.toString())
|
||||||
|
} catch (ex: CancellationException) {
|
||||||
|
throw ex
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Timber.e(ex, "Error requesting %s", id)
|
||||||
|
showToast(context, "An error occurred")
|
||||||
|
}
|
||||||
|
|
||||||
fetchAndSetItem().await()?.let {
|
fetchAndSetItem().await()?.let {
|
||||||
updateSeasonStatus(it)
|
updateSeasonStatus(it)
|
||||||
updateCanCancel()
|
updateCanCancel()
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
|
@ -30,7 +29,6 @@ import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusProperties
|
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
@ -43,8 +41,8 @@ import androidx.tv.material3.Surface
|
||||||
import androidx.tv.material3.SurfaceDefaults
|
import androidx.tv.material3.SurfaceDefaults
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.preferences.AppPreferences
|
|
||||||
import com.github.damontecres.wholphin.preferences.LiveTvPreferences
|
import com.github.damontecres.wholphin.preferences.LiveTvPreferences
|
||||||
|
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.wholphin.ui.components.CircularProgress
|
import com.github.damontecres.wholphin.ui.components.CircularProgress
|
||||||
import com.github.damontecres.wholphin.ui.components.DialogItem
|
import com.github.damontecres.wholphin.ui.components.DialogItem
|
||||||
import com.github.damontecres.wholphin.ui.components.DialogParams
|
import com.github.damontecres.wholphin.ui.components.DialogParams
|
||||||
|
|
@ -57,6 +55,7 @@ import com.github.damontecres.wholphin.ui.data.RowColumn
|
||||||
import com.github.damontecres.wholphin.ui.ifElse
|
import com.github.damontecres.wholphin.ui.ifElse
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
|
import com.github.damontecres.wholphin.ui.rememberInt
|
||||||
import com.github.damontecres.wholphin.ui.rememberPosition
|
import com.github.damontecres.wholphin.ui.rememberPosition
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
|
|
@ -75,14 +74,14 @@ import kotlin.math.abs
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TvGuideGrid(
|
fun TvGuideGrid(
|
||||||
|
preferences: UserPreferences,
|
||||||
onRowPosition: (Int) -> Unit,
|
onRowPosition: (Int) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: LiveTvViewModel = hiltViewModel(),
|
viewModel: LiveTvViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsState()
|
||||||
val preferences by viewModel.preferences.data
|
val preferences by viewModel.preferences.data.collectAsState(preferences.appPreferences)
|
||||||
.collectAsState(AppPreferences.getDefaultInstance())
|
|
||||||
val tvPrefs = preferences.interfacePreferences.liveTvPreferences
|
val tvPrefs = preferences.interfacePreferences.liveTvPreferences
|
||||||
var showViewOptions by remember { mutableStateOf(false) }
|
var showViewOptions by remember { mutableStateOf(false) }
|
||||||
var showChannelDialog by remember { mutableStateOf<Pair<Int, TvChannel>?>(null) }
|
var showChannelDialog by remember { mutableStateOf<Pair<Int, TvChannel>?>(null) }
|
||||||
|
|
@ -196,11 +195,11 @@ fun TvGuideGrid(
|
||||||
showItemDialog = index
|
showItemDialog = index
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
focusRequester = focusRequester,
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(MaterialTheme.colorScheme.background)
|
.background(MaterialTheme.colorScheme.background),
|
||||||
.focusRequester(focusRequester),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -308,6 +307,7 @@ fun TvGuideGridContent(
|
||||||
onClickChannel: (Int, TvChannel) -> Unit,
|
onClickChannel: (Int, TvChannel) -> Unit,
|
||||||
onClickProgram: (Int, TvProgram) -> Unit,
|
onClickProgram: (Int, TvProgram) -> Unit,
|
||||||
onFocus: (RowColumn) -> Unit,
|
onFocus: (RowColumn) -> Unit,
|
||||||
|
focusRequester: FocusRequester,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
@ -315,8 +315,10 @@ fun TvGuideGridContent(
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val guideStart = remember(guideTimes) { guideTimes.first() }
|
val guideStart = remember(guideTimes) { guideTimes.first() }
|
||||||
|
|
||||||
|
var focusedChannelIndex by rememberInt(-1)
|
||||||
var focusedItem by rememberPosition(RowColumn(0, 0))
|
var focusedItem by rememberPosition(RowColumn(0, 0))
|
||||||
var focusedProgramIndex by remember { mutableIntStateOf(0) }
|
var focusedProgramIndex by rememberInt(0)
|
||||||
|
|
||||||
LaunchedEffect(onFocus, focusedProgramIndex) {
|
LaunchedEffect(onFocus, focusedProgramIndex) {
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
val program = programs.programs.getOrNull(focusedProgramIndex)
|
val program = programs.programs.getOrNull(focusedProgramIndex)
|
||||||
|
|
@ -358,16 +360,13 @@ fun TvGuideGridContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(modifier = modifier) {
|
Box(
|
||||||
|
modifier = modifier,
|
||||||
|
) {
|
||||||
ProgramGuide(
|
ProgramGuide(
|
||||||
state = state,
|
state = state,
|
||||||
dimensions = tvGuideDimensions,
|
dimensions = tvGuideDimensions,
|
||||||
modifier =
|
modifier = Modifier.fillMaxSize(),
|
||||||
Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.focusProperties {
|
|
||||||
onEnter = { programFocusRequester.tryRequestFocus() }
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
guideStartHour = 0f
|
guideStartHour = 0f
|
||||||
currentTime(
|
currentTime(
|
||||||
|
|
@ -465,8 +464,12 @@ fun TvGuideGridContent(
|
||||||
.ifElse(
|
.ifElse(
|
||||||
programIndex == focusedProgramIndex,
|
programIndex == focusedProgramIndex,
|
||||||
Modifier.focusRequester(programFocusRequester),
|
Modifier.focusRequester(programFocusRequester),
|
||||||
|
).ifElse(
|
||||||
|
focusedChannelIndex < 0 && programIndex == focusedProgramIndex,
|
||||||
|
Modifier.focusRequester(focusRequester),
|
||||||
).onFocusChanged {
|
).onFocusChanged {
|
||||||
if (it.isFocused) {
|
if (it.isFocused) {
|
||||||
|
focusedChannelIndex = -1
|
||||||
focusedProgramIndex = programIndex
|
focusedProgramIndex = programIndex
|
||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
|
|
@ -497,8 +500,12 @@ fun TvGuideGridContent(
|
||||||
onLongClick = {},
|
onLongClick = {},
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.onFocusChanged {
|
.ifElse(
|
||||||
|
focusedChannelIndex == channelIndex,
|
||||||
|
Modifier.focusRequester(focusRequester),
|
||||||
|
).onFocusChanged {
|
||||||
if (it.isFocused) {
|
if (it.isFocused) {
|
||||||
|
focusedChannelIndex = channelIndex
|
||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
state.animateToChannel(
|
state.animateToChannel(
|
||||||
|
|
|
||||||
|
|
@ -808,6 +808,7 @@ fun SearchPage(
|
||||||
position = position,
|
position = position,
|
||||||
focusRequester = focusRequesters[SEERR_ROW],
|
focusRequester = focusRequesters[SEERR_ROW],
|
||||||
onClickItem = onClickItem,
|
onClickItem = onClickItem,
|
||||||
|
onClickDiscover = onClickDiscover,
|
||||||
onClickPosition = { position = it },
|
onClickPosition = { position = it },
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -628,12 +628,11 @@ class MpvPlayer(
|
||||||
|
|
||||||
MPVProperty.PAUSED_FOR_CACHE -> {
|
MPVProperty.PAUSED_FOR_CACHE -> {
|
||||||
Timber.v("paused-for-cache %s", value)
|
Timber.v("paused-for-cache %s", value)
|
||||||
|
val newState = if (value) STATE_BUFFERING else STATE_READY
|
||||||
playbackState.update {
|
playbackState.update {
|
||||||
it.copy(
|
it.copy(state = newState)
|
||||||
state = if (value) STATE_BUFFERING else it.state,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
notifyListeners(EVENT_PLAYBACK_STATE_CHANGED) { onPlaybackStateChanged(playbackState.load().state) }
|
notifyListeners(EVENT_PLAYBACK_STATE_CHANGED) { onPlaybackStateChanged(newState) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -842,6 +841,7 @@ class MpvPlayer(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
notifyListeners(EVENT_IS_LOADING_CHANGED) { onIsLoadingChanged(true) }
|
notifyListeners(EVENT_IS_LOADING_CHANGED) { onIsLoadingChanged(true) }
|
||||||
|
notifyListeners(EVENT_PLAYBACK_STATE_CHANGED) { onPlaybackStateChanged(STATE_READY) }
|
||||||
val url =
|
val url =
|
||||||
media.mediaItem.localConfiguration
|
media.mediaItem.localConfiguration
|
||||||
?.uri
|
?.uri
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue