From d77415783aa5e55e0f0988c48b942c33474ee7e7 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Tue, 7 May 2019 21:58:12 -0700 Subject: [PATCH 01/25] Remove the unnecessary mutex from gcal --- modules/gcal/display.go | 3 --- modules/gcal/widget.go | 2 -- 2 files changed, 5 deletions(-) diff --git a/modules/gcal/display.go b/modules/gcal/display.go index 749fa81b..65ec1a5f 100644 --- a/modules/gcal/display.go +++ b/modules/gcal/display.go @@ -29,9 +29,6 @@ func (widget *Widget) display() { return } - widget.mutex.Lock() - defer widget.mutex.Unlock() - widget.View.SetTitle(widget.ContextualTitle(widget.settings.common.Title)) widget.View.SetText(widget.contentFrom(widget.calEvents)) } diff --git a/modules/gcal/widget.go b/modules/gcal/widget.go index ccc22efc..dfac54a1 100644 --- a/modules/gcal/widget.go +++ b/modules/gcal/widget.go @@ -1,7 +1,6 @@ package gcal import ( - "sync" "time" "github.com/rivo/tview" @@ -14,7 +13,6 @@ type Widget struct { app *tview.Application calEvents []*CalEvent ch chan struct{} - mutex sync.Mutex settings *Settings } From a53593f8c6f7e5fca54c89073fec5df453cc6784 Mon Sep 17 00:00:00 2001 From: Graham Anderson Date: Wed, 8 May 2019 18:50:15 +0100 Subject: [PATCH 02/25] fix(gcal): remove possible extraneous variation codepoint --- modules/gcal/display.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gcal/display.go b/modules/gcal/display.go index 65ec1a5f..6f9e2ddc 100644 --- a/modules/gcal/display.go +++ b/modules/gcal/display.go @@ -214,7 +214,7 @@ func (widget *Widget) responseIcon(calEvent *CalEvent) string { switch calEvent.ResponseFor(widget.settings.email) { case "accepted": - return icon + "✔︎" + return icon + "✔" case "declined": return icon + "✘" case "needsAction": From e6a55d5a7ba9dab33234b5f8d9520774cc11a837 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 8 May 2019 14:34:46 -0700 Subject: [PATCH 03/25] Add @gnanderson as a contributor --- .all-contributorsrc | 7 +++++++ README.md | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ffcfda6e..3f2e2922 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -469,6 +469,13 @@ "name": "Levi Baber", "avatar_url": "https://avatars0.githubusercontent.com/u/5819098?v=4", "profile": "http://researchit.las.iastate.edu", + "contributions": [] + }, + { + "login": "gnanderson", + "name": "Graham Anderson", + "avatar_url": "https://avatars0.githubusercontent.com/u/38514?v=4", + "profile": "https://github.com/gnanderson", "contributions": [ ] } diff --git a/README.md b/README.md index 55b185c9..5af71087 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![All Contributors](https://img.shields.io/badge/all_contributors-66-orange.svg?style=flat-square)](#contributors) +[![All Contributors](https://img.shields.io/badge/all_contributors-67-orange.svg?style=flat-square)](#contributors) [![Build Status](https://travis-ci.com/wtfutil/wtf.svg?branch=master)](https://travis-ci.com/wtfutil/wtf) [![Gitter Chat](https://badges.gitter.im/wtfutil/Lobby.svg)](https://gitter.im/wtfutil/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Twitter](https://img.shields.io/badge/follow-on%20twitter-blue.svg)](https://twitter.com/wtfutil) @@ -97,7 +97,7 @@ Dependency management in WTF is handled by [Go modules](https://github.com/golan | [Renán Romero
Renán Romero](http://www.romeroruiz.com)
| [Bastian Groß
Bastian Groß](https://github.com/sticreations)
| [nicholas-eden
nicholas-eden](https://github.com/nicholas-eden)
| [Dan Rabinowitz
Dan Rabinowitz](https://github.com/danrabinowitz)
| [David Missmann
David Missmann](https://github.com/dvdmssmnn)
| [Mathias Weber
Mathias Weber](https://github.com/mweb)
| [TheRedSpy15
TheRedSpy15](https://github.com/TheRedSpy15)
| | [Harald Nordgren
Harald Nordgren](https://www.linkedin.com/in/harald-nordgren-44778192)
| [Matei Alexandru Gardus
Matei Alexandru Gardus](http://stormfirefox1.github.io)
| [Sean Smith
Sean Smith](https://github.com/Seanstoppable)
| [Halil Kaskavalci
Halil Kaskavalci](http://kaskavalci.com)
| [Johan Denoyer
Johan Denoyer](http://www.johandenoyer.fr)
| [Jelle Vink
Jelle Vink](https://skymeyer.be)
| [Devin Collins
Devin Collins](http://imdevinc.com)
| | [Danne Stayskal
Danne Stayskal](http://danne.stayskal.com/)
| [Max Beizer
Max Beizer](https://www.maxbeizer.com)
| [E:V:A
E:V:A](http://tinyurl.com/nwmj4as)
| [Gabriel
Gabriel](https://github.com/GaboFDC)
| [Andrew Scibek
Andrew Scibek](https://github.com/AndrewScibek)
| [FriedCosey
FriedCosey](https://github.com/FriedCosey)
| [Michele Gerarduzzi
Michele Gerarduzzi](https://michelegera.dev/)
| -| [Jack Morris
Jack Morris](https://github.com/rudolphjacksonm)
| [foorb
foorb](https://github.com/foorb)
| [Levi Baber
Levi Baber](http://researchit.las.iastate.edu)
| +| [Jack Morris
Jack Morris](https://github.com/rudolphjacksonm)
| [foorb
foorb](https://github.com/foorb)
| [Levi Baber
Levi Baber](http://researchit.las.iastate.edu)
| [Graham Anderson
Graham Anderson](https://github.com/gnanderson)
| ## Acknowledgments From a5f98c138a45c0f9fea01af7005dc07d371077ea Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Thu, 9 May 2019 10:59:04 -0400 Subject: [PATCH 04/25] Move closing region tag to the end of the line Highlight works by highlighting the entire region that exists Since current region starts and immediately ends, there is no highlighting --- modules/gitter/widget.go | 2 +- modules/hackernews/widget.go | 2 +- modules/jenkins/widget.go | 2 +- modules/jira/widget.go | 3 ++- modules/todo/display.go | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/gitter/widget.go b/modules/gitter/widget.go index 2acf0893..319c6231 100644 --- a/modules/gitter/widget.go +++ b/modules/gitter/widget.go @@ -113,7 +113,7 @@ func (widget *Widget) contentFrom(messages []Message) string { var str string for idx, message := range messages { str = str + fmt.Sprintf( - `["%d"][""][%s] [blue]%s [lightslategray]%s: [%s]%s [aqua]%s`, + `["%d"][%s] [blue]%s [lightslategray]%s: [%s]%s [aqua]%s[""]`, idx, widget.rowColor(idx), message.From.DisplayName, diff --git a/modules/hackernews/widget.go b/modules/hackernews/widget.go index d2a3f68f..ef602515 100644 --- a/modules/hackernews/widget.go +++ b/modules/hackernews/widget.go @@ -114,7 +114,7 @@ func (widget *Widget) contentFrom(stories []Story) string { for idx, story := range stories { u, _ := url.Parse(story.URL) str = str + fmt.Sprintf( - `["%d"][""][%s] [yellow]%d. [%s]%s [blue](%s)`, + `["%d"][%s] [yellow]%d. [%s]%s [blue](%s)[""]`, idx, widget.rowColor(idx), idx+1, diff --git a/modules/jenkins/widget.go b/modules/jenkins/widget.go index 64d76270..000e34b2 100644 --- a/modules/jenkins/widget.go +++ b/modules/jenkins/widget.go @@ -108,7 +108,7 @@ func (widget *Widget) contentFrom(view *View) string { if validID.MatchString(job.Name) { str = str + fmt.Sprintf( - `["%d"][""][%s] [%s]%-6s[white]`, + `["%d"][%s] [%s]%-6s[white][""]`, idx, widget.rowColor(idx), widget.jobColor(&job), diff --git a/modules/jira/widget.go b/modules/jira/widget.go index 1621eaa9..bef1449b 100644 --- a/modules/jira/widget.go +++ b/modules/jira/widget.go @@ -122,6 +122,7 @@ func (widget *Widget) openItem() { func (widget *Widget) unselect() { widget.selected = -1 + widget.display() } func (widget *Widget) contentFrom(searchResult *SearchResult) string { @@ -129,7 +130,7 @@ func (widget *Widget) contentFrom(searchResult *SearchResult) string { for idx, issue := range searchResult.Issues { fmtStr := fmt.Sprintf( - `["%d"][""][%s] [%s]%-6s[white] [green]%-10s[white] [yellow][%s][white] [%s]%s`, + `["%d"][%s] [%s]%-6s[white] [green]%-10s[white] [yellow][%s][white] [%s]%s[""]`, idx, widget.rowColor(idx), widget.issueTypeColor(&issue), diff --git a/modules/todo/display.go b/modules/todo/display.go index dae2a963..8f021a74 100644 --- a/modules/todo/display.go +++ b/modules/todo/display.go @@ -52,7 +52,7 @@ func (widget *Widget) formattedItemLine(idx int, item *checklist.ChecklistItem, } str := fmt.Sprintf( - `["%d"][""][%s:%s]|%s| %s[white]`, + `["%d"][%s:%s]|%s| %s[white][""]`, idx, foreColor, backColor, From 4e8c85bc34ccae6a004a723a52b4eceb758e127a Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Thu, 9 May 2019 19:27:53 -0700 Subject: [PATCH 05/25] Fix line highlighting in HackerNews and Todo modules --- modules/hackernews/widget.go | 2 +- modules/todo/display.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/hackernews/widget.go b/modules/hackernews/widget.go index ef602515..5caf66f1 100644 --- a/modules/hackernews/widget.go +++ b/modules/hackernews/widget.go @@ -114,7 +114,7 @@ func (widget *Widget) contentFrom(stories []Story) string { for idx, story := range stories { u, _ := url.Parse(story.URL) str = str + fmt.Sprintf( - `["%d"][%s] [yellow]%d. [%s]%s [blue](%s)[""]`, + `["%d"][""][%s] [yellow]%d. [%s]%s [blue](%s)[""]`, idx, widget.rowColor(idx), idx+1, diff --git a/modules/todo/display.go b/modules/todo/display.go index 8f021a74..3baea999 100644 --- a/modules/todo/display.go +++ b/modules/todo/display.go @@ -52,7 +52,7 @@ func (widget *Widget) formattedItemLine(idx int, item *checklist.ChecklistItem, } str := fmt.Sprintf( - `["%d"][%s:%s]|%s| %s[white][""]`, + `["%d"][""][%s:%s]|%s| %s[white][""]`, idx, foreColor, backColor, From 8c4bf5abc6d53b788493c9c309b7be6b05223fe3 Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Thu, 9 May 2019 23:06:34 -0400 Subject: [PATCH 06/25] Make datadog widget scrollable/interactive --- maker/widget_maker.go | 2 +- modules/datadog/keyboard.go | 17 +++++ modules/datadog/widget.go | 121 ++++++++++++++++++++++++++++++------ 3 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 modules/datadog/keyboard.go diff --git a/maker/widget_maker.go b/maker/widget_maker.go index 521559a1..4e460d2e 100644 --- a/maker/widget_maker.go +++ b/maker/widget_maker.go @@ -90,7 +90,7 @@ func MakeWidget( widget = cryptolive.NewWidget(app, settings) case "datadog": settings := datadog.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) - widget = datadog.NewWidget(app, settings) + widget = datadog.NewWidget(app, pages, settings) case "gcal": settings := gcal.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) widget = gcal.NewWidget(app, settings) diff --git a/modules/datadog/keyboard.go b/modules/datadog/keyboard.go new file mode 100644 index 00000000..af9b18e5 --- /dev/null +++ b/modules/datadog/keyboard.go @@ -0,0 +1,17 @@ +package datadog + +import ( + "github.com/gdamore/tcell" +) + +func (widget *Widget) initializeKeyboardControls() { + widget.SetKeyboardChar("/", widget.ShowHelp) + widget.SetKeyboardChar("j", widget.next) + widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("o", widget.openItem) + + widget.SetKeyboardKey(tcell.KeyDown, widget.next) + widget.SetKeyboardKey(tcell.KeyEnter, widget.openItem) + widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.prev) +} diff --git a/modules/datadog/widget.go b/modules/datadog/widget.go index c8a9665c..c15592be 100644 --- a/modules/datadog/widget.go +++ b/modules/datadog/widget.go @@ -2,27 +2,56 @@ package datadog import ( "fmt" + "strconv" "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" datadog "github.com/zorkian/go-datadog-api" ) +const HelpText = ` + Keyboard commands for Datadog: + + /: Show/hide this help window + j: Select the next item in the list + k: Select the previous item in the list + + arrow down: Select the next item in the list + arrow up: Select the previous item in the list + + return: Open the selected issue in a browser +` + type Widget struct { + wtf.HelpfulWidget wtf.TextWidget + wtf.KeyboardWidget app *tview.Application + selected int + monitors []datadog.Monitor settings *Settings } -func NewWidget(app *tview.Application, settings *Settings) *Widget { +func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - TextWidget: wtf.NewTextWidget(app, settings.common, false), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + TextWidget: wtf.NewTextWidget(app, settings.common, true), app: app, settings: settings, } + widget.initializeKeyboardControls() + widget.View.SetInputCapture(widget.InputCapture) + + widget.unselect() + + widget.View.SetScrollable(true) + widget.View.SetRegions(true) + widget.HelpfulWidget.SetView(widget.View) + return &widget } @@ -35,22 +64,12 @@ func (widget *Widget) Refresh() { if monitorErr != nil { widget.View.SetWrap(true) content = monitorErr.Error() - } else { - widget.View.SetWrap(false) - content = widget.contentFrom(monitors) + widget.app.QueueUpdateDraw(func() { + widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) + widget.View.SetText(content) + }) + return } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.Clear() - widget.View.SetText(content) - }) -} - -/* -------------------- Unexported Functions -------------------- */ - -func (widget *Widget) contentFrom(monitors []datadog.Monitor) string { - var str string - triggeredMonitors := []datadog.Monitor{} for _, monitor := range monitors { @@ -60,13 +79,39 @@ func (widget *Widget) contentFrom(monitors []datadog.Monitor) string { triggeredMonitors = append(triggeredMonitors, monitor) } } + widget.monitors = triggeredMonitors + + widget.display() +} + +func (widget *Widget) display() { + content := widget.contentFrom(widget.monitors) + widget.app.QueueUpdateDraw(func() { + widget.View.SetWrap(false) + widget.View.Clear() + widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) + widget.View.SetText(content) + widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + }) +} + +/* -------------------- Unexported Functions -------------------- */ + +func (widget *Widget) contentFrom(triggeredMonitors []datadog.Monitor) string { + var str string + if len(triggeredMonitors) > 0 { str = str + fmt.Sprintf( " %s\n", "[red]Triggered Monitors[white]", ) - for _, triggeredMonitor := range triggeredMonitors { - str = str + fmt.Sprintf("[red] %s\n", *triggeredMonitor.Name) + for idx, triggeredMonitor := range triggeredMonitors { + str = str + fmt.Sprintf(`["%d"][%s][red] %s[%s][""]`, + idx, + widget.rowColor(idx), + *triggeredMonitor.Name, + widget.rowColor(idx), + ) + "\n" } } else { str = str + fmt.Sprintf( @@ -77,3 +122,41 @@ func (widget *Widget) contentFrom(monitors []datadog.Monitor) string { return str } + +func (widget *Widget) unselect() { + widget.selected = -1 + widget.display() +} + +func (widget *Widget) next() { + widget.selected++ + if widget.monitors != nil && widget.selected >= len(widget.monitors) { + widget.selected = 0 + } + widget.display() +} + +func (widget *Widget) prev() { + widget.selected-- + if widget.selected < 0 && widget.monitors != nil { + widget.selected = len(widget.monitors) - 1 + } + widget.display() +} + +func (widget *Widget) openItem() { + + sel := widget.selected + if sel >= 0 && widget.monitors != nil && sel < len(widget.monitors) { + item := &widget.monitors[widget.selected] + wtf.OpenFile(fmt.Sprintf("https://app.datadoghq.com/monitors/%d?q=*", *item.Id)) + } +} + +func (widget *Widget) rowColor(idx int) string { + if widget.View.HasFocus() && (idx == widget.selected) { + widget.settings.common.DefaultFocussedRowColor() + } + + return widget.settings.common.RowColor(idx) +} From aedcf9dd512f606e274816e91c62a8c3e4eb553a Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 07:01:03 -0700 Subject: [PATCH 07/25] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ceb890e2..94310733 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,18 @@ ### ⚡️ Added +* DataDog module is now scrollable and interactive, by [@Seanstoppable](https://github.com/Seanstoppable) + +## v0.9.2 + +### ⚡️ Added + * Keyboard management system for modules reworked. Now has a KeyboardWidget to simplify adding keyboard commands +### Fixed + +* WTF versions are now prefixed with `v` again so module systems pick up the latest versions + ## 0.9.1 ### ⚡️ Added From 018d2af3ae4c17a93e6a0da4881263d6d993f577 Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Tue, 7 May 2019 20:49:46 -0400 Subject: [PATCH 08/25] Add a global Redraw method for TextWidget Partially addresses #429, by centralizing widget drawing --- generator/textwidget.tpl | 19 ++-------- modules/bamboohr/widget.go | 5 +-- modules/circleci/widget.go | 12 +++---- modules/cmdrunner/widget.go | 7 +--- modules/datadog/widget.go | 1 - modules/gcal/display.go | 5 ++- modules/gcal/widget.go | 35 ++----------------- modules/gerrit/display.go | 6 ++-- modules/gerrit/widget.go | 11 ++---- modules/git/display.go | 5 ++- modules/git/widget.go | 12 +++---- modules/github/display.go | 7 ++-- modules/gitlab/display.go | 7 ++-- modules/gitlab/widget.go | 6 +--- modules/gitter/widget.go | 30 +++++++--------- modules/gspreadsheets/widget.go | 6 +--- modules/hackernews/widget.go | 18 +++++----- modules/ipaddresses/ipinfo/widget.go | 7 +--- modules/jenkins/widget.go | 25 ++++++------- modules/jira/widget.go | 29 ++++++--------- modules/mercurial/display.go | 5 ++- modules/mercurial/widget.go | 17 ++++----- modules/nbascore/widget.go | 24 ++++--------- modules/newrelic/widget.go | 13 +++---- modules/opsgenie/widget.go | 11 ++---- modules/pagerduty/widget.go | 14 ++------ modules/power/widget.go | 6 +--- modules/rollbar/widget.go | 25 +++++-------- modules/security/widget.go | 6 +--- modules/spotify/widget.go | 13 +++---- modules/spotifyweb/widget.go | 13 ++----- modules/status/widget.go | 6 +--- modules/system/widget.go | 29 +++++++-------- modules/textfile/widget.go | 8 ++--- modules/todo/display.go | 5 +-- modules/todo/widget.go | 13 ++----- modules/todoist/display.go | 3 +- modules/todoist/widget.go | 6 +--- modules/travisci/widget.go | 24 ++++--------- modules/trello/widget.go | 10 ++---- modules/twitter/widget.go | 10 ++---- modules/unknown/widget.go | 10 ++---- modules/victorops/widget.go | 17 ++++----- .../weatherservices/prettyweather/widget.go | 6 +--- modules/weatherservices/weather/display.go | 31 ++++++++-------- modules/weatherservices/weather/widget.go | 6 +--- modules/zendesk/widget.go | 10 ++---- wtf/text_widget.go | 12 +++++++ 48 files changed, 194 insertions(+), 412 deletions(-) diff --git a/generator/textwidget.tpl b/generator/textwidget.tpl index 3c1e6513..f39df08e 100644 --- a/generator/textwidget.tpl +++ b/generator/textwidget.tpl @@ -18,7 +18,6 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application settings *Settings } @@ -28,15 +27,12 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - widget.View.SetScrollable(true) widget.View.SetRegions(true) @@ -50,22 +46,11 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * func (widget *Widget) Refresh() { // The last call should always be to the display function - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ func (widget *Widget) display() { - widget.View.SetWrap(false) - - widget.View.Clear() - widget.View.SetText("Some Text") - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + widget.Redraw(widget.CommonSettings.Title, "Some text", false) } - -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} \ No newline at end of file diff --git a/modules/bamboohr/widget.go b/modules/bamboohr/widget.go index 890144b1..8885fe6c 100644 --- a/modules/bamboohr/widget.go +++ b/modules/bamboohr/widget.go @@ -42,10 +42,7 @@ func (widget *Widget) Refresh() { wtf.Now().Format(wtf.DateFormat), ) - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.SetText(widget.contentFrom(todayItems)) - }) + widget.Redraw(widget.CommonSettings.Title, widget.contentFrom(todayItems), false) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/circleci/widget.go b/modules/circleci/widget.go index 718d6998..64f09b1b 100644 --- a/modules/circleci/widget.go +++ b/modules/circleci/widget.go @@ -11,7 +11,6 @@ type Widget struct { wtf.TextWidget *Client - app *tview.Application settings *Settings } @@ -20,7 +19,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { TextWidget: wtf.NewTextWidget(app, settings.common, false), Client: NewClient(settings.apiKey), - app: app, settings: settings, } @@ -36,19 +34,17 @@ func (widget *Widget) Refresh() { builds, err := widget.Client.BuildsFor() + title := fmt.Sprintf("%s - Builds", widget.CommonSettings.Title) var content string + wrap := false if err != nil { - widget.View.SetWrap(true) + wrap = true content = err.Error() } else { - widget.View.SetWrap(false) content = widget.contentFrom(builds) } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(fmt.Sprintf("%s - Builds", widget.CommonSettings.Title)) - widget.View.SetText(content) - }) + widget.Redraw(title, content, wrap) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/cmdrunner/widget.go b/modules/cmdrunner/widget.go index 83cd37fc..6ecbdf6e 100644 --- a/modules/cmdrunner/widget.go +++ b/modules/cmdrunner/widget.go @@ -12,7 +12,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application args []string cmd string settings *Settings @@ -23,7 +22,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, args: settings.args, cmd: settings.cmd, settings: settings, @@ -41,10 +39,7 @@ func (widget *Widget) Refresh() { ansiTitle := tview.TranslateANSI(widget.String()) ansiResult := tview.TranslateANSI(result) - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(ansiTitle) - widget.View.SetText(ansiResult) - }) + widget.Redraw(ansiTitle, ansiResult, false) } // String returns the string representation of the widget diff --git a/modules/datadog/widget.go b/modules/datadog/widget.go index c15592be..137dfbf1 100644 --- a/modules/datadog/widget.go +++ b/modules/datadog/widget.go @@ -39,7 +39,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), - app: app, settings: settings, } diff --git a/modules/gcal/display.go b/modules/gcal/display.go index 6f9e2ddc..65ee7221 100644 --- a/modules/gcal/display.go +++ b/modules/gcal/display.go @@ -29,13 +29,12 @@ func (widget *Widget) display() { return } - widget.View.SetTitle(widget.ContextualTitle(widget.settings.common.Title)) - widget.View.SetText(widget.contentFrom(widget.calEvents)) + widget.TextWidget.Redraw(widget.settings.common.Title, widget.contentFrom(widget.calEvents), false) } func (widget *Widget) contentFrom(calEvents []*CalEvent) string { if (calEvents == nil) || (len(calEvents) == 0) { - return "" + return "No calendar events" } var str string diff --git a/modules/gcal/widget.go b/modules/gcal/widget.go index dfac54a1..964fc4e3 100644 --- a/modules/gcal/widget.go +++ b/modules/gcal/widget.go @@ -1,8 +1,6 @@ package gcal import ( - "time" - "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" ) @@ -12,7 +10,6 @@ type Widget struct { app *tview.Application calEvents []*CalEvent - ch chan struct{} settings *Settings } @@ -21,27 +18,21 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { TextWidget: wtf.NewTextWidget(app, settings.common, true), app: app, - ch: make(chan struct{}), settings: settings, } - go updateLoop(&widget) - return &widget } /* -------------------- Exported Functions -------------------- */ func (widget *Widget) Disable() { - close(widget.ch) widget.TextWidget.Disable() } func (widget *Widget) Refresh() { if isAuthenticated() { - widget.app.QueueUpdateDraw(func() { - widget.fetchAndDisplayEvents() - }) + widget.fetchAndDisplayEvents() return } @@ -59,27 +50,5 @@ func (widget *Widget) fetchAndDisplayEvents() { widget.calEvents = calEvents } - widget.app.QueueUpdateDraw(func() { - widget.display() - }) -} - -func updateLoop(widget *Widget) { - if widget.settings.textInterval == 0 { - return - } - - tick := time.NewTicker(time.Duration(widget.settings.textInterval) * time.Second) - defer tick.Stop() -outer: - for { - select { - case <-tick.C: - widget.app.QueueUpdateDraw(func() { - widget.display() - }) - case <-widget.ch: - break outer - } - } + widget.display() } diff --git a/modules/gerrit/display.go b/modules/gerrit/display.go index ecb048a7..8fc9e188 100644 --- a/modules/gerrit/display.go +++ b/modules/gerrit/display.go @@ -8,11 +8,11 @@ func (widget *Widget) display() { project := widget.currentGerritProject() if project == nil { - widget.View.SetText(fmt.Sprintf("%s", " Gerrit project data is unavailable (1)")) + widget.Redraw(widget.CommonSettings.Title, "Gerrit project data is unavailable", true) return } - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s- %s", widget.CommonSettings.Title, widget.title(project)))) + title := fmt.Sprintf("%s- %s", widget.CommonSettings.Title, widget.title(project)) _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GerritProjects), widget.Idx, width) + "\n" @@ -25,7 +25,7 @@ func (widget *Widget) display() { str = str + " [red]My Outgoing Reviews[white]\n" str = str + widget.displayMyOutgoingReviews(project, widget.settings.username) - widget.View.SetText(str) + widget.Redraw(title, str, false) } func (widget *Widget) displayMyIncomingReviews(project *GerritProject, username string) string { diff --git a/modules/gerrit/widget.go b/modules/gerrit/widget.go index 41de5bce..e1536ce0 100644 --- a/modules/gerrit/widget.go +++ b/modules/gerrit/widget.go @@ -39,7 +39,6 @@ type Widget struct { GerritProjects []*GerritProject Idx int - app *tview.Application selected int settings *Settings } @@ -56,7 +55,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * Idx: 0, - app: app, settings: settings, } @@ -99,9 +97,7 @@ func (widget *Widget) Refresh() { if err != nil { widget.View.SetWrap(true) - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(err.Error()) - }) + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) return } widget.gerrit = gerrit @@ -111,10 +107,7 @@ func (widget *Widget) Refresh() { project.Refresh(widget.settings.username) } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/git/display.go b/modules/git/display.go index 4db18818..85712c2c 100644 --- a/modules/git/display.go +++ b/modules/git/display.go @@ -9,12 +9,11 @@ import ( func (widget *Widget) display() { repoData := widget.currentData() if repoData == nil { - widget.View.SetText(" Git repo data is unavailable ") + widget.Redraw(widget.CommonSettings.Title, " Git repo data is unavailable ", false) return } title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings.Title, repoData.Repository) - widget.View.SetTitle(widget.ContextualTitle(title)) _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GitRepos), widget.Idx, width) + "\n" @@ -25,7 +24,7 @@ func (widget *Widget) display() { str = str + "\n" str = str + widget.formatCommits(repoData.Commits) - widget.View.SetText(str) + widget.Redraw(title, str, false) } func (widget *Widget) formatChanges(data []string) string { diff --git a/modules/git/widget.go b/modules/git/widget.go index 0c44252c..41026d6c 100644 --- a/modules/git/widget.go +++ b/modules/git/widget.go @@ -97,9 +97,7 @@ func (widget *Widget) Refresh() { return widget.GitRepos[i].Path < widget.GitRepos[j].Path }) - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -125,9 +123,11 @@ func (widget *Widget) addCancelButton(form *tview.Form) { } func (widget *Widget) modalFocus(form *tview.Form) { - frame := widget.modalFrame(form) - widget.pages.AddPage("modal", frame, false, true) - widget.app.SetFocus(frame) + widget.app.QueueUpdateDraw(func() { + frame := widget.modalFrame(form) + widget.pages.AddPage("modal", frame, false, true) + widget.app.SetFocus(frame) + }) } func (widget *Widget) modalForm(lbl, text string) *tview.Form { diff --git a/modules/github/display.go b/modules/github/display.go index 68f8edf0..8d49d65d 100644 --- a/modules/github/display.go +++ b/modules/github/display.go @@ -8,13 +8,12 @@ import ( func (widget *Widget) display() { repo := widget.currentGithubRepo() + title := fmt.Sprintf("%s - %s", widget.CommonSettings.Title, widget.title(repo)) if repo == nil { - widget.View.SetText(" GitHub repo data is unavailable ") + widget.TextWidget.Redraw(title, " GitHub repo data is unavailable ", false) return } - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.CommonSettings.Title, widget.title(repo)))) - _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GithubRepos), widget.Idx, width) + "\n" str = str + " [red]Stats[white]\n" @@ -26,7 +25,7 @@ func (widget *Widget) display() { str = str + " [red]My Pull Requests[white]\n" str = str + widget.displayMyPullRequests(repo, widget.settings.username) - widget.View.SetText(str) + widget.TextWidget.Redraw(title, str, false) } func (widget *Widget) displayMyPullRequests(repo *GithubRepo, username string) string { diff --git a/modules/gitlab/display.go b/modules/gitlab/display.go index 2501d11c..040bef5f 100644 --- a/modules/gitlab/display.go +++ b/modules/gitlab/display.go @@ -8,11 +8,11 @@ func (widget *Widget) display() { project := widget.currentGitlabProject() if project == nil { - widget.View.SetText(" Gitlab project data is unavailable ") + widget.Redraw(widget.CommonSettings.Title, " Gitlab project data is unavailable ", true) return } - widget.View.SetTitle(fmt.Sprintf("%s- %s", widget.CommonSettings.Title, widget.title(project))) + title := fmt.Sprintf("%s- %s", widget.CommonSettings.Title, widget.title(project)) _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.GitlabProjects), widget.Idx, width) + "\n" @@ -24,8 +24,7 @@ func (widget *Widget) display() { str = str + "\n" str = str + " [red]My Merge Requests[white]\n" str = str + widget.displayMyMergeRequests(project, widget.settings.username) - - widget.View.SetText(str) + widget.Redraw(title, str, false) } func (widget *Widget) displayMyMergeRequests(project *GitlabProject, username string) string { diff --git a/modules/gitlab/widget.go b/modules/gitlab/widget.go index d28ffaed..05aebe62 100644 --- a/modules/gitlab/widget.go +++ b/modules/gitlab/widget.go @@ -26,7 +26,6 @@ type Widget struct { GitlabProjects []*GitlabProject Idx int - app *tview.Application gitlab *glb.Client settings *Settings } @@ -46,7 +45,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * Idx: 0, - app: app, gitlab: gitlab, settings: settings, } @@ -68,9 +66,7 @@ func (widget *Widget) Refresh() { project.Refresh() } - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } func (widget *Widget) Next() { diff --git a/modules/gitter/widget.go b/modules/gitter/widget.go index 319c6231..4bf7ff2c 100644 --- a/modules/gitter/widget.go +++ b/modules/gitter/widget.go @@ -26,7 +26,8 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application + app *tview.Application + messages []Message selected int settings *Settings @@ -80,19 +81,12 @@ func (widget *Widget) Refresh() { if err != nil { widget.View.SetWrap(true) - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.CommonSettings.Title) - widget.View.SetText(err.Error()) - }) - } else { - widget.messages = messages + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) + return } + widget.messages = messages - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.display() - widget.View.ScrollToEnd() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -102,11 +96,13 @@ func (widget *Widget) display() { return } - widget.View.SetWrap(true) - widget.View.Clear() - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.CommonSettings.Title, widget.settings.roomURI))) - widget.View.SetText(widget.contentFrom(widget.messages)) - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + title := fmt.Sprintf("%s - %s", widget.CommonSettings.Title, widget.settings.roomURI) + + widget.Redraw(title, widget.contentFrom(widget.messages), true) + widget.app.QueueUpdateDraw(func() { + widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + widget.View.ScrollToEnd() + }) } func (widget *Widget) contentFrom(messages []Message) string { diff --git a/modules/gspreadsheets/widget.go b/modules/gspreadsheets/widget.go index b52b9455..d1728474 100644 --- a/modules/gspreadsheets/widget.go +++ b/modules/gspreadsheets/widget.go @@ -11,7 +11,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application settings *Settings } @@ -19,7 +18,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -31,9 +29,7 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { func (widget *Widget) Refresh() { cells, _ := widget.Fetch() - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(widget.contentFrom(cells)) - }) + widget.Redraw(widget.CommonSettings.Title, widget.contentFrom(cells), false) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/hackernews/widget.go b/modules/hackernews/widget.go index 5caf66f1..b8c97803 100644 --- a/modules/hackernews/widget.go +++ b/modules/hackernews/widget.go @@ -30,7 +30,8 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application + app *tview.Application + stories []Story selected int settings *Settings @@ -89,9 +90,7 @@ func (widget *Widget) Refresh() { widget.stories = stories } - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -101,12 +100,11 @@ func (widget *Widget) display() { return } - widget.View.SetWrap(false) - - widget.View.Clear() - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %sstories", widget.CommonSettings.Title, widget.settings.storyType))) - widget.View.SetText(widget.contentFrom(widget.stories)) - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + title := fmt.Sprintf("%s - %sstories", widget.CommonSettings.Title, widget.settings.storyType) + widget.Redraw(title, widget.contentFrom(widget.stories), false) + widget.app.QueueUpdateDraw(func() { + widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + }) } func (widget *Widget) contentFrom(stories []Story) string { diff --git a/modules/ipaddresses/ipinfo/widget.go b/modules/ipaddresses/ipinfo/widget.go index 5edc3a40..1454d987 100644 --- a/modules/ipaddresses/ipinfo/widget.go +++ b/modules/ipaddresses/ipinfo/widget.go @@ -14,7 +14,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application result string settings *Settings } @@ -34,7 +33,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -46,10 +44,7 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { func (widget *Widget) Refresh() { widget.ipinfo() - widget.app.QueueUpdateDraw(func() { - widget.View.Clear() - widget.View.SetText(widget.result) - }) + widget.TextWidget.Redraw(widget.CommonSettings.Title, widget.result, false) } //this method reads the config and calls ipinfo for ip information diff --git a/modules/jenkins/widget.go b/modules/jenkins/widget.go index 000e34b2..3d453e40 100644 --- a/modules/jenkins/widget.go +++ b/modules/jenkins/widget.go @@ -29,7 +29,8 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application + app *tview.Application + selected int settings *Settings view *View @@ -73,17 +74,11 @@ func (widget *Widget) Refresh() { widget.view = view if err != nil { - widget.View.SetWrap(true) - - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(err.Error()) - }) + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) + return } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -93,12 +88,12 @@ func (widget *Widget) display() { return } - widget.View.SetWrap(false) + title := fmt.Sprintf("%s: [red]%s", widget.CommonSettings.Title, widget.view.Name) - widget.View.Clear() - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s: [red]%s", widget.CommonSettings.Title, widget.view.Name))) - widget.View.SetText(widget.contentFrom(widget.view)) - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + widget.Redraw(title, widget.contentFrom(widget.view), false) + widget.app.QueueUpdateDraw(func() { + widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + }) } func (widget *Widget) contentFrom(view *View) string { diff --git a/modules/jira/widget.go b/modules/jira/widget.go index bef1449b..e7bf259f 100644 --- a/modules/jira/widget.go +++ b/modules/jira/widget.go @@ -2,7 +2,6 @@ package jira import ( "fmt" - "strconv" "github.com/rivo/tview" @@ -27,7 +26,8 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application + app *tview.Application + result *SearchResult selected int settings *Settings @@ -67,19 +67,11 @@ func (widget *Widget) Refresh() { if err != nil { widget.result = nil - widget.View.SetWrap(true) - - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.CommonSettings.Title) - widget.View.SetText(err.Error()) - }) - } else { - widget.result = searchResult + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) + return } - - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.result = searchResult + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -88,14 +80,13 @@ func (widget *Widget) display() { if widget.result == nil { return } - widget.View.SetWrap(false) str := fmt.Sprintf("%s- [green]%s[white]", widget.CommonSettings.Title, widget.settings.projects) - widget.View.Clear() - widget.View.SetTitle(widget.ContextualTitle(str)) - widget.View.SetText(fmt.Sprintf("%s", widget.contentFrom(widget.result))) - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + widget.Redraw(str, widget.contentFrom(widget.result), false) + widget.app.QueueUpdateDraw(func() { + widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + }) } func (widget *Widget) next() { diff --git a/modules/mercurial/display.go b/modules/mercurial/display.go index 8dae5e94..9ffbc3b0 100644 --- a/modules/mercurial/display.go +++ b/modules/mercurial/display.go @@ -9,12 +9,11 @@ import ( func (widget *Widget) display() { repoData := widget.currentData() if repoData == nil { - widget.View.SetText(" Mercurial repo data is unavailable ") + widget.Redraw(widget.CommonSettings.Title, " Mercurial repo data is unavailable ", false) return } title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings.Title, repoData.Repository) - widget.View.SetTitle(widget.ContextualTitle(title)) _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.Data), widget.Idx, width) + "\n" @@ -25,7 +24,7 @@ func (widget *Widget) display() { str = str + "\n" str = str + widget.formatCommits(repoData.Commits) - widget.View.SetText(str) + widget.Redraw(title, str, false) } func (widget *Widget) formatChanges(data []string) string { diff --git a/modules/mercurial/widget.go b/modules/mercurial/widget.go index d6625c20..36748dd4 100644 --- a/modules/mercurial/widget.go +++ b/modules/mercurial/widget.go @@ -71,9 +71,7 @@ func (widget *Widget) Checkout() { widget.pages.RemovePage("modal") widget.app.SetFocus(widget.View) - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() widget.Refresh() } @@ -86,7 +84,6 @@ func (widget *Widget) Pull() { repoToPull := widget.Data[widget.Idx] repoToPull.pull() widget.Refresh() - } func (widget *Widget) Refresh() { @@ -94,9 +91,7 @@ func (widget *Widget) Refresh() { widget.Data = widget.mercurialRepos(repoPaths) - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -122,9 +117,11 @@ func (widget *Widget) addCancelButton(form *tview.Form) { } func (widget *Widget) modalFocus(form *tview.Form) { - frame := widget.modalFrame(form) - widget.pages.AddPage("modal", frame, false, true) - widget.app.SetFocus(frame) + widget.app.QueueUpdateDraw(func() { + frame := widget.modalFrame(form) + widget.pages.AddPage("modal", frame, false, true) + widget.app.SetFocus(frame) + }) } func (widget *Widget) modalForm(lbl, text string) *tview.Form { diff --git a/modules/nbascore/widget.go b/modules/nbascore/widget.go index 6f6cd9bd..ac7a47d6 100644 --- a/modules/nbascore/widget.go +++ b/modules/nbascore/widget.go @@ -25,7 +25,6 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application language string result string settings *Settings @@ -40,7 +39,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), - app: app, settings: settings, } @@ -55,39 +53,32 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * } func (widget *Widget) Refresh() { - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.nbascore() - }) + widget.Redraw(widget.CommonSettings.Title, widget.nbascore(), false) } -func (widget *Widget) nbascore() { +func (widget *Widget) nbascore() string { cur := time.Now().AddDate(0, 0, offset) // Go back/forward offset days curString := cur.Format("20060102") // Need 20060102 format to feed to api client := &http.Client{} req, err := http.NewRequest("GET", "http://data.nba.net/10s/prod/v1/"+curString+"/scoreboard.json", nil) if err != nil { - widget.result = err.Error() - return + return err.Error() } req.Header.Set("Accept-Language", widget.language) req.Header.Set("User-Agent", "curl") response, err := client.Do(req) if err != nil { - widget.result = err.Error() - return + return err.Error() } defer response.Body.Close() if response.StatusCode != 200 { - widget.result = err.Error() - return + return err.Error() } // Get data from data.nba.net and check if successful contents, err := ioutil.ReadAll(response.Body) if err != nil { - widget.result = err.Error() - return + return err.Error() } result := map[string]interface{}{} json.Unmarshal(contents, &result) @@ -146,6 +137,5 @@ func (widget *Widget) nbascore() { } allGame += fmt.Sprintf("%s%5s%v[white] %s %3s [white]vs %s%-3s %s\n", qColor, "Q", quarter, vTeam, vScore, hColor, hScore, hTeam) // Format the score and store in allgame } - widget.View.SetText(allGame) - + return allGame } diff --git a/modules/newrelic/widget.go b/modules/newrelic/widget.go index 3a6b611b..62d7d971 100644 --- a/modules/newrelic/widget.go +++ b/modules/newrelic/widget.go @@ -11,7 +11,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application client *Client settings *Settings } @@ -20,7 +19,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -41,19 +39,16 @@ func (widget *Widget) Refresh() { } var content string + title := fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings.Title, appName) + wrap := false if depErr != nil { - widget.View.SetWrap(true) + wrap = true content = depErr.Error() } else { - widget.View.SetWrap(false) content = widget.contentFrom(deploys) } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - [green]%s[white]", widget.CommonSettings.Title, appName))) - widget.View.Clear() - widget.View.SetText(content) - }) + widget.Redraw(title, content, wrap) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/opsgenie/widget.go b/modules/opsgenie/widget.go index 149e2a74..aef05445 100644 --- a/modules/opsgenie/widget.go +++ b/modules/opsgenie/widget.go @@ -11,7 +11,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application settings *Settings } @@ -19,7 +18,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -35,18 +33,15 @@ func (widget *Widget) Refresh() { ) var content string + wrap := false if err != nil { - widget.View.SetWrap(true) + wrap = true content = err.Error() } else { - widget.View.SetWrap(false) content = widget.contentFrom(data) } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.SetText(content) - }) + widget.Redraw(widget.CommonSettings.Title, content, wrap) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/pagerduty/widget.go b/modules/pagerduty/widget.go index 70d931de..a032e43f 100644 --- a/modules/pagerduty/widget.go +++ b/modules/pagerduty/widget.go @@ -12,7 +12,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application settings *Settings } @@ -20,7 +19,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -44,14 +42,10 @@ func (widget *Widget) Refresh() { incidents, err2 = GetIncidents(widget.settings.apiKey) } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.Clear() - }) - var content string + wrap := false if err1 != nil || err2 != nil { - widget.View.SetWrap(true) + wrap = true if err1 != nil { content = content + err1.Error() } @@ -63,9 +57,7 @@ func (widget *Widget) Refresh() { content = widget.contentFrom(onCalls, incidents) } - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(content) - }) + widget.Redraw(widget.CommonSettings.Title, content, wrap) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/power/widget.go b/modules/power/widget.go index 5ef57f08..0dfa167c 100644 --- a/modules/power/widget.go +++ b/modules/power/widget.go @@ -12,7 +12,6 @@ type Widget struct { Battery *Battery - app *tview.Application settings *Settings } @@ -22,7 +21,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { Battery: NewBattery(), - app: app, settings: settings, } @@ -39,7 +37,5 @@ func (widget *Widget) Refresh() { content = content + "\n" content = content + widget.Battery.String() - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(content) - }) + widget.Redraw(widget.CommonSettings.Title, content, true) } diff --git a/modules/rollbar/widget.go b/modules/rollbar/widget.go index 95a6e2d5..8b23af71 100644 --- a/modules/rollbar/widget.go +++ b/modules/rollbar/widget.go @@ -28,7 +28,6 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application items *Result selected int settings *Settings @@ -41,7 +40,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), - app: app, settings: settings, } @@ -69,19 +67,12 @@ func (widget *Widget) Refresh() { ) if err != nil { - widget.View.SetWrap(true) - - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(err.Error()) - }) - } else { - widget.items = &items.Results + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) + return } + widget.items = &items.Results - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -91,12 +82,14 @@ func (widget *Widget) display() { return } - widget.View.SetWrap(false) - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.CommonSettings.Title, widget.settings.projectName))) - widget.View.SetText(widget.contentFrom(widget.items)) + title := fmt.Sprintf("%s - %s", widget.CommonSettings.Title, widget.settings.projectName) + widget.Redraw(title, widget.contentFrom(widget.items), false) } func (widget *Widget) contentFrom(result *Result) string { + if result == nil { + return "No results" + } var str string if len(result.Items) > widget.settings.count { result.Items = result.Items[:widget.settings.count] diff --git a/modules/security/widget.go b/modules/security/widget.go index b10b7013..368aaa1f 100644 --- a/modules/security/widget.go +++ b/modules/security/widget.go @@ -11,7 +11,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application settings *Settings } @@ -19,7 +18,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -37,9 +35,7 @@ func (widget *Widget) Refresh() { data := NewSecurityData() data.Fetch() - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(widget.contentFrom(data)) - }) + widget.Redraw(widget.CommonSettings.Title, widget.contentFrom(data), false) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/spotify/widget.go b/modules/spotify/widget.go index dc82836b..dfb151fb 100644 --- a/modules/spotify/widget.go +++ b/modules/spotify/widget.go @@ -21,7 +21,6 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application settings *Settings spotigopher.Info spotigopher.SpotifyClient @@ -38,7 +37,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * Info: spotigopher.Info{}, SpotifyClient: spotifyClient, - app: app, settings: settings, } @@ -63,19 +61,18 @@ func (w *Widget) refreshSpotifyInfos() error { } func (w *Widget) Refresh() { - w.app.QueueUpdateDraw(func() { - w.render() - }) + w.render() } func (w *Widget) render() { err := w.refreshSpotifyInfos() - w.View.Clear() + var content string if err != nil { - w.TextWidget.View.SetText(err.Error()) + content = err.Error() } else { - w.TextWidget.View.SetText(w.createOutput()) + content = w.createOutput() } + w.Redraw(w.CommonSettings.Title, content, true) } func (w *Widget) createOutput() string { diff --git a/modules/spotifyweb/widget.go b/modules/spotifyweb/widget.go index a5747c26..047b37ae 100644 --- a/modules/spotifyweb/widget.go +++ b/modules/spotifyweb/widget.go @@ -48,7 +48,6 @@ type Widget struct { Info - app *tview.Application client *spotify.Client clientChan chan *spotify.Client playerState *spotify.PlayerState @@ -99,7 +98,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * Info: Info{}, - app: app, client: client, clientChan: tempClientChan, playerState: playerState, @@ -181,18 +179,11 @@ func (w *Widget) refreshSpotifyInfos() error { // Refresh refreshes the current view of the widget func (w *Widget) Refresh() { - w.app.QueueUpdateDraw(func() { - w.render() - }) -} - -func (w *Widget) render() { err := w.refreshSpotifyInfos() - w.View.Clear() if err != nil { - w.TextWidget.View.SetText(err.Error()) + w.Redraw(w.CommonSettings.Title, err.Error(), true) } else { - w.TextWidget.View.SetText(w.createOutput()) + w.Redraw(w.CommonSettings.Title, w.createOutput(), false) } } diff --git a/modules/status/widget.go b/modules/status/widget.go index cf02188d..e205dae8 100644 --- a/modules/status/widget.go +++ b/modules/status/widget.go @@ -10,7 +10,6 @@ type Widget struct { CurrentIcon int - app *tview.Application settings *Settings } @@ -20,7 +19,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { CurrentIcon: 0, - app: app, settings: settings, } @@ -30,9 +28,7 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { /* -------------------- Exported Functions -------------------- */ func (widget *Widget) Refresh() { - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(widget.animation()) - }) + widget.Redraw(widget.CommonSettings.Title, widget.animation(), false) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/system/widget.go b/modules/system/widget.go index 802d9a2b..d3f249b9 100644 --- a/modules/system/widget.go +++ b/modules/system/widget.go @@ -14,7 +14,6 @@ type Widget struct { Date string Version string - app *tview.Application settings *Settings systemInfo *SystemInfo } @@ -25,7 +24,6 @@ func NewWidget(app *tview.Application, date, version string, settings *Settings) Date: date, - app: app, settings: settings, Version: version, } @@ -36,21 +34,18 @@ func NewWidget(app *tview.Application, date, version string, settings *Settings) } func (widget *Widget) Refresh() { - widget.app.QueueUpdateDraw(func() { - widget.View.SetText( - fmt.Sprintf( - "%8s: %s\n%8s: %s\n\n%8s: %s\n%8s: %s", - "Built", - widget.prettyDate(), - "Vers", - widget.Version, - "OS", - widget.systemInfo.ProductVersion, - "Build", - widget.systemInfo.BuildVersion, - ), - ) - }) + content := fmt.Sprintf( + "%8s: %s\n%8s: %s\n\n%8s: %s\n%8s: %s", + "Built", + widget.prettyDate(), + "Vers", + widget.Version, + "OS", + widget.systemInfo.ProductVersion, + "Build", + widget.systemInfo.BuildVersion, + ) + widget.Redraw(widget.CommonSettings.Title, content, false) } func (widget *Widget) prettyDate() string { diff --git a/modules/textfile/widget.go b/modules/textfile/widget.go index d27fb24b..06beda1b 100644 --- a/modules/textfile/widget.go +++ b/modules/textfile/widget.go @@ -73,16 +73,13 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * // Refresh is only called once on start-up. Its job is to display the // text files that first time. After that, the watcher takes over func (widget *Widget) Refresh() { - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ func (widget *Widget) display() { title := fmt.Sprintf("[green]%s[white]", widget.CurrentSource()) - title = widget.ContextualTitle(title) _, _, width, _ := widget.View.GetRect() text := widget.settings.common.SigilStr(len(widget.Sources), widget.Idx, width) + "\n" @@ -93,8 +90,7 @@ func (widget *Widget) display() { text = text + widget.plainText() } - widget.View.SetTitle(title) // <- Writes to TextView's title - widget.View.SetText(text) // <- Writes to TextView's text + widget.Redraw(title, text, false) } func (widget *Widget) fileName() string { diff --git a/modules/todo/display.go b/modules/todo/display.go index 3baea999..179e81a3 100644 --- a/modules/todo/display.go +++ b/modules/todo/display.go @@ -2,7 +2,6 @@ package todo import ( "fmt" - "strconv" "github.com/rivo/tview" "github.com/wtfutil/wtf/checklist" @@ -34,9 +33,7 @@ func (widget *Widget) display() { newList.SetSelectedByItem(widget.list.SelectedItem()) widget.SetList(newList) - widget.View.Clear() - widget.View.SetText(str) - widget.View.Highlight(strconv.Itoa(widget.list.Selected())).ScrollToHighlight() + widget.Redraw(widget.CommonSettings.Title, str, false) } func (widget *Widget) formattedItemLine(idx int, item *checklist.ChecklistItem, selectedItem *checklist.ChecklistItem, maxLen int) string { diff --git a/modules/todo/widget.go b/modules/todo/widget.go index 13713d4d..8e0c7f8e 100644 --- a/modules/todo/widget.go +++ b/modules/todo/widget.go @@ -79,13 +79,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * func (widget *Widget) Refresh() { widget.load() - - widget.app.QueueUpdateDraw(func() { - title := widget.ContextualTitle(widget.CommonSettings.Title) - widget.View.SetTitle(title) - widget.display() - }) - + widget.display() } func (widget *Widget) SetList(list checklist.Checklist) { @@ -198,10 +192,9 @@ func (widget *Widget) addSaveButton(form *tview.Form, fctn func()) { } func (widget *Widget) modalFocus(form *tview.Form) { - frame := widget.modalFrame(form) - widget.pages.AddPage("modal", frame, false, true) - widget.app.QueueUpdateDraw(func() { + frame := widget.modalFrame(form) + widget.pages.AddPage("modal", frame, false, true) widget.app.SetFocus(frame) }) } diff --git a/modules/todoist/display.go b/modules/todoist/display.go index fbd7d3f2..ca4aeaba 100644 --- a/modules/todoist/display.go +++ b/modules/todoist/display.go @@ -17,7 +17,6 @@ func (widget *Widget) display() { } title := fmt.Sprintf("[green]%s[white]", proj.Project.Name) - widget.View.SetTitle(widget.ContextualTitle(title)) _, _, width, _ := widget.View.GetRect() str := widget.settings.common.SigilStr(len(widget.projects), widget.idx, width) + "\n" @@ -47,5 +46,5 @@ func (widget *Widget) display() { str = str + row + wtf.PadRow((checkWidth+len(item.Content)), (checkWidth+maxLen+1)) + "\n" } - widget.View.SetText(str) + widget.TextWidget.Redraw(title, str, false) } diff --git a/modules/todoist/widget.go b/modules/todoist/widget.go index 0cb3540f..329ef96c 100644 --- a/modules/todoist/widget.go +++ b/modules/todoist/widget.go @@ -31,7 +31,6 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application idx int projects []*Project settings *Settings @@ -44,7 +43,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), - app: app, settings: settings, } @@ -96,9 +94,7 @@ func (w *Widget) Refresh() { return } - w.app.QueueUpdateDraw(func() { - w.display() - }) + w.display() } /* -------------------- Keyboard Movement -------------------- */ diff --git a/modules/travisci/widget.go b/modules/travisci/widget.go index e13925ba..0a385e4e 100644 --- a/modules/travisci/widget.go +++ b/modules/travisci/widget.go @@ -27,7 +27,6 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application builds *Builds selected int settings *Settings @@ -39,7 +38,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), - app: app, settings: settings, } @@ -63,19 +61,11 @@ func (widget *Widget) Refresh() { builds, err := BuildsFor(widget.settings.apiKey, widget.settings.pro) if err != nil { - widget.View.SetWrap(true) - - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(err.Error()) - }) - } else { - widget.builds = builds + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) + return } - - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.display() - }) + widget.builds = builds + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -85,10 +75,8 @@ func (widget *Widget) display() { return } - widget.View.SetWrap(false) - - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - Builds", widget.CommonSettings.Title))) - widget.View.SetText(widget.contentFrom(widget.builds)) + title := fmt.Sprintf("%s - Builds", widget.CommonSettings.Title) + widget.Redraw(title, widget.contentFrom(widget.builds), false) } func (widget *Widget) contentFrom(builds *Builds) string { diff --git a/modules/trello/widget.go b/modules/trello/widget.go index a4afbe58..dbac1389 100644 --- a/modules/trello/widget.go +++ b/modules/trello/widget.go @@ -11,7 +11,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application settings *Settings } @@ -19,7 +18,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -45,8 +43,9 @@ func (widget *Widget) Refresh() { var title string var content string + wrap := false if err != nil { - widget.View.SetWrap(true) + wrap = true title = widget.CommonSettings.Title content = err.Error() } else { @@ -59,10 +58,7 @@ func (widget *Widget) Refresh() { content = widget.contentFrom(searchResult) } - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(title) - widget.View.SetText(content) - }) + widget.Redraw(title, content, wrap) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/twitter/widget.go b/modules/twitter/widget.go index 9fd9e2b4..7f94caee 100644 --- a/modules/twitter/widget.go +++ b/modules/twitter/widget.go @@ -28,7 +28,6 @@ type Widget struct { wtf.MultiSourceWidget wtf.TextWidget - app *tview.Application client *Client idx int settings *Settings @@ -42,7 +41,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * MultiSourceWidget: wtf.NewMultiSourceWidget(settings.common, "screenName", "screenNames"), TextWidget: wtf.NewTextWidget(app, settings.common, true), - app: app, idx: 0, settings: settings, } @@ -67,9 +65,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * // Refresh is called on the interval and refreshes the data func (widget *Widget) Refresh() { - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ @@ -78,7 +74,7 @@ func (widget *Widget) display() { widget.client.screenName = widget.CurrentSource() tweets := widget.client.Tweets() - widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("Twitter - [green]@%s[white]", widget.CurrentSource()))) + title := fmt.Sprintf("Twitter - [green]@%s[white]", widget.CurrentSource()) if len(tweets) == 0 { str := fmt.Sprintf("\n\n\n%s", wtf.CenterText("[blue]No Tweets[white]", 50)) @@ -92,7 +88,7 @@ func (widget *Widget) display() { str = str + widget.format(tweet) } - widget.View.SetText(str) + widget.Redraw(title, str, false) } // If the tweet's Username is the same as the account we're watching, no diff --git a/modules/unknown/widget.go b/modules/unknown/widget.go index 6493c6c1..8232aa7a 100644 --- a/modules/unknown/widget.go +++ b/modules/unknown/widget.go @@ -10,7 +10,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application settings *Settings } @@ -18,7 +17,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -28,10 +26,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { /* -------------------- Exported Functions -------------------- */ func (widget *Widget) Refresh() { - widget.app.QueueUpdateDraw(func() { - widget.View.Clear() - - content := fmt.Sprintf("Widget %s and/or type %s does not exist", widget.Name(), widget.CommonSettings.Module.Type) - widget.View.SetText(content) - }) + content := fmt.Sprintf("Widget %s and/or type %s does not exist", widget.Name(), widget.CommonSettings.Module.Type) + widget.Redraw(widget.CommonSettings.Title, content, true) } diff --git a/modules/victorops/widget.go b/modules/victorops/widget.go index cc57118a..735c3dcd 100644 --- a/modules/victorops/widget.go +++ b/modules/victorops/widget.go @@ -20,7 +20,6 @@ const HelpText = ` type Widget struct { wtf.TextWidget - app *tview.Application teams []OnCallTeam settings *Settings } @@ -47,19 +46,11 @@ func (widget *Widget) Refresh() { widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) if err != nil { - widget.View.SetWrap(true) - - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(err.Error()) - }) + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) } else { widget.teams = teams + widget.Redraw(widget.CommonSettings.Title, widget.contentFrom(widget.teams), true) } - - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.display() - }) } func (widget *Widget) display() { @@ -75,6 +66,10 @@ func (widget *Widget) display() { func (widget *Widget) contentFrom(teams []OnCallTeam) string { var str string + if teams == nil || len(teams) == 0 { + return "No teams specified" + } + for _, team := range teams { if len(widget.settings.team) > 0 && widget.settings.team != team.Slug { continue diff --git a/modules/weatherservices/prettyweather/widget.go b/modules/weatherservices/prettyweather/widget.go index f7b7a500..a88b209d 100644 --- a/modules/weatherservices/prettyweather/widget.go +++ b/modules/weatherservices/prettyweather/widget.go @@ -12,7 +12,6 @@ import ( type Widget struct { wtf.TextWidget - app *tview.Application result string settings *Settings } @@ -21,7 +20,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), - app: app, settings: settings, } @@ -31,9 +29,7 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { func (widget *Widget) Refresh() { widget.prettyWeather() - widget.app.QueueUpdateDraw(func() { - widget.View.SetText(widget.result) - }) + widget.Redraw(widget.CommonSettings.Title, widget.result, false) } //this method reads the config and calls wttr.in for pretty weather diff --git a/modules/weatherservices/weather/display.go b/modules/weatherservices/weather/display.go index cc357cc2..e916b7b0 100644 --- a/modules/weatherservices/weather/display.go +++ b/modules/weatherservices/weather/display.go @@ -9,31 +9,34 @@ import ( ) func (widget *Widget) display() { + err := "" if widget.apiKeyValid() == false { - widget.View.SetText(" Environment variable WTF_OWM_API_KEY is not set") - return + err += " Environment variable WTF_OWM_API_KEY is not set\n" } cityData := widget.currentData() if cityData == nil { - widget.View.SetText(" Weather data is unavailable: no city data") - return + err += " Weather data is unavailable: no city data\n" } if len(cityData.Weather) == 0 { - widget.View.SetText(" Weather data is unavailable: no weather data") - return + err += " Weather data is unavailable: no weather data" } - widget.View.SetTitle(widget.title(cityData)) + title := widget.CommonSettings.Title + var content string + if err != "" { + content = err + } else { + title = widget.title(cityData) + _, _, width, _ := widget.View.GetRect() + content = widget.settings.common.SigilStr(len(widget.Data), widget.Idx, width) + "\n" + content = content + widget.description(cityData) + "\n\n" + content = content + widget.temperatures(cityData) + "\n" + content = content + widget.sunInfo(cityData) + } - _, _, width, _ := widget.View.GetRect() - content := widget.settings.common.SigilStr(len(widget.Data), widget.Idx, width) + "\n" - content = content + widget.description(cityData) + "\n\n" - content = content + widget.temperatures(cityData) + "\n" - content = content + widget.sunInfo(cityData) - - widget.View.SetText(content) + widget.Redraw(title, content, false) } func (widget *Widget) description(cityData *owm.CurrentWeatherData) string { diff --git a/modules/weatherservices/weather/widget.go b/modules/weatherservices/weather/widget.go index 586123b8..458d08af 100644 --- a/modules/weatherservices/weather/widget.go +++ b/modules/weatherservices/weather/widget.go @@ -27,7 +27,6 @@ type Widget struct { Data []*owm.CurrentWeatherData Idx int - app *tview.Application settings *Settings } @@ -40,7 +39,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * Idx: 0, - app: app, settings: settings, } @@ -77,9 +75,7 @@ func (widget *Widget) Refresh() { widget.Data = widget.Fetch(wtf.ToInts(widget.settings.cityIDs)) } - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } // Next displays data for the next city data in the list. If the current city is the last diff --git a/modules/zendesk/widget.go b/modules/zendesk/widget.go index 79224237..8882c54f 100644 --- a/modules/zendesk/widget.go +++ b/modules/zendesk/widget.go @@ -13,7 +13,6 @@ type Widget struct { wtf.KeyboardWidget wtf.TextWidget - app *tview.Application result *TicketArray selected int settings *Settings @@ -25,7 +24,6 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), - app: app, settings: settings, } @@ -46,16 +44,14 @@ func (widget *Widget) Refresh() { widget.result = ticketArray } - widget.app.QueueUpdateDraw(func() { - widget.display() - }) + widget.display() } /* -------------------- Unexported Functions -------------------- */ func (widget *Widget) display() { - widget.View.SetTitle(fmt.Sprintf("%s (%d)", widget.CommonSettings.Title, widget.result.Count)) - widget.View.SetText(widget.textContent(widget.result.Tickets)) + title := fmt.Sprintf("%s (%d)", widget.CommonSettings.Title, widget.result.Count) + widget.Redraw(title, widget.textContent(widget.result.Tickets), false) } func (widget *Widget) textContent(items []Ticket) string { diff --git a/wtf/text_widget.go b/wtf/text_widget.go index de403606..373f1f51 100644 --- a/wtf/text_widget.go +++ b/wtf/text_widget.go @@ -13,6 +13,7 @@ type TextWidget struct { focusChar string name string refreshInterval int + app *tview.Application View *tview.TextView @@ -24,6 +25,7 @@ func NewTextWidget(app *tview.Application, commonSettings *cfg.Common, focusable widget := TextWidget{ CommonSettings: commonSettings, + app: app, enabled: commonSettings.Enabled, focusable: focusable, focusChar: commonSettings.FocusChar(), @@ -107,6 +109,16 @@ func (widget *TextWidget) TextView() *tview.TextView { return widget.View } +func (widget *TextWidget) Redraw(title, text string, wrap bool) { + + widget.app.QueueUpdateDraw(func() { + widget.View.Clear() + widget.View.SetWrap(wrap) + widget.View.SetTitle(widget.ContextualTitle(title)) + widget.View.SetText(text) + }) +} + /* -------------------- Unexported Functions -------------------- */ func (widget *TextWidget) addView() *tview.TextView { From 68ed842c8782af0c09b67f7300570c1a0d6e95e9 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 08:09:50 -0700 Subject: [PATCH 09/25] Fix double-render of title in Weather --- modules/weatherservices/weather/display.go | 4 +++- wtf/text_widget.go | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/weatherservices/weather/display.go b/modules/weatherservices/weather/display.go index e916b7b0..059fbd0a 100644 --- a/modules/weatherservices/weather/display.go +++ b/modules/weatherservices/weather/display.go @@ -24,6 +24,7 @@ func (widget *Widget) display() { } title := widget.CommonSettings.Title + var content string if err != "" { content = err @@ -74,5 +75,6 @@ func (widget *Widget) temperatures(cityData *owm.CurrentWeatherData) string { func (widget *Widget) title(cityData *owm.CurrentWeatherData) string { str := fmt.Sprintf("%s %s", widget.emojiFor(cityData), cityData.Name) - return widget.ContextualTitle(str) + return str + // return widget.ContextualTitle(str) } diff --git a/wtf/text_widget.go b/wtf/text_widget.go index 373f1f51..a6016ca4 100644 --- a/wtf/text_widget.go +++ b/wtf/text_widget.go @@ -131,7 +131,6 @@ func (widget *TextWidget) addView() *tview.TextView { view.SetBorder(true) view.SetDynamicColors(true) - view.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) view.SetWrap(false) return view From 075402315e8d24d5abe8bc014b77c103f7ac1250 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 08:36:47 -0700 Subject: [PATCH 10/25] Fix missing title in Clocks --- modules/clocks/display.go | 2 +- modules/textfile/widget.go | 2 +- modules/twitter/widget.go | 2 +- modules/weatherservices/weather/display.go | 8 +++----- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/clocks/display.go b/modules/clocks/display.go index 9448aa06..58e46e52 100644 --- a/modules/clocks/display.go +++ b/modules/clocks/display.go @@ -27,5 +27,5 @@ func (widget *Widget) display(clocks []Clock, dateFormat string, timeFormat stri ) } - widget.View.SetText(str) + widget.Redraw(widget.CommonSettings.Title, str, false) } diff --git a/modules/textfile/widget.go b/modules/textfile/widget.go index 06beda1b..64d01e27 100644 --- a/modules/textfile/widget.go +++ b/modules/textfile/widget.go @@ -90,7 +90,7 @@ func (widget *Widget) display() { text = text + widget.plainText() } - widget.Redraw(title, text, false) + widget.Redraw(title, text, true) } func (widget *Widget) fileName() string { diff --git a/modules/twitter/widget.go b/modules/twitter/widget.go index 7f94caee..5ae8640f 100644 --- a/modules/twitter/widget.go +++ b/modules/twitter/widget.go @@ -88,7 +88,7 @@ func (widget *Widget) display() { str = str + widget.format(tweet) } - widget.Redraw(title, str, false) + widget.Redraw(title, str, true) } // If the tweet's Username is the same as the account we're watching, no diff --git a/modules/weatherservices/weather/display.go b/modules/weatherservices/weather/display.go index 059fbd0a..ba852095 100644 --- a/modules/weatherservices/weather/display.go +++ b/modules/weatherservices/weather/display.go @@ -29,7 +29,7 @@ func (widget *Widget) display() { if err != "" { content = err } else { - title = widget.title(cityData) + title = widget.buildTitle(cityData) _, _, width, _ := widget.View.GetRect() content = widget.settings.common.SigilStr(len(widget.Data), widget.Idx, width) + "\n" content = content + widget.description(cityData) + "\n\n" @@ -73,8 +73,6 @@ func (widget *Widget) temperatures(cityData *owm.CurrentWeatherData) string { return str } -func (widget *Widget) title(cityData *owm.CurrentWeatherData) string { - str := fmt.Sprintf("%s %s", widget.emojiFor(cityData), cityData.Name) - return str - // return widget.ContextualTitle(str) +func (widget *Widget) buildTitle(cityData *owm.CurrentWeatherData) string { + return fmt.Sprintf("%s %s", widget.emojiFor(cityData), cityData.Name) } From 0b59a3b62f48c41f8de89e8d918492313d05364a Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 08:40:42 -0700 Subject: [PATCH 11/25] Fix slow render of new item modal in Todo --- modules/todo/widget.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/todo/widget.go b/modules/todo/widget.go index 8e0c7f8e..bc8e3852 100644 --- a/modules/todo/widget.go +++ b/modules/todo/widget.go @@ -144,6 +144,10 @@ func (widget *Widget) newItem() { widget.addButtons(form, saveFctn) widget.modalFocus(form) + + widget.app.QueueUpdate(func() { + widget.app.Draw() + }) } // persist writes the todo list to Yaml file From bc0813b8c7f070743a008003ceb05f0b3d306d7c Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 08:47:31 -0700 Subject: [PATCH 12/25] Add Windows build support in goreleaser config --- .goreleaser.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index ba068113..28c8c267 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -7,6 +7,7 @@ builds: goos: - darwin - linux + - windows goarch: - 386 - amd64 From 6765404beea68024af1b8791f46af2cfad5b77b6 Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Fri, 10 May 2019 14:27:26 -0400 Subject: [PATCH 13/25] Add help text to zendesk widget It has keyboard input, so should have a help page --- maker/widget_maker.go | 2 +- modules/zendesk/widget.go | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/maker/widget_maker.go b/maker/widget_maker.go index 4e460d2e..6a40a1d8 100644 --- a/maker/widget_maker.go +++ b/maker/widget_maker.go @@ -198,7 +198,7 @@ func MakeWidget( widget = weather.NewWidget(app, pages, settings) case "zendesk": settings := zendesk.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) - widget = zendesk.NewWidget(app, settings) + widget = zendesk.NewWidget(app, pages, settings) default: settings := unknown.NewSettingsFromYAML(widgetName, moduleConfig, globalConfig) widget = unknown.NewWidget(app, settings) diff --git a/modules/zendesk/widget.go b/modules/zendesk/widget.go index 8882c54f..4f57b582 100644 --- a/modules/zendesk/widget.go +++ b/modules/zendesk/widget.go @@ -8,8 +8,23 @@ import ( "github.com/wtfutil/wtf/wtf" ) +const HelpText = ` + Keyboard commands for Zendesk: + + /: Show/hide this help window + j: Select the next item in the list + k: Select the previous item in the list + o: Open the selected item in a browser + + arrow down: Select the next item in the list + arrow up: Select the previous item in the list + + return: Open the selected item in a browser +` + // A Widget represents a Zendesk widget type Widget struct { + wtf.HelpfulWidget wtf.KeyboardWidget wtf.TextWidget @@ -19,8 +34,9 @@ type Widget struct { } // NewWidget creates a new instance of a widget -func NewWidget(app *tview.Application, settings *Settings) *Widget { +func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), From 210723cd74fba962a156679e7eedc63ec2f9359c Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Thu, 9 May 2019 22:43:01 -0400 Subject: [PATCH 14/25] Create abtract scrollable widget This cleans up a bunch of boilerplate for scrollable items and standardizes their usage --- modules/datadog/keyboard.go | 10 ++-- modules/datadog/widget.go | 76 ++++++--------------------- modules/gitter/keyboard.go | 10 ++-- modules/gitter/widget.go | 70 +++++-------------------- modules/hackernews/keyboard.go | 13 +++-- modules/hackernews/widget.go | 96 +++++++++------------------------- modules/jenkins/keyboard.go | 10 ++-- modules/jenkins/widget.go | 66 +++++------------------ modules/jira/keyboard.go | 20 ++----- modules/jira/widget.go | 62 +++++----------------- modules/rollbar/keyboard.go | 12 ++--- modules/rollbar/widget.go | 56 +++++--------------- modules/travisci/keyboard.go | 10 ++-- modules/travisci/widget.go | 56 +++++--------------- modules/zendesk/keyboard.go | 20 ++----- modules/zendesk/widget.go | 36 ++++--------- wtf/scrollable.go | 79 ++++++++++++++++++++++++++++ 17 files changed, 232 insertions(+), 470 deletions(-) create mode 100644 wtf/scrollable.go diff --git a/modules/datadog/keyboard.go b/modules/datadog/keyboard.go index af9b18e5..58daa141 100644 --- a/modules/datadog/keyboard.go +++ b/modules/datadog/keyboard.go @@ -6,12 +6,12 @@ import ( func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp) - widget.SetKeyboardChar("j", widget.next) - widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("o", widget.openItem) - widget.SetKeyboardKey(tcell.KeyDown, widget.next) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) widget.SetKeyboardKey(tcell.KeyEnter, widget.openItem) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) - widget.SetKeyboardKey(tcell.KeyUp, widget.prev) + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) } diff --git a/modules/datadog/widget.go b/modules/datadog/widget.go index 137dfbf1..3f9dbb79 100644 --- a/modules/datadog/widget.go +++ b/modules/datadog/widget.go @@ -2,7 +2,6 @@ package datadog import ( "fmt" - "strconv" "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" @@ -24,31 +23,26 @@ const HelpText = ` type Widget struct { wtf.HelpfulWidget - wtf.TextWidget wtf.KeyboardWidget + wtf.ScrollableWidget - app *tview.Application - selected int monitors []datadog.Monitor settings *Settings } func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), settings: settings, } + widget.SetRenderFunction(widget.Render) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - - widget.View.SetScrollable(true) - widget.View.SetRegions(true) widget.HelpfulWidget.SetView(widget.View) return &widget @@ -59,14 +53,10 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * func (widget *Widget) Refresh() { monitors, monitorErr := widget.Monitors() - var content string if monitorErr != nil { - widget.View.SetWrap(true) - content = monitorErr.Error() - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.SetText(content) - }) + widget.monitors = nil + widget.SetItemCount(0) + widget.Redraw(widget.CommonSettings.Title, monitorErr.Error(), true) return } triggeredMonitors := []datadog.Monitor{} @@ -79,19 +69,14 @@ func (widget *Widget) Refresh() { } } widget.monitors = triggeredMonitors + widget.SetItemCount(len(widget.monitors)) - widget.display() + widget.Render() } -func (widget *Widget) display() { +func (widget *Widget) Render() { content := widget.contentFrom(widget.monitors) - widget.app.QueueUpdateDraw(func() { - widget.View.SetWrap(false) - widget.View.Clear() - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.SetText(content) - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() - }) + widget.Redraw(widget.CommonSettings.Title, content, false) } /* -------------------- Unexported Functions -------------------- */ @@ -107,9 +92,9 @@ func (widget *Widget) contentFrom(triggeredMonitors []datadog.Monitor) string { for idx, triggeredMonitor := range triggeredMonitors { str = str + fmt.Sprintf(`["%d"][%s][red] %s[%s][""]`, idx, - widget.rowColor(idx), + widget.RowColor(idx), *triggeredMonitor.Name, - widget.rowColor(idx), + widget.RowColor(idx), ) + "\n" } } else { @@ -122,40 +107,11 @@ func (widget *Widget) contentFrom(triggeredMonitors []datadog.Monitor) string { return str } -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} - -func (widget *Widget) next() { - widget.selected++ - if widget.monitors != nil && widget.selected >= len(widget.monitors) { - widget.selected = 0 - } - widget.display() -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.monitors != nil { - widget.selected = len(widget.monitors) - 1 - } - widget.display() -} - func (widget *Widget) openItem() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.monitors != nil && sel < len(widget.monitors) { - item := &widget.monitors[widget.selected] + item := &widget.monitors[sel] wtf.OpenFile(fmt.Sprintf("https://app.datadoghq.com/monitors/%d?q=*", *item.Id)) } } - -func (widget *Widget) rowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { - widget.settings.common.DefaultFocussedRowColor() - } - - return widget.settings.common.RowColor(idx) -} diff --git a/modules/gitter/keyboard.go b/modules/gitter/keyboard.go index 250b2f8a..77abbc84 100644 --- a/modules/gitter/keyboard.go +++ b/modules/gitter/keyboard.go @@ -4,11 +4,11 @@ import "github.com/gdamore/tcell" func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp) - widget.SetKeyboardChar("j", widget.next) - widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("r", widget.Refresh) - widget.SetKeyboardKey(tcell.KeyDown, widget.next) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) - widget.SetKeyboardKey(tcell.KeyUp, widget.prev) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) } diff --git a/modules/gitter/widget.go b/modules/gitter/widget.go index 4bf7ff2c..a0976871 100644 --- a/modules/gitter/widget.go +++ b/modules/gitter/widget.go @@ -2,7 +2,6 @@ package gitter import ( "fmt" - "strconv" "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" @@ -24,34 +23,26 @@ const HelpText = ` type Widget struct { wtf.HelpfulWidget wtf.KeyboardWidget - wtf.TextWidget - - app *tview.Application + wtf.ScrollableWidget messages []Message - selected int settings *Settings } // NewWidget creates a new instance of a widget func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), - app: app, settings: settings, } + widget.SetRenderFunction(widget.Refresh) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - - widget.View.SetScrollable(true) - widget.View.SetRegions(true) - widget.HelpfulWidget.SetView(widget.View) return &widget @@ -66,25 +57,23 @@ func (widget *Widget) Refresh() { room, err := GetRoom(widget.settings.roomURI, widget.settings.apiToken) if err != nil { - widget.View.SetWrap(true) - widget.View.SetTitle(widget.CommonSettings.Title) - widget.View.SetText(err.Error()) + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) return } if room == nil { + widget.Redraw(widget.CommonSettings.Title, "No room", true) return } messages, err := GetMessages(room.ID, widget.settings.numberOfMessages, widget.settings.apiToken) if err != nil { - widget.View.SetWrap(true) - widget.Redraw(widget.CommonSettings.Title, err.Error(), true) return } widget.messages = messages + widget.SetItemCount(len(messages)) widget.display() } @@ -99,10 +88,6 @@ func (widget *Widget) display() { title := fmt.Sprintf("%s - %s", widget.CommonSettings.Title, widget.settings.roomURI) widget.Redraw(title, widget.contentFrom(widget.messages), true) - widget.app.QueueUpdateDraw(func() { - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() - widget.View.ScrollToEnd() - }) } func (widget *Widget) contentFrom(messages []Message) string { @@ -111,10 +96,10 @@ func (widget *Widget) contentFrom(messages []Message) string { str = str + fmt.Sprintf( `["%d"][%s] [blue]%s [lightslategray]%s: [%s]%s [aqua]%s[""]`, idx, - widget.rowColor(idx), + widget.RowColor(idx), message.From.DisplayName, message.From.Username, - widget.rowColor(idx), + widget.RowColor(idx), message.Text, message.Sent.Format("Jan 02, 15:04 MST"), ) @@ -125,41 +110,10 @@ func (widget *Widget) contentFrom(messages []Message) string { return str } -func (widget *Widget) rowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { - return widget.settings.common.DefaultFocussedRowColor() - } - - return widget.settings.common.RowColor(idx) -} - -func (widget *Widget) next() { - widget.selected++ - if widget.messages != nil && widget.selected >= len(widget.messages) { - widget.selected = 0 - } - - widget.display() -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.messages != nil { - widget.selected = len(widget.messages) - 1 - } - - widget.display() -} - func (widget *Widget) openMessage() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.messages != nil && sel < len(widget.messages) { - message := &widget.messages[widget.selected] + message := &widget.messages[sel] wtf.OpenFile(message.Text) } } - -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} diff --git a/modules/hackernews/keyboard.go b/modules/hackernews/keyboard.go index afa89ff6..ef305ba4 100644 --- a/modules/hackernews/keyboard.go +++ b/modules/hackernews/keyboard.go @@ -1,18 +1,17 @@ - package hackernews import "github.com/gdamore/tcell" func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp) - widget.SetKeyboardChar("j", widget.next) - widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("o", widget.openStory) widget.SetKeyboardChar("r", widget.Refresh) widget.SetKeyboardChar("c", widget.openComments) - widget.SetKeyboardKey(tcell.KeyDown, widget.next) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) widget.SetKeyboardKey(tcell.KeyEnter, widget.openStory) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) - widget.SetKeyboardKey(tcell.KeyUp, widget.prev) -} \ No newline at end of file + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) +} diff --git a/modules/hackernews/widget.go b/modules/hackernews/widget.go index b8c97803..44a15328 100644 --- a/modules/hackernews/widget.go +++ b/modules/hackernews/widget.go @@ -3,7 +3,6 @@ package hackernews import ( "fmt" "net/url" - "strconv" "strings" "github.com/rivo/tview" @@ -28,33 +27,25 @@ const HelpText = ` type Widget struct { wtf.HelpfulWidget wtf.KeyboardWidget - wtf.TextWidget - - app *tview.Application + wtf.ScrollableWidget stories []Story - selected int settings *Settings } func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), - app: app, settings: settings, } + widget.SetRenderFunction(widget.Render) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - - widget.View.SetScrollable(true) - widget.View.SetRegions(true) - widget.HelpfulWidget.SetView(widget.View) return &widget @@ -73,38 +64,34 @@ func (widget *Widget) Refresh() { } if err != nil { - widget.View.SetWrap(true) - widget.View.SetTitle(widget.ContextualTitle(widget.CommonSettings.Title)) - widget.View.SetText(err.Error()) - } else { - var stories []Story - for idx := 0; idx < widget.settings.numberOfStories; idx++ { - story, e := GetStory(storyIds[idx]) - if e != nil { - // panic(e) - } else { - stories = append(stories, story) - } + widget.Redraw(widget.CommonSettings.Title, err.Error(), true) + return + } + var stories []Story + for idx := 0; idx < widget.settings.numberOfStories; idx++ { + story, e := GetStory(storyIds[idx]) + if e != nil { + // panic(e) + } else { + stories = append(stories, story) } - - widget.stories = stories } - widget.display() + widget.stories = stories + widget.SetItemCount(len(stories)) + + widget.Render() } /* -------------------- Unexported Functions -------------------- */ -func (widget *Widget) display() { +func (widget *Widget) Render() { if widget.stories == nil { return } title := fmt.Sprintf("%s - %sstories", widget.CommonSettings.Title, widget.settings.storyType) widget.Redraw(title, widget.contentFrom(widget.stories), false) - widget.app.QueueUpdateDraw(func() { - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() - }) } func (widget *Widget) contentFrom(stories []Story) string { @@ -114,9 +101,9 @@ func (widget *Widget) contentFrom(stories []Story) string { str = str + fmt.Sprintf( `["%d"][""][%s] [yellow]%d. [%s]%s [blue](%s)[""]`, idx, - widget.rowColor(idx), + widget.RowColor(idx), idx+1, - widget.rowColor(idx), + widget.RowColor(idx), story.Title, strings.TrimPrefix(u.Host, "www."), ) @@ -127,49 +114,18 @@ func (widget *Widget) contentFrom(stories []Story) string { return str } -func (widget *Widget) rowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { - return widget.settings.common.DefaultFocussedRowColor() - } - - return widget.settings.common.RowColor(idx) -} - -func (widget *Widget) next() { - widget.selected++ - if widget.stories != nil && widget.selected >= len(widget.stories) { - widget.selected = 0 - } - - widget.display() -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.stories != nil { - widget.selected = len(widget.stories) - 1 - } - - widget.display() -} - func (widget *Widget) openStory() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.stories != nil && sel < len(widget.stories) { - story := &widget.stories[widget.selected] + story := &widget.stories[sel] wtf.OpenFile(story.URL) } } func (widget *Widget) openComments() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.stories != nil && sel < len(widget.stories) { - story := &widget.stories[widget.selected] + story := &widget.stories[sel] wtf.OpenFile(fmt.Sprintf("https://news.ycombinator.com/item?id=%d", story.ID)) } } - -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} diff --git a/modules/jenkins/keyboard.go b/modules/jenkins/keyboard.go index 1ed01883..20735a3f 100644 --- a/modules/jenkins/keyboard.go +++ b/modules/jenkins/keyboard.go @@ -4,13 +4,13 @@ import "github.com/gdamore/tcell" func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp) - widget.SetKeyboardChar("j", widget.next) - widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("o", widget.openJob) widget.SetKeyboardChar("r", widget.Refresh) - widget.SetKeyboardKey(tcell.KeyDown, widget.next) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) widget.SetKeyboardKey(tcell.KeyEnter, widget.openJob) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) - widget.SetKeyboardKey(tcell.KeyUp, widget.prev) + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) } diff --git a/modules/jenkins/widget.go b/modules/jenkins/widget.go index 3d453e40..9db9a7d1 100644 --- a/modules/jenkins/widget.go +++ b/modules/jenkins/widget.go @@ -2,8 +2,6 @@ package jenkins import ( "fmt" - "strconv" - "regexp" "github.com/rivo/tview" @@ -27,33 +25,25 @@ const HelpText = ` type Widget struct { wtf.HelpfulWidget wtf.KeyboardWidget - wtf.TextWidget + wtf.ScrollableWidget - app *tview.Application - - selected int settings *Settings view *View } func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), - app: app, settings: settings, } + widget.SetRenderFunction(widget.Render) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - - widget.View.SetScrollable(true) - widget.View.SetRegions(true) - widget.HelpfulWidget.SetView(widget.View) return &widget @@ -78,12 +68,14 @@ func (widget *Widget) Refresh() { return } - widget.display() + widget.SetItemCount(len(widget.view.Jobs)) + + widget.Render() } /* -------------------- Unexported Functions -------------------- */ -func (widget *Widget) display() { +func (widget *Widget) Render() { if widget.view == nil { return } @@ -91,9 +83,6 @@ func (widget *Widget) display() { title := fmt.Sprintf("%s: [red]%s", widget.CommonSettings.Title, widget.view.Name) widget.Redraw(title, widget.contentFrom(widget.view), false) - widget.app.QueueUpdateDraw(func() { - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() - }) } func (widget *Widget) contentFrom(view *View) string { @@ -105,7 +94,7 @@ func (widget *Widget) contentFrom(view *View) string { str = str + fmt.Sprintf( `["%d"][%s] [%s]%-6s[white][""]`, idx, - widget.rowColor(idx), + widget.RowColor(idx), widget.jobColor(&job), job.Name, ) @@ -117,14 +106,6 @@ func (widget *Widget) contentFrom(view *View) string { return str } -func (widget *Widget) rowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { - return widget.settings.common.DefaultFocussedRowColor() - } - - return widget.settings.common.RowColor(idx) -} - func (widget *Widget) jobColor(job *Job) string { switch job.Color { case "blue": @@ -137,33 +118,10 @@ func (widget *Widget) jobColor(job *Job) string { } } -func (widget *Widget) next() { - widget.selected++ - if widget.view != nil && widget.selected >= len(widget.view.Jobs) { - widget.selected = 0 - } - - widget.display() -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.view != nil { - widget.selected = len(widget.view.Jobs) - 1 - } - - widget.display() -} - func (widget *Widget) openJob() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.view != nil && sel < len(widget.view.Jobs) { - job := &widget.view.Jobs[widget.selected] + job := &widget.view.Jobs[sel] wtf.OpenFile(job.Url) } } - -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} diff --git a/modules/jira/keyboard.go b/modules/jira/keyboard.go index e6178a8a..b89b27da 100644 --- a/modules/jira/keyboard.go +++ b/modules/jira/keyboard.go @@ -6,22 +6,12 @@ import ( func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp) - widget.SetKeyboardChar("j", widget.selectNext) - widget.SetKeyboardChar("k", widget.selectPrev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("o", widget.openItem) - widget.SetKeyboardKey(tcell.KeyDown, widget.selectNext) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) widget.SetKeyboardKey(tcell.KeyEnter, widget.openItem) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) - widget.SetKeyboardKey(tcell.KeyUp, widget.selectPrev) -} - -func (widget *Widget) selectNext() { - widget.next() - widget.display() -} - -func (widget *Widget) selectPrev() { - widget.prev() - widget.display() + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) } diff --git a/modules/jira/widget.go b/modules/jira/widget.go index e7bf259f..ba1b8008 100644 --- a/modules/jira/widget.go +++ b/modules/jira/widget.go @@ -2,7 +2,6 @@ package jira import ( "fmt" - "strconv" "github.com/rivo/tview" "github.com/wtfutil/wtf/wtf" @@ -24,33 +23,25 @@ const HelpText = ` type Widget struct { wtf.HelpfulWidget wtf.KeyboardWidget - wtf.TextWidget - - app *tview.Application + wtf.ScrollableWidget result *SearchResult - selected int settings *Settings } func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), - app: app, settings: settings, } + widget.SetRenderFunction(widget.Render) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - - widget.View.SetScrollable(true) - widget.View.SetRegions(true) - widget.HelpfulWidget.SetView(widget.View) return &widget @@ -71,12 +62,13 @@ func (widget *Widget) Refresh() { return } widget.result = searchResult - widget.display() + widget.SetItemCount(len(searchResult.Issues)) + widget.Render() } /* -------------------- Unexported Functions -------------------- */ -func (widget *Widget) display() { +func (widget *Widget) Render() { if widget.result == nil { return } @@ -84,38 +76,16 @@ func (widget *Widget) display() { str := fmt.Sprintf("%s- [green]%s[white]", widget.CommonSettings.Title, widget.settings.projects) widget.Redraw(str, widget.contentFrom(widget.result), false) - widget.app.QueueUpdateDraw(func() { - widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() - }) -} - -func (widget *Widget) next() { - widget.selected++ - if widget.result != nil && widget.selected >= len(widget.result.Issues) { - widget.selected = 0 - } -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.result != nil { - widget.selected = len(widget.result.Issues) - 1 - } } func (widget *Widget) openItem() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.result != nil && sel < len(widget.result.Issues) { - issue := &widget.result.Issues[widget.selected] + issue := &widget.result.Issues[sel] wtf.OpenFile(widget.settings.domain + "/browse/" + issue.Key) } } -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} - func (widget *Widget) contentFrom(searchResult *SearchResult) string { str := " [red]Assigned Issues[white]\n" @@ -123,12 +93,12 @@ func (widget *Widget) contentFrom(searchResult *SearchResult) string { fmtStr := fmt.Sprintf( `["%d"][%s] [%s]%-6s[white] [green]%-10s[white] [yellow][%s][white] [%s]%s[""]`, idx, - widget.rowColor(idx), + widget.RowColor(idx), widget.issueTypeColor(&issue), issue.IssueFields.IssueType.Name, issue.Key, issue.IssueFields.IssueStatus.IName, - widget.rowColor(idx), + widget.RowColor(idx), issue.IssueFields.Summary, ) @@ -141,14 +111,6 @@ func (widget *Widget) contentFrom(searchResult *SearchResult) string { return str } -func (widget *Widget) rowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { - widget.settings.common.DefaultFocussedRowColor() - } - - return widget.settings.common.RowColor(idx) -} - func (widget *Widget) issueTypeColor(issue *Issue) string { switch issue.IssueFields.IssueType.Name { case "Bug": diff --git a/modules/rollbar/keyboard.go b/modules/rollbar/keyboard.go index 7a43b83a..a89e6ec1 100644 --- a/modules/rollbar/keyboard.go +++ b/modules/rollbar/keyboard.go @@ -4,14 +4,14 @@ import "github.com/gdamore/tcell" func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp) - widget.SetKeyboardChar("j", widget.next) - widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("o", widget.openBuild) widget.SetKeyboardChar("r", widget.Refresh) - widget.SetKeyboardChar("u", widget.unselect) + widget.SetKeyboardChar("u", widget.Unselect) - widget.SetKeyboardKey(tcell.KeyDown, widget.next) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) widget.SetKeyboardKey(tcell.KeyEnter, widget.openBuild) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) - widget.SetKeyboardKey(tcell.KeyUp, widget.prev) + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) } diff --git a/modules/rollbar/widget.go b/modules/rollbar/widget.go index 8b23af71..fa847ae0 100644 --- a/modules/rollbar/widget.go +++ b/modules/rollbar/widget.go @@ -26,28 +26,26 @@ const HelpText = ` type Widget struct { wtf.HelpfulWidget wtf.KeyboardWidget - wtf.TextWidget + wtf.ScrollableWidget items *Result - selected int settings *Settings } // NewWidget creates a new instance of a widget func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), settings: settings, } + widget.SetRenderFunction(widget.Render) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - widget.HelpfulWidget.SetView(widget.View) return &widget @@ -71,13 +69,14 @@ func (widget *Widget) Refresh() { return } widget.items = &items.Results + widget.SetItemCount(len(widget.items.Items)) - widget.display() + widget.Refresh() } /* -------------------- Unexported Functions -------------------- */ -func (widget *Widget) display() { +func (widget *Widget) Render() { if widget.items == nil { return } @@ -98,12 +97,12 @@ func (widget *Widget) contentFrom(result *Result) string { str = str + fmt.Sprintf( "[%s] [%s] %s [%s] %s [%s]count: %d [%s]%s\n", - widget.rowColor(idx), + widget.RowColor(idx), levelColor(&item), item.Level, statusColor(&item), item.Title, - widget.rowColor(idx), + widget.RowColor(idx), item.TotalOccurrences, "blue", item.Environment, @@ -113,14 +112,6 @@ func (widget *Widget) contentFrom(result *Result) string { return str } -func (widget *Widget) rowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { - return widget.settings.common.DefaultFocussedRowColor() - } - - return widget.settings.common.RowColor(idx) -} - func statusColor(item *Item) string { switch item.Status { case "active": @@ -144,27 +135,9 @@ func levelColor(item *Item) string { } } -func (widget *Widget) next() { - widget.selected++ - if widget.items != nil && widget.selected >= len(widget.items.Items) { - widget.selected = 0 - } - - widget.display() -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.items.Items != nil { - widget.selected = len(widget.items.Items) - 1 - } - - widget.display() -} - func (widget *Widget) openBuild() { - if widget.selected >= 0 && widget.items != nil && widget.selected < len(widget.items.Items) { - item := &widget.items.Items[widget.selected] + if widget.GetSelected() >= 0 && widget.items != nil && widget.GetSelected() < len(widget.items.Items) { + item := &widget.items.Items[widget.GetSelected()] wtf.OpenFile( fmt.Sprintf( @@ -177,8 +150,3 @@ func (widget *Widget) openBuild() { ) } } - -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} diff --git a/modules/travisci/keyboard.go b/modules/travisci/keyboard.go index 55f9d455..b8143aec 100644 --- a/modules/travisci/keyboard.go +++ b/modules/travisci/keyboard.go @@ -4,13 +4,13 @@ import "github.com/gdamore/tcell" func (widget *Widget) initializeKeyboardControls() { widget.SetKeyboardChar("/", widget.ShowHelp) - widget.SetKeyboardChar("j", widget.next) - widget.SetKeyboardChar("k", widget.prev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("o", widget.openBuild) widget.SetKeyboardChar("r", widget.Refresh) - widget.SetKeyboardKey(tcell.KeyDown, widget.next) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) widget.SetKeyboardKey(tcell.KeyEnter, widget.openBuild) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) - widget.SetKeyboardKey(tcell.KeyUp, widget.prev) + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) } diff --git a/modules/travisci/widget.go b/modules/travisci/widget.go index 0a385e4e..49170a43 100644 --- a/modules/travisci/widget.go +++ b/modules/travisci/widget.go @@ -25,27 +25,25 @@ const HelpText = ` type Widget struct { wtf.HelpfulWidget wtf.KeyboardWidget - wtf.TextWidget + wtf.ScrollableWidget builds *Builds - selected int settings *Settings } func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), settings: settings, } + widget.SetRenderFunction(widget.Render) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) - widget.unselect() - widget.HelpfulWidget.SetView(widget.View) return &widget @@ -65,12 +63,13 @@ func (widget *Widget) Refresh() { return } widget.builds = builds - widget.display() + widget.SetItemCount(len(builds.Builds)) + widget.Render() } /* -------------------- Unexported Functions -------------------- */ -func (widget *Widget) display() { +func (widget *Widget) Render() { if widget.builds == nil { return } @@ -85,12 +84,12 @@ func (widget *Widget) contentFrom(builds *Builds) string { str = str + fmt.Sprintf( "[%s] [%s] %s-%s (%s) [%s]%s - [blue]%s\n", - widget.rowColor(idx), + widget.RowColor(idx), buildColor(&build), build.Repository.Name, build.Number, build.Branch.Name, - widget.rowColor(idx), + widget.RowColor(idx), strings.Split(build.Commit.Message, "\n")[0], build.CreatedBy.Login, ) @@ -99,14 +98,6 @@ func (widget *Widget) contentFrom(builds *Builds) string { return str } -func (widget *Widget) rowColor(idx int) string { - if widget.View.HasFocus() && (idx == widget.selected) { - return widget.settings.common.DefaultFocussedRowColor() - } - - return widget.settings.common.RowColor(idx) -} - func buildColor(build *Build) string { switch build.State { case "broken": @@ -128,34 +119,11 @@ func buildColor(build *Build) string { } } -func (widget *Widget) next() { - widget.selected++ - if widget.builds != nil && widget.selected >= len(widget.builds.Builds) { - widget.selected = 0 - } - - widget.display() -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.builds != nil { - widget.selected = len(widget.builds.Builds) - 1 - } - - widget.display() -} - func (widget *Widget) openBuild() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.builds != nil && sel < len(widget.builds.Builds) { - build := &widget.builds.Builds[widget.selected] + build := &widget.builds.Builds[sel] travisHost := TRAVIS_HOSTS[widget.settings.pro] wtf.OpenFile(fmt.Sprintf("https://%s/%s/%s/%d", travisHost, build.Repository.Slug, "builds", build.ID)) } } - -func (widget *Widget) unselect() { - widget.selected = -1 - widget.display() -} diff --git a/modules/zendesk/keyboard.go b/modules/zendesk/keyboard.go index 9ccc6e31..0c59044c 100644 --- a/modules/zendesk/keyboard.go +++ b/modules/zendesk/keyboard.go @@ -3,22 +3,12 @@ package zendesk import "github.com/gdamore/tcell" func (widget *Widget) initializeKeyboardControls() { - widget.SetKeyboardChar("j", widget.selectNext) - widget.SetKeyboardChar("k", widget.selectPrev) + widget.SetKeyboardChar("j", widget.Next) + widget.SetKeyboardChar("k", widget.Prev) widget.SetKeyboardChar("o", widget.openTicket) - widget.SetKeyboardKey(tcell.KeyDown, widget.selectNext) - widget.SetKeyboardKey(tcell.KeyUp, widget.selectPrev) + widget.SetKeyboardKey(tcell.KeyDown, widget.Next) + widget.SetKeyboardKey(tcell.KeyUp, widget.Prev) widget.SetKeyboardKey(tcell.KeyEnter, widget.openTicket) - widget.SetKeyboardKey(tcell.KeyEsc, widget.unselect) -} - -func (widget *Widget) selectNext() { - widget.next() - widget.display() -} - -func (widget *Widget) selectPrev() { - widget.prev() - widget.display() + widget.SetKeyboardKey(tcell.KeyEsc, widget.Unselect) } diff --git a/modules/zendesk/widget.go b/modules/zendesk/widget.go index 8882c54f..1d9caf51 100644 --- a/modules/zendesk/widget.go +++ b/modules/zendesk/widget.go @@ -11,22 +11,22 @@ import ( // A Widget represents a Zendesk widget type Widget struct { wtf.KeyboardWidget - wtf.TextWidget + wtf.ScrollableWidget result *TicketArray - selected int settings *Settings } // NewWidget creates a new instance of a widget func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ - KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), + KeyboardWidget: wtf.NewKeyboardWidget(), + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), settings: settings, } + widget.SetRenderFunction(widget.Render) widget.initializeKeyboardControls() widget.View.SetInputCapture(widget.InputCapture) @@ -44,12 +44,12 @@ func (widget *Widget) Refresh() { widget.result = ticketArray } - widget.display() + widget.Render() } /* -------------------- Unexported Functions -------------------- */ -func (widget *Widget) display() { +func (widget *Widget) Render() { title := fmt.Sprintf("%s (%d)", widget.CommonSettings.Title, widget.result.Count) widget.Redraw(title, widget.textContent(widget.result.Tickets), false) } @@ -69,7 +69,7 @@ func (widget *Widget) textContent(items []Ticket) string { func (widget *Widget) format(ticket Ticket, idx int) string { textColor := widget.settings.common.Colors.Background - if idx == widget.selected { + if idx == widget.GetSelected() { textColor = widget.settings.common.Colors.BorderFocused } @@ -91,29 +91,11 @@ func (widget *Widget) parseRequester(ticket Ticket) interface{} { return fromName } -func (widget *Widget) next() { - widget.selected++ - if widget.result != nil && widget.selected >= len(widget.result.Tickets) { - widget.selected = 0 - } -} - -func (widget *Widget) prev() { - widget.selected-- - if widget.selected < 0 && widget.result != nil { - widget.selected = len(widget.result.Tickets) - 1 - } -} - func (widget *Widget) openTicket() { - sel := widget.selected + sel := widget.GetSelected() if sel >= 0 && widget.result != nil && sel < len(widget.result.Tickets) { - issue := &widget.result.Tickets[widget.selected] + issue := &widget.result.Tickets[sel] ticketURL := fmt.Sprintf("https://%s.zendesk.com/agent/tickets/%d", widget.settings.subdomain, issue.Id) wtf.OpenFile(ticketURL) } } - -func (widget *Widget) unselect() { - widget.selected = -1 -} diff --git a/wtf/scrollable.go b/wtf/scrollable.go new file mode 100644 index 00000000..a81e0277 --- /dev/null +++ b/wtf/scrollable.go @@ -0,0 +1,79 @@ +package wtf + +import ( + "strconv" + + "github.com/rivo/tview" + "github.com/wtfutil/wtf/cfg" +) + +type ScrollableWidget struct { + TextWidget + + selected int + maxItems int + RenderFunction func() +} + +func NewScrollableWidget(app *tview.Application, commonSettings *cfg.Common, focusable bool) ScrollableWidget { + + widget := ScrollableWidget{ + TextWidget: NewTextWidget(app, commonSettings, focusable), + } + + widget.Unselect() + widget.View.SetScrollable(true) + widget.View.SetRegions(true) + return widget +} + +func (widget *ScrollableWidget) SetRenderFunction(displayFunc func()) { + widget.RenderFunction = displayFunc +} + +func (widget *ScrollableWidget) SetItemCount(items int) { + widget.maxItems = items +} + +func (widget *ScrollableWidget) GetSelected() int { + return widget.selected +} + +func (widget *ScrollableWidget) RowColor(idx int) string { + if widget.View.HasFocus() && (idx == widget.selected) { + widget.CommonSettings.DefaultFocussedRowColor() + } + + return widget.CommonSettings.RowColor(idx) +} + +func (widget *ScrollableWidget) Next() { + widget.selected++ + if widget.selected >= widget.maxItems { + widget.selected = 0 + } + widget.RenderFunction() +} + +func (widget *ScrollableWidget) Prev() { + widget.selected-- + if widget.selected < 0 { + widget.selected = widget.maxItems - 1 + } + widget.RenderFunction() +} + +func (widget *ScrollableWidget) Unselect() { + widget.selected = -1 + if widget.RenderFunction != nil { + widget.RenderFunction() + } +} + +func (widget *ScrollableWidget) Redraw(title, content string, wrap bool) { + + widget.TextWidget.Redraw(title, content, wrap) + widget.app.QueueUpdateDraw(func() { + widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight() + }) +} From 0d2667685e1ae9d64c21b7234087e3d095854005 Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Fri, 10 May 2019 18:46:31 -0400 Subject: [PATCH 15/25] Add stable sort for focusable windows Addresses #435 --- wtf/focus_tracker.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/wtf/focus_tracker.go b/wtf/focus_tracker.go index 002c5e10..de935c96 100644 --- a/wtf/focus_tracker.go +++ b/wtf/focus_tracker.go @@ -1,6 +1,8 @@ package wtf import ( + "sort" + "github.com/olebedev/config" "github.com/rivo/tview" ) @@ -177,6 +179,17 @@ func (tracker *FocusTracker) focusables() []Wtfable { } } + // Sort for deterministic ordering + sort.SliceStable(focusable[:], func(i, j int) bool { + if focusable[i].Top() < focusable[j].Top() { + return true + } + if focusable[i].Top() == focusable[j].Top() { + return focusable[i].Left() < focusable[j].Left() + } + return false + }) + return focusable } From c328ba4c11224ed1e76ea8b26be9db4b56b6d716 Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Fri, 10 May 2019 18:21:52 -0400 Subject: [PATCH 16/25] Split up logger and widget This allows us to use the logger from the wtf directory For example when trying to debug sort ordering in focus_tracker --- flags/flags.go | 4 +- logger/log.go | 111 ++----------------------- main.go | 3 +- maker/widget_maker.go | 2 +- modules/datadog/widget.go | 1 + modules/gcal/client.go | 6 +- modules/gspreadsheets/client.go | 3 +- {logger => modules/logger}/settings.go | 0 modules/logger/widget.go | 105 +++++++++++++++++++++++ modules/textfile/widget.go | 7 +- {wtf => utils}/homedir.go | 2 +- wtf/utils.go | 4 +- 12 files changed, 131 insertions(+), 117 deletions(-) rename {logger => modules/logger}/settings.go (100%) create mode 100644 modules/logger/widget.go rename {wtf => utils}/homedir.go (98%) diff --git a/flags/flags.go b/flags/flags.go index 8f3e9af9..05da8042 100644 --- a/flags/flags.go +++ b/flags/flags.go @@ -7,7 +7,7 @@ import ( goFlags "github.com/jessevdk/go-flags" "github.com/wtfutil/wtf/help" - "github.com/wtfutil/wtf/wtf" + "github.com/wtfutil/wtf/utils" ) type Flags struct { @@ -63,7 +63,7 @@ func (flags *Flags) Parse() { // If no config file is explicitly passed in as a param, // set the flag to the default config file if !flags.HasConfig() { - homeDir, err := wtf.Home() + homeDir, err := utils.Home() if err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) diff --git a/logger/log.go b/logger/log.go index 3e45aac8..c095ea42 100644 --- a/logger/log.go +++ b/logger/log.go @@ -1,46 +1,21 @@ package logger import ( - "fmt" "log" "os" "path/filepath" - "strings" - "github.com/rivo/tview" - "github.com/wtfutil/wtf/wtf" + "github.com/wtfutil/wtf/utils" ) -const maxBufferSize int64 = 1024 - -type Widget struct { - wtf.TextWidget - - app *tview.Application - filePath string - settings *Settings -} - -func NewWidget(app *tview.Application, settings *Settings) *Widget { - widget := Widget{ - TextWidget: wtf.NewTextWidget(app, settings.common, true), - - app: app, - filePath: logFilePath(), - settings: settings, - } - - return &widget -} - /* -------------------- Exported Functions -------------------- */ func Log(msg string) { - if logFileMissing() { + if LogFileMissing() { return } - f, err := os.OpenFile(logFilePath(), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) + f, err := os.OpenFile(LogFilePath(), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) if err != nil { log.Fatalf("error opening file: %v", err) } @@ -50,87 +25,15 @@ func Log(msg string) { log.Println(msg) } -// Refresh updates the onscreen contents of the widget -func (widget *Widget) Refresh() { - if logFileMissing() { - return - } - - logLines := widget.tailFile() - - widget.app.QueueUpdateDraw(func() { - widget.View.SetTitle(widget.CommonSettings.Title) - widget.View.SetText(widget.contentFrom(logLines)) - }) +func LogFileMissing() bool { + return LogFilePath() == "" } -/* -------------------- Unexported Functions -------------------- */ - -func (widget *Widget) contentFrom(logLines []string) string { - str := "" - - for _, line := range logLines { - chunks := strings.Split(line, " ") - - if len(chunks) >= 4 { - str = str + fmt.Sprintf( - "[green]%s[white] [yellow]%s[white] %s\n", - chunks[0], - chunks[1], - strings.Join(chunks[3:], " "), - ) - } - } - - return str -} - -func logFileMissing() bool { - return logFilePath() == "" -} - -func logFilePath() string { - dir, err := wtf.Home() +func LogFilePath() string { + dir, err := utils.Home() if err != nil { return "" } return filepath.Join(dir, ".config", "wtf", "log.txt") } - -func (widget *Widget) tailFile() []string { - file, err := os.Open(widget.filePath) - if err != nil { - return []string{} - } - defer file.Close() - - stat, err := file.Stat() - if err != nil { - return []string{} - } - - bufferSize := maxBufferSize - if maxBufferSize > stat.Size() { - bufferSize = stat.Size() - } - - startPos := stat.Size() - bufferSize - - buff := make([]byte, bufferSize) - _, err = file.ReadAt(buff, startPos) - if err != nil { - return []string{} - } - - logLines := strings.Split(string(buff), "\n") - - // Reverse the array of lines - // Offset by two to account for the blank line at the end - last := len(logLines) - 2 - for i := 0; i < len(logLines)/2; i++ { - logLines[i], logLines[last-i] = logLines[last-i], logLines[i] - } - - return logLines -} diff --git a/main.go b/main.go index 6cc080a3..1b6cb4e3 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( "github.com/wtfutil/wtf/cfg" "github.com/wtfutil/wtf/flags" "github.com/wtfutil/wtf/maker" + "github.com/wtfutil/wtf/utils" "github.com/wtfutil/wtf/wtf" ) @@ -65,7 +66,7 @@ func refreshAllWidgets(widgets []wtf.Wtfable) { func watchForConfigChanges(app *tview.Application, configFilePath string, grid *tview.Grid, pages *tview.Pages) { watch := watcher.New() - absPath, _ := wtf.ExpandHomeDir(configFilePath) + absPath, _ := utils.ExpandHomeDir(configFilePath) // Notify write events watch.FilterOps(watcher.Write) diff --git a/maker/widget_maker.go b/maker/widget_maker.go index 4e460d2e..309d9228 100644 --- a/maker/widget_maker.go +++ b/maker/widget_maker.go @@ -3,7 +3,6 @@ package maker import ( "github.com/olebedev/config" "github.com/rivo/tview" - "github.com/wtfutil/wtf/logger" "github.com/wtfutil/wtf/modules/bamboohr" "github.com/wtfutil/wtf/modules/bargraph" "github.com/wtfutil/wtf/modules/circleci" @@ -25,6 +24,7 @@ import ( "github.com/wtfutil/wtf/modules/ipaddresses/ipinfo" "github.com/wtfutil/wtf/modules/jenkins" "github.com/wtfutil/wtf/modules/jira" + "github.com/wtfutil/wtf/modules/logger" "github.com/wtfutil/wtf/modules/mercurial" "github.com/wtfutil/wtf/modules/nbascore" "github.com/wtfutil/wtf/modules/newrelic" diff --git a/modules/datadog/widget.go b/modules/datadog/widget.go index 137dfbf1..c15592be 100644 --- a/modules/datadog/widget.go +++ b/modules/datadog/widget.go @@ -39,6 +39,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), TextWidget: wtf.NewTextWidget(app, settings.common, true), + app: app, settings: settings, } diff --git a/modules/gcal/client.go b/modules/gcal/client.go index ee475af5..23c45601 100644 --- a/modules/gcal/client.go +++ b/modules/gcal/client.go @@ -19,7 +19,7 @@ import ( "time" "github.com/wtfutil/wtf/cfg" - "github.com/wtfutil/wtf/wtf" + "github.com/wtfutil/wtf/utils" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "google.golang.org/api/calendar/v3" @@ -30,7 +30,7 @@ import ( func (widget *Widget) Fetch() ([]*CalEvent, error) { ctx := context.Background() - secretPath, _ := wtf.ExpandHomeDir(widget.settings.secretFile) + secretPath, _ := utils.ExpandHomeDir(widget.settings.secretFile) b, err := ioutil.ReadFile(secretPath) if err != nil { @@ -123,7 +123,7 @@ func isAuthenticated() bool { } func (widget *Widget) authenticate() { - secretPath, _ := wtf.ExpandHomeDir(widget.settings.secretFile) + secretPath, _ := utils.ExpandHomeDir(widget.settings.secretFile) b, err := ioutil.ReadFile(secretPath) if err != nil { diff --git a/modules/gspreadsheets/client.go b/modules/gspreadsheets/client.go index 929f9748..e4adf75f 100644 --- a/modules/gspreadsheets/client.go +++ b/modules/gspreadsheets/client.go @@ -18,6 +18,7 @@ import ( "path/filepath" "strings" + "github.com/wtfutil/wtf/utils" "github.com/wtfutil/wtf/wtf" "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -29,7 +30,7 @@ import ( func (widget *Widget) Fetch() ([]*sheets.ValueRange, error) { ctx := context.Background() - secretPath, _ := wtf.ExpandHomeDir(widget.settings.secretFile) + secretPath, _ := utils.ExpandHomeDir(widget.settings.secretFile) b, err := ioutil.ReadFile(secretPath) if err != nil { diff --git a/logger/settings.go b/modules/logger/settings.go similarity index 100% rename from logger/settings.go rename to modules/logger/settings.go diff --git a/modules/logger/widget.go b/modules/logger/widget.go new file mode 100644 index 00000000..b58d10e6 --- /dev/null +++ b/modules/logger/widget.go @@ -0,0 +1,105 @@ +package logger + +import ( + "fmt" + "os" + "strings" + + "github.com/rivo/tview" + log "github.com/wtfutil/wtf/logger" + "github.com/wtfutil/wtf/wtf" +) + +const maxBufferSize int64 = 1024 + +type Widget struct { + wtf.TextWidget + + app *tview.Application + filePath string + settings *Settings +} + +func NewWidget(app *tview.Application, settings *Settings) *Widget { + widget := Widget{ + TextWidget: wtf.NewTextWidget(app, settings.common, true), + + app: app, + filePath: log.LogFilePath(), + settings: settings, + } + + return &widget +} + +// Refresh updates the onscreen contents of the widget +func (widget *Widget) Refresh() { + if log.LogFileMissing() { + return + } + + logLines := widget.tailFile() + + widget.app.QueueUpdateDraw(func() { + widget.View.SetTitle(widget.CommonSettings.Title) + widget.View.SetText(widget.contentFrom(logLines)) + }) +} + +/* -------------------- Unexported Functions -------------------- */ + +func (widget *Widget) contentFrom(logLines []string) string { + str := "" + + for _, line := range logLines { + chunks := strings.Split(line, " ") + + if len(chunks) >= 4 { + str = str + fmt.Sprintf( + "[green]%s[white] [yellow]%s[white] %s\n", + chunks[0], + chunks[1], + strings.Join(chunks[3:], " "), + ) + } + } + + return str +} + +func (widget *Widget) tailFile() []string { + file, err := os.Open(widget.filePath) + if err != nil { + return []string{} + } + defer file.Close() + + stat, err := file.Stat() + if err != nil { + return []string{} + } + + bufferSize := maxBufferSize + if maxBufferSize > stat.Size() { + bufferSize = stat.Size() + } + + startPos := stat.Size() - bufferSize + + buff := make([]byte, bufferSize) + _, err = file.ReadAt(buff, startPos) + if err != nil { + return []string{} + } + + logLines := strings.Split(string(buff), "\n") + + // Reverse the array of lines + // Offset by two to account for the blank line at the end + last := len(logLines) - 2 + for i := 0; i < len(logLines)/2; i++ { + logLines[i], logLines[last-i] = logLines[last-i], logLines[i] + } + + return logLines +} diff --git a/modules/textfile/widget.go b/modules/textfile/widget.go index 64d01e27..7a53752d 100644 --- a/modules/textfile/widget.go +++ b/modules/textfile/widget.go @@ -14,6 +14,7 @@ import ( "github.com/alecthomas/chroma/styles" "github.com/radovskyb/watcher" "github.com/rivo/tview" + "github.com/wtfutil/wtf/utils" "github.com/wtfutil/wtf/wtf" ) @@ -98,7 +99,7 @@ func (widget *Widget) fileName() string { } func (widget *Widget) formattedText() string { - filePath, _ := wtf.ExpandHomeDir(widget.CurrentSource()) + filePath, _ := utils.ExpandHomeDir(widget.CurrentSource()) file, err := os.Open(filePath) if err != nil { @@ -129,7 +130,7 @@ func (widget *Widget) formattedText() string { } func (widget *Widget) plainText() string { - filePath, _ := wtf.ExpandHomeDir(widget.CurrentSource()) + filePath, _ := utils.ExpandHomeDir(widget.CurrentSource()) fmt.Println(filePath) @@ -159,7 +160,7 @@ func (widget *Widget) watchForFileChanges() { // Watch each textfile for changes for _, source := range widget.Sources { - fullPath, err := wtf.ExpandHomeDir(source) + fullPath, err := utils.ExpandHomeDir(source) if err == nil { if err := watch.Add(fullPath); err != nil { log.Fatalln(err) diff --git a/wtf/homedir.go b/utils/homedir.go similarity index 98% rename from wtf/homedir.go rename to utils/homedir.go index ef43abf7..7c208de7 100644 --- a/wtf/homedir.go +++ b/utils/homedir.go @@ -2,7 +2,7 @@ // Copied (mostly) verbatim from https://github.com/Atrox/homedir -package wtf +package utils import ( "errors" diff --git a/wtf/utils.go b/wtf/utils.go index a5a2f60a..fc743dec 100644 --- a/wtf/utils.go +++ b/wtf/utils.go @@ -7,6 +7,8 @@ import ( "regexp" "runtime" "strings" + + "github.com/wtfutil/wtf/utils" ) const SimpleDateFormat = "Jan 2" @@ -92,7 +94,7 @@ func OpenFile(path string) { default: } } else { - filePath, _ := ExpandHomeDir(path) + filePath, _ := utils.ExpandHomeDir(path) cmd := exec.Command(OpenFileUtil, filePath) ExecuteCommand(cmd) } From 7be64c0558472577ba3277b316f7b6306adc1a45 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 23:12:10 -0700 Subject: [PATCH 17/25] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94310733..a514b24a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ ### ⚡️ Added -* DataDog module is now scrollable and interactive, by [@Seanstoppable](https://github.com/Seanstoppable) +* DataDog module is now scrollable and interactive, by @Seanstoppable +* Focusable hot key numbers are now assigned in a stable order, [#435](https://github.com/wtfutil/wtf/issues/435) by @Seanstoppable ## v0.9.2 From d1670413cc361f8e040bff04eacb806fe1bf2011 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 23:12:35 -0700 Subject: [PATCH 18/25] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a514b24a..def47a50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ ### ⚡️ Added -* DataDog module is now scrollable and interactive, by @Seanstoppable -* Focusable hot key numbers are now assigned in a stable order, [#435](https://github.com/wtfutil/wtf/issues/435) by @Seanstoppable +* DataDog module is now scrollable and interactive, by [@Seanstoppable](https://github.com/Seanstoppable) +* Focusable hot key numbers are now assigned in a stable order, [#435](https://github.com/wtfutil/wtf/issues/435) by [@Seanstoppable](https://github.com/Seanstoppable) ## v0.9.2 From 04fae35f5b0fe1731ee06fdbb26dea1f049ac533 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 23:23:39 -0700 Subject: [PATCH 19/25] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index def47a50..6edb2047 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * DataDog module is now scrollable and interactive, by [@Seanstoppable](https://github.com/Seanstoppable) * Focusable hot key numbers are now assigned in a stable order, [#435](https://github.com/wtfutil/wtf/issues/435) by [@Seanstoppable](https://github.com/Seanstoppable) +* Zendesk widget now has help text, by [@Seanstoppable](https://github.com/Seanstoppable) ## v0.9.2 From 78fc097818e873105277153fb94997ab10e35de8 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 23:27:48 -0700 Subject: [PATCH 20/25] Update widget.go --- modules/zendesk/widget.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/zendesk/widget.go b/modules/zendesk/widget.go index 2b9ad4ed..47a20ebf 100644 --- a/modules/zendesk/widget.go +++ b/modules/zendesk/widget.go @@ -35,11 +35,10 @@ type Widget struct { // NewWidget creates a new instance of a widget func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { widget := Widget{ - ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText), KeyboardWidget: wtf.NewKeyboardWidget(), - TextWidget: wtf.NewTextWidget(app, settings.common, true), - + ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), + settings: settings, } From 2067a7307290567d693551689c2a5ab93d1ba52a Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Sat, 11 May 2019 08:41:00 -0700 Subject: [PATCH 21/25] Fix a bug in scrollable.RowColor --- modules/hackernews/widget.go | 5 +++-- wtf/scrollable.go | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/hackernews/widget.go b/modules/hackernews/widget.go index 44a15328..9131f88d 100644 --- a/modules/hackernews/widget.go +++ b/modules/hackernews/widget.go @@ -97,13 +97,14 @@ func (widget *Widget) Render() { func (widget *Widget) contentFrom(stories []Story) string { var str string for idx, story := range stories { + u, _ := url.Parse(story.URL) + str = str + fmt.Sprintf( - `["%d"][""][%s] [yellow]%d. [%s]%s [blue](%s)[""]`, + `["%d"][""][%s]%2d. %s [lightblue](%s)[white][""]`, idx, widget.RowColor(idx), idx+1, - widget.RowColor(idx), story.Title, strings.TrimPrefix(u.Host, "www."), ) diff --git a/wtf/scrollable.go b/wtf/scrollable.go index a81e0277..fe716a32 100644 --- a/wtf/scrollable.go +++ b/wtf/scrollable.go @@ -41,7 +41,7 @@ func (widget *ScrollableWidget) GetSelected() int { func (widget *ScrollableWidget) RowColor(idx int) string { if widget.View.HasFocus() && (idx == widget.selected) { - widget.CommonSettings.DefaultFocussedRowColor() + return widget.CommonSettings.DefaultFocussedRowColor() } return widget.CommonSettings.RowColor(idx) From 197b3a50effc0b4a1c14de5f3fbffa87cb760cca Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Sat, 11 May 2019 08:42:58 -0700 Subject: [PATCH 22/25] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6edb2047..5a191dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * DataDog module is now scrollable and interactive, by [@Seanstoppable](https://github.com/Seanstoppable) * Focusable hot key numbers are now assigned in a stable order, [#435](https://github.com/wtfutil/wtf/issues/435) by [@Seanstoppable](https://github.com/Seanstoppable) * Zendesk widget now has help text, by [@Seanstoppable](https://github.com/Seanstoppable) +* Scrollable widget added to provide common keyboard-navigation list functionality, by [@Seanstoppable](https://github.com/Seanstoppable) ## v0.9.2 From db746802c9c3c321d7f0a517813a05e088e7bf36 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Sat, 11 May 2019 08:49:26 -0700 Subject: [PATCH 23/25] Improve the display of Twitter; less-harsh colours --- modules/twitter/widget.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/twitter/widget.go b/modules/twitter/widget.go index 5ae8640f..f26564a0 100644 --- a/modules/twitter/widget.go +++ b/modules/twitter/widget.go @@ -77,7 +77,7 @@ func (widget *Widget) display() { title := fmt.Sprintf("Twitter - [green]@%s[white]", widget.CurrentSource()) if len(tweets) == 0 { - str := fmt.Sprintf("\n\n\n%s", wtf.CenterText("[blue]No Tweets[white]", 50)) + str := fmt.Sprintf("\n\n\n%s", wtf.CenterText("[lightblue]No Tweets[white]", 50)) widget.View.SetText(str) return } @@ -112,7 +112,7 @@ func (widget *Widget) formatText(text string) string { // @name mentions atRegExp := regexp.MustCompile(`@[0-9A-Za-z_]*`) - result = atRegExp.ReplaceAllString(result, "[blue]${0}[white]") + result = atRegExp.ReplaceAllString(result, "[lightblue]${0}[white]") // HTTP(S) links linkRegExp := regexp.MustCompile(`http[s:\/.0-9A-Za-z]*`) From 03b1abd7402c3ac59072fa4814009caa3afb801f Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Sat, 11 May 2019 11:54:52 -0400 Subject: [PATCH 24/25] Remove datadog app reference --- modules/datadog/widget.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/datadog/widget.go b/modules/datadog/widget.go index 1ee95bf1..3f9dbb79 100644 --- a/modules/datadog/widget.go +++ b/modules/datadog/widget.go @@ -36,7 +36,6 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * KeyboardWidget: wtf.NewKeyboardWidget(), ScrollableWidget: wtf.NewScrollableWidget(app, settings.common, true), - app: app, settings: settings, } From 42461c6e55097469216bb0ba9f504fed34da8dd7 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Sat, 11 May 2019 08:59:24 -0700 Subject: [PATCH 25/25] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a191dc7..16260f07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Focusable hot key numbers are now assigned in a stable order, [#435](https://github.com/wtfutil/wtf/issues/435) by [@Seanstoppable](https://github.com/Seanstoppable) * Zendesk widget now has help text, by [@Seanstoppable](https://github.com/Seanstoppable) * Scrollable widget added to provide common keyboard-navigation list functionality, by [@Seanstoppable](https://github.com/Seanstoppable) +* Logging functionality extracted out from Log module, by [@Seanstoppable](https://github.com/Seanstoppable) ## v0.9.2