Manage recordings on dvr schedule page

This commit is contained in:
Damontecres 2025-10-21 14:33:59 -04:00
parent 724519a6fa
commit 9dd3813b35
No known key found for this signature in database
2 changed files with 56 additions and 4 deletions

View file

@ -12,7 +12,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
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
@ -34,7 +36,10 @@ import com.github.damontecres.wholphin.ui.SlimItemFields
import com.github.damontecres.wholphin.ui.components.ErrorMessage import com.github.damontecres.wholphin.ui.components.ErrorMessage
import com.github.damontecres.wholphin.ui.components.LoadingPage import com.github.damontecres.wholphin.ui.components.LoadingPage
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.NavigationManager
import com.github.damontecres.wholphin.ui.tryRequestFocus import com.github.damontecres.wholphin.ui.tryRequestFocus
import com.github.damontecres.wholphin.util.ExceptionHandler
import com.github.damontecres.wholphin.util.LoadingExceptionHandler import com.github.damontecres.wholphin.util.LoadingExceptionHandler
import com.github.damontecres.wholphin.util.LoadingState import com.github.damontecres.wholphin.util.LoadingState
import com.github.damontecres.wholphin.util.seasonEpisode import com.github.damontecres.wholphin.util.seasonEpisode
@ -53,13 +58,14 @@ class DvrScheduleViewModel
@Inject @Inject
constructor( constructor(
private val api: ApiClient, private val api: ApiClient,
val navigationManager: NavigationManager,
) : ViewModel() { ) : ViewModel() {
val loading = MutableLiveData<LoadingState>(LoadingState.Pending) val loading = MutableLiveData<LoadingState>(LoadingState.Loading)
val active = MutableLiveData<List<BaseItem>>() val active = MutableLiveData<List<BaseItem>>()
val scheduled = MutableLiveData<Map<LocalDate, List<BaseItem>>>() val scheduled = MutableLiveData<Map<LocalDate, List<BaseItem>>>()
fun init() { fun init() {
loading.value = LoadingState.Loading // loading.value = LoadingState.Loading
viewModelScope.launchIO(LoadingExceptionHandler(loading, "Error fetching DVR Schedule")) { viewModelScope.launchIO(LoadingExceptionHandler(loading, "Error fetching DVR Schedule")) {
val active = val active =
api.liveTvApi api.liveTvApi
@ -87,6 +93,20 @@ class DvrScheduleViewModel
} }
} }
} }
fun cancelRecording(
timerId: String,
series: Boolean,
) {
viewModelScope.launchIO(ExceptionHandler(autoToast = true)) {
if (series) {
api.liveTvApi.cancelSeriesTimer(timerId)
} else {
api.liveTvApi.cancelTimer(timerId)
}
init()
}
}
} }
@Composable @Composable
@ -109,6 +129,7 @@ fun DvrSchedule(
-> LoadingPage(modifier) -> LoadingPage(modifier)
LoadingState.Success -> { LoadingState.Success -> {
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) { focusRequester.tryRequestFocus() }
@ -116,11 +137,42 @@ fun DvrSchedule(
DvrScheduleContent( DvrScheduleContent(
activeRecordings = active, activeRecordings = active,
scheduledRecordings = recordings, scheduledRecordings = recordings,
onClickItem = {}, onClickItem = {
showDialog = it
},
modifier = modifier =
modifier modifier
.focusRequester(focusRequester), .focusRequester(focusRequester),
) )
showDialog?.let { item ->
ProgramDialog(
item = item,
loading = LoadingState.Success,
onDismissRequest = {
showDialog = null
},
onWatch = {
item.data.channelId?.let {
viewModel.navigationManager.navigateTo(
Destination.Playback(
itemId = it,
positionMs = 0L,
),
)
}
},
onRecord = {
// no-op
},
onCancelRecord = { series ->
showDialog = null
val timerId = if (series) item.data.seriesTimerId else item.data.timerId
if (timerId != null) {
viewModel.cancelRecording(timerId, series)
}
},
)
}
} }
} }
} }

View file

@ -197,7 +197,7 @@ class LiveTvViewModel
timerId: String?, timerId: String?,
) { ) {
if (timerId != null) { if (timerId != null) {
viewModelScope.launch(ExceptionHandler(autoToast = true)) { viewModelScope.launchIO(ExceptionHandler(autoToast = true)) {
if (series) { if (series) {
api.liveTvApi.cancelSeriesTimer(timerId) api.liveTvApi.cancelSeriesTimer(timerId)
fetchPrograms(channels.value.orEmpty()) fetchPrograms(channels.value.orEmpty())