mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-11-05 18:30:59 +01:00
Several UI fixes (#1730)
## Description - Fixes not scrolling to the last season on series overview if there is a Specials season - Apply the "bouncing" fix from #1543 to all applicable card types - Fix card images not automatically reloading when changing image type on grid pages - Get rid of the sticky headers which overlap items on view options dialogs and use a fixed header as elsewhere in the app ### Related issues Related to #1708 which didn't introduce the bug, but made it much more likely to occur ### Testing Emulator & unit tests ## Screenshots N/A, the sticky header UI changes are very minor ## AI or LLM usage None
This commit is contained in:
parent
2aae7eed38
commit
0a4ab7a547
12 changed files with 159 additions and 130 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package com.github.damontecres.wholphin.ui.cards
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
||||
|
|
@ -219,13 +218,11 @@ fun BannerCardWithTitle(
|
|||
useSeriesForPrimary: Boolean = item?.useSeriesForPrimary ?: true,
|
||||
) {
|
||||
val focused by interactionSource.collectIsFocusedAsState()
|
||||
val spaceBetween by animateDpAsState(if (focused) 12.dp else 4.dp)
|
||||
val spaceBelow by animateDpAsState(if (focused) 0.dp else 8.dp)
|
||||
val focusedAfterDelay by rememberFocusedAfterDelay(interactionSource)
|
||||
val aspectRationToUse = aspectRatio.coerceAtLeast(AspectRatios.MIN)
|
||||
val width = cardHeight * aspectRationToUse
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(spaceBetween),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = modifier.width(width),
|
||||
) {
|
||||
BannerCard(
|
||||
|
|
@ -245,13 +242,7 @@ fun BannerCardWithTitle(
|
|||
imageContentScale = imageContentScale,
|
||||
useSeriesForPrimary = useSeriesForPrimary,
|
||||
)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(bottom = spaceBelow)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
SlidingCardText(focused) {
|
||||
Text(
|
||||
text = title ?: "",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ fun DiscoverItemCard(
|
|||
width: Dp = Cards.height2x3 * AspectRatios.TALL,
|
||||
) {
|
||||
val focused by interactionSource.collectIsFocusedAsState()
|
||||
val spaceBetween by animateDpAsState(if (focused) 12.dp else 4.dp)
|
||||
val spaceBelow by animateDpAsState(if (focused) 4.dp else 12.dp)
|
||||
var focusedAfterDelay by remember { mutableStateOf(false) }
|
||||
|
||||
val hideOverlayDelay = 500L
|
||||
|
|
@ -78,7 +76,7 @@ fun DiscoverItemCard(
|
|||
}
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(spaceBetween),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = modifier.size(width, Dp.Unspecified),
|
||||
) {
|
||||
Card(
|
||||
|
|
@ -180,13 +178,7 @@ fun DiscoverItemCard(
|
|||
}
|
||||
}
|
||||
}
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(bottom = spaceBelow)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
SlidingCardText(focused) {
|
||||
Text(
|
||||
text = item?.title ?: "",
|
||||
maxLines = 1,
|
||||
|
|
|
|||
|
|
@ -51,8 +51,6 @@ fun EpisodeCard(
|
|||
) {
|
||||
val dto = item?.data
|
||||
val focused by interactionSource.collectIsFocusedAsState()
|
||||
val spaceBetween by animateDpAsState(if (focused) 12.dp else 4.dp)
|
||||
val spaceBelow by animateDpAsState(if (focused) 4.dp else 12.dp)
|
||||
var focusedAfterDelay by remember { mutableStateOf(false) }
|
||||
|
||||
val hideOverlayDelay = 500L
|
||||
|
|
@ -74,7 +72,7 @@ fun EpisodeCard(
|
|||
val density = LocalDensity.current
|
||||
val imageWidthPx = remember(imageWidth) { with(density) { imageWidth.roundToPx() } }
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(spaceBetween),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = modifier.size(width, height),
|
||||
) {
|
||||
Card(
|
||||
|
|
@ -126,13 +124,7 @@ fun EpisodeCard(
|
|||
}
|
||||
}
|
||||
}
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(bottom = spaceBelow)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
SlidingCardText(focused) {
|
||||
Text(
|
||||
text = dto?.seriesName ?: "",
|
||||
maxLines = 1,
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ fun GridCard(
|
|||
) {
|
||||
val dto = item?.data
|
||||
val focused by interactionSource.collectIsFocusedAsState()
|
||||
val spaceBetween by animateDpAsState(if (focused) 12.dp else 4.dp)
|
||||
val spaceBelow by animateDpAsState(if (focused) 4.dp else 12.dp)
|
||||
var focusedAfterDelay by remember { mutableStateOf(false) }
|
||||
|
||||
val hideOverlayDelay = 500L
|
||||
|
|
@ -71,7 +69,7 @@ fun GridCard(
|
|||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(spaceBetween),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = modifier,
|
||||
) {
|
||||
Card(
|
||||
|
|
@ -107,13 +105,7 @@ fun GridCard(
|
|||
)
|
||||
}
|
||||
AnimatedVisibility(showTitle) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(bottom = spaceBelow)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
SlidingCardText(focused) {
|
||||
Text(
|
||||
text = item?.title ?: "",
|
||||
maxLines = 1,
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ fun ItemCardImage(
|
|||
) {
|
||||
val imageUrlService = LocalImageUrlService.current
|
||||
val imageUrl =
|
||||
remember(item) {
|
||||
remember(item, imageType, fillWidth, fillHeight) {
|
||||
item?.let {
|
||||
imageUrlService.getItemImageUrl(
|
||||
item,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.github.damontecres.wholphin.ui.cards
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
|
|
@ -11,7 +10,6 @@ import androidx.compose.foundation.layout.Column
|
|||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
|
|
@ -26,11 +24,9 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.layout
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.tv.material3.Border
|
||||
|
|
@ -99,10 +95,6 @@ fun PersonCard(
|
|||
focusedAfterDelay = false
|
||||
}
|
||||
|
||||
// Do not use `by` here, this way we are Defer reads and recompositions to only when modifier calculates
|
||||
val spaceBetweenState = animateDpAsState(if (focused) 12.dp else 4.dp, label = "spaceBetween")
|
||||
val spaceBelowState = animateDpAsState(if (focused) 4.dp else 12.dp, label = "spaceBelow")
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp), // Fixed base spacing
|
||||
modifier = modifier,
|
||||
|
|
@ -170,21 +162,7 @@ fun PersonCard(
|
|||
.clip(CircleShape),
|
||||
)
|
||||
}
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
// Optimization: move animation reads to layout/draw phase
|
||||
.offset {
|
||||
IntOffset(0, (spaceBetweenState.value - 4.dp).roundToPx())
|
||||
}.layout { measurable, constraints ->
|
||||
val paddingPx = spaceBelowState.value.roundToPx()
|
||||
val placeable = measurable.measure(constraints)
|
||||
layout(placeable.width, placeable.height + paddingPx) {
|
||||
placeable.placeRelative(0, 0)
|
||||
}
|
||||
}.fillMaxWidth(),
|
||||
) {
|
||||
SlidingCardText(focused) {
|
||||
Text(
|
||||
text = name ?: "",
|
||||
maxLines = 1,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
package com.github.damontecres.wholphin.ui.cards
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.layout
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Slides the [content] up/down as the card is [focused] or not
|
||||
*
|
||||
* This is used for the card's title, moving it down when focused as the card itself scales up
|
||||
*/
|
||||
@Composable
|
||||
fun SlidingCardText(
|
||||
focused: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
spaceBetweenFocused: Dp = 4.dp,
|
||||
spaceBetweenUnfocused: Dp = 12.dp,
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
val spaceBetween =
|
||||
animateDpAsState(
|
||||
if (focused) spaceBetweenFocused else spaceBetweenUnfocused,
|
||||
label = "spaceBetween",
|
||||
)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
modifier
|
||||
.layout { measurable, constraints ->
|
||||
val topPaddingPx = (spaceBetweenUnfocused - spaceBetween.value).roundToPx()
|
||||
val bottomPaddingPx = spaceBetween.value.roundToPx()
|
||||
val placeable = measurable.measure(constraints)
|
||||
layout(placeable.width, placeable.height + bottomPaddingPx + topPaddingPx) {
|
||||
placeable.placeRelative(0, topPaddingPx)
|
||||
}
|
||||
}.fillMaxWidth(),
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
|
@ -53,8 +53,6 @@ fun ViewMoreCard(
|
|||
showTitle: Boolean = true,
|
||||
) {
|
||||
val focused by interactionSource.collectIsFocusedAsState()
|
||||
val spaceBetween by animateDpAsState(if (focused) 12.dp else 4.dp)
|
||||
val spaceBelow by animateDpAsState(if (focused) 4.dp else 12.dp)
|
||||
var focusedAfterDelay by remember { mutableStateOf(false) }
|
||||
|
||||
val hideOverlayDelay = 500L
|
||||
|
|
@ -79,7 +77,7 @@ fun ViewMoreCard(
|
|||
size.height.takeIf { it.isSpecified } ?: (size.height * (1f / aspectRatio.ratio))
|
||||
}
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(spaceBetween),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = modifier,
|
||||
) {
|
||||
Card(
|
||||
|
|
@ -108,14 +106,7 @@ fun ViewMoreCard(
|
|||
}
|
||||
}
|
||||
if (showTitle) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier =
|
||||
Modifier
|
||||
.width(width)
|
||||
.padding(bottom = spaceBelow),
|
||||
) {
|
||||
SlidingCardText(focused) {
|
||||
Text(
|
||||
text = stringResource(R.string.view_more),
|
||||
maxLines = 1,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,11 @@ import android.view.Gravity
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
|
|
@ -19,6 +22,7 @@ import androidx.compose.ui.focus.FocusRequester
|
|||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
|
|
@ -74,45 +78,52 @@ fun ViewOptionsDialog(
|
|||
ViewOptionsType.DENSE_LIST -> ViewOptions.LIST_OPTIONS
|
||||
}
|
||||
}
|
||||
LazyColumn(
|
||||
state = columnState,
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.width(256.dp)
|
||||
.heightIn(max = 380.dp)
|
||||
.focusRequester(focusRequester)
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceColorAtElevation(6.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
),
|
||||
) {
|
||||
stickyHeader {
|
||||
Text(
|
||||
text = stringResource(R.string.view_options),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
}
|
||||
items(options, key = { it.title }) { pref ->
|
||||
pref as AppPreference<ViewOptions, Any>
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val value = pref.getter.invoke(viewOptions)
|
||||
ComposablePreference(
|
||||
preference = pref,
|
||||
value = value,
|
||||
onNavigate = {},
|
||||
onValueChange = { newValue ->
|
||||
onViewOptionsChange.invoke(pref.setter(viewOptions, newValue))
|
||||
},
|
||||
interactionSource = interactionSource,
|
||||
modifier = Modifier,
|
||||
onClickPreference = { pref ->
|
||||
if (pref == ViewOptions.ViewOptionsReset) {
|
||||
onViewOptionsChange.invoke(defaultViewOptions)
|
||||
}
|
||||
},
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.view_options),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
LazyColumn(
|
||||
state = columnState,
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier = Modifier.focusRequester(focusRequester),
|
||||
) {
|
||||
items(options, key = { it.title }) { pref ->
|
||||
pref as AppPreference<ViewOptions, Any>
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val value = pref.getter.invoke(viewOptions)
|
||||
ComposablePreference(
|
||||
preference = pref,
|
||||
value = value,
|
||||
onNavigate = {},
|
||||
onValueChange = { newValue ->
|
||||
onViewOptionsChange.invoke(pref.setter(viewOptions, newValue))
|
||||
},
|
||||
interactionSource = interactionSource,
|
||||
modifier = Modifier,
|
||||
onClickPreference = { pref ->
|
||||
if (pref == ViewOptions.ViewOptionsReset) {
|
||||
onViewOptionsChange.invoke(defaultViewOptions)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,11 @@ import android.view.Gravity
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
|
|
@ -19,6 +22,7 @@ import androidx.compose.ui.focus.FocusRequester
|
|||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
|
|
@ -54,40 +58,47 @@ fun LiveTvViewOptionsDialog(
|
|||
window.setGravity(Gravity.END)
|
||||
window.setDimAmount(0f)
|
||||
}
|
||||
LazyColumn(
|
||||
state = columnState,
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.width(256.dp)
|
||||
.heightIn(max = 380.dp)
|
||||
.focusRequester(focusRequester)
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceColorAtElevation(6.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
),
|
||||
) {
|
||||
stickyHeader {
|
||||
Text(
|
||||
text = stringResource(R.string.view_options),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
}
|
||||
items(liveTvPreferences) { pref ->
|
||||
pref as AppPreference<AppPreferences, Any>
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val value = pref.getter.invoke(preferences)
|
||||
ComposablePreference(
|
||||
preference = pref,
|
||||
value = value,
|
||||
onNavigate = {},
|
||||
onValueChange = { newValue ->
|
||||
onViewOptionsChange.invoke(pref.setter(preferences, newValue))
|
||||
},
|
||||
interactionSource = interactionSource,
|
||||
modifier = Modifier,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.view_options),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
LazyColumn(
|
||||
state = columnState,
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||
modifier = Modifier.focusRequester(focusRequester),
|
||||
) {
|
||||
items(liveTvPreferences) { pref ->
|
||||
pref as AppPreference<AppPreferences, Any>
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val value = pref.getter.invoke(preferences)
|
||||
ComposablePreference(
|
||||
preference = pref,
|
||||
value = value,
|
||||
onNavigate = {},
|
||||
onValueChange = { newValue ->
|
||||
onViewOptionsChange.invoke(pref.setter(preferences, newValue))
|
||||
},
|
||||
interactionSource = interactionSource,
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@ suspend fun findIndexByNumberOrId(
|
|||
// Start searching from the target number and choose direction from there
|
||||
val num = list.getBlocking(listIndex)?.indexNumber
|
||||
if (num.lt(targetNum)) {
|
||||
for (i in listIndex + 1 until list.lastIndex) {
|
||||
for (i in listIndex + 1 until list.size) {
|
||||
val item = list.getBlocking(i)
|
||||
if (checkNumberOrId(targetNum, targetId, item?.indexNumber, item?.id)) {
|
||||
return i
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class TestFindIndexByNumberOrId {
|
|||
val epS02E03 = create(3, 2)
|
||||
val epS02E04 = create(4, 2)
|
||||
val epS02E05 = create(5, 2)
|
||||
val epS02E06 = create(6, 2)
|
||||
val epS00E08 = create(8, 0)
|
||||
val epS00E02 = create(2, 0)
|
||||
|
||||
|
|
@ -70,6 +71,30 @@ class TestFindIndexByNumberOrId {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Test last index with zero start`() =
|
||||
runTest {
|
||||
val episodes =
|
||||
BlockingList.of(
|
||||
listOf(
|
||||
create(0, 2),
|
||||
epS02E01,
|
||||
epS02E02,
|
||||
epS02E03,
|
||||
epS02E04,
|
||||
epS02E05,
|
||||
epS02E06,
|
||||
),
|
||||
)
|
||||
findIndexByNumberOrId(
|
||||
targetNum = 6,
|
||||
targetId = epS02E06.id,
|
||||
list = BlockingList.of(episodes),
|
||||
).let { index ->
|
||||
Assert.assertEquals(6, index)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Test missing episodes`() =
|
||||
runTest {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue