From 210723cd74fba962a156679e7eedc63ec2f9359c Mon Sep 17 00:00:00 2001 From: Sean Smith Date: Thu, 9 May 2019 22:43:01 -0400 Subject: [PATCH] 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() + }) +}