More bug fixes (#45)

Fixes:
* Issue from #39 where pressing back from playback went back two screens
instead of one
* Sometimes having to click on a server twice to switch to it
* Update UI when marking a single season as watched
* Fix needing to press back twice to hide skip segment buttons
* Fix skip intro/outro behaviors being swapped
* Always attempt to save playback progress when stopping playback
This commit is contained in:
damontecres 2025-10-19 22:35:47 -04:00 committed by GitHub
parent 95a74b73ff
commit 77aaa87126
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 51 additions and 35 deletions

View file

@ -135,6 +135,8 @@ class MainActivity : AppCompatActivity() {
val initialDestination =
if (server != null && user != null) {
Destination.Home()
} else if (server != null) {
Destination.UserList
} else {
Destination.ServerList
}
@ -164,4 +166,11 @@ class MainActivity : AppCompatActivity() {
}
}
}
override fun onPause() {
if (navigationManager.backStack.lastOrNull() is Destination.Playback) {
navigationManager.goBack()
}
super.onPause()
}
}

View file

@ -127,11 +127,7 @@ fun SeriesDetails(
season,
onClickItem = { viewModel.navigateTo(it.destination()) },
markPlayed = { played ->
viewModel.setWatched(
season.id,
played,
null,
)
viewModel.setSeasonWatched(season.id, played)
},
)
},

View file

@ -220,7 +220,7 @@ class SeriesViewModel
itemId: UUID,
played: Boolean,
listIndex: Int?,
) = viewModelScope.launch(ExceptionHandler()) {
) = viewModelScope.launch(Dispatchers.IO + ExceptionHandler()) {
if (played) {
api.playStateApi.markPlayedItem(itemId)
} else {
@ -231,6 +231,16 @@ class SeriesViewModel
}
}
fun setSeasonWatched(
seasonId: UUID,
played: Boolean,
) = viewModelScope.launch(Dispatchers.IO + ExceptionHandler()) {
setWatched(seasonId, played, null)
val series = fetchItem(seriesId, null)
val seasons = getSeasons(series)
this@SeriesViewModel.seasons.setValueOnMain(seasons)
}
fun setWatchedSeries(played: Boolean) =
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
if (played) {

View file

@ -373,32 +373,32 @@ fun PlaybackPage(
currentSegment = currentSegment,
)
}
}
// Ask to skip intros, etc button
AnimatedVisibility(
showSegment,
modifier =
Modifier
.padding(40.dp)
.align(Alignment.BottomEnd),
) {
currentSegment?.let { segment ->
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.tryRequestFocus()
delay(10.seconds)
segmentCancelled = false
}
Button(
onClick = {
player.seekTo(segment.endTicks.ticks.inWholeMilliseconds)
},
modifier = Modifier.focusRequester(focusRequester),
) {
Text(
text = "Skip ${segment.type.serialName}",
)
}
// Ask to skip intros, etc button
AnimatedVisibility(
showSegment,
modifier =
Modifier
.padding(40.dp)
.align(Alignment.BottomEnd),
) {
currentSegment?.let { segment ->
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.tryRequestFocus()
delay(10.seconds)
segmentCancelled = false
}
Button(
onClick = {
player.seekTo(segment.endTicks.ticks.inWholeMilliseconds)
},
modifier = Modifier.focusRequester(focusRequester),
) {
Text(
text = "Skip ${segment.type.serialName}",
)
}
}
}

View file

@ -619,8 +619,8 @@ class PlaybackViewModel
MediaSegmentType.COMMERCIAL -> prefs.skipCommercials
MediaSegmentType.PREVIEW -> prefs.skipPreviews
MediaSegmentType.RECAP -> prefs.skipRecaps
MediaSegmentType.OUTRO -> prefs.skipIntros
MediaSegmentType.INTRO -> prefs.skipOutros
MediaSegmentType.OUTRO -> prefs.skipOutros
MediaSegmentType.INTRO -> prefs.skipIntros
MediaSegmentType.UNKNOWN -> SkipSegmentBehavior.IGNORE
}
withContext(Dispatchers.Main) {
@ -731,8 +731,8 @@ class PlaybackViewModel
}
fun release() {
activityListener?.release()
player.release()
navigationManager.goBack()
}
}

View file

@ -92,11 +92,12 @@ class TrackActivityPlaybackListener(
fun release() {
task.cancel()
TIMER.purge()
val position = player.currentPosition.milliseconds.inWholeTicks
coroutineScope.launch(Dispatchers.IO + ExceptionHandler()) {
api.playStateApi.reportPlaybackStopped(
PlaybackStopInfo(
itemId = itemPlayback.itemId,
positionTicks = withContext(Dispatchers.Main) { player.currentPosition.milliseconds.inWholeTicks },
positionTicks = position,
failed = false,
playSessionId = playback.playSessionId,
),