Create recordings

This commit is contained in:
Damontecres 2025-10-21 13:29:29 -04:00
parent 748101db74
commit fd853acdd5
No known key found for this signature in database
2 changed files with 71 additions and 17 deletions

View file

@ -9,6 +9,7 @@ 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.NavigationManager import com.github.damontecres.wholphin.ui.nav.NavigationManager
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.util.ExceptionHandler import com.github.damontecres.wholphin.util.ExceptionHandler
import com.github.damontecres.wholphin.util.GetProgramsDtoHandler import com.github.damontecres.wholphin.util.GetProgramsDtoHandler
import com.github.damontecres.wholphin.util.LoadingExceptionHandler import com.github.damontecres.wholphin.util.LoadingExceptionHandler
@ -20,10 +21,10 @@ import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.imageApi import org.jellyfin.sdk.api.client.extensions.imageApi
import org.jellyfin.sdk.api.client.extensions.liveTvApi import org.jellyfin.sdk.api.client.extensions.liveTvApi
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
import org.jellyfin.sdk.model.api.GetProgramsDto import org.jellyfin.sdk.model.api.GetProgramsDto
import org.jellyfin.sdk.model.api.ImageType import org.jellyfin.sdk.model.api.ImageType
import org.jellyfin.sdk.model.api.ItemSortBy import org.jellyfin.sdk.model.api.ItemSortBy
import org.jellyfin.sdk.model.api.TimerInfoDto
import org.jellyfin.sdk.model.api.request.GetLiveTvChannelsRequest import org.jellyfin.sdk.model.api.request.GetLiveTvChannelsRequest
import org.jellyfin.sdk.model.extensions.ticks import org.jellyfin.sdk.model.extensions.ticks
import timber.log.Timber import timber.log.Timber
@ -159,12 +160,12 @@ class LiveTvViewModel
} }
} }
fun getItem(itemId: UUID) { fun getItem(programId: UUID) {
fetchingItem.value = LoadingState.Loading fetchingItem.value = LoadingState.Loading
viewModelScope.launchIO(LoadingExceptionHandler(fetchingItem, "Error")) { viewModelScope.launchIO(LoadingExceptionHandler(fetchingItem, "Error")) {
val result = val result =
api.userLibraryApi api.liveTvApi
.getItem(itemId = itemId) .getProgram(programId.toServerString())
.content .content
.let { BaseItem.from(it, api) } .let { BaseItem.from(it, api) }
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
@ -175,6 +176,8 @@ class LiveTvViewModel
} }
fun cancelRecording( fun cancelRecording(
programIndex: Int,
programId: UUID,
series: Boolean, series: Boolean,
timerId: String?, timerId: String?,
) { ) {
@ -185,26 +188,68 @@ class LiveTvViewModel
} else { } else {
api.liveTvApi.cancelTimer(timerId) api.liveTvApi.cancelTimer(timerId)
} }
refreshProgram(programIndex, programId)
} }
} }
} }
suspend fun refreshProgram( fun record(
index: Int, programIndex: Int,
timerId: String?, programId: UUID,
seriesTimerId: String?, series: Boolean,
) { ) {
val newProgram = viewModelScope.launchIO {
programs.value?.getOrNull(index)?.copy( val d by api.liveTvApi.getDefaultTimer(programId.toServerString())
isRecording = timerId.isNotNullOrBlank(), if (series) {
isSeriesRecording = seriesTimerId.isNotNullOrBlank(), api.liveTvApi.createSeriesTimer(d)
} else {
val payload =
TimerInfoDto(
id = d.id,
type = d.type,
serverId = d.serverId,
externalId = d.externalId,
channelId = d.channelId,
externalChannelId = d.externalChannelId,
channelName = d.channelName,
programId = d.programId,
externalProgramId = d.externalProgramId,
name = d.name,
overview = d.overview,
startDate = d.startDate,
endDate = d.endDate,
serviceName = d.serviceName,
priority = d.priority,
prePaddingSeconds = d.prePaddingSeconds,
postPaddingSeconds = d.postPaddingSeconds,
isPrePaddingRequired = d.isPrePaddingRequired,
isPostPaddingRequired = d.isPostPaddingRequired,
keepUntil = d.keepUntil,
) )
api.liveTvApi.createTimer(payload)
}
refreshProgram(programIndex, programId)
}
}
suspend fun refreshProgram(
programIndex: Int,
programId: UUID,
) {
val program by api.liveTvApi.getProgram(programId.toServerString())
val newProgram =
programs.value?.getOrNull(programIndex)?.copy(
isRecording = program.timerId.isNotNullOrBlank(),
isSeriesRecording = program.seriesTimerId.isNotNullOrBlank(),
)
Timber.v("new program %s", newProgram)
if (newProgram != null) { if (newProgram != null) {
programs.value programs.value
?.toMutableList() ?.toMutableList()
?.apply { set(index, newProgram) } ?.apply {
?.let { this[programIndex] = newProgram
programs.setValueOnMain(it) }?.let {
this@LiveTvViewModel.programs.setValueOnMain(it)
} }
} }
} }

View file

@ -136,16 +136,25 @@ fun TvGuideGrid(
} }
}, },
onRecord = { series -> onRecord = { series ->
fetchedItem?.let {
viewModel.record(
programIndex = showItemDialog!!,
programId = it.id,
series = series,
)
}
onDismissRequest.invoke() onDismissRequest.invoke()
}, },
onCancelRecord = { series -> onCancelRecord = { series ->
onDismissRequest.invoke()
fetchedItem?.data?.let { fetchedItem?.data?.let {
viewModel.cancelRecording( viewModel.cancelRecording(
series, programIndex = showItemDialog!!,
if (series) it.seriesTimerId else it.timerId, programId = it.id,
series = series,
timerId = if (series) it.seriesTimerId else it.timerId,
) )
} }
onDismissRequest.invoke()
}, },
) )
} }