158 lines
5 KiB
Go
158 lines
5 KiB
Go
package tui
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.skdevstudios.com/SK-Development-Studios/go-cal-tui/internal/storage"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
)
|
|
|
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
switch m.mode {
|
|
case monthView:
|
|
return m.updateMonthView(msg)
|
|
case hourlyView:
|
|
return m.updateHourlyView(msg)
|
|
default:
|
|
return m, nil
|
|
}
|
|
}
|
|
|
|
func (m model) updateMonthView(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
firstDay := time.Date(m.year, time.Month(m.monthIndex+1), 1, 0, 0, 0, 0, time.UTC)
|
|
m.startOffset = int(firstDay.Weekday())
|
|
m.daysInMonth = time.Date(m.year, time.Month(m.monthIndex+2), 0, 0, 0, 0, 0, time.UTC).Day()
|
|
|
|
switch msg := msg.(type) {
|
|
|
|
case tea.WindowSizeMsg:
|
|
m.width = msg.Width
|
|
m.height = msg.Height
|
|
case tea.KeyMsg:
|
|
switch msg.String() {
|
|
case "ctrl+c", "q":
|
|
return m, tea.Quit
|
|
case "a": // Previous month
|
|
if m.monthIndex == 0 {
|
|
m.monthIndex = 11
|
|
m.year--
|
|
} else {
|
|
m.monthIndex--
|
|
}
|
|
case "d": // Next month
|
|
if m.monthIndex == 11 {
|
|
m.monthIndex = 0
|
|
m.year++
|
|
} else {
|
|
m.monthIndex++
|
|
}
|
|
case "up":
|
|
if m.cursorRow > 0 {
|
|
m.cursorRow--
|
|
}
|
|
case "down":
|
|
if m.cursorRow < numRows-1 {
|
|
m.cursorRow++
|
|
}
|
|
case "left":
|
|
if m.cursorCol > 0 {
|
|
m.cursorCol--
|
|
}
|
|
case "right":
|
|
if m.cursorCol < numCols-1 {
|
|
m.cursorCol++
|
|
}
|
|
case "enter":
|
|
dayIndex := m.cursorRow*numCols + m.cursorCol
|
|
if dayIndex >= m.startOffset && dayIndex < m.startOffset+m.daysInMonth {
|
|
m.selectedDay = dayIndex - m.startOffset + 1
|
|
m.hourCursor = 0
|
|
m.mode = hourlyView
|
|
fmt.Print("\033[H\033[2J") // Clear terminal screen
|
|
}
|
|
}
|
|
|
|
// Clamp cursor to valid days
|
|
dayIndex := m.cursorRow*numCols + m.cursorCol
|
|
if dayIndex < m.startOffset || dayIndex >= m.startOffset+m.daysInMonth {
|
|
m.cursorRow = m.startOffset / numCols
|
|
m.cursorCol = m.startOffset % numCols
|
|
}
|
|
return m, nil
|
|
default:
|
|
return m, nil
|
|
}
|
|
return m, nil // ← This is the missing line
|
|
|
|
}
|
|
|
|
func (m model) updateHourlyView(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
switch msg.String() {
|
|
case "n":
|
|
showEventForm(func(e storage.EventInput) {
|
|
_ = storage.SaveEvent(e)
|
|
})
|
|
case "e":
|
|
event, err := storage.GetEvent(int32(m.year), int32(m.monthIndex+1), int32(m.selectedDay), int32(m.hourCursor))
|
|
if err != nil || event == nil {
|
|
break // No event to edit at this hour
|
|
}
|
|
|
|
// Create editable input struct
|
|
input := storage.EventInput{
|
|
Title: event.Title,
|
|
Description: event.Description,
|
|
Year: event.Year,
|
|
Month: event.Month,
|
|
Day: event.Day,
|
|
StartHour: event.StartHour,
|
|
EndHour: event.EndHour,
|
|
Color: event.Color,
|
|
}
|
|
|
|
showEditForm(&input, func(updated storage.EventInput) {
|
|
_ = storage.EditEvent(event.Year, event.Month, event.Day, event.StartHour, updated)
|
|
})
|
|
|
|
case "x": // or "delete"
|
|
event, err := storage.GetEvent(int32(m.year), int32(m.monthIndex+1), int32(m.selectedDay), int32(m.hourCursor))
|
|
if err != nil || event == nil {
|
|
break // No event to delete
|
|
}
|
|
|
|
input := storage.EventInput{
|
|
Title: event.Title,
|
|
Description: event.Description,
|
|
Year: event.Year,
|
|
Month: event.Month,
|
|
Day: event.Day,
|
|
StartHour: event.StartHour,
|
|
EndHour: event.EndHour,
|
|
Color: event.Color,
|
|
}
|
|
|
|
showDeleteConfirm(&input, func() {
|
|
_ = storage.DeleteEvent(event.Year, event.Month, event.Day, event.StartHour)
|
|
})
|
|
case "esc":
|
|
m.mode = monthView
|
|
fmt.Print("\033[H\033[2J") // Clear terminal screen
|
|
return m, nil
|
|
case "ctrl+c", "q":
|
|
return m, tea.Quit
|
|
case "up":
|
|
if m.hourCursor > 0 {
|
|
m.hourCursor--
|
|
}
|
|
case "down":
|
|
if m.hourCursor < 23 {
|
|
m.hourCursor++
|
|
}
|
|
}
|
|
}
|
|
return m, nil
|
|
}
|