[WIP] Task editing
This commit is contained in:
@ -21,9 +21,12 @@ type Keymap struct {
|
||||
SetProject key.Binding
|
||||
Select key.Binding
|
||||
Insert key.Binding
|
||||
Tag key.Binding
|
||||
Undo key.Binding
|
||||
StartStop key.Binding
|
||||
}
|
||||
|
||||
// TODO: use config values for key bindings
|
||||
// NewKeymap creates a new Keymap.
|
||||
func NewKeymap() *Keymap {
|
||||
return &Keymap{
|
||||
@ -102,9 +105,19 @@ func NewKeymap() *Keymap {
|
||||
key.WithHelp("insert", "Insert mode"),
|
||||
),
|
||||
|
||||
Tag: key.NewBinding(
|
||||
key.WithKeys("t"),
|
||||
key.WithHelp("tag", "Tag"),
|
||||
),
|
||||
|
||||
Undo: key.NewBinding(
|
||||
key.WithKeys("u"),
|
||||
key.WithHelp("undo", "Undo"),
|
||||
),
|
||||
|
||||
StartStop: key.NewBinding(
|
||||
key.WithKeys("s"),
|
||||
key.WithHelp("start/stop", "Start/Stop"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,11 @@ type Styles struct {
|
||||
Form *huh.Theme
|
||||
TableStyle TableStyle
|
||||
|
||||
ColumnFocused lipgloss.Style
|
||||
ColumnBlurred lipgloss.Style
|
||||
ColumnInsert lipgloss.Style
|
||||
|
||||
// TODO: make color config completely dynamic to account for keyword., project., tag. and uda. colors
|
||||
Active lipgloss.Style
|
||||
Alternate lipgloss.Style
|
||||
Blocked lipgloss.Style
|
||||
@ -100,6 +105,10 @@ func NewStyles(config *taskwarrior.TWConfig) *Styles {
|
||||
|
||||
styles.Form = formTheme
|
||||
|
||||
styles.ColumnFocused = lipgloss.NewStyle().Width(30).Height(50).Border(lipgloss.DoubleBorder(), true)
|
||||
styles.ColumnBlurred = lipgloss.NewStyle().Width(30).Height(50).Border(lipgloss.HiddenBorder(), true)
|
||||
styles.ColumnInsert = lipgloss.NewStyle().Width(30).Height(50).Border(lipgloss.DoubleBorder(), true).BorderForeground(styles.Active.GetForeground())
|
||||
|
||||
return styles
|
||||
}
|
||||
|
||||
|
||||
21
go.mod
21
go.mod
@ -2,32 +2,31 @@ module tasksquire
|
||||
|
||||
go 1.22.2
|
||||
|
||||
require (
|
||||
github.com/charmbracelet/bubbles v0.18.0
|
||||
github.com/charmbracelet/bubbletea v0.26.1
|
||||
github.com/charmbracelet/huh v0.3.0
|
||||
github.com/charmbracelet/lipgloss v0.10.1-0.20240506202754-3ee5dcab73cb
|
||||
github.com/mattn/go-runewidth v0.0.15
|
||||
golang.org/x/term v0.20.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/catppuccin/go v0.2.0 // indirect
|
||||
github.com/charmbracelet/bubbles v0.18.0 // indirect
|
||||
github.com/charmbracelet/bubbletea v0.26.1 // indirect
|
||||
github.com/charmbracelet/huh v0.3.0 // indirect
|
||||
github.com/charmbracelet/huh/spinner v0.0.0-20240508140610-13957916abf0 // indirect
|
||||
github.com/charmbracelet/lipgloss v0.10.1-0.20240506202754-3ee5dcab73cb // indirect
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240515162549-69ee4f765313 // indirect
|
||||
github.com/charmbracelet/x/exp/term v0.0.0-20240506152644-8135bef4e495 // indirect
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/ethanefung/bubble-datepicker v0.1.0 // 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/moustachioed/go-taskwarrior v0.0.0-20220111032313-0ea4f466b47c // 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/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/term v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
)
|
||||
|
||||
33
go.sum
33
go.sum
@ -4,34 +4,20 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA=
|
||||
github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
|
||||
github.com/charmbracelet/bubbles v0.17.2-0.20240108170749-ec883029c8e6 h1:6nVCV8pqGaeyxetur3gpX3AAaiyKgzjIoCPV3NXKZBE=
|
||||
github.com/charmbracelet/bubbles v0.17.2-0.20240108170749-ec883029c8e6/go.mod h1:9HxZWlkCqz2PRwsCbYl7a3KXvGzFaDHpYbSYMJ+nE3o=
|
||||
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.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
|
||||
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
|
||||
github.com/charmbracelet/bubbletea v0.26.1 h1:xujcQeF73rh4jwu3+zhfQsvV18x+7zIjlw7/CYbzGJ0=
|
||||
github.com/charmbracelet/bubbletea v0.26.1/go.mod h1:FzKr7sKoO8iFVcdIBM9J0sJOcQv5nDQaYwsee3kpbgo=
|
||||
github.com/charmbracelet/huh v0.3.0 h1:CxPplWkgW2yUTDDG0Z4S5HH8SJOosWHd4LxCvi0XsKE=
|
||||
github.com/charmbracelet/huh v0.3.0/go.mod h1:fujUdKX8tC45CCSaRQdw789O6uaCRwx8l2NDyKfC4jA=
|
||||
github.com/charmbracelet/huh/spinner v0.0.0-20240508140610-13957916abf0 h1:79JTuYRirtyCn9ac6rzPt5AQKtBDFc1gKxpw0wBrI+Y=
|
||||
github.com/charmbracelet/huh/spinner v0.0.0-20240508140610-13957916abf0/go.mod h1:Zxt9FH6togK9kY71pRJGtmyNkJ1eIWdK1gRaXrS/FKA=
|
||||
github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg=
|
||||
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
|
||||
github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s=
|
||||
github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE=
|
||||
github.com/charmbracelet/lipgloss v0.10.1-0.20240506202754-3ee5dcab73cb h1:Hs3xzxHuruNT2Iuo87iS40c0PhLqpnUKBI6Xw6Ad3wQ=
|
||||
github.com/charmbracelet/lipgloss v0.10.1-0.20240506202754-3ee5dcab73cb/go.mod h1:EPP2QJ0ectp3zo6gx9f8oJGq8keirqPJ3XpYEI8wrrs=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240515162549-69ee4f765313 h1:3RsFsshW5j6I2GcEg7Qy//ZOFBqmwTqQ/KIFpU8kiIM=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240515162549-69ee4f765313/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ=
|
||||
github.com/charmbracelet/x/exp/term v0.0.0-20240506152644-8135bef4e495 h1:+0U9qX8Pv8KiYgRxfBvORRjgBzLgHMjtElP4O0PyKYA=
|
||||
github.com/charmbracelet/x/exp/term v0.0.0-20240506152644-8135bef4e495/go.mod h1:qeR6w1zITbkF7vEhcx0CqX5GfnIiQloJWQghN6HfP+c=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
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/ethanefung/bubble-datepicker v0.1.0 h1:dOD6msw3cWZv8O8fvHIPwFWIldtfWT6AfiSsVvZgWWo=
|
||||
github.com/ethanefung/bubble-datepicker v0.1.0/go.mod h1:8nxOYB9Oqays5U0JHKcIsbT7ZP/TwuJz8Uju9n5ueVU=
|
||||
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=
|
||||
@ -41,8 +27,6 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei
|
||||
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/moustachioed/go-taskwarrior v0.0.0-20220111032313-0ea4f466b47c h1:9w8HAhnAJKvNrus/zZM0yMSSeOIh6fdY2vInYPLqZJE=
|
||||
github.com/moustachioed/go-taskwarrior v0.0.0-20220111032313-0ea4f466b47c/go.mod h1:/sBiMzFAOI/NxkONwgm9omrpBjYlmkmdmZ074a9PbX0=
|
||||
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=
|
||||
@ -53,26 +37,17 @@ github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo
|
||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||
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.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
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=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
|
||||
@ -17,6 +17,7 @@ func NewMainPage(common *common.Common) *MainPage {
|
||||
}
|
||||
|
||||
m.activePage = NewReportPage(common, common.TW.GetReport(common.TW.GetConfig().Get("uda.tasksquire.report.default")))
|
||||
// m.activePage = NewTaskEditorPage(common, taskwarrior.Task{})
|
||||
|
||||
return m
|
||||
|
||||
|
||||
69
pages/messaging.go
Normal file
69
pages/messaging.go
Normal file
@ -0,0 +1,69 @@
|
||||
package pages
|
||||
|
||||
import tea "github.com/charmbracelet/bubbletea"
|
||||
|
||||
type UpdatedTasksMsg struct{}
|
||||
|
||||
type nextColumnMsg struct{}
|
||||
|
||||
func nextColumn() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return nextColumnMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
type prevColumnMsg struct{}
|
||||
|
||||
func prevColumn() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return prevColumnMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
type nextFieldMsg struct{}
|
||||
|
||||
func nextField() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return nextFieldMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
type prevFieldMsg struct{}
|
||||
|
||||
func prevField() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return prevFieldMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
type nextAreaMsg struct{}
|
||||
|
||||
func nextArea() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return nextAreaMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
type prevAreaMsg struct{}
|
||||
|
||||
func prevArea() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return prevAreaMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
type changeAreaMsg area
|
||||
|
||||
func changeArea(a area) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return changeAreaMsg(a)
|
||||
}
|
||||
}
|
||||
|
||||
func changeMode(mode mode) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return changeModeMsg(mode)
|
||||
}
|
||||
}
|
||||
|
||||
type changeModeMsg mode
|
||||
@ -24,17 +24,30 @@ type ReportPage struct {
|
||||
taskTable table.Model
|
||||
|
||||
subpage tea.Model
|
||||
subpageActive bool
|
||||
}
|
||||
|
||||
func NewReportPage(com *common.Common, report *taskwarrior.Report) *ReportPage {
|
||||
return &ReportPage{
|
||||
// return &ReportPage{
|
||||
// common: com,
|
||||
// activeReport: report,
|
||||
// activeContext: com.TW.GetActiveContext(),
|
||||
// activeProject: "",
|
||||
// taskTable: table.New(com),
|
||||
// }
|
||||
|
||||
p := &ReportPage{
|
||||
common: com,
|
||||
activeReport: report,
|
||||
activeContext: com.TW.GetActiveContext(),
|
||||
activeProject: "",
|
||||
taskTable: table.New(com),
|
||||
}
|
||||
|
||||
p.subpage = NewTaskEditorPage(p.common, taskwarrior.Task{})
|
||||
p.subpage.Init()
|
||||
p.common.PushPage(p)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *ReportPage) SetSize(width int, height int) {
|
||||
@ -53,8 +66,7 @@ func (p *ReportPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
p.SetSize(msg.Width, msg.Height)
|
||||
case BackMsg:
|
||||
p.subpageActive = false
|
||||
// case BackMsg:
|
||||
case TaskMsg:
|
||||
p.tasks = taskwarrior.Tasks(msg)
|
||||
p.populateTaskTable(p.tasks)
|
||||
@ -77,25 +89,21 @@ func (p *ReportPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case key.Matches(msg, p.common.Keymap.SetReport):
|
||||
p.subpage = NewReportPickerPage(p.common, p.activeReport)
|
||||
p.subpage.Init()
|
||||
p.subpageActive = true
|
||||
p.common.PushPage(p)
|
||||
return p.subpage, nil
|
||||
case key.Matches(msg, p.common.Keymap.SetContext):
|
||||
p.subpage = NewContextPickerPage(p.common)
|
||||
p.subpage.Init()
|
||||
p.subpageActive = true
|
||||
p.common.PushPage(p)
|
||||
return p.subpage, nil
|
||||
case key.Matches(msg, p.common.Keymap.Add):
|
||||
p.subpage = NewTaskEditorPage(p.common, taskwarrior.Task{})
|
||||
p.subpage.Init()
|
||||
p.subpageActive = true
|
||||
p.common.PushPage(p)
|
||||
return p.subpage, nil
|
||||
case key.Matches(msg, p.common.Keymap.Edit):
|
||||
p.subpage = NewTaskEditorPage(p.common, *p.selectedTask)
|
||||
p.subpage.Init()
|
||||
p.subpageActive = true
|
||||
p.common.PushPage(p)
|
||||
return p.subpage, nil
|
||||
case key.Matches(msg, p.common.Keymap.Ok):
|
||||
@ -104,12 +112,32 @@ func (p *ReportPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case key.Matches(msg, p.common.Keymap.SetProject):
|
||||
p.subpage = NewProjectPickerPage(p.common, p.activeProject)
|
||||
p.subpage.Init()
|
||||
p.subpageActive = true
|
||||
p.common.PushPage(p)
|
||||
return p.subpage, nil
|
||||
case key.Matches(msg, p.common.Keymap.Tag):
|
||||
if p.selectedTask != nil {
|
||||
tag := p.common.TW.GetConfig().Get("uda.tasksquire.tag.default")
|
||||
if p.selectedTask.HasTag(tag) {
|
||||
p.selectedTask.RemoveTag(tag)
|
||||
} else {
|
||||
p.selectedTask.AddTag(tag)
|
||||
}
|
||||
p.common.TW.ImportTask(p.selectedTask)
|
||||
return p, p.getTasks()
|
||||
}
|
||||
return p, nil
|
||||
case key.Matches(msg, p.common.Keymap.Undo):
|
||||
p.common.TW.Undo()
|
||||
return p, p.getTasks()
|
||||
case key.Matches(msg, p.common.Keymap.StartStop):
|
||||
if p.selectedTask != nil && p.selectedTask.Status == "pending" {
|
||||
if p.selectedTask.Start == "" {
|
||||
p.common.TW.StartTask(p.selectedTask)
|
||||
} else {
|
||||
p.common.TW.StopTask(p.selectedTask)
|
||||
}
|
||||
return p, p.getTasks()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1097
pages/taskEditor.go
1097
pages/taskEditor.go
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@ type TWConfig struct {
|
||||
var (
|
||||
defaultConfig = map[string]string{
|
||||
"uda.tasksquire.report.default": "next",
|
||||
"uda.tasksquire.tag.default": "next",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -197,6 +197,30 @@ func (t *Task) GetDate(dateString string) time.Time {
|
||||
return dt
|
||||
}
|
||||
|
||||
func (t *Task) HasTag(tag string) bool {
|
||||
for _, t := range t.Tags {
|
||||
if t == tag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Task) AddTag(tag string) {
|
||||
if !t.HasTag(tag) {
|
||||
t.Tags = append(t.Tags, tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Task) RemoveTag(tag string) {
|
||||
for i, ttag := range t.Tags {
|
||||
if ttag == tag {
|
||||
t.Tags = append(t.Tags[:i], t.Tags[i+1:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Tasks []*Task
|
||||
|
||||
type Context struct {
|
||||
@ -291,3 +315,97 @@ func parseCountdown(d time.Duration) string {
|
||||
|
||||
return fmt.Sprintf("%d:%02d:%02d", hours, minutes, seconds)
|
||||
}
|
||||
|
||||
var (
|
||||
dateFormats = []string{
|
||||
"2006-01-02",
|
||||
"2006-01-02T15:04",
|
||||
"20060102T150405Z",
|
||||
}
|
||||
|
||||
specialDateFormats = []string{
|
||||
"",
|
||||
"now",
|
||||
"today",
|
||||
"sod",
|
||||
"eod",
|
||||
"yesterday",
|
||||
"tomorrow",
|
||||
"monday",
|
||||
"tuesday",
|
||||
"wednesday",
|
||||
"thursday",
|
||||
"friday",
|
||||
"saturday",
|
||||
"sunday",
|
||||
"mon",
|
||||
"tue",
|
||||
"wed",
|
||||
"thu",
|
||||
"fri",
|
||||
"sat",
|
||||
"sun",
|
||||
"soy",
|
||||
"eoy",
|
||||
"soq",
|
||||
"eoq",
|
||||
"som",
|
||||
"eom",
|
||||
"socm",
|
||||
"eocm",
|
||||
"sow",
|
||||
"eow",
|
||||
"socw",
|
||||
"eocw",
|
||||
"soww",
|
||||
"eoww",
|
||||
"1st",
|
||||
"2nd",
|
||||
"3rd",
|
||||
"4th",
|
||||
"5th",
|
||||
"6th",
|
||||
"7th",
|
||||
"8th",
|
||||
"9th",
|
||||
"10th",
|
||||
"11th",
|
||||
"12th",
|
||||
"13th",
|
||||
"14th",
|
||||
"15th",
|
||||
"16th",
|
||||
"17th",
|
||||
"18th",
|
||||
"19th",
|
||||
"20th",
|
||||
"21st",
|
||||
"22nd",
|
||||
"23rd",
|
||||
"24th",
|
||||
"25th",
|
||||
"26th",
|
||||
"27th",
|
||||
"28th",
|
||||
"29th",
|
||||
"30th",
|
||||
"31st",
|
||||
}
|
||||
)
|
||||
|
||||
func ValidateDate(s string) error {
|
||||
|
||||
for _, f := range dateFormats {
|
||||
if _, err := time.Parse(f, s); err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range specialDateFormats {
|
||||
if s == f {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid date")
|
||||
}
|
||||
|
||||
@ -93,6 +93,8 @@ type TaskWarrior interface {
|
||||
AddTask(task *Task) error
|
||||
ImportTask(task *Task)
|
||||
SetTaskDone(task *Task)
|
||||
StartTask(task *Task)
|
||||
StopTask(task *Task)
|
||||
|
||||
Undo()
|
||||
}
|
||||
@ -403,6 +405,28 @@ func (ts *TaskSquire) Undo() {
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TaskSquire) StartTask(task *Task) {
|
||||
ts.mutex.Lock()
|
||||
defer ts.mutex.Unlock()
|
||||
|
||||
cmd := exec.Command(twBinary, append(ts.defaultArgs, []string{"start", task.Uuid}...)...)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
slog.Error("Failed starting task:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TaskSquire) StopTask(task *Task) {
|
||||
ts.mutex.Lock()
|
||||
defer ts.mutex.Unlock()
|
||||
|
||||
cmd := exec.Command(twBinary, append(ts.defaultArgs, []string{"stop", task.Uuid}...)...)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
slog.Error("Failed stopping task:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TaskSquire) extractConfig() *TWConfig {
|
||||
cmd := exec.Command(twBinary, append(ts.defaultArgs, []string{"_show"}...)...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
Reference in New Issue
Block a user