Skip to content

Commit

Permalink
Consolidate clocks
Browse files Browse the repository at this point in the history
  • Loading branch information
wyne authored and oz committed Aug 29, 2024
1 parent 6e62971 commit 0bdd6e2
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 75 deletions.
18 changes: 9 additions & 9 deletions clock.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ func (c *Clock) AddDays(n int) {
c.t = c.t.AddDate(0, 0, n)
}

// AddDays adds n days to the current date.
// AddDays adds n days to the current date and clears the minutes
func (c *Clock) AddHours(n int) {
c.t = time.Date(
c.t.Year(), // Year
c.t.Month(), // Month
c.t.Day(), // Day
c.t.Hour(), // Hour
0, // Minutes set to 0
0, // Seconds set to 0
0, // Nanoseconds set to 0
c.t.Location(), // Location (timezone)
c.t.Year(),
c.t.Month(),
c.t.Day(),
c.t.Hour(),
0, // Minutes set to 0
0, // Seconds set to 0
0, // Nanoseconds set to 0
c.t.Location(),
)
c.t = c.t.Add(time.Hour * time.Duration(n))
}
Expand Down
5 changes: 2 additions & 3 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,15 @@ func LoadConfig(tzConfigs []string) (*Config, error) {
zones := make([]*Zone, len(tzConfigs)+1)

// Setup with Local time zone
now := Now.Time()
localZoneName, _ := now.Zone()
localZoneName, _ := time.Now().Zone()
zones[0] = &Zone{
Name: fmt.Sprintf("(%s) Local", localZoneName),
DbName: localZoneName,
}

// Add zones from TZ_LIST
for i, zoneConf := range tzConfigs {
zone, err := SetupZone(now, zoneConf)
zone, err := SetupZone(time.Now(), zoneConf)
if err != nil {
return nil, err
}
Expand Down
58 changes: 26 additions & 32 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ const CurrentVersion = "0.7.0"
var (
term = termenv.ColorProfile()
hasDarkBackground = termenv.HasDarkBackground()

// Now is used around tz to share/set the current time.
Now *Clock = NewClock(0)
)

type tickMsg time.Time
Expand Down Expand Up @@ -75,8 +72,7 @@ func openInTimeAndDateDotCom(t time.Time) error {

type model struct {
zones []*Zone
now time.Time
hour int
clock Clock
showDates bool
interactive bool
isMilitary bool
Expand All @@ -103,39 +99,28 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Quit

case "left", "h":
if m.hour == 0 {
m.hour = 23
} else {
m.hour--
}
Now.AddHours(-1)
m.clock.AddHours(-1)

case "right", "l":
if m.hour > 22 {
m.hour = 0
} else {
m.hour++
}
Now.AddHours(1)
m.clock.AddHours(1)

case "H":
Now.AddDays(-1)
m.clock.AddDays(-1)

case "L":
Now.AddDays(1)
m.clock.AddDays(1)

case "<":
Now.AddDays(-7)
m.clock.AddDays(-7)

case ">":
Now.AddDays(7)
m.clock.AddDays(7)

case "o":
openInTimeAndDateDotCom(Now.Time())
openInTimeAndDateDotCom(m.clock.Time())

case "t":
Now = NewClock(0)
m.hour = Now.Time().Hour()
m.clock = *NewClock(0)

case "?":
m.showHelp = !m.showHelp
Expand All @@ -146,9 +131,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

case tickMsg:
if m.watch {
m.now = time.Time(msg)
Now = NewClock(0)
m.hour = Now.Time().Hour()
m.clock = *NewClock(0)
}
return m, tick()
}
Expand Down Expand Up @@ -179,29 +162,40 @@ func main() {
os.Exit(0)
}

if *when != 0 {
Now = NewClock(*when)
}
config, err := LoadConfig(flag.Args())
if err != nil {
fmt.Fprintf(os.Stderr, "Config error: %s\n", err)
os.Exit(2)
}
var initialModel = model{
zones: config.Zones,
now: Now.Time(),
hour: Now.Time().Hour(),
clock: *NewClock(0),
showDates: false,
isMilitary: *military,
watch: *watch,
showHelp: false,
}

if *when != 0 {
initialModel.clock = *NewClock(*when)
}

initialModel.interactive = !*exitQuick

// if len(os.Getenv("DEBUG")) > 0 {
// f, err := tea.LogToFile("debug.log", "debug")
// if err != nil {
// fmt.Println("fatal:", err)
// os.Exit(1)
// }
// defer f.Close()
// }

p := tea.NewProgram(initialModel)
if err := p.Start(); err != nil {
fmt.Printf("Alas, there's been an error: %v", err)
os.Exit(1)
}

// loadConfigFile()
}
39 changes: 27 additions & 12 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,27 @@ package main
import (
"strings"
"testing"
"time"

tea "github.com/charmbracelet/bubbletea"
)

func getTimestampWithHour(hour int) int64 {
if hour == -1 {
hour = time.Now().Hour()
}
return time.Date(
time.Now().Year(),
time.Now().Month(),
time.Now().Day(),
hour,
0, // Minutes set to 0
0, // Seconds set to 0
0, // Nanoseconds set to 0
time.Now().Location(),
).Unix()
}

func TestUpdateIncHour(t *testing.T) {
// "l" key -> go right
msg := tea.KeyMsg{
Expand All @@ -45,19 +62,18 @@ func TestUpdateIncHour(t *testing.T) {
for _, test := range tests {
m := model{
zones: DefaultZones,
hour: test.startHour,
clock: *NewClock(getTimestampWithHour(test.startHour)),
}

// Do we enjoy global mutable state?
db := Now.Time().Day()
db := m.clock.Time().Day()
nextState, cmd := m.Update(msg)
da := Now.Time().Day()
da := m.clock.Time().Day()

if cmd != nil {
t.Errorf("Expected nil Cmd, but got %v", cmd)
return
}
h := nextState.(model).hour
h := nextState.(model).clock.t.Hour()
if h != test.nextHour {
t.Errorf("Expected %d, but got %d", test.nextHour, h)
}
Expand Down Expand Up @@ -88,14 +104,14 @@ func TestUpdateDecHour(t *testing.T) {
for _, test := range tests {
m := model{
zones: DefaultZones,
hour: test.startHour,
clock: *NewClock(getTimestampWithHour(test.startHour)),
}
nextState, cmd := m.Update(msg)
if cmd != nil {
t.Errorf("Expected nil Cmd, but got %v", cmd)
return
}
h := nextState.(model).hour
h := nextState.(model).clock.t.Hour()
if h != test.nextHour {
t.Errorf("Expected %d, but got %d", test.nextHour, h)
}
Expand All @@ -112,7 +128,7 @@ func TestUpdateQuitMsg(t *testing.T) {

m := model{
zones: DefaultZones,
hour: 10,
clock: *NewClock(getTimestampWithHour(-1)),
}
_, cmd := m.Update(msg)
if cmd == nil {
Expand All @@ -126,13 +142,12 @@ func TestUpdateQuitMsg(t *testing.T) {
func TestMilitaryTime(t *testing.T) {
m := model{
zones: DefaultZones,
hour: 14,
now: Now.Time(),
clock: *NewClock(getTimestampWithHour(-1)),
isMilitary: true,
showDates: true,
}
s := m.View()
if !strings.Contains(s, m.now.Format("15:04")) {
t.Errorf("Expected military time of %s, but got %s", m.now.Format("15:04"), s)
if !strings.Contains(s, m.clock.t.Format("15:04")) {
t.Errorf("Expected military time of %s, but got %s", m.clock.t.Format("15:04"), s)
}
}
14 changes: 7 additions & 7 deletions view.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (m model) View() string {

startHour := 0
if zi > 0 {
startHour = (zone.currentTime().Hour() - m.zones[0].currentTime().Hour()) % 24
startHour = (zone.currentTime(m.clock.t).Hour() - m.zones[0].currentTime(m.clock.t).Hour()) % 24
}

dateChanged := false
Expand All @@ -46,7 +46,7 @@ func (m model) View() string {

out = out.Foreground(term.Color(hourColorCode(hour)))
// Cursor
if m.hour == i-startHour {
if m.clock.t.Hour() == i-startHour {
out = out.Background(term.Color(hourColorCode(hour)))
if hasDarkBackground {
out = out.Foreground(term.Color("#262626")).Bold()
Expand All @@ -72,12 +72,12 @@ func (m model) View() string {

var datetime string
if m.isMilitary {
datetime = zone.ShortMT()
datetime = zone.ShortMT(m.clock.t)
} else {
datetime = zone.ShortDT()
datetime = zone.ShortDT(m.clock.t)
}

zoneHeader := fmt.Sprintf("%s %-60s %76s", zone.ClockEmoji(), normalTextStyle(zone.String()), dateTimeStyle(datetime))
zoneHeader := fmt.Sprintf("%s %-60s %76s", zone.ClockEmoji(m.clock.t), normalTextStyle(zone.String()), dateTimeStyle(datetime))

s += fmt.Sprintf(" %s\n %s\n %s\n", zoneHeader, hours.String(), dates.String())
}
Expand Down Expand Up @@ -117,8 +117,8 @@ func status(m model) string {
}

func formatDayChange(m *model, z *Zone) string {
zTime := z.currentTime()
if zTime.Hour() > m.now.Hour() {
zTime := z.currentTime(m.clock.t)
if zTime.Hour() > m.clock.t.Hour() {
zTime = zTime.AddDate(0, 0, 1)
}

Expand Down
23 changes: 11 additions & 12 deletions zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,30 +57,29 @@ func (z Zone) String() string {
}

// ClockEmoji returns the corresponding emoji clock for a given hour
func (z Zone) ClockEmoji() string {
h := ((z.currentTime().Hour() % 12) + 12) % 12
func (z Zone) ClockEmoji(t time.Time) string {
h := ((z.currentTime(t).Hour() % 12) + 12) % 12
return EmojiClocks[h]
}

// ShortDT returns the current time in short format.
func (z Zone) ShortDT() string {
return z.currentTime().Format("3:04PM, Mon Jan 02, 2006")
func (z Zone) ShortDT(t time.Time) string {
return z.currentTime(t).Format("3:04PM, Mon Jan 02, 2006")
}

// ShortMT returns the current military time in short format.
func (z Zone) ShortMT() string {
return z.currentTime().Format("15:04, Mon Jan 02, 2006")
func (z Zone) ShortMT(t time.Time) string {
return z.currentTime(t).Format("15:04, Mon Jan 02, 2006")
}

func (z Zone) currentTime() time.Time {
now := Now.Time()
zName, _ := now.Zone()
func (z Zone) currentTime(t time.Time) time.Time {
zName, _ := t.Zone()
if z.DbName != zName {
loc, err := time.LoadLocation(z.DbName)
if err != nil {
return now
return t
}
return now.In(loc)
return t.In(loc)
}
return now
return t
}

0 comments on commit 0bdd6e2

Please sign in to comment.