1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00
wtf/gcal/display.go
2018-11-28 14:47:06 +01:00

241 lines
5.2 KiB
Go

package gcal
import (
"fmt"
"regexp"
"strings"
"time"
"github.com/wtfutil/wtf/wtf"
)
func (widget *Widget) sortedEvents() ([]*CalEvent, []*CalEvent) {
allDayEvents := []*CalEvent{}
timedEvents := []*CalEvent{}
for _, calEvent := range widget.calEvents {
if calEvent.AllDay() {
allDayEvents = append(allDayEvents, calEvent)
} else {
timedEvents = append(timedEvents, calEvent)
}
}
return allDayEvents, timedEvents
}
func (widget *Widget) display() {
if widget.calEvents == nil || len(widget.calEvents) == 0 {
return
}
widget.mutex.Lock()
defer widget.mutex.Unlock()
widget.View.SetTitle(widget.ContextualTitle(widget.Name))
widget.View.SetText(widget.contentFrom(widget.calEvents))
}
func (widget *Widget) contentFrom(calEvents []*CalEvent) string {
if (calEvents == nil) || (len(calEvents) == 0) {
return ""
}
var str string
var prevEvent *CalEvent
if !wtf.Config.UBool("wtf.mods.gcal.showDeclined", false) {
calEvents = removeDeclined(calEvents)
}
for _, calEvent := range calEvents {
timestamp := fmt.Sprintf("[%s]%s", widget.descriptionColor(calEvent), calEvent.Timestamp())
if calEvent.AllDay() {
timestamp = ""
}
title := fmt.Sprintf("[%s]%s",
widget.titleColor(calEvent),
widget.eventSummary(calEvent, calEvent.ConflictsWith(calEvents)),
)
lineOne := fmt.Sprintf(
"%s %s %s %s[white]\n",
widget.dayDivider(calEvent, prevEvent),
widget.responseIcon(calEvent),
timestamp,
title,
)
str = str + fmt.Sprintf("%s %s%s\n",
lineOne,
widget.location(calEvent),
widget.timeUntil(calEvent),
)
if (widget.location(calEvent) != "") || (widget.timeUntil(calEvent) != "") {
str = str + "\n"
}
prevEvent = calEvent
}
return str
}
func (widget *Widget) dayDivider(event, prevEvent *CalEvent) string {
var prevStartTime time.Time
if prevEvent != nil {
prevStartTime = prevEvent.Start()
}
// round times to midnight for comparison
toMidnight := func(t time.Time) time.Time {
t = t.Local()
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
}
prevStartDay := toMidnight(prevStartTime)
eventStartDay := toMidnight(event.Start())
if !eventStartDay.Equal(prevStartDay) {
return fmt.Sprintf("[%s::b]",
wtf.Config.UString("wtf.mods.gcal.colors.day", "forestgreen")) +
event.Start().Format(wtf.FullDateFormat) +
"\n"
}
return ""
}
func (widget *Widget) descriptionColor(calEvent *CalEvent) string {
if calEvent.Past() {
return wtf.Config.UString("wtf.mods.gcal.colors.past", "gray")
}
return wtf.Config.UString("wtf.mods.gcal.colors.description", "white")
}
func (widget *Widget) eventSummary(calEvent *CalEvent, conflict bool) string {
summary := calEvent.event.Summary
if calEvent.Now() {
summary = fmt.Sprintf(
"%s %s",
wtf.Config.UString("wtf.mods.gcal.currentIcon", "🔸"),
summary,
)
}
if conflict {
return fmt.Sprintf("%s %s", wtf.Config.UString("wtf.mods.gcal.conflictIcon", "🚨"), summary)
}
return summary
}
// timeUntil returns the number of hours or days until the event
// If the event is in the past, returns nil
func (widget *Widget) timeUntil(calEvent *CalEvent) string {
duration := time.Until(calEvent.Start()).Round(time.Minute)
if duration < 0 {
return ""
}
days := duration / (24 * time.Hour)
duration -= days * (24 * time.Hour)
hours := duration / time.Hour
duration -= hours * time.Hour
mins := duration / time.Minute
untilStr := ""
color := "[lightblue]"
if days > 0 {
untilStr = fmt.Sprintf("%dd", days)
} else if hours > 0 {
untilStr = fmt.Sprintf("%dh", hours)
} else {
untilStr = fmt.Sprintf("%dm", mins)
if mins < 30 {
color = "[red]"
}
}
return color + untilStr + "[white]"
}
func (widget *Widget) titleColor(calEvent *CalEvent) string {
color := wtf.Config.UString("wtf.mods.gcal.colors.title", "white")
for _, untypedArr := range wtf.Config.UList("wtf.mods.gcal.colors.highlights") {
highlightElements := wtf.ToStrs(untypedArr.([]interface{}))
match, _ := regexp.MatchString(
strings.ToLower(highlightElements[0]),
strings.ToLower(calEvent.event.Summary),
)
if match == true {
color = highlightElements[1]
}
}
if calEvent.Past() {
color = wtf.Config.UString("wtf.mods.gcal.colors.past", "gray")
}
return color
}
func (widget *Widget) location(calEvent *CalEvent) string {
if wtf.Config.UBool("wtf.mods.gcal.displayLocation", true) == false {
return ""
}
if calEvent.event.Location == "" {
return ""
}
return fmt.Sprintf(
"[%s]%s ",
widget.descriptionColor(calEvent),
calEvent.event.Location,
)
}
func (widget *Widget) responseIcon(calEvent *CalEvent) string {
if false == wtf.Config.UBool("wtf.mods.gcal.displayResponseStatus", true) {
return ""
}
icon := "[gray]"
switch calEvent.ResponseFor(wtf.Config.UString("wtf.mods.gcal.email")) {
case "accepted":
return icon + "✔︎"
case "declined":
return icon + "✘"
case "needsAction":
return icon + "?"
case "tentative":
return icon + "~"
default:
return icon + " "
}
}
func removeDeclined(events []*CalEvent) []*CalEvent {
var ret []*CalEvent
for _, e := range events {
if e.ResponseFor(wtf.Config.UString("wtf.mods.gcal.email")) != "declined" {
ret = append(ret, e)
}
}
return ret
}