initial tui and keyring
This commit is contained in:
parent
10cdeaae12
commit
fc9971696c
202
caldav.go
202
caldav.go
@ -1,32 +1,30 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// "github.com/studio-b12/gowebdav"
|
|
||||||
"context"
|
"context"
|
||||||
// "fmt"
|
// "fmt"
|
||||||
webdav "github.com/emersion/go-webdav"
|
webdav "github.com/emersion/go-webdav"
|
||||||
"github.com/emersion/go-webdav/caldav"
|
"github.com/emersion/go-webdav/caldav"
|
||||||
|
|
||||||
// "log"
|
|
||||||
"time"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TODO struct {
|
type TODO struct {
|
||||||
Name string
|
Name string
|
||||||
Description string
|
Desc string
|
||||||
Time string
|
Time string
|
||||||
// Priority int //TODO
|
// Priority int //TODO
|
||||||
// Subtasks []TODO //TODO
|
// Subtasks []TODO //TODO
|
||||||
// Repeat //TODO
|
// Repeat //TODO
|
||||||
// Alarm //TODO
|
// Alarm //TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var clientWebDAV *webdav.Client
|
var clientWebDAV *webdav.Client
|
||||||
var client *caldav.Client // clientCalDAV
|
var client *caldav.Client // clientCalDAV
|
||||||
// var calendarObjects []caldav.CalendarObject
|
// var calendarObjects []caldav.CalendarObject
|
||||||
var ctx = context.Background()
|
var ctx = context.Background()
|
||||||
|
|
||||||
// var authSession caldav.Client // clientCalDAV
|
// var authSession caldav.Client // clientCalDAV
|
||||||
|
|
||||||
func (options *Options) InitDAVclients() error {
|
func (options *Options) InitDAVclients() error {
|
||||||
@ -47,142 +45,143 @@ func (options *Options) InitDAVclients() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCalendars() ([]caldav.Calendar,error) {
|
func GetCalendars() ([]caldav.Calendar, error) {
|
||||||
|
|
||||||
principal, err := clientWebDAV.FindCurrentUserPrincipal(ctx)
|
principal, err := clientWebDAV.FindCurrentUserPrincipal(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Handle error
|
// Handle error
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
// fmt.Println("principal: ",principal) TODO log
|
// fmt.Println("principal: ",principal) TODO log
|
||||||
|
|
||||||
|
|
||||||
// Find the calendar home set
|
// Find the calendar home set
|
||||||
calendarHomeSet, err := client.FindCalendarHomeSet(ctx, principal)
|
calendarHomeSet, err := client.FindCalendarHomeSet(ctx, principal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find calendars in the calendar home set
|
// Find calendars in the calendar home set
|
||||||
calendars, err := client.FindCalendars(ctx, calendarHomeSet)
|
calendars, err := client.FindCalendars(ctx, calendarHomeSet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return calendars, nil
|
return calendars, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTODOs(calendarPath string) (calendarObjects []caldav.CalendarObject,err error) {
|
func GetTODOs(calendarPath string) (calendarObjects []caldav.CalendarObject, err error) {
|
||||||
date := time.Now()
|
date := time.Now()
|
||||||
dateStart:= time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, 0, date.Location()).AddDate(0, 0, -1) //TODO too complex - time.Now().Add(-92 * time.Hour),
|
dateStart := time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, 0, date.Location()).AddDate(0, 0, -1) //TODO too complex - time.Now().Add(-92 * time.Hour),
|
||||||
// dateEnd:= time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, 0, date.Location()) //date +1 day
|
// dateEnd:= time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, 0, date.Location()) //date +1 day
|
||||||
dateEnd:= date.AddDate(0,1,0) //TODO we hard limit pulling events only for this month, to prevent getting tooo much events
|
dateEnd := date.AddDate(0, 1, 0) //TODO we hard limit pulling events only for this month, to prevent getting tooo much events
|
||||||
|
|
||||||
calQuery := caldav.CalendarQuery{
|
calQuery := caldav.CalendarQuery{
|
||||||
CompRequest: caldav.CalendarCompRequest{
|
CompRequest: caldav.CalendarCompRequest{
|
||||||
Name: "VCALENDAR",
|
Name: "VCALENDAR",
|
||||||
Comps: []caldav.CalendarCompRequest{{
|
Comps: []caldav.CalendarCompRequest{{
|
||||||
Name: "VTODO",
|
Name: "VTODO",
|
||||||
Props: []string{
|
Props: []string{
|
||||||
"UID",
|
"UID",
|
||||||
"SUMMARY",
|
"SUMMARY",
|
||||||
"COMPLETED",
|
"COMPLETED",
|
||||||
"DESCRIPTION",
|
"DESCRIPTION",
|
||||||
"DUE",
|
"DUE",
|
||||||
"PRIORITY",
|
"PRIORITY",
|
||||||
"RELATED-TO",
|
"RELATED-TO",
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
CompFilter: caldav.CompFilter{
|
|
||||||
Name: "VCALENDAR",
|
|
||||||
Comps: []caldav.CompFilter{
|
|
||||||
{
|
|
||||||
Name: "VTODO",
|
|
||||||
Start: dateStart,
|
|
||||||
End: dateEnd,
|
|
||||||
// FYI: server-side filtering is not supported for Nextcloud
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CompFilter: caldav.CompFilter{
|
||||||
|
Name: "VCALENDAR",
|
||||||
|
Comps: []caldav.CompFilter{
|
||||||
|
{
|
||||||
|
Name: "VTODO",
|
||||||
|
Start: dateStart,
|
||||||
|
End: dateEnd,
|
||||||
|
// FYI: server-side filtering is not supported for Nextcloud
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
calendarObjects, err = client.QueryCalendar(ctx, calendarPath, &calQuery)
|
calendarObjects, err = client.QueryCalendar(ctx, calendarPath, &calQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
return calendarObjects,nil
|
return calendarObjects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseDueDateTODOs(calObjs []caldav.CalendarObject,date time.Time) ([]TODO,error) {
|
func ParseDueDateTODOs(calObjs []caldav.CalendarObject, date time.Time) ([]TODO, error) {
|
||||||
var output []TODO
|
var output []TODO
|
||||||
|
|
||||||
for _,calObj := range calObjs {
|
for _, calObj := range calObjs {
|
||||||
// fmt.Println((*(*calObj.Data).Children[0]).Name)
|
// fmt.Println((*(*calObj.Data).Children[0]).Name)
|
||||||
// TODO STATUS map[] COMPLETED
|
// TODO STATUS map[] COMPLETED
|
||||||
for _,event := range (*calObj.Data).Children {
|
for _, event := range (*calObj.Data).Children {
|
||||||
// if (*event).Name == "VTODO" {
|
// if (*event).Name == "VTODO" {
|
||||||
var notCompletedTODO, withDate, fromToday bool
|
var notCompletedTODO, withDate, fromToday bool
|
||||||
//TODO we can optimize there if we encounter wrong state to forcefully stop next analysis
|
//TODO we can optimize there if we encounter wrong state to forcefully stop next analysis
|
||||||
// notCompletedTODO
|
// notCompletedTODO
|
||||||
if (*event).Props["COMPLETED"] == nil {
|
if (*event).Props["COMPLETED"] == nil {
|
||||||
if ((*event).Props["STATUS"] == nil) { notCompletedTODO = true } else {
|
if (*event).Props["STATUS"] == nil {
|
||||||
if ((*event).Props["STATUS"][0].Value != "COMPLETED") { notCompletedTODO = true }
|
notCompletedTODO = true
|
||||||
|
} else {
|
||||||
|
if (*event).Props["STATUS"][0].Value != "COMPLETED" {
|
||||||
|
notCompletedTODO = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// withTodayDate
|
// withTodayDate
|
||||||
if (*event).Props["DUE"] != nil {
|
if (*event).Props["DUE"] != nil {
|
||||||
withDate = true
|
withDate = true
|
||||||
// fromToday
|
// fromToday
|
||||||
if strings.HasPrefix((*event).Props["DUE"][0].Value, date.Format("20060102")) { fromToday = true }
|
if strings.HasPrefix((*event).Props["DUE"][0].Value, date.Format("20060102")) {
|
||||||
|
fromToday = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if notCompletedTODO && withDate && fromToday {
|
||||||
|
|
||||||
|
var tmpTODO TODO
|
||||||
|
|
||||||
|
if (*event).Props["SUMMARY"] != nil {
|
||||||
|
name := (*event).Props["SUMMARY"][0].Value
|
||||||
|
tmpTODO.Name = name
|
||||||
|
} else {
|
||||||
|
tmpTODO.Name = "<EMPTY>"
|
||||||
|
}
|
||||||
|
if (*event).Props["DESCRIPTION"] != nil {
|
||||||
|
description := (*event).Props["DESCRIPTION"][0].Value
|
||||||
|
tmpTODO.Desc = description
|
||||||
}
|
}
|
||||||
|
|
||||||
if notCompletedTODO && withDate && fromToday {
|
var todoTime string
|
||||||
|
due := (*event).Props["DUE"][0].Value
|
||||||
|
index := strings.Index(due, "T")
|
||||||
|
if index != -1 {
|
||||||
|
str := due[index+1:]
|
||||||
|
todoTime = str[:2] + ":" + str[2:4]
|
||||||
|
|
||||||
var tmpTODO TODO
|
tmpTODO.Time = todoTime
|
||||||
|
|
||||||
if ((*event).Props["SUMMARY"] != nil) {
|
|
||||||
name := (*event).Props["SUMMARY"][0].Value
|
|
||||||
tmpTODO.Name = name
|
|
||||||
} else {
|
|
||||||
tmpTODO.Name = "<EMPTY>"
|
|
||||||
}
|
|
||||||
if ((*event).Props["DESCRIPTION"] != nil) {
|
|
||||||
description := (*event).Props["DESCRIPTION"][0].Value
|
|
||||||
tmpTODO.Description = description
|
|
||||||
}
|
|
||||||
|
|
||||||
var todoTime string
|
|
||||||
due := (*event).Props["DUE"][0].Value
|
|
||||||
index := strings.Index(due, "T")
|
|
||||||
if index != -1 {
|
|
||||||
str := due[index+1:]
|
|
||||||
todoTime = str[:2] + ":" + str[2:4]
|
|
||||||
|
|
||||||
tmpTODO.Time = todoTime
|
|
||||||
}
|
|
||||||
output = append(output, tmpTODO)
|
|
||||||
}
|
}
|
||||||
|
output = append(output, tmpTODO)
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// //TODO sort: time, priority (if no time)
|
// //TODO sort: time, priority (if no time)
|
||||||
// // it means, put DUE at first, other DUE;VALUE=DATE in priority order
|
// // it means, put DUE at first, other DUE;VALUE=DATE in priority order
|
||||||
// //TODO color: priority, add time icon if have time
|
// //TODO color: priority, add time icon if have time
|
||||||
// //TODO UID:7ed30f40-fce1-422c-be3b-0486dcfe8943
|
// //TODO UID:7ed30f40-fce1-422c-be3b-0486dcfe8943
|
||||||
// //TODO RELATED-TO:7ed30f40-fce1-422c-be3b-0486dcfe8943 # subtask
|
// //TODO RELATED-TO:7ed30f40-fce1-422c-be3b-0486dcfe8943 # subtask
|
||||||
// //TODO PRIORITY:1 #1-high, 5-mid, 9-low
|
// //TODO PRIORITY:1 #1-high, 5-mid, 9-low
|
||||||
//TODO repeat function???
|
//TODO repeat function???
|
||||||
|
|
||||||
return output,nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO on complete -repeat function
|
//TODO on complete -repeat function
|
||||||
// RRULE:FREQ=WEEKLY;INTERVAL=1
|
// RRULE:FREQ=WEEKLY;INTERVAL=1
|
||||||
|
|
||||||
@ -200,20 +199,3 @@ func ParseDueDateTODOs(calObjs []caldav.CalendarObject,date time.Time) ([]TODO,e
|
|||||||
// DESCRIPTION:Default Tasks.org description
|
// DESCRIPTION:Default Tasks.org description
|
||||||
// END:VALARM
|
// END:VALARM
|
||||||
// END:VTODO
|
// END:VTODO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
33
go.mod
33
go.mod
@ -3,32 +3,61 @@ module git.sual.in/casual/tempus
|
|||||||
go 1.22.3
|
go 1.22.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/charmbracelet/bubbles v0.18.0
|
||||||
|
github.com/charmbracelet/bubbletea v0.26.4
|
||||||
|
github.com/charmbracelet/lipgloss v0.11.0
|
||||||
github.com/emersion/go-webdav v0.5.0
|
github.com/emersion/go-webdav v0.5.0
|
||||||
github.com/projectdiscovery/goflags v0.1.56
|
github.com/projectdiscovery/goflags v0.1.56
|
||||||
|
github.com/zalando/go-keyring v0.2.5
|
||||||
|
golang.org/x/term v0.18.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/alessio/shellescape v1.4.1 // indirect
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
|
github.com/atotto/clipboard v0.1.4 // indirect
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
|
github.com/charmbracelet/x/ansi v0.1.2 // indirect
|
||||||
|
github.com/charmbracelet/x/input v0.1.0 // indirect
|
||||||
|
github.com/charmbracelet/x/term v0.1.1 // indirect
|
||||||
|
github.com/charmbracelet/x/windows v0.1.0 // indirect
|
||||||
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect
|
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 // indirect
|
||||||
|
github.com/danieljoos/wincred v1.2.0 // indirect
|
||||||
github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f // indirect
|
github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f // indirect
|
||||||
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||||
|
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/gorilla/css v1.0.0 // indirect
|
github.com/gorilla/css v1.0.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/microcosm-cc/bluemonday v1.0.25 // indirect
|
github.com/microcosm-cc/bluemonday v1.0.25 // indirect
|
||||||
github.com/miekg/dns v1.1.56 // indirect
|
github.com/miekg/dns v1.1.56 // indirect
|
||||||
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||||
|
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||||
|
github.com/muesli/reflow v0.3.0 // indirect
|
||||||
|
github.com/muesli/termenv v0.15.2 // indirect
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/projectdiscovery/blackrock v0.0.1 // indirect
|
github.com/projectdiscovery/blackrock v0.0.1 // indirect
|
||||||
github.com/projectdiscovery/utils v0.1.3 // indirect
|
github.com/projectdiscovery/utils v0.1.3 // indirect
|
||||||
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
|
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
|
||||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
||||||
github.com/teambition/rrule-go v1.8.2 // indirect
|
github.com/teambition/rrule-go v1.8.2 // indirect
|
||||||
github.com/tidwall/gjson v1.14.3 // indirect
|
github.com/tidwall/gjson v1.14.3 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||||
golang.org/x/mod v0.12.0 // indirect
|
golang.org/x/mod v0.12.0 // indirect
|
||||||
golang.org/x/net v0.23.0 // indirect
|
golang.org/x/net v0.23.0 // indirect
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
|
golang.org/x/sys v0.21.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
golang.org/x/tools v0.13.0 // indirect
|
golang.org/x/tools v0.13.0 // indirect
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
80
go.sum
80
go.sum
@ -1,9 +1,31 @@
|
|||||||
|
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
|
||||||
|
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
|
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||||
|
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
|
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
|
||||||
|
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
|
||||||
|
github.com/charmbracelet/bubbletea v0.26.4 h1:2gDkkzLZaTjMl/dQBpNVtnvcCxsh/FCkimep7FC9c40=
|
||||||
|
github.com/charmbracelet/bubbletea v0.26.4/go.mod h1:P+r+RRA5qtI1DOHNFn0otoNwB4rn+zNAzSj/EXz6xU0=
|
||||||
|
github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g=
|
||||||
|
github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8=
|
||||||
|
github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
|
||||||
|
github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||||
|
github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ=
|
||||||
|
github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28=
|
||||||
|
github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
|
||||||
|
github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw=
|
||||||
|
github.com/charmbracelet/x/windows v0.1.0 h1:gTaxdvzDM5oMa/I2ZNF7wN78X/atWemG9Wph7Ika2k4=
|
||||||
|
github.com/charmbracelet/x/windows v0.1.0/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
|
||||||
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdknSRMDrAr8mfxPCfSZolH+/qQnyQ=
|
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdknSRMDrAr8mfxPCfSZolH+/qQnyQ=
|
||||||
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4=
|
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4=
|
||||||
|
github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE=
|
||||||
|
github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f h1:feGUUxxvOtWVOhTko8Cbmp33a+tU0IMZxMEmnkoAISQ=
|
github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f h1:feGUUxxvOtWVOhTko8Cbmp33a+tU0IMZxMEmnkoAISQ=
|
||||||
@ -11,16 +33,42 @@ github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f/go.mod h1:2MKFUgf
|
|||||||
github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM=
|
github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM=
|
||||||
github.com/emersion/go-webdav v0.5.0 h1:Ak/BQLgAihJt/UxJbCsEXDPxS5Uw4nZzgIMOq3rkKjc=
|
github.com/emersion/go-webdav v0.5.0 h1:Ak/BQLgAihJt/UxJbCsEXDPxS5Uw4nZzgIMOq3rkKjc=
|
||||||
github.com/emersion/go-webdav v0.5.0/go.mod h1:ycyIzTelG5pHln4t+Y32/zBvmrM7+mV7x+V+Gx4ZQno=
|
github.com/emersion/go-webdav v0.5.0/go.mod h1:ycyIzTelG5pHln4t+Y32/zBvmrM7+mV7x+V+Gx4ZQno=
|
||||||
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||||
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||||
|
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||||
|
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||||
|
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||||
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
|
github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
|
github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
|
||||||
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
|
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
|
||||||
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
|
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
|
||||||
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
|
||||||
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
|
||||||
|
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||||
|
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||||
|
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||||
|
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||||
|
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||||
|
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
@ -31,8 +79,16 @@ github.com/projectdiscovery/goflags v0.1.56 h1:tJYiZN7s9Jk9DxfYOUiqOoybaIDlXyX4Z
|
|||||||
github.com/projectdiscovery/goflags v0.1.56/go.mod h1:DsGF0NPpM5hGg75N3MTSvWJ4MIT7HFEAOEeWZ074+Fg=
|
github.com/projectdiscovery/goflags v0.1.56/go.mod h1:DsGF0NPpM5hGg75N3MTSvWJ4MIT7HFEAOEeWZ074+Fg=
|
||||||
github.com/projectdiscovery/utils v0.1.3 h1:yhHkrbYZA1eOO8e+fPDUvRMS5aUIalyM3Nab7rK4tpg=
|
github.com/projectdiscovery/utils v0.1.3 h1:yhHkrbYZA1eOO8e+fPDUvRMS5aUIalyM3Nab7rK4tpg=
|
||||||
github.com/projectdiscovery/utils v0.1.3/go.mod h1:gny8RbNYXE55IoamF6thRDQ8tcJEw+r0FOGAvncz/oQ=
|
github.com/projectdiscovery/utils v0.1.3/go.mod h1:gny8RbNYXE55IoamF6thRDQ8tcJEw+r0FOGAvncz/oQ=
|
||||||
|
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
|
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y=
|
||||||
|
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
|
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
|
||||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||||
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/teambition/rrule-go v1.7.2/go.mod h1:mBJ1Ht5uboJ6jexKdNUJg2NcwP8uUMNvStWXlJD3MvU=
|
github.com/teambition/rrule-go v1.7.2/go.mod h1:mBJ1Ht5uboJ6jexKdNUJg2NcwP8uUMNvStWXlJD3MvU=
|
||||||
@ -44,20 +100,30 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
|||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||||
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||||
|
github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8=
|
||||||
|
github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk=
|
||||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||||
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
121
keyring.go
Normal file
121
keyring.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "log"
|
||||||
|
|
||||||
|
"github.com/zalando/go-keyring"
|
||||||
|
// "github.com/99designs/keyring"
|
||||||
|
"encoding/base64"
|
||||||
|
// "fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const (
|
||||||
|
service = "Tempus"
|
||||||
|
user = "login"
|
||||||
|
)
|
||||||
|
|
||||||
|
// func debugKeyring() {
|
||||||
|
// service := "Tempus"
|
||||||
|
// user := "login"
|
||||||
|
// password := "secr123123et"
|
||||||
|
// encoded := base64.StdEncoding.EncodeToString([]byte(password))
|
||||||
|
// // set password
|
||||||
|
// err := keyring.Set(service, user, encoded)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // get password
|
||||||
|
// secret, err := keyring.Get(service, user)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// log.Println(secret)
|
||||||
|
//
|
||||||
|
// decodedByte, err := base64.StdEncoding.DecodeString(secret)
|
||||||
|
// decoded := string(decodedByte)
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Println("decode error:", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// log.Println(decoded)
|
||||||
|
// }
|
||||||
|
|
||||||
|
func storeCredentialsToKeyring(url,login,password string) error {
|
||||||
|
url = base64.StdEncoding.EncodeToString([]byte(url))
|
||||||
|
login = base64.StdEncoding.EncodeToString([]byte(login))
|
||||||
|
password = base64.StdEncoding.EncodeToString([]byte(password))
|
||||||
|
|
||||||
|
credentials := url + " " + login + " " + password
|
||||||
|
|
||||||
|
err := keyring.Set(service, user, credentials)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCredentialsFromKeyring() (url,login,password string, err error) {
|
||||||
|
secret, err := keyring.Get(service, user)
|
||||||
|
if err != nil {
|
||||||
|
return "","","",err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := strings.Split(secret," ")
|
||||||
|
|
||||||
|
urlByte, err := base64.StdEncoding.DecodeString(v[0])
|
||||||
|
if err != nil {
|
||||||
|
return "","","",err
|
||||||
|
}
|
||||||
|
loginByte, err := base64.StdEncoding.DecodeString(v[1])
|
||||||
|
if err != nil {
|
||||||
|
return "","","",err
|
||||||
|
}
|
||||||
|
passwordByte, err := base64.StdEncoding.DecodeString(v[2])
|
||||||
|
if err != nil {
|
||||||
|
return "","","",err
|
||||||
|
}
|
||||||
|
|
||||||
|
url = string(urlByte)
|
||||||
|
login = string(loginByte)
|
||||||
|
password = string(passwordByte)
|
||||||
|
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// func debugKeyring() {
|
||||||
|
//
|
||||||
|
// kr, err := keyring.Open(keyring.Config{
|
||||||
|
// AllowedBackends: []keyring.BackendType{
|
||||||
|
// keyring.SecretServiceBackend,
|
||||||
|
// },
|
||||||
|
// LibSecretCollectionName: "Defaultkeyring",
|
||||||
|
// ServiceName: "myapp",
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// err = kr.Set(keyring.Item{
|
||||||
|
// Key: "foo",
|
||||||
|
// // Data: []byte("secret-bar"),
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// v, err := kr.Get("llamas")
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// log.Printf("llamas was %v", v)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
78
main.go
78
main.go
@ -5,7 +5,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/bubbles/list"
|
||||||
|
|
||||||
|
// "strconv"
|
||||||
|
)
|
||||||
|
|
||||||
var waitGroup sync.WaitGroup
|
var waitGroup sync.WaitGroup
|
||||||
|
|
||||||
@ -20,25 +25,82 @@ func main() {
|
|||||||
options, err := ParseOptions()
|
options, err := ParseOptions()
|
||||||
errHandler(err, "Error parsing options")
|
errHandler(err, "Error parsing options")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// debugKeyring()
|
||||||
|
|
||||||
|
err = storeCredentialsToKeyring("https://pkg.go.dev/encoding/base64#Encoding.EncodeToString","casual","h>ÕdzPlÇqQ+çCQ{ð±;Kм7¸Âhð~Ümy)v")
|
||||||
|
errHandler(err, "Error parsing options")
|
||||||
|
|
||||||
|
// url1,login1,password1,err := getCredentialsFromKeyring()
|
||||||
|
// errHandler(err, "Error parsing options")
|
||||||
|
// m.loginInputs[url].Value()
|
||||||
|
// m.loginInputs[login].Value()
|
||||||
|
// m.loginInputs[pass].Value()
|
||||||
|
|
||||||
|
// if true {os.Exit(1)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
options.InitDAVclients()
|
options.InitDAVclients()
|
||||||
|
|
||||||
calendars, err := GetCalendars()
|
calendars, err := GetCalendars()
|
||||||
errHandler(err, "Error getting calendars")
|
errHandler(err, "Error getting calendars")
|
||||||
|
|
||||||
for _,calendar := range calendars {
|
for _, calendar := range calendars {
|
||||||
fmt.Println(calendar.Name, "-", calendar.Path)
|
fmt.Println(calendar.Name, "-", calendar.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
calendarObjects, err := GetTODOs(calendars[1].Path)
|
calendarObjects, err := GetTODOs(calendars[1].Path)
|
||||||
errHandler(err, "Error getting TODOs")
|
errHandler(err, "Error getting TODOs")
|
||||||
|
|
||||||
today := time.Now()
|
today := time.Now()
|
||||||
todos,err := ParseDueDateTODOs(calendarObjects ,today)
|
todayTodos, err := ParseDueDateTODOs(calendarObjects, today)
|
||||||
|
tomorrow := time.Now().AddDate(0,0,1)
|
||||||
|
tomorrowTodos, err := ParseDueDateTODOs(calendarObjects, tomorrow)
|
||||||
|
|
||||||
fmt.Println(todos)
|
// fmt.Println(todos)
|
||||||
|
|
||||||
fmt.Println("In total we have",len(calendarObjects), "todos")
|
fmt.Println("In total we have", len(calendarObjects), "todos")
|
||||||
|
|
||||||
|
var itemsToday []list.Item
|
||||||
|
var itemsTomorrow []list.Item
|
||||||
|
|
||||||
|
for _,todo := range todayTodos {
|
||||||
|
itemsToday = append(itemsToday,todo)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _,todo := range tomorrowTodos {
|
||||||
|
itemsTomorrow = append(itemsTomorrow,todo)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := InitModel()
|
||||||
|
m.TodayTab = list.New(itemsToday, list.NewDefaultDelegate(), 0, 0)
|
||||||
|
m.TodayTab.Title = "Today"
|
||||||
|
m.TomorrowTab = list.New(itemsTomorrow, list.NewDefaultDelegate(), 0, 0)
|
||||||
|
m.TomorrowTab.Title = "Tomorrow"
|
||||||
|
// m.LoggedIn = true
|
||||||
|
m.ActiveWindow = "login"
|
||||||
|
|
||||||
|
p := tea.NewProgram(m, tea.WithAltScreen())
|
||||||
|
if _, err := p.Run(); err != nil {
|
||||||
|
fmt.Println("Error running program:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(m.loginInputs[login].Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
270
tui.go
Normal file
270
tui.go
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
// "os"
|
||||||
|
// "strings"
|
||||||
|
|
||||||
|
"github.com/charmbracelet/bubbles/list"
|
||||||
|
"github.com/charmbracelet/bubbles/textinput"
|
||||||
|
// textblink "github.com/charmbracelet/bubbles/textinput"
|
||||||
|
// "github.com/erikgeiser/promptkit/textinput"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
"golang.org/x/term"
|
||||||
|
)
|
||||||
|
|
||||||
|
var docStyle = lipgloss.NewStyle().Margin(1, 2)
|
||||||
|
|
||||||
|
var loginStyle = lipgloss.NewStyle().Width(40).Align(lipgloss.Center).BorderStyle(lipgloss.NormalBorder())
|
||||||
|
|
||||||
|
var inputStyle = lipgloss.NewStyle()
|
||||||
|
|
||||||
|
func (i TODO) Title() string { return i.Name }
|
||||||
|
func (i TODO) Description() string { return i.Desc }
|
||||||
|
func (i TODO) FilterValue() string { return i.Name }
|
||||||
|
|
||||||
|
type model struct {
|
||||||
|
Tabs []string
|
||||||
|
// TabContent []string
|
||||||
|
LoggedIn bool
|
||||||
|
ActiveWindow string
|
||||||
|
|
||||||
|
TodayTab list.Model
|
||||||
|
TomorrowTab list.Model
|
||||||
|
|
||||||
|
loginInputs []textinput.Model
|
||||||
|
focused int
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m model) Init() tea.Cmd {
|
||||||
|
return textinput.Blink
|
||||||
|
// return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
url = iota
|
||||||
|
login
|
||||||
|
pass
|
||||||
|
)
|
||||||
|
//TODO add changing calendar
|
||||||
|
|
||||||
|
func InitModel() model {
|
||||||
|
var inputs []textinput.Model = make([]textinput.Model, 3)
|
||||||
|
inputs[url] = textinput.New()
|
||||||
|
inputs[url].Placeholder = "https://nextcloud.example/remote.php/dav"
|
||||||
|
inputs[url].Focus()
|
||||||
|
// inputs[url].CharLimit = 20
|
||||||
|
inputs[url].Width = 30
|
||||||
|
inputs[url].Prompt = ""
|
||||||
|
// inputs[url].Validate = urlValidator
|
||||||
|
|
||||||
|
inputs[login] = textinput.New()
|
||||||
|
inputs[login].Placeholder = "username"
|
||||||
|
// inputs[login].CharLimit = 5
|
||||||
|
inputs[login].Width = 30
|
||||||
|
inputs[login].Prompt = ""
|
||||||
|
// inputs[login].Validate = loginValidator
|
||||||
|
|
||||||
|
inputs[pass] = textinput.New()
|
||||||
|
inputs[pass].Placeholder = "MySecurePassword"
|
||||||
|
// inputs[pass].CharLimit = 3
|
||||||
|
inputs[pass].Width = 30
|
||||||
|
inputs[pass].Prompt = ""
|
||||||
|
// inputs[pass].Validate = passValidator
|
||||||
|
|
||||||
|
output := model{
|
||||||
|
Tabs: []string{"Today", "Tomorrow", "Add"},
|
||||||
|
loginInputs: inputs,
|
||||||
|
focused: 0,
|
||||||
|
err: nil,
|
||||||
|
// TabContent: []string{"ERROR?", "Mascara Tab", "Foundation Tab"},
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case tea.KeyMsg:
|
||||||
|
if m.ActiveWindow == "login" {
|
||||||
|
switch keypress := msg.String(); keypress {
|
||||||
|
case "ctrl+c", "q":
|
||||||
|
return m, tea.Quit
|
||||||
|
case "enter":
|
||||||
|
if m.focused == len(m.loginInputs)-1 {
|
||||||
|
//TODO submit
|
||||||
|
|
||||||
|
// try login -> store -> move to getting stuff
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
|
m.nextInput()
|
||||||
|
case "shift+tab", "up":
|
||||||
|
m.prevInput()
|
||||||
|
case "tab", "down":
|
||||||
|
m.nextInput()
|
||||||
|
}
|
||||||
|
for i := range m.loginInputs {
|
||||||
|
m.loginInputs[i].Blur()
|
||||||
|
}
|
||||||
|
m.loginInputs[m.focused].Focus()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch keypress := msg.String(); keypress {
|
||||||
|
case "ctrl+c", "q":
|
||||||
|
return m, tea.Quit
|
||||||
|
// case "right", "l", "n", "tab":
|
||||||
|
//TODO add to help
|
||||||
|
case "tab":
|
||||||
|
if m.LoggedIn {
|
||||||
|
h, v := docStyle.GetFrameSize()
|
||||||
|
width, height, _ := term.GetSize(0)
|
||||||
|
switch m.ActiveWindow {
|
||||||
|
case "today":
|
||||||
|
m.ActiveWindow = "tomorrow"
|
||||||
|
m.TomorrowTab.SetSize(width-h, height-v)
|
||||||
|
case "tomorrow":
|
||||||
|
m.ActiveWindow = "today"
|
||||||
|
m.TodayTab.SetSize(width-h, height-v)
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// case "a" {
|
||||||
|
// TODO add new element
|
||||||
|
// return m, tea.Quit
|
||||||
|
// }
|
||||||
|
case "t":
|
||||||
|
// TODO add new element
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
|
|
||||||
|
case tea.WindowSizeMsg:
|
||||||
|
h, v := docStyle.GetFrameSize()
|
||||||
|
switch m.ActiveWindow {
|
||||||
|
case "login":
|
||||||
|
m.TodayTab.SetSize(msg.Width-h, msg.Height-v)
|
||||||
|
case "today":
|
||||||
|
m.TodayTab.SetSize(msg.Width-h, msg.Height-v)
|
||||||
|
case "tomorrow":
|
||||||
|
m.TomorrowTab.SetSize(msg.Width-h, msg.Height-v)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var cmd tea.Cmd
|
||||||
|
// text input
|
||||||
|
switch m.ActiveWindow {
|
||||||
|
case "login":
|
||||||
|
for i := range m.loginInputs {
|
||||||
|
m.loginInputs[i], cmd = m.loginInputs[i].Update(msg)
|
||||||
|
}
|
||||||
|
case "today":
|
||||||
|
m.TodayTab, cmd = m.TodayTab.Update(msg)
|
||||||
|
case "tomorrow":
|
||||||
|
m.TomorrowTab, cmd = m.TomorrowTab.Update(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// m.TodayTab, cmd = m.TodayTab.Update(msg)
|
||||||
|
// m.TomorrowTab, cmd = m.TomorrowTab.Update(msg)
|
||||||
|
|
||||||
|
return m, cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m model) View() string {
|
||||||
|
|
||||||
|
var tabOutput string
|
||||||
|
|
||||||
|
switch m.ActiveWindow {
|
||||||
|
case "login":
|
||||||
|
width, height, _ := term.GetSize(0)
|
||||||
|
width -=2
|
||||||
|
height -=2
|
||||||
|
loginStyle = loginStyle.
|
||||||
|
// Width(30).
|
||||||
|
// Height(height/5).
|
||||||
|
MarginTop(height/5).
|
||||||
|
MarginLeft(width/2-20)
|
||||||
|
// MarginRight(width/3)
|
||||||
|
tabOutput = loginStyle.Render(m.RenderLogin())
|
||||||
|
// w, h := lipgloss.Size(tabOutput)
|
||||||
|
|
||||||
|
|
||||||
|
case "today":
|
||||||
|
tabOutput = docStyle.Render(m.TodayTab.View())
|
||||||
|
case "tomorrow":
|
||||||
|
tabOutput = docStyle.Render(m.TomorrowTab.View())
|
||||||
|
case "":
|
||||||
|
width, height, _ := term.GetSize(0)
|
||||||
|
width -=2
|
||||||
|
height -=2
|
||||||
|
loginStyle = loginStyle.
|
||||||
|
Width(width/3).
|
||||||
|
Height(1).
|
||||||
|
MarginTop(height/2).
|
||||||
|
MarginLeft(width/3+2).
|
||||||
|
MarginRight(width/3)
|
||||||
|
tabOutput = loginStyle.Render("ERROR")
|
||||||
|
}
|
||||||
|
// if m.activeTab == 0 {
|
||||||
|
// tabOutput = docStyle.Render(m.TodayTab.View())
|
||||||
|
// }
|
||||||
|
// if m.activeTab == 1 {
|
||||||
|
// tabOutput = docStyle.Render(m.TomorrowTab.View())
|
||||||
|
// }
|
||||||
|
|
||||||
|
return tabOutput
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m model) RenderLogin() string {
|
||||||
|
|
||||||
|
return fmt.Sprintf(
|
||||||
|
`%s
|
||||||
|
|
||||||
|
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
|
||||||
|
|
||||||
|
%s
|
||||||
|
`,
|
||||||
|
|
||||||
|
inputStyle.Width(30).Align(lipgloss.Center).Render("Login"),
|
||||||
|
inputStyle.Width(30).Foreground(lipgloss.AdaptiveColor{Dark: "50"}).Render("WebDAV server URL"),
|
||||||
|
m.loginInputs[url].View(),
|
||||||
|
inputStyle.Width(30).Foreground(lipgloss.AdaptiveColor{Dark: "50"}).Render("Login"),
|
||||||
|
m.loginInputs[login].View(),
|
||||||
|
inputStyle.Width(30).Foreground(lipgloss.AdaptiveColor{Dark: "50"}).Render("Password"),
|
||||||
|
m.loginInputs[pass].View(), //TODO hide
|
||||||
|
inputStyle.Render("Continue ->"),
|
||||||
|
)
|
||||||
|
// .Align(lipgloss.Center).BorderStyle(lipgloss.NormalBorder())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *model) nextInput() {
|
||||||
|
m.focused = (m.focused + 1) % len(m.loginInputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevInput focuses the previous input field
|
||||||
|
func (m *model) prevInput() {
|
||||||
|
m.focused--
|
||||||
|
// Wrap around
|
||||||
|
if m.focused < 0 {
|
||||||
|
m.focused = len(m.loginInputs) - 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user