Lascia trasmissibili le partite anche dopo l'orario previsto.
Se l'operatore è in ritardo deve ancora trovare la gara nell'app: restano in hub per tutta la giornata e, nei tornei aperti, fino alla fine dell'evento. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -51,3 +51,11 @@ private fun parseInstantOrNull(value: String): Instant? {
|
||||
}
|
||||
|
||||
fun Instant.isScheduledFuture(now: Instant = Instant.now()): Boolean = isAfter(now)
|
||||
|
||||
fun Instant.isScheduledOnCalendar(
|
||||
now: Instant = Instant.now(),
|
||||
zone: ZoneId = ZoneId.of("Europe/Rome"),
|
||||
): Boolean {
|
||||
val startOfToday = now.atZone(zone).toLocalDate().atStartOfDay(zone).toInstant()
|
||||
return !isBefore(startOfToday)
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
package com.matchlivetv.match_live_tv.domain
|
||||
|
||||
import com.matchlivetv.match_live_tv.core.isScheduledFuture
|
||||
import com.matchlivetv.match_live_tv.core.isScheduledOnCalendar
|
||||
import com.matchlivetv.match_live_tv.core.parseApiInstant
|
||||
import java.time.Instant
|
||||
|
||||
/** Partite visibili nell'hub coach: dirette attive, wizard in corso, programmate future. */
|
||||
/** Partite visibili nell'hub coach: dirette attive, wizard in corso, in calendario oggi o future. */
|
||||
fun Match.isCoachHubVisible(now: Instant = Instant.now()): Boolean {
|
||||
coachHubVisible?.let { return it }
|
||||
|
||||
@@ -15,7 +15,7 @@ fun Match.isCoachHubVisible(now: Instant = Instant.now()): Boolean {
|
||||
if (streamCompleted) return false
|
||||
|
||||
val scheduled = parseApiInstant(scheduledAt)
|
||||
return scheduled != null && scheduled.isScheduledFuture(now)
|
||||
return scheduled != null && scheduled.isScheduledOnCalendar(now)
|
||||
}
|
||||
|
||||
fun List<Match>.coachHubVisible(now: Instant = Instant.now()): List<Match> =
|
||||
|
||||
+1
-3
@@ -47,8 +47,6 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.matchlivetv.match_live_tv.R
|
||||
import com.matchlivetv.match_live_tv.core.isScheduledFuture
|
||||
import com.matchlivetv.match_live_tv.core.parseApiInstant
|
||||
import com.matchlivetv.match_live_tv.data.AppContainer
|
||||
import com.matchlivetv.match_live_tv.data.repository.MatchSessionLauncher
|
||||
import com.matchlivetv.match_live_tv.domain.Match
|
||||
@@ -161,7 +159,7 @@ fun MatchesScreen(
|
||||
(match.hasActiveSession && match.activeSessionStatus == "idle")
|
||||
}
|
||||
val scheduledMatches = matches.filter { match ->
|
||||
!match.hasActiveSession && parseApiInstant(match.scheduledAt)?.isScheduledFuture() == true
|
||||
!match.hasActiveSession && !match.scheduledAt.isNullOrBlank()
|
||||
}
|
||||
val draftMatches = matches.filter { !it.hasActiveSession && it.scheduledAt == null }
|
||||
val calendarMatches = (scheduledMatches + draftMatches).distinctBy { it.id }
|
||||
|
||||
+16
-1
@@ -10,7 +10,22 @@ class ApiInstantTest {
|
||||
fun parseApiInstant_railsOffsetWithMillis() {
|
||||
val instant = parseApiInstant("2026-06-06T20:00:00.000+02:00")
|
||||
assertNotNull(instant)
|
||||
assertTrue(instant!!.isScheduledFuture(Instant.parse("2026-06-06T16:00:00Z")))
|
||||
assertTrue(instant!!.isScheduledOnCalendar(Instant.parse("2026-06-06T16:00:00Z")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isScheduledOnCalendar_keepsThisMorningAfterKickoff() {
|
||||
val kickoff = Instant.parse("2026-09-06T07:00:00Z")
|
||||
val now = Instant.parse("2026-09-06T08:30:00Z")
|
||||
assertTrue(kickoff.isScheduledOnCalendar(now))
|
||||
assertTrue(!kickoff.isScheduledFuture(now))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isScheduledOnCalendar_hidesYesterday() {
|
||||
val yesterday = Instant.parse("2026-09-05T10:00:00Z")
|
||||
val now = Instant.parse("2026-09-06T08:30:00Z")
|
||||
assertTrue(!yesterday.isScheduledOnCalendar(now))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -19,6 +19,14 @@ enum ApiInstant {
|
||||
return date > now
|
||||
}
|
||||
|
||||
static func isScheduledOnCalendar(_ raw: String?, now: Date = Date()) -> Bool {
|
||||
guard let date = parse(raw) else { return false }
|
||||
var calendar = Calendar(identifier: .gregorian)
|
||||
calendar.timeZone = TimeZone(identifier: "Europe/Rome") ?? .current
|
||||
let startOfToday = calendar.startOfDay(for: now)
|
||||
return date >= startOfToday
|
||||
}
|
||||
|
||||
static func formatMatchDate(_ raw: String?) -> String? {
|
||||
guard let date = parse(raw) else { return nil }
|
||||
let f = DateFormatter()
|
||||
|
||||
@@ -12,13 +12,17 @@ enum MatchHubFilter {
|
||||
}
|
||||
if match.streamCompleted { return false }
|
||||
|
||||
return ApiInstant.isScheduledFuture(match.scheduledAt, now: now)
|
||||
return ApiInstant.isScheduledOnCalendar(match.scheduledAt, now: now)
|
||||
}
|
||||
|
||||
static func isScheduledFuture(_ match: Match, now: Date = Date()) -> Bool {
|
||||
ApiInstant.isScheduledFuture(match.scheduledAt, now: now)
|
||||
}
|
||||
|
||||
static func isOnCalendar(_ match: Match, now: Date = Date()) -> Bool {
|
||||
ApiInstant.isScheduledOnCalendar(match.scheduledAt, now: now)
|
||||
}
|
||||
|
||||
static func isDraft(_ match: Match) -> Bool {
|
||||
!match.hasActiveSession && (match.scheduledAt == nil || match.scheduledAt?.isEmpty == true)
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ struct MatchesScreen: View {
|
||||
}
|
||||
|
||||
private var scheduledMatches: [Match] {
|
||||
matches.filter { !$0.hasActiveSession && MatchHubFilter.isScheduledFuture($0) }
|
||||
matches.filter { !$0.hasActiveSession && !($0.scheduledAt ?? "").isEmpty }
|
||||
}
|
||||
|
||||
private var calendarMatches: [Match] {
|
||||
|
||||
Reference in New Issue
Block a user