mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 11:54:59 -04:00
Fixed Date Logic
This commit is contained in:
@@ -151,6 +151,24 @@ func (m *CalendarModel) ensureCursorVisible() {
|
||||
|
||||
func (m CalendarModel) findNextRaceIndex() int {
|
||||
now := time.Now()
|
||||
|
||||
// First: return the index of a meeting currently underway (started but not ended).
|
||||
for i, meeting := range m.meetings {
|
||||
start, err := time.Parse(time.RFC3339, meeting.DateStart)
|
||||
if err != nil {
|
||||
start, _ = time.Parse("2006-01-02", meeting.DateStart[:min(len(meeting.DateStart), 10)])
|
||||
}
|
||||
end, err2 := time.Parse(time.RFC3339, meeting.DateEnd)
|
||||
if err2 != nil {
|
||||
end, _ = time.Parse("2006-01-02", meeting.DateEnd[:min(len(meeting.DateEnd), 10)])
|
||||
end = end.Add(24 * time.Hour)
|
||||
}
|
||||
if now.After(start.Local()) && now.Before(end.Local()) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
// Second: return the next upcoming meeting (start is in the future).
|
||||
for i, meeting := range m.meetings {
|
||||
start, err := time.Parse(time.RFC3339, meeting.DateStart)
|
||||
if err != nil {
|
||||
|
||||
@@ -110,15 +110,30 @@ func (m DashboardModel) Update(msg tea.Msg) (DashboardModel, tea.Cmd) {
|
||||
m.meetings = msg.meetings
|
||||
now := time.Now()
|
||||
|
||||
// First priority: find a meeting that has already started but not yet ended
|
||||
// (i.e. we're currently in a GP weekend).
|
||||
for i := range m.meetings {
|
||||
mtg := m.meetings[i]
|
||||
start, _ := time.Parse(time.RFC3339, mtg.DateStart)
|
||||
end, _ := time.Parse(time.RFC3339, mtg.DateEnd)
|
||||
if now.Before(end.Local()) || now.Sub(end.Local()) < 24*time.Hour { // also keep showing for 24h after
|
||||
if now.After(start.Local()) && now.Before(end.Local().Add(24*time.Hour)) {
|
||||
m.next = &mtg
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Second priority: if no ongoing weekend, find the next upcoming meeting.
|
||||
if m.next == nil {
|
||||
for i := range m.meetings {
|
||||
mtg := m.meetings[i]
|
||||
start, _ := time.Parse(time.RFC3339, mtg.DateStart)
|
||||
if now.Before(start.Local()) {
|
||||
m.next = &mtg
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if m.next != nil {
|
||||
return m, fetchDashboardSessions(m.client, int(m.next.MeetingKey))
|
||||
}
|
||||
@@ -166,21 +181,32 @@ func (m DashboardModel) View() string {
|
||||
Foreground(lipgloss.Color(colorF1Red)).
|
||||
Bold(true)
|
||||
|
||||
// Determine if the weekend has started
|
||||
now := time.Now()
|
||||
meetingStart, _ := time.Parse(time.RFC3339, m.next.DateStart)
|
||||
meetingStart = meetingStart.Local()
|
||||
weekendUnderway := now.After(meetingStart)
|
||||
|
||||
sb.WriteString("\n")
|
||||
sb.WriteString(titleStyle.Render(fmt.Sprintf(" NEXT RACE: %s", m.next.MeetingOfficialName)) + "\n")
|
||||
if weekendUnderway {
|
||||
sb.WriteString(titleStyle.Render(fmt.Sprintf(" CURRENT RACE: %s", m.next.MeetingOfficialName)) + "\n")
|
||||
} else {
|
||||
sb.WriteString(titleStyle.Render(fmt.Sprintf(" NEXT RACE: %s", m.next.MeetingOfficialName)) + "\n")
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf(" %s • %s\n", countryFlag(m.next.CountryCode), m.next.Location))
|
||||
|
||||
now := time.Now()
|
||||
end, _ := time.Parse(time.RFC3339, m.next.DateEnd)
|
||||
endLocal := end.Local()
|
||||
|
||||
// Show countdown to first session if available, else use start date
|
||||
// Show countdown to next session if available, else use start date
|
||||
var nextStart time.Time
|
||||
var nextSession *models.Session
|
||||
startFound := false
|
||||
for _, s := range m.sessions {
|
||||
st, _ := time.Parse(time.RFC3339, s.DateStart)
|
||||
for i := range m.sessions {
|
||||
st, _ := time.Parse(time.RFC3339, m.sessions[i].DateStart)
|
||||
if now.Before(st.Local()) {
|
||||
nextStart = st.Local()
|
||||
nextSession = &m.sessions[i]
|
||||
startFound = true
|
||||
break
|
||||
}
|
||||
@@ -201,7 +227,11 @@ func (m DashboardModel) View() string {
|
||||
hours := int(diff.Hours()) % 24
|
||||
mins := int(diff.Minutes()) % 60
|
||||
secs := int(diff.Seconds()) % 60
|
||||
sb.WriteString(fmt.Sprintf(" Starts in: %dd %02dh %02dm %02ds\n", days, hours, mins, secs))
|
||||
if nextSession != nil {
|
||||
sb.WriteString(fmt.Sprintf(" Next: %s in %dd %02dh %02dm %02ds\n", nextSession.SessionName, days, hours, mins, secs))
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf(" Starts in: %dd %02dh %02dm %02ds\n", days, hours, mins, secs))
|
||||
}
|
||||
} else {
|
||||
sb.WriteString(" " + lipgloss.NewStyle().Foreground(lipgloss.Color(colorMuted)).Render("Weekend Finished") + "\n")
|
||||
}
|
||||
|
||||
@@ -141,17 +141,28 @@ func (m RaceDetailModel) Update(msg tea.Msg) (RaceDetailModel, tea.Cmd) {
|
||||
return m, nil
|
||||
}
|
||||
m.sessions = msg.sessions
|
||||
// Auto-select the Race session and load its data
|
||||
raceIdx := -1
|
||||
|
||||
// Auto-select the best session to show:
|
||||
// 1. The last session that has already started (ongoing or completed).
|
||||
// 2. If no session has started yet, fall back to the first session.
|
||||
now := time.Now()
|
||||
autoIdx := -1
|
||||
for i, s := range m.sessions {
|
||||
if s.SessionName == "Race" {
|
||||
raceIdx = i
|
||||
break
|
||||
st, err := time.Parse(time.RFC3339, s.DateStart)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if now.After(st.Local()) {
|
||||
autoIdx = i // keep updating — we want the LAST one that has started
|
||||
}
|
||||
}
|
||||
if raceIdx >= 0 {
|
||||
m.sessionCursor = raceIdx
|
||||
sess := m.sessions[raceIdx]
|
||||
if autoIdx < 0 && len(m.sessions) > 0 {
|
||||
autoIdx = 0 // nothing started yet, show first session
|
||||
}
|
||||
|
||||
if autoIdx >= 0 {
|
||||
m.sessionCursor = autoIdx
|
||||
sess := m.sessions[autoIdx]
|
||||
m.selectedSession = &sess
|
||||
m.loadingResults = true
|
||||
m.driversLoaded = false
|
||||
@@ -159,17 +170,7 @@ func (m RaceDetailModel) Update(msg tea.Msg) (RaceDetailModel, tea.Cmd) {
|
||||
m.results = nil
|
||||
m.rcMsgs = nil
|
||||
m.weather = nil
|
||||
m.drivers = make(map[int]models.Driver)
|
||||
cmds = append(cmds, m.spinner.Tick, fetchSessionData(m.client, sess.SessionKey))
|
||||
} else if len(m.sessions) > 0 {
|
||||
// Fallback: select last session
|
||||
lastIdx := len(m.sessions) - 1
|
||||
m.sessionCursor = lastIdx
|
||||
sess := m.sessions[lastIdx]
|
||||
m.selectedSession = &sess
|
||||
m.loadingResults = true
|
||||
m.driversLoaded = false
|
||||
m.secondaryLoading = false
|
||||
m.overtakes = nil
|
||||
m.drivers = make(map[int]models.Driver)
|
||||
cmds = append(cmds, m.spinner.Tick, fetchSessionData(m.client, sess.SessionKey))
|
||||
}
|
||||
|
||||
@@ -288,7 +288,15 @@ func renderPointsBar(points, maxPoints float64, width int, color string) string
|
||||
}
|
||||
|
||||
// meetingStatus returns a status indicator for a meeting.
|
||||
// isNext is true when this meeting is the "current or next" highlighted one.
|
||||
func meetingStatus(m models.Meeting, now time.Time, isNext bool) string {
|
||||
start, err := time.Parse(time.RFC3339, m.DateStart)
|
||||
if err != nil {
|
||||
start, _ = time.Parse("2006-01-02", m.DateStart[:min(len(m.DateStart), 10)])
|
||||
} else {
|
||||
start = start.Local()
|
||||
}
|
||||
|
||||
end, err := time.Parse(time.RFC3339, m.DateEnd)
|
||||
if err != nil {
|
||||
end, err = time.Parse("2006-01-02", m.DateEnd[:min(len(m.DateEnd), 10)])
|
||||
@@ -296,8 +304,14 @@ func meetingStatus(m models.Meeting, now time.Time, isNext bool) string {
|
||||
return " "
|
||||
}
|
||||
end = end.Add(24 * time.Hour)
|
||||
} else {
|
||||
end = end.Local()
|
||||
}
|
||||
|
||||
// Currently underway: started but not ended
|
||||
if now.After(start) && now.Before(end) {
|
||||
return styleNext.Render("▶")
|
||||
}
|
||||
if end.Before(now) {
|
||||
return stylePast.Render("✓")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user