mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Clean up and protect against bad data
This commit is contained in:
parent
1ecbc37a07
commit
8f08f0d118
2 changed files with 34 additions and 77 deletions
|
|
@ -40,7 +40,7 @@ import javax.inject.Inject
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
const val MAX_HOURS = 3L
|
const val MAX_HOURS = 48L
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class LiveTvViewModel
|
class LiveTvViewModel
|
||||||
|
|
@ -64,10 +64,7 @@ class LiveTvViewModel
|
||||||
val fetchingItem = MutableLiveData<LoadingState>(LoadingState.Pending)
|
val fetchingItem = MutableLiveData<LoadingState>(LoadingState.Pending)
|
||||||
val fetchedItem = MutableLiveData<BaseItem?>(null)
|
val fetchedItem = MutableLiveData<BaseItem?>(null)
|
||||||
|
|
||||||
val offset = MutableLiveData(0)
|
|
||||||
val programOffset = MutableLiveData(0)
|
|
||||||
private val range = 8
|
private val range = 8
|
||||||
private var currentIndex = 0
|
|
||||||
val fetchedRange = MutableLiveData<IntRange>(0..<range)
|
val fetchedRange = MutableLiveData<IntRange>(0..<range)
|
||||||
|
|
||||||
fun init(firstLoad: Boolean) {
|
fun init(firstLoad: Boolean) {
|
||||||
|
|
@ -196,13 +193,21 @@ class LiveTvViewModel
|
||||||
channelProgramCount[channelId] = programs.size
|
channelProgramCount[channelId] = programs.size
|
||||||
}
|
}
|
||||||
val finalProgramList =
|
val finalProgramList =
|
||||||
(programs + fake).sortedWith(
|
(programs + fake)
|
||||||
compareBy(
|
.filterNot {
|
||||||
{ channelsIdToIndex[it.channelId]!! },
|
// TODO filter out items that start after end
|
||||||
{ it.start },
|
// This can happen due to daylight savings switch or just be bad data
|
||||||
),
|
it.startHours >= it.endHours
|
||||||
)
|
}.sortedWith(
|
||||||
|
compareBy(
|
||||||
|
{ channelsIdToIndex[it.channelId]!! },
|
||||||
|
{ it.start },
|
||||||
|
),
|
||||||
|
)
|
||||||
Timber.d("Got ${programs.size} programs & ${fake.size} fake programs")
|
Timber.d("Got ${programs.size} programs & ${fake.size} fake programs")
|
||||||
|
finalProgramList
|
||||||
|
.filter { it.startHours == it.endHours }
|
||||||
|
.let { Timber.e("Items with same start & end!!! %s", it) }
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
this@LiveTvViewModel.programs.value = finalProgramList
|
this@LiveTvViewModel.programs.value = finalProgramList
|
||||||
this@LiveTvViewModel.programsByChannel.value = finalProgramsByChannel
|
this@LiveTvViewModel.programsByChannel.value = finalProgramsByChannel
|
||||||
|
|
@ -336,11 +341,6 @@ class LiveTvViewModel
|
||||||
Timber.v("Loading more programs for channels $newFetchRange")
|
Timber.v("Loading more programs for channels $newFetchRange")
|
||||||
return viewModelScope.launchIO {
|
return viewModelScope.launchIO {
|
||||||
fetchPrograms(channels, newFetchRange)
|
fetchPrograms(channels, newFetchRange)
|
||||||
// withContext(Dispatchers.Main) {
|
|
||||||
// this@LiveTvViewModel.offset.value = fetchStart
|
|
||||||
// currentIndex = index
|
|
||||||
// this@LiveTvViewModel.programOffset.value = programOffset
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ fun TvGuideGrid(
|
||||||
val channels by viewModel.channels.observeAsState(listOf())
|
val channels by viewModel.channels.observeAsState(listOf())
|
||||||
val programs by viewModel.programs.observeAsState(listOf())
|
val programs by viewModel.programs.observeAsState(listOf())
|
||||||
val programsByChannel by viewModel.programsByChannel.observeAsState(mapOf())
|
val programsByChannel by viewModel.programsByChannel.observeAsState(mapOf())
|
||||||
val channelOffset by viewModel.offset.observeAsState(0)
|
val fetchedRange by viewModel.fetchedRange.observeAsState(0..0)
|
||||||
when (val state = loading) {
|
when (val state = loading) {
|
||||||
is LoadingState.Error -> ErrorMessage(state, modifier)
|
is LoadingState.Error -> ErrorMessage(state, modifier)
|
||||||
LoadingState.Pending,
|
LoadingState.Pending,
|
||||||
|
|
@ -107,7 +107,7 @@ fun TvGuideGrid(
|
||||||
programs = programsByChannel,
|
programs = programsByChannel,
|
||||||
channelProgramCount = viewModel.channelProgramCount,
|
channelProgramCount = viewModel.channelProgramCount,
|
||||||
start = viewModel.start,
|
start = viewModel.start,
|
||||||
channelOffset = channelOffset,
|
channelOffset = fetchedRange.start,
|
||||||
onClickChannel = { index, channel ->
|
onClickChannel = { index, channel ->
|
||||||
viewModel.navigationManager.navigateTo(
|
viewModel.navigationManager.navigateTo(
|
||||||
Destination.Playback(
|
Destination.Playback(
|
||||||
|
|
@ -209,8 +209,6 @@ fun TvGuideGrid(
|
||||||
val focusManager = LocalFocusManager.current
|
val focusManager = LocalFocusManager.current
|
||||||
val state = rememberSaveableProgramGuideState()
|
val state = rememberSaveableProgramGuideState()
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
// var focusedProgramIndex by rememberInt(0)
|
|
||||||
// var focusedChannelIndex by rememberInt(0)
|
|
||||||
|
|
||||||
var focusedItem by rememberPosition(RowColumn(0, 0))
|
var focusedItem by rememberPosition(RowColumn(0, 0))
|
||||||
val focusedChannelIndex = focusedItem.row
|
val focusedChannelIndex = focusedItem.row
|
||||||
|
|
@ -222,9 +220,9 @@ fun TvGuideGrid(
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(focusedProgramIndex) {
|
LaunchedEffect(focusedProgramIndex) {
|
||||||
val (channelIndex, programIndex) = focusedItem
|
// Timber.v("Focusing on $focusedItem, programIndex=$focusedProgramIndex")
|
||||||
Timber.v("Focusing on $focusedItem, programIndex=$focusedProgramIndex")
|
|
||||||
scope.launch(ExceptionHandler()) {
|
scope.launch(ExceptionHandler()) {
|
||||||
|
// Timber.v("program=${programList.getOrNull(focusedProgramIndex)}")
|
||||||
state.animateToProgram(focusedProgramIndex, Alignment.Center)
|
state.animateToProgram(focusedProgramIndex, Alignment.Center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -236,35 +234,6 @@ fun TvGuideGrid(
|
||||||
channelHeight = 80.dp,
|
channelHeight = 80.dp,
|
||||||
currentTimeWidth = 2.dp,
|
currentTimeWidth = 2.dp,
|
||||||
)
|
)
|
||||||
|
|
||||||
// val programsBeforeChannel =
|
|
||||||
// remember {
|
|
||||||
// CacheBuilder
|
|
||||||
// .newBuilder()
|
|
||||||
// .maximumSize(200)
|
|
||||||
// .build<Int, Int>(
|
|
||||||
// object : CacheLoader<Int, Int>() {
|
|
||||||
// override fun load(key: Int): Int =
|
|
||||||
// (
|
|
||||||
// channels
|
|
||||||
// .subList(0, key)
|
|
||||||
// .map { it.id }
|
|
||||||
// .sumOf {
|
|
||||||
// channelProgramCount[it] ?: 0
|
|
||||||
// } - programOffset
|
|
||||||
// ).coerceAtLeast(0)
|
|
||||||
// },
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
var movementEnabled by remember { mutableStateOf(true) }
|
|
||||||
// LaunchedEffect(programOffset) {
|
|
||||||
// movementEnabled = false
|
|
||||||
// programsBeforeChannel.invalidateAll()
|
|
||||||
// Timber.v("Adjusting focusedProgramIndex, $focusedProgramIndex - $programOffset")
|
|
||||||
// focusedProgramIndex = (focusedProgramIndex - programOffset).coerceAtLeast(0)
|
|
||||||
// movementEnabled = true
|
|
||||||
// }
|
|
||||||
|
|
||||||
var gridHasFocus by rememberSaveable { mutableStateOf(false) }
|
var gridHasFocus by rememberSaveable { mutableStateOf(false) }
|
||||||
var channelColumnFocused by rememberSaveable { mutableStateOf(false) }
|
var channelColumnFocused by rememberSaveable { mutableStateOf(false) }
|
||||||
Box(modifier = modifier) {
|
Box(modifier = modifier) {
|
||||||
|
|
@ -281,9 +250,6 @@ fun TvGuideGrid(
|
||||||
if (it.type == KeyEventType.KeyUp) {
|
if (it.type == KeyEventType.KeyUp) {
|
||||||
return@onPreviewKeyEvent false
|
return@onPreviewKeyEvent false
|
||||||
}
|
}
|
||||||
if (!movementEnabled) {
|
|
||||||
return@onPreviewKeyEvent true
|
|
||||||
}
|
|
||||||
val item = focusedItem
|
val item = focusedItem
|
||||||
val newFocusedItem =
|
val newFocusedItem =
|
||||||
when (it.key) {
|
when (it.key) {
|
||||||
|
|
@ -429,32 +395,23 @@ fun TvGuideGrid(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFocusedItem != null) {
|
if (newFocusedItem != null) {
|
||||||
focusedItem = newFocusedItem
|
val channel = channels[newFocusedItem.row]
|
||||||
onFocus(newFocusedItem)
|
val programs = programs[channel.id].orEmpty()
|
||||||
|
// Ensure it isn't going out of range
|
||||||
|
val toFocus =
|
||||||
|
newFocusedItem
|
||||||
|
.copy(
|
||||||
|
row = newFocusedItem.row.coerceIn(0, channels.size - 1),
|
||||||
|
column =
|
||||||
|
newFocusedItem.column.coerceIn(
|
||||||
|
0,
|
||||||
|
programs.size - 1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
focusedItem = toFocus
|
||||||
|
onFocus(toFocus)
|
||||||
return@onPreviewKeyEvent true
|
return@onPreviewKeyEvent true
|
||||||
}
|
}
|
||||||
// if (newIndex != null) {
|
|
||||||
// // Timber.v("newIndex=$newIndex")
|
|
||||||
// if (newIndex >= 0) {
|
|
||||||
// val before = programsBeforeChannel.get(focusedChannelIndex)
|
|
||||||
// val max =
|
|
||||||
// before +
|
|
||||||
// channels[focusedChannelIndex].let {
|
|
||||||
// programs[it.id]?.size ?: 0
|
|
||||||
// } - 1
|
|
||||||
// val index = newIndex.coerceIn(before, max)
|
|
||||||
// Timber.v("move: programIndex=$index, channelIndex=$focusedChannelIndex")
|
|
||||||
// scope.launch(ExceptionHandler()) {
|
|
||||||
// focusedProgramIndex = index
|
|
||||||
// state.animateToProgram(index, Alignment.Center)
|
|
||||||
// onFocusChannel.invoke(focusedChannelIndex)
|
|
||||||
// }
|
|
||||||
// return@onPreviewKeyEvent true
|
|
||||||
// } else {
|
|
||||||
// Timber.w("newIndex is <0: $newIndex")
|
|
||||||
// return@onPreviewKeyEvent true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return@onPreviewKeyEvent false
|
return@onPreviewKeyEvent false
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue