From 6f46f8773a2e00df7c3b9e14af1a5edf16df49c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 13:59:47 +0200 Subject: [PATCH 1/8] feat: add id to row --- ui/components/table-tasks/taskstable.go | 4 ++++ ui/components/table-tasks/utils.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ui/components/table-tasks/taskstable.go b/ui/components/table-tasks/taskstable.go index ee68ff8..6dbdfbd 100644 --- a/ui/components/table-tasks/taskstable.go +++ b/ui/components/table-tasks/taskstable.go @@ -120,6 +120,10 @@ func InitialModel(ctx *context.UserContext, logger *log.Logger) Model { Column: table.NewFlexColumn("url", "url", 0), Hidden: true, }, + { + Column: table.NewFlexColumn("id", "id", 0), + Hidden: true, + }, } columnsVisible := []Column{ { diff --git a/ui/components/table-tasks/utils.go b/ui/components/table-tasks/utils.go index e4a829e..8340e70 100644 --- a/ui/components/table-tasks/utils.go +++ b/ui/components/table-tasks/utils.go @@ -23,6 +23,8 @@ func taskToRow(task clickup.Task, columns []string) table.Row { values[column] = task.Name case "url": values[column] = task.Url + case "id": + values[column] = task.Id // After migration from charm to evertras/bubble-table I temporary removed all columns // except "status" and "name" since they are not supported yet. See autoColumns feature // case "assignee": @@ -71,6 +73,8 @@ func rowToTask(row table.Row, columns []string) clickup.Task { // values = append(values, task.Space.Id) // case "id": // values = append(values, task.Id) + case "id": + task.Id = data[column].(string) } } From ccf000c456ba45562d13c714da8175ca03d660c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 13:59:53 +0200 Subject: [PATCH 2/8] chore: remove comment --- ui/components/table-tasks/utils.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/ui/components/table-tasks/utils.go b/ui/components/table-tasks/utils.go index 8340e70..e4386ff 100644 --- a/ui/components/table-tasks/utils.go +++ b/ui/components/table-tasks/utils.go @@ -57,22 +57,6 @@ func rowToTask(row table.Row, columns []string) clickup.Task { task.Name = data[column].(string) case "url": task.Url = data[column].(string) - // After migration from charm to evertras/bubble-table I temporary removed all columns - // except "status" and "name" since they are not supported yet. See autoColumns feature - // case "assignee": - // values = append(values, task.GetAssignees()) - // case "list": - // values = append(values, task.List.String()) - // case "tags": - // values = append(values, task.GetTags()) - // case "folder": - // values = append(values, task.Folder.String()) - // case "url": - // values = append(values, task.Url) - // case "space": - // values = append(values, task.Space.Id) - // case "id": - // values = append(values, task.Id) case "id": task.Id = data[column].(string) } From c7e95c804b420d4481ccd7b2cdc03a507005d4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 14:01:09 +0200 Subject: [PATCH 3/8] feat: add set and with prop --- ui/components/table-tasks/taskstable.go | 7 ++++++- ui/components/tasks-sidebar/tasksidebar.go | 14 +++++++++++-- ui/widgets/tasks/tasks.go | 24 +++++++++++----------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/ui/components/table-tasks/taskstable.go b/ui/components/table-tasks/taskstable.go index 6dbdfbd..484bef9 100644 --- a/ui/components/table-tasks/taskstable.go +++ b/ui/components/table-tasks/taskstable.go @@ -270,7 +270,12 @@ func (m Model) GetFocused() bool { return m.Focused } -func (m Model) SetFocused(f bool) Model { +func (m Model) WithFocused(f bool) Model { + m.Focused = f + return m +} + +func (m *Model) SetFocused(f bool) *Model { m.Focused = f return m } diff --git a/ui/components/tasks-sidebar/tasksidebar.go b/ui/components/tasks-sidebar/tasksidebar.go index 20ee952..4ef0319 100644 --- a/ui/components/tasks-sidebar/tasksidebar.go +++ b/ui/components/tasks-sidebar/tasksidebar.go @@ -164,7 +164,12 @@ func (m Model) GetFocused() bool { return m.Focused } -func (m Model) SetFocused(f bool) Model { +func (m Model) WithFocused(f bool) Model { + m.Focused = f + return m +} + +func (m *Model) SetFocused(f bool) *Model { m.Focused = f return m } @@ -173,7 +178,12 @@ func (m Model) GetHidden() bool { return m.Hidden } -func (m Model) SetHidden(h bool) Model { +func (m *Model) SetHidden(h bool) *Model { + m.Hidden = h + return m +} + +func (m Model) WithHidden(h bool) Model { m.Hidden = h return m } diff --git a/ui/widgets/tasks/tasks.go b/ui/widgets/tasks/tasks.go index 5b60d3d..a85ffc7 100644 --- a/ui/widgets/tasks/tasks.go +++ b/ui/widgets/tasks/tasks.go @@ -49,7 +49,7 @@ func InitialModel(ctx *context.UserContext, logger *log.Logger) Model { } var ( componenetTasksTable = tabletasks.InitialModel(ctx, log) - componenetTasksSidebar = taskssidebar.InitialModel(ctx, log).SetHidden(true) + componenetTasksSidebar = taskssidebar.InitialModel(ctx, log).WithHidden(true) ) return Model{ @@ -153,19 +153,17 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { } case key.Matches(msg, m.keyMap.ToggleSidebar): - m.componenetTasksSidebar = m.componenetTasksSidebar.SetHidden(!m.componenetTasksSidebar.GetHidden()) - } + m.log.Debug("Toggle sidebar") + m.componenetTasksSidebar.SetHidden(!m.componenetTasksSidebar.GetHidden()) switch keypress := msg.String(); keypress { case "esc": switch m.state { case m.componenetTasksSidebar.ComponentId: m.state = m.componenetTasksTable.ComponentId - m.componenetTasksSidebar = m.componenetTasksSidebar.SetFocused(false) - m.componenetTasksTable = m.componenetTasksTable.SetFocused(true) + m.componenetTasksSidebar.SetFocused(false) + m.componenetTasksTable.SetFocused(true) case m.componenetTasksTable.ComponentId: - m.componenetTasksSidebar = m.componenetTasksSidebar.SetFocused(false) - m.componenetTasksTable = m.componenetTasksTable.SetFocused(false) m.componenetTasksSidebar, cmd = m.componenetTasksSidebar.Update(msg) cmds = append(cmds, cmd) @@ -173,6 +171,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { cmds = append(cmds, cmd) cmds = append(cmds, LostFocusCmd()) return m, tea.Batch(cmds...) + m.componenetTasksSidebar.SetFocused(false) + m.componenetTasksTable.SetFocused(false) } } @@ -191,11 +191,11 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.state = m.componenetTasksSidebar.ComponentId - m.componenetTasksSidebar = m.componenetTasksSidebar. + m.componenetTasksSidebar. SetFocused(true). SetHidden(false) - m.componenetTasksTable = m.componenetTasksTable.SetFocused(false) + m.componenetTasksTable.SetFocused(false) if err := m.componenetTasksSidebar.SetTask(id); err != nil { cmds = append(cmds, common.ErrCmd(err)) @@ -218,7 +218,7 @@ func (m *Model) SetTasks(tasks []clickup.Task) { m.componenetTasksTable.SetTasks(tasks) if len(tasks) == 0 { - m.componenetTasksSidebar = m.componenetTasksSidebar.SetHidden(true) + m.componenetTasksSidebar.SetHidden(true) return } @@ -350,9 +350,9 @@ func (m Model) SetFocused(f bool) Model { switch m.state { case m.componenetTasksSidebar.ComponentId: - m.componenetTasksSidebar = m.componenetTasksSidebar.SetFocused(f) + m.componenetTasksSidebar.SetFocused(f) case m.componenetTasksTable.ComponentId: - m.componenetTasksTable = m.componenetTasksTable.SetFocused(f) + m.componenetTasksTable.SetFocused(f) } return m From 70d24ac27f338c83ac2813cebac3c728346fbe55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 14:01:43 +0200 Subject: [PATCH 4/8] feat: add copy mode to tasks widget for copying id, url, and nice markdown with url --- go.mod | 10 ++-- go.sum | 13 +++++ main.go | 7 +++ ui/theme/theme.go | 2 + ui/widgets/tasks/tasks.go | 111 ++++++++++++++++++++++++++++++++++---- 5 files changed, 130 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index b8f40e1..b0a7a17 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,11 @@ require ( github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect github.com/yuin/goldmark v1.5.2 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect + golang.design/x/clipboard v0.7.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/exp/shiny v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/image v0.14.0 // indirect + golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect golang.org/x/net v0.16.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -45,7 +49,7 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect - golang.org/x/sync v0.4.0 - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sync v0.5.0 + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 32f2834..0c7efc2 100644 --- a/go.sum +++ b/go.sum @@ -79,13 +79,23 @@ github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU= github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= +golang.design/x/clipboard v0.7.0 h1:4Je8M/ys9AJumVnl8m+rZnIvstSnYj1fvzqYrU3TXvo= +golang.design/x/clipboard v0.7.0/go.mod h1:PQIvqYO9GP29yINEfsEn5zSQKAz3UgXmZKzDA6dnq2E= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp/shiny v0.0.0-20240506185415-9bf2ced13842 h1:kEvPiBVeT1JJGw/3THfe1W1zvTAvU1V6pCFV0icZvQs= +golang.org/x/exp/shiny v0.0.0-20240506185415-9bf2ced13842/go.mod h1:3F+MieQB7dRYLTmnncoFbb1crS5lfQoTfDgQy6K4N0o= +golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= +golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a h1:sYbmY3FwUWCBTodZL1S3JUuOvaW6kM2o+clDzzDNBWg= +golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a/go.mod h1:Ede7gF0KGoHlj822RtphAHK1jLdrcuRBZg0sF1Q+SPc= golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 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= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -93,12 +103,15 @@ 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.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 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/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 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.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= diff --git a/main.go b/main.go index b4c21fb..c929229 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "github.com/prgrs/clickup/ui" "github.com/prgrs/clickup/ui/context" "github.com/spf13/pflag" + "golang.design/x/clipboard" ) const ( @@ -140,10 +141,16 @@ func main() { } } + logger.Info("Loading cache...") if err := cache.Load(); err != nil { termLogger.Fatal(err) } + logger.Info("Initializing clipboard...") + if err := clipboard.Init(); err != nil { + termLogger.Fatal(err) + } + logger.Info("Initializing api...") api := api.NewApi(logger, cache, cfg.Token) diff --git a/ui/theme/theme.go b/ui/theme/theme.go index 073d093..11d7ab3 100644 --- a/ui/theme/theme.go +++ b/ui/theme/theme.go @@ -7,9 +7,11 @@ import ( type Theme struct { BordersColorActive lipgloss.Color BordersColorInactive lipgloss.Color + BordersColorCopyMode lipgloss.Color } var DefaultTheme = &Theme{ BordersColorActive: lipgloss.Color("#8909FF"), BordersColorInactive: lipgloss.Color("#FFF"), + BordersColorCopyMode: lipgloss.Color("#e6cc00"), } diff --git a/ui/widgets/tasks/tasks.go b/ui/widgets/tasks/tasks.go index a85ffc7..79782a7 100644 --- a/ui/widgets/tasks/tasks.go +++ b/ui/widgets/tasks/tasks.go @@ -14,6 +14,7 @@ import ( tabletasks "github.com/prgrs/clickup/ui/components/table-tasks" taskssidebar "github.com/prgrs/clickup/ui/components/tasks-sidebar" "github.com/prgrs/clickup/ui/context" + "golang.design/x/clipboard" ) const WidgetId = "tasks" @@ -35,6 +36,8 @@ type Model struct { componenetTasksTable tabletasks.Model componenetTasksSidebar taskssidebar.Model + + copyMode bool // TODO make as a widget } func InitialModel(ctx *context.UserContext, logger *log.Logger) Model { @@ -69,6 +72,8 @@ func InitialModel(ctx *context.UserContext, logger *log.Logger) Model { spinner: s, showSpinner: false, + + copyMode: false, } } @@ -76,6 +81,11 @@ type KeyMap struct { OpenTicketInWebBrowserBatch key.Binding OpenTicketInWebBrowser key.Binding ToggleSidebar key.Binding + CopyMode key.Binding + CopyTaskId key.Binding + CopyTaskUrl key.Binding + CopyTaskUrlMd key.Binding + LostFocus key.Binding } func DefaultKeyMap() KeyMap { @@ -92,12 +102,55 @@ func DefaultKeyMap() KeyMap { key.WithKeys("p"), key.WithHelp("p", "toggle sidebar"), ), + CopyMode: key.NewBinding( + key.WithKeys("y"), + key.WithHelp("y", "toggle copy mode"), + ), + CopyTaskId: key.NewBinding( + key.WithKeys("i"), + key.WithHelp("i", "copy task id to clipboard"), + ), + CopyTaskUrl: key.NewBinding( + key.WithKeys("u"), + key.WithHelp("u", "copy task url to clipboard"), + ), + CopyTaskUrlMd: key.NewBinding( + key.WithKeys("m"), + key.WithHelp("m", "copy task url as markdown to clipboard"), + ), + LostFocus: key.NewBinding( + key.WithKeys("esc"), + key.WithHelp("esc", "lost pane focus"), + ), } } func (m Model) KeyMap() help.KeyMap { var km help.KeyMap + if m.copyMode { + return common.NewKeyMap( + func() [][]key.Binding { + return [][]key.Binding{ + { + m.keyMap.CopyTaskId, + m.keyMap.CopyTaskUrl, + m.keyMap.CopyTaskUrlMd, + m.keyMap.LostFocus, + }, + } + }, + func() []key.Binding { + return []key.Binding{ + m.keyMap.CopyTaskId, + m.keyMap.CopyTaskUrl, + m.keyMap.CopyTaskUrlMd, + m.keyMap.LostFocus, + } + }, + ) + } + switch m.state { case m.componenetTasksSidebar.ComponentId: km = m.componenetTasksSidebar.KeyMap() @@ -119,7 +172,7 @@ func (m Model) KeyMap() help.KeyMap { return append( km.ShortHelp(), m.keyMap.OpenTicketInWebBrowser, - m.keyMap.ToggleSidebar, + m.keyMap.CopyMode, ) }, ) @@ -135,6 +188,31 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: + if m.copyMode { + switch { + case key.Matches(msg, m.keyMap.CopyTaskId): + task := m.componenetTasksTable.GetHighlightedTask() + clipboard.Write(clipboard.FmtText, []byte(task.Id)) + m.copyMode = false + + case key.Matches(msg, m.keyMap.CopyTaskUrl): + task := m.componenetTasksTable.GetHighlightedTask() + clipboard.Write(clipboard.FmtText, []byte(task.Url)) + m.copyMode = false + + case key.Matches(msg, m.keyMap.CopyTaskUrlMd): + task := m.componenetTasksTable.GetHighlightedTask() + md := fmt.Sprintf("[[#%s] - %s](%s)", task.Id, task.Name, task.Url) + clipboard.Write(clipboard.FmtText, []byte(md)) + m.copyMode = false + + case key.Matches(msg, m.keyMap.LostFocus): + m.copyMode = false + } + + break + } + switch { case key.Matches(msg, m.keyMap.OpenTicketInWebBrowserBatch): tasks := m.componenetTasksTable.GetSelectedTasks() @@ -156,24 +234,29 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.log.Debug("Toggle sidebar") m.componenetTasksSidebar.SetHidden(!m.componenetTasksSidebar.GetHidden()) - switch keypress := msg.String(); keypress { - case "esc": + case key.Matches(msg, m.keyMap.CopyMode): + m.log.Debug("Toggle copy mode") + m.copyMode = true + + case key.Matches(msg, m.keyMap.LostFocus): switch m.state { case m.componenetTasksSidebar.ComponentId: m.state = m.componenetTasksTable.ComponentId m.componenetTasksSidebar.SetFocused(false) m.componenetTasksTable.SetFocused(true) - case m.componenetTasksTable.ComponentId: - m.componenetTasksSidebar, cmd = m.componenetTasksSidebar.Update(msg) - cmds = append(cmds, cmd) - m.componenetTasksTable, cmd = m.componenetTasksTable.Update(msg) - cmds = append(cmds, cmd) - cmds = append(cmds, LostFocusCmd()) - return m, tea.Batch(cmds...) + case m.componenetTasksTable.ComponentId: m.componenetTasksSidebar.SetFocused(false) m.componenetTasksTable.SetFocused(false) } + + m.componenetTasksSidebar, cmd = m.componenetTasksSidebar.Update(msg) + cmds = append(cmds, cmd) + m.componenetTasksTable, cmd = m.componenetTasksTable.Update(msg) + cmds = append(cmds, cmd) + + cmds = append(cmds, LostFocusCmd()) + return m, tea.Batch(cmds...) } switch m.state { @@ -182,7 +265,9 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { case m.componenetTasksTable.ComponentId: m.componenetTasksTable, cmd = m.componenetTasksTable.Update(msg) } + cmds = append(cmds, cmd) + return m, tea.Batch(cmds...) case tabletasks.TaskSelectedMsg: @@ -234,6 +319,9 @@ func (m Model) View() string { if m.Focused { bColor = m.ctx.Theme.BordersColorActive } + if m.copyMode { + bColor = m.ctx.Theme.BordersColorCopyMode + } style := lipgloss.NewStyle(). Width(m.size.Width). @@ -292,6 +380,9 @@ func (m Model) View() string { if m.componenetTasksTable.GetFocused() { tasksTableBorders = m.ctx.Theme.BordersColorActive } + if m.copyMode { + tasksTableBorders = m.ctx.Theme.BordersColorCopyMode + } tmpStyle := style.Copy(). Inherit(styleBorders) From 848b3751a54f004e170a638670d20cb0971f3f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 18:22:30 +0200 Subject: [PATCH 5/8] chore: format --- ui/widgets/tasks/tasks.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/widgets/tasks/tasks.go b/ui/widgets/tasks/tasks.go index 79782a7..f804aca 100644 --- a/ui/widgets/tasks/tasks.go +++ b/ui/widgets/tasks/tasks.go @@ -210,7 +210,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { m.copyMode = false } - break + return m, tea.Batch(cmds...) } switch { @@ -396,8 +396,8 @@ func (m Model) View() string { m.componenetTasksTable.SetSize(size) tmpStyle = tmpStyle.Copy(). - Width(size.Width). BorderForeground(tasksTableBorders). + Width(size.Width). MaxWidth(size.Width + borderMargin). Height(size.Height). MaxHeight(m.size.Height + borderMargin) From 5754198c4d15237dd65b35c63c95862ba224370c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 18:22:43 +0200 Subject: [PATCH 6/8] chore: add WindowSize.Set --- ui/context/context.go | 5 +++++ ui/ui.go | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ui/context/context.go b/ui/context/context.go index 097253b..965f329 100644 --- a/ui/context/context.go +++ b/ui/context/context.go @@ -21,6 +21,11 @@ type WindowSize struct { MetaHeight int } +func (w *WindowSize) Set(width, height int) { + w.Width = width + w.Height = height +} + func NewUserContext(logger *log.Logger, api *api.Api, config *config.Config) UserContext { return UserContext{ Style: theme.DefautlStyle, diff --git a/ui/ui.go b/ui/ui.go index e811592..3c2ce2d 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -78,12 +78,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { "Received: tea.WindowSizeMsg", "width", msg.Width, "height", msg.Height) + m.ctx.WindowSize.Set(msg.Width, msg.Height) - m.ctx.WindowSize.Width = msg.Width - m.ctx.WindowSize.Height = msg.Height - m.ctx.WindowSize.Height = msg.Height - m.ctx.WindowSize.Height = msg.Height - m.ctx.WindowSize.Height = msg.Height } m.viewCompact, cmd = m.viewCompact.Update(msg) From b4267c9091ac2c23b5245345445fe8633293c147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 18:23:14 +0200 Subject: [PATCH 7/8] chore: add const Colors: black and white --- ui/theme/theme.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/theme/theme.go b/ui/theme/theme.go index 11d7ab3..e5fcd7e 100644 --- a/ui/theme/theme.go +++ b/ui/theme/theme.go @@ -4,6 +4,11 @@ import ( "github.com/charmbracelet/lipgloss" ) +const ( + ColorWhite = lipgloss.Color("#FFFFFF") + ColorBlack = lipgloss.Color("#000000") +) + type Theme struct { BordersColorActive lipgloss.Color BordersColorInactive lipgloss.Color From 1f59aa10b416202766818cc0186e8e9607341f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Wi=C4=99cek?= Date: Mon, 20 May 2024 18:23:30 +0200 Subject: [PATCH 8/8] chore: bump go to 1.21 and tidy --- go.mod | 6 +++--- go.sum | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index b0a7a17..ad44472 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/prgrs/clickup -go 1.18 +go 1.21 require ( github.com/charmbracelet/bubbletea v0.24.2 @@ -8,6 +8,7 @@ require ( github.com/charmbracelet/lipgloss v0.9.1 github.com/charmbracelet/log v0.3.1 github.com/spf13/pflag v1.0.5 + golang.design/x/clipboard v0.7.0 golang.org/x/term v0.13.0 ) @@ -24,7 +25,6 @@ require ( github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect github.com/yuin/goldmark v1.5.2 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect - golang.design/x/clipboard v0.7.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/exp/shiny v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/image v0.14.0 // indirect @@ -46,7 +46,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/reflow v0.3.0 github.com/muesli/termenv v0.15.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect golang.org/x/sync v0.5.0 diff --git a/go.sum b/go.sum index 0c7efc2..b602073 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,7 @@ github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl github.com/kkyr/fig v0.3.2 h1:+vMj52FL6RJUxeKOBB6JXIMyyi1/2j1ERDrZXjoBjzM= github.com/kkyr/fig v0.3.2/go.mod h1:ItUILF8IIzgZOMhx5xpJ1W/bviQsWRKOwKXfE/tqUoA= 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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -74,6 +75,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU= github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -92,8 +94,6 @@ golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a/go.mod h1:Ede7gF0KGoHlj82 golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -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= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -101,16 +101,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 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/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=