Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/src/main/kotlin/com/arflix/tv/data/model/IptvModels.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ data class IptvChannel(
val logo: String? = null,
val epgId: String? = null,
val rawTitle: String = name,
val xtreamStreamId: Int? = null
val xtreamStreamId: Int? = null,
val catchupDays: Int = 0,
val catchupType: String? = null,
val catchupSource: String? = null
)

/**
Expand Down
204 changes: 181 additions & 23 deletions app/src/main/kotlin/com/arflix/tv/data/repository/IptvRepository.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,11 @@ class TvViewModel @Inject constructor(
private fun hasAnyEpgData(snapshot: IptvSnapshot): Boolean {
if (snapshot.nowNext.isEmpty()) return false
return snapshot.nowNext.values.any { item ->
item.now != null || item.next != null || item.later != null || item.upcoming.isNotEmpty()
item.now != null ||
item.next != null ||
item.later != null ||
item.upcoming.isNotEmpty() ||
item.recent.isNotEmpty()
}
}

Expand All @@ -376,7 +380,8 @@ class TvViewModel @Inject constructor(
item.now != null ||
item.next != null ||
item.later != null ||
item.upcoming.isNotEmpty()
item.upcoming.isNotEmpty() ||
item.recent.isNotEmpty()
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ fun CategorySidebar(
onFocusEnter: () -> Unit = {},
onMoveRight: () -> Unit = {},
onTopBoundaryFocusChanged: (Boolean) -> Unit = {},
focusSearchSignal: Int = 0,
modifier: Modifier = Modifier,
) {
val targetWidth = if (expanded) LiveDims.SidebarExpanded else LiveDims.SidebarCollapsed
Expand All @@ -110,6 +111,16 @@ fun CategorySidebar(
var expandedCountry by rememberSaveable { mutableStateOf<String?>(null) }
var expandedAll by rememberSaveable { mutableStateOf(false) }
var menuForGroup by rememberSaveable { mutableStateOf<String?>(null) }
val searchFocusRequester = remember { FocusRequester() }

LaunchedEffect(focusSearchSignal) {
if (focusSearchSignal > 0) {
repeat(3) {
runCatching { searchFocusRequester.requestFocus() }
delay(50L)
}
}
}

LaunchedEffect(selectedId, tree) {
val countryId = selectedCountryGroupId(selectedId, tree)
Expand Down Expand Up @@ -149,6 +160,7 @@ fun CategorySidebar(
onClick = onOpenSearch,
expanded = expanded,
onFocusChanged = onTopBoundaryFocusChanged,
focusRequester = searchFocusRequester,
)
Spacer(Modifier.height(8.dp))
LazyColumn(
Expand Down Expand Up @@ -316,6 +328,7 @@ private fun SearchEntry(
onClick: () -> Unit,
expanded: Boolean,
onFocusChanged: (Boolean) -> Unit = {},
focusRequester: FocusRequester? = null,
) {
var focused by remember { mutableStateOf(false) }
Row(
Expand All @@ -326,6 +339,7 @@ private fun SearchEntry(
focused = it.isFocused
onFocusChanged(it.isFocused)
}
.then(if (focusRequester != null) Modifier.focusRequester(focusRequester) else Modifier)
.border(
width = if (focused) 3.dp else 0.dp,
color = if (focused) LiveColors.FocusRing else Color.Transparent,
Expand Down Expand Up @@ -411,6 +425,7 @@ private fun SidebarRow(
isOpenGroup: Boolean = false,
indent: androidx.compose.ui.unit.Dp = 0.dp,
labelSize: androidx.compose.ui.unit.TextUnit = 11.sp,
focusRequester: FocusRequester? = null,
) {
var focused by remember { mutableStateOf(false) }
var consumedLongPress by remember { mutableStateOf(false) }
Expand Down Expand Up @@ -446,6 +461,7 @@ private fun SidebarRow(
focused = it.isFocused
if (it.isFocused) onFocused?.invoke()
}
.then(if (focusRequester != null) Modifier.focusRequester(focusRequester) else Modifier)
.border(
width = if (focused) 3.dp else 0.dp,
color = if (focused) LiveColors.FocusRing else Color.Transparent,
Expand Down
27 changes: 23 additions & 4 deletions app/src/main/kotlin/com/arflix/tv/ui/screens/tv/live/ChannelRow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.History
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator
Expand All @@ -39,6 +40,7 @@ import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -67,6 +69,8 @@ fun ChannelRow(
onClick: () -> Unit,
onFavoriteToggle: () -> Unit,
onMoveLeft: () -> Unit = {},
onMoveRight: () -> Boolean = { false },
onMoveUp: () -> Boolean = { false },
onFocused: () -> Unit = {},
rowHeight: androidx.compose.ui.unit.Dp = LiveDims.EpgRowHeight,
forceFocused: Boolean = false,
Expand Down Expand Up @@ -109,6 +113,16 @@ fun ChannelRow(
)
.background(if (visuallyFocused) LiveColors.PanelRaised else bg)
.focusable()
.onPreviewKeyEvent { ev ->
if (ev.type == KeyEventType.KeyDown) {
when (ev.key) {
Key.DirectionLeft -> { onMoveLeft(); return@onPreviewKeyEvent true }
Key.DirectionRight -> if (onMoveRight()) return@onPreviewKeyEvent true
Key.DirectionUp -> if (onMoveUp()) return@onPreviewKeyEvent true
}
}
false
}
.combinedClickable(
onClick = onClick,
onLongClick = onFavoriteToggle,
Expand All @@ -119,10 +133,6 @@ fun ChannelRow(
// repeatCount == 1) on CENTER / ENTER / MENU triggers favorite
// toggle, giving the user the "hold OK" gesture everywhere.
.onKeyEvent { ev ->
if (ev.type == KeyEventType.KeyDown && ev.key == Key.DirectionLeft) {
onMoveLeft()
return@onKeyEvent true
}
val isLongHoldCenter = ev.type == KeyEventType.KeyDown &&
(ev.key == Key.DirectionCenter || ev.key == Key.Enter) &&
ev.nativeKeyEvent.repeatCount == 1
Expand Down Expand Up @@ -185,6 +195,15 @@ fun ChannelRow(
modifier = Modifier.size(11.dp),
)
}
if (channel.catchupDays > 0) {
Spacer(Modifier.width(4.dp))
Icon(
imageVector = Icons.Filled.History,
contentDescription = "Catchup available",
tint = LiveColors.Accent.copy(alpha = 0.8f),
modifier = Modifier.size(11.dp),
)
}
}
// Only the thin progress underline stays here — programme info
// itself is shown exclusively in the time-aligned grid cells to
Expand Down
Loading
Loading