From bc0813b8c7f070743a008003ceb05f0b3d306d7c Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 08:47:31 -0700 Subject: [PATCH 01/10] 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 02/10] 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 03/10] 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 04/10] 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 7be64c0558472577ba3277b316f7b6306adc1a45 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Fri, 10 May 2019 23:12:10 -0700 Subject: [PATCH 05/10] 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 06/10] 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 07/10] 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 08/10] 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 09/10] 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 10/10] 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