userinterface.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // localizing all of the functions required to construct the user interface
  2. package itashi
  3. import (
  4. "fmt"
  5. "time"
  6. tea "github.com/charmbracelet/bubbletea"
  7. )
  8. const SPRING_EQUINOX = 81
  9. const SUMMER_SOLSTICE = 173
  10. const AUTUMN_EQUINOX = 265
  11. const WINTER_SOLSTICE = 356
  12. func getSeason(dayofyear int) string {
  13. if dayofyear > 365 {
  14. return "[REDACTED]"
  15. }
  16. if dayofyear < 0 {
  17. return "[REDACTED]"
  18. }
  19. if dayofyear > 0 && dayofyear < SPRING_EQUINOX {
  20. return "Winter"
  21. }
  22. if dayofyear > SPRING_EQUINOX && dayofyear < SUMMER_SOLSTICE {
  23. return "Spring"
  24. }
  25. if dayofyear > SUMMER_SOLSTICE && dayofyear < AUTUMN_EQUINOX {
  26. return "Summer"
  27. }
  28. if dayofyear > AUTUMN_EQUINOX && dayofyear < WINTER_SOLSTICE {
  29. return "Autumn"
  30. }
  31. if dayofyear > WINTER_SOLSTICE && dayofyear < 365 {
  32. return "Winter"
  33. }
  34. return "Dont know how you got here...."
  35. }
  36. type model struct {
  37. choices []string
  38. cursor int
  39. selected map[int]struct{}
  40. }
  41. func InitialModel() model {
  42. shelf := NewFilesystemShelf(FS_SAVE_LOCATION)
  43. shelf.AddTask(Task{Id: 1, Title: "This is a sample task", Desc: "Quick sample task that im testing the storage with",
  44. Due: time.Now().AddDate(0, 0, 2), Done: false, Priority: 1})
  45. return model{
  46. // Our to-do list is a grocery list
  47. choices: GetTaskNames(shelf.GetAll()),
  48. // A map which indicates which choices are selected. We're using
  49. // the map like a mathematical set. The keys refer to the indexes
  50. // of the `choices` slice, above.
  51. selected: make(map[int]struct{}),
  52. }
  53. }
  54. func (m model) Init() tea.Cmd {
  55. // Just return `nil`, which means "no I/O right now, please."
  56. return nil
  57. }
  58. func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
  59. switch msg := msg.(type) {
  60. // Is it a key press?
  61. case tea.KeyMsg:
  62. // Cool, what was the actual key pressed?
  63. switch msg.String() {
  64. // These keys should exit the program.
  65. case "ctrl+c", "q":
  66. return m, tea.Quit
  67. // The "up" and "k" keys move the cursor up
  68. case "up", "k":
  69. if m.cursor > 0 {
  70. m.cursor--
  71. }
  72. // The "down" and "j" keys move the cursor down
  73. case "down", "j":
  74. if m.cursor < len(m.choices)-1 {
  75. m.cursor++
  76. }
  77. // The "enter" key and the spacebar (a literal space) toggle
  78. // the selected state for the item that the cursor is pointing at.
  79. case "enter", " ":
  80. _, ok := m.selected[m.cursor]
  81. if ok {
  82. delete(m.selected, m.cursor)
  83. } else {
  84. m.selected[m.cursor] = struct{}{}
  85. }
  86. }
  87. }
  88. // Return the updated model to the Bubble Tea runtime for processing.
  89. // Note that we're not returning a command.
  90. return m, nil
  91. }
  92. func (m model) View() string {
  93. // The header
  94. rn := time.Now()
  95. rnString := fmt.Sprintf("%s %v, %v", rn.Month().String(), rn.Day(), rn.Year())
  96. season := getSeason(rn.YearDay())
  97. solsticeDiff := 10
  98. day := rn.Weekday()
  99. timenow := fmt.Sprintf("%v:%v %s", rn.Hour(), rn.Minute(), "AM")
  100. toEod := 5
  101. toSd := 6
  102. s := fmt.Sprintf(
  103. `
  104. %s %s, %v days until the next solstice.
  105. %s
  106. %s (%vH, %vM -> EoD, %vH, %vM -> sunset)
  107. `, rnString, season, solsticeDiff, day, timenow, toEod, toEod, toSd, toSd)
  108. // Iterate over our choices
  109. for i, choice := range m.choices {
  110. // Is the cursor pointing at this choice?
  111. cursor := " " // no cursor
  112. if m.cursor == i {
  113. cursor = ">" // cursor!
  114. }
  115. // Is this choice selected?
  116. checked := " " // not selected
  117. if _, ok := m.selected[i]; ok {
  118. checked = "x" // selected!
  119. }
  120. // Render the row
  121. s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
  122. }
  123. // The footer
  124. s += "\nPress q to quit.\n"
  125. // Send the UI for rendering
  126. return s
  127. }