Club shortcut: a rail group for "where is my club on tonight"
Some checks failed
Build TV app / build (push) Failing after 2s
Some checks failed
Build TV app / build (push) Failing after 2s
Adds an optional rail entry per club that lists every channel whose EPG mentions the club within the next three hours, with the matching kick-off instead of the usual Now/Next. Only sport and free-to-air groups are scanned (NFL excluded), so the scan stays cheap and quiet. Which clubs appear is a per-TV setting: the signed-in viewer's own club is on by default, and every club can be switched on or off under Einstellungen -> Vereinsmenüs, so a household can follow more than one. Crests are trademarks, so the icon is a plain shield in the club colours. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import androidx.compose.runtime.setValue
|
||||
import dev.castarr.tv.auth.DeviceAuth
|
||||
import dev.castarr.tv.data.DispatcharrRepository
|
||||
import dev.castarr.tv.data.NowNext
|
||||
import dev.castarr.tv.data.isEpgPlaceholder
|
||||
import dev.castarr.tv.data.SourceRepository
|
||||
import dev.castarr.tv.player.PlayerController
|
||||
import dev.castarr.tv.playlist.Channel
|
||||
@@ -38,6 +39,30 @@ class AppState(
|
||||
var isLive by mutableStateOf(false)
|
||||
var favoritesOnly by mutableStateOf(false)
|
||||
var groupFilter by mutableStateOf<String?>(null)
|
||||
|
||||
/** Club shortcut currently open in the rail, if any. */
|
||||
var activeTeam by mutableStateOf<String?>(null)
|
||||
|
||||
/**
|
||||
* Club menus switched on for this TV. Seeded from the signed-in viewer's
|
||||
* own club; every club can be toggled on in the settings, so a household
|
||||
* can watch for more than one.
|
||||
*/
|
||||
var enabledTeams by mutableStateOf(loadEnabledTeams())
|
||||
private set
|
||||
|
||||
private fun loadEnabledTeams(): Set<String> {
|
||||
val stored = prefs.getStringSet("teams", null)
|
||||
if (stored != null) return stored.toSet()
|
||||
return setOfNotNull(dev.castarr.tv.data.TeamFilters.defaultKeyFor(auth.username))
|
||||
}
|
||||
|
||||
fun toggleTeam(key: String) {
|
||||
enabledTeams =
|
||||
if (key in enabledTeams) enabledTeams - key else enabledTeams + key
|
||||
prefs.edit().putStringSet("teams", enabledTeams).apply()
|
||||
if (activeTeam == key && key !in enabledTeams) activeTeam = null
|
||||
}
|
||||
var audioTracks by mutableStateOf<List<PlayerController.AudioTrack>>(emptyList())
|
||||
private set
|
||||
private var lastNowTitle: String? = null
|
||||
@@ -132,6 +157,29 @@ class AppState(
|
||||
SourceMode.DISPATCHARR -> dispatcharr.nowNext(channel)
|
||||
}
|
||||
|
||||
private fun upcoming(channel: Channel, windowMs: Long) = when (sourceMode) {
|
||||
SourceMode.GENERIC -> source.upcoming(channel, windowMs)
|
||||
SourceMode.DISPATCHARR -> dispatcharr.upcoming(channel, windowMs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Channels showing the viewer's club within the scanned window, paired
|
||||
* with the programme that matched — earliest kick-off first, so whatever
|
||||
* is running right now sits on top.
|
||||
*/
|
||||
fun teamMatches(key: String): List<Pair<Channel, dev.castarr.tv.data.Programme>> {
|
||||
val filter = dev.castarr.tv.data.TeamFilters.byKey(key) ?: return emptyList()
|
||||
val window = dev.castarr.tv.data.TeamFilters.WINDOW_MS
|
||||
return activeChannels()
|
||||
.filter { dev.castarr.tv.data.TeamFilters.scansGroup(it.group) }
|
||||
.mapNotNull { channel ->
|
||||
upcoming(channel, window)
|
||||
.firstOrNull { !isEpgPlaceholder(it.title) && filter.matches(it.title) }
|
||||
?.let { channel to it }
|
||||
}
|
||||
.sortedBy { it.second.start }
|
||||
}
|
||||
|
||||
fun refreshActive() {
|
||||
when (sourceMode) {
|
||||
SourceMode.GENERIC -> source.refresh()
|
||||
@@ -168,6 +216,8 @@ class AppState(
|
||||
}
|
||||
|
||||
fun startOnboarding() {
|
||||
prefs.edit().remove("teams").apply()
|
||||
activeTeam = null
|
||||
auth.logout()
|
||||
appError = AppError.NONE
|
||||
welcomePhase = WelcomePhase.WAIT_PHONE
|
||||
|
||||
Reference in New Issue
Block a user