1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-12-04 14:46:29 -05:00

Update dependencies, browse using TabbedPanels (#104)

Co-authored-by: makeworld <25111343+makeworld-the-better-one@users.noreply.github.com>
This commit is contained in:
Trevor Slocum 2020-10-29 11:56:14 -07:00 committed by GitHub
parent f5024068d0
commit 3ef059ad5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 300 additions and 357 deletions

View File

@ -21,37 +21,38 @@ var bkmkCh = make(chan int) // 1, 0, -1 for add/update, cancel, and remove
var bkmkModalText string // The current text of the input field in the modal
func bkmkInit() {
m := bkmkModal
if viper.GetBool("a-general.color") {
bkmkModal.SetBackgroundColor(config.GetColor("bkmk_modal_bg")).
SetButtonBackgroundColor(config.GetColor("btn_bg")).
SetButtonTextColor(config.GetColor("btn_text")).
SetTextColor(config.GetColor("bkmk_modal_text"))
bkmkModal.GetForm().
SetLabelColor(config.GetColor("bkmk_modal_label")).
SetFieldBackgroundColor(config.GetColor("bkmk_modal_field_bg")).
SetFieldTextColor(config.GetColor("bkmk_modal_field_text"))
bkmkModal.GetFrame().
SetBorderColor(config.GetColor("bkmk_modal_text")).
SetTitleColor(config.GetColor("bkmk_modal_text"))
m.SetBackgroundColor(config.GetColor("bkmk_modal_bg"))
m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
m.SetButtonTextColor(config.GetColor("btn_text"))
m.SetTextColor(config.GetColor("bkmk_modal_text"))
form := m.GetForm()
form.SetLabelColor(config.GetColor("bkmk_modal_label"))
form.SetFieldBackgroundColor(config.GetColor("bkmk_modal_field_bg"))
form.SetFieldTextColor(config.GetColor("bkmk_modal_field_text"))
frame := m.GetFrame()
frame.SetBorderColor(config.GetColor("bkmk_modal_text"))
frame.SetTitleColor(config.GetColor("bkmk_modal_text"))
} else {
bkmkModal.SetBackgroundColor(tcell.ColorBlack).
SetButtonBackgroundColor(tcell.ColorWhite).
SetButtonTextColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
bkmkModal.GetForm().
SetLabelColor(tcell.ColorWhite).
SetFieldBackgroundColor(tcell.ColorWhite).
SetFieldTextColor(tcell.ColorBlack)
bkmkModal.GetFrame().
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
m.SetBackgroundColor(tcell.ColorBlack)
m.SetButtonBackgroundColor(tcell.ColorWhite)
m.SetButtonTextColor(tcell.ColorBlack)
m.SetTextColor(tcell.ColorWhite)
form := m.GetForm()
form.SetLabelColor(tcell.ColorWhite)
form.SetFieldBackgroundColor(tcell.ColorWhite)
form.SetFieldTextColor(tcell.ColorBlack)
frame := m.GetFrame()
frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
}
bkmkModal.SetBorder(true)
bkmkModal.GetFrame().
SetTitleAlign(cview.AlignCenter).
SetTitle(" Add Bookmark ")
bkmkModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
m.SetBorder(true)
frame := m.GetFrame()
frame.SetTitleAlign(cview.AlignCenter)
frame.SetTitle(" Add Bookmark ")
m.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
switch buttonLabel {
case "Add":
bkmkCh <- 1
@ -95,13 +96,12 @@ func openBkmkModal(name string, exists bool, favicon string) (string, int) {
bkmkModalText = text
})
tabPages.ShowPage("bkmk")
tabPages.SendToFront("bkmk")
panels.ShowPanel("bkmk")
App.SetFocus(bkmkModal)
App.Draw()
action := <-bkmkCh
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()

View File

@ -26,37 +26,27 @@ var termH int
// The user input and URL display bar at the bottom
var bottomBar = cview.NewInputField()
// Viewer for the tab primitives
// Pages are named as strings of tab numbers - so the textview for the first tab
// is held in the page named "0".
// The only pages that don't confine to this scheme are those named after modals,
// which are used to draw modals on top the current tab.
// Viewer for primitives
// This contains the browser and any modals modals drawn on top of it.
// Ex: "info", "error", "input", "yesno"
var tabPages = cview.NewPages()
var panels = cview.NewPanels()
// The tabs at the top with titles
var tabRow = cview.NewTextView().
SetDynamicColors(true).
SetRegions(true).
SetScrollable(true).
SetWrap(false).
SetHighlightedFunc(func(added, removed, remaining []string) {
// There will always only be one string in added - never multiple highlights
// Remaining should always be empty
i, _ := strconv.Atoi(added[0])
tabPages.SwitchToPage(strconv.Itoa(i)) // Tab names are just numbers, zero-indexed
})
// Tabbed viewer for primitives
// Panels are named as strings of tab numbers - so the textview for the first tab
// is held in the page named "0".
var browser = cview.NewTabbedPanels()
// Root layout
var layout = cview.NewFlex().
SetDirection(cview.FlexRow)
var layout = cview.NewFlex()
var newTabPage structs.Page
var App = cview.NewApplication().
EnableMouse(false).
SetRoot(layout, true).
SetAfterResizeFunc(func(width int, height int) {
var App = cview.NewApplication()
func Init() {
App.EnableMouse(false)
App.SetRoot(layout, true)
App.SetAfterResizeFunc(func(width int, height int) {
// Store for calculations
termW = width
termH = height
@ -70,35 +60,26 @@ var App = cview.NewApplication().
}(tabs[curTab])
})
func Init() {
tabRow.SetChangedFunc(func() {
App.Draw()
})
panels.AddPanel("browser", browser, true, true)
helpInit()
layout.
AddItem(tabRow, 1, 1, false).
AddItem(nil, 1, 1, false). // One line of empty space above the page
AddItem(tabPages, 0, 1, true).
AddItem(nil, 1, 1, false). // One line of empty space before bottomBar
AddItem(bottomBar, 1, 1, false)
layout.SetDirection(cview.FlexRow)
layout.AddItem(panels, 0, 1, true)
layout.AddItem(bottomBar, 1, 1, false)
if viper.GetBool("a-general.color") {
layout.SetBackgroundColor(config.GetColor("bg"))
tabRow.SetBackgroundColor(config.GetColor("bg"))
bottomBar.SetBackgroundColor(config.GetColor("bottombar_bg"))
bottomBar.
SetLabelColor(config.GetColor("bottombar_label")).
SetFieldBackgroundColor(config.GetColor("bottombar_bg")).
SetFieldTextColor(config.GetColor("bottombar_text"))
bottomBar.SetLabelColor(config.GetColor("bottombar_label"))
bottomBar.SetFieldBackgroundColor(config.GetColor("bottombar_bg"))
bottomBar.SetFieldTextColor(config.GetColor("bottombar_text"))
} else {
bottomBar.SetBackgroundColor(tcell.ColorWhite)
bottomBar.
SetLabelColor(tcell.ColorBlack).
SetFieldBackgroundColor(tcell.ColorWhite).
SetFieldTextColor(tcell.ColorBlack)
bottomBar.SetLabelColor(tcell.ColorBlack)
bottomBar.SetFieldBackgroundColor(tcell.ColorWhite)
bottomBar.SetFieldTextColor(tcell.ColorBlack)
}
bottomBar.SetDoneFunc(func(key tcell.Key) {
tab := curTab
@ -429,23 +410,10 @@ func NewTab() {
// The first page will be the next one the user goes to.
tabs[curTab].history.pos = -1
tabPages.AddAndSwitchToPage(strconv.Itoa(curTab), tabs[curTab].view, true)
browser.AddTab(strconv.Itoa(curTab), strconv.Itoa(curTab+1), tabs[curTab].view)
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
// Add tab number to the actual place where tabs are show on the screen
// Tab regions are 0-indexed but text displayed on the screen starts at 1
if viper.GetBool("a-general.color") {
fmt.Fprintf(tabRow, `["%d"][%s] %d [%s][""]|`,
curTab,
config.GetColorString("tab_num"),
curTab+1,
config.GetColorString("tab_divider"),
)
} else {
fmt.Fprintf(tabRow, `["%d"] %d [""]|`, curTab, curTab+1)
}
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
bottomBar.SetLabel("")
bottomBar.SetText("")
tabs[curTab].saveBottomBar()
@ -472,7 +440,7 @@ func CloseTab() {
}
tabs = tabs[:len(tabs)-1]
tabPages.RemovePage(strconv.Itoa(curTab))
browser.RemoveTab(strconv.Itoa(curTab))
if curTab <= 0 {
curTab = NumTabs() - 1
@ -480,8 +448,7 @@ func CloseTab() {
curTab--
}
tabPages.SwitchToPage(strconv.Itoa(curTab)) // Go to previous page
rewriteTabRow()
browser.SetCurrentTab(strconv.Itoa(curTab)) // Go to previous page
// Restore previous tab's state
tabs[curTab].applyAll()
@ -513,8 +480,7 @@ func SwitchTab(tab int) {
// Display tab
reformatPageAndSetView(tabs[curTab], tabs[curTab].page)
tabPages.SwitchToPage(strconv.Itoa(curTab))
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
browser.SetCurrentTab(strconv.Itoa(curTab))
tabs[curTab].applyAll()
App.SetFocus(tabs[curTab].view)

View File

@ -22,8 +22,7 @@ import (
)
// For choosing between download and the portal - copy of YesNo basically
var dlChoiceModal = cview.NewModal().
AddButtons([]string{"Download", "Open in portal", "Cancel"})
var dlChoiceModal = cview.NewModal()
// Channel to indicate what choice they made using the button text
var dlChoiceCh = make(chan string)
@ -31,52 +30,55 @@ var dlChoiceCh = make(chan string)
var dlModal = cview.NewModal()
func dlInit() {
dlm := dlModal
chm := dlChoiceModal
if viper.GetBool("a-general.color") {
dlChoiceModal.SetButtonBackgroundColor(config.GetColor("btn_bg")).
SetButtonTextColor(config.GetColor("btn_text")).
SetBackgroundColor(config.GetColor("dl_choice_modal_bg")).
SetTextColor(config.GetColor("dl_choice_modal_text"))
dlChoiceModal.GetFrame().
SetBorderColor(config.GetColor("dl_choice_modal_text")).
SetTitleColor(config.GetColor("dl_choice_modal_text"))
chm.SetButtonBackgroundColor(config.GetColor("btn_bg"))
chm.SetButtonTextColor(config.GetColor("btn_text"))
chm.SetBackgroundColor(config.GetColor("dl_choice_modal_bg"))
chm.SetTextColor(config.GetColor("dl_choice_modal_text"))
frame := chm.GetFrame()
frame.SetBorderColor(config.GetColor("dl_choice_modal_text"))
frame.SetTitleColor(config.GetColor("dl_choice_modal_text"))
dlModal.SetButtonBackgroundColor(config.GetColor("btn_bg")).
SetButtonTextColor(config.GetColor("btn_text")).
SetBackgroundColor(config.GetColor("dl_modal_bg")).
SetTextColor(config.GetColor("dl_modal_text"))
dlModal.GetFrame().
SetBorderColor(config.GetColor("dl_modal_text")).
SetTitleColor(config.GetColor("dl_modal_text"))
dlm.SetButtonBackgroundColor(config.GetColor("btn_bg"))
dlm.SetButtonTextColor(config.GetColor("btn_text"))
dlm.SetBackgroundColor(config.GetColor("dl_modal_bg"))
dlm.SetTextColor(config.GetColor("dl_modal_text"))
frame = dlm.GetFrame()
frame.SetBorderColor(config.GetColor("dl_modal_text"))
frame.SetTitleColor(config.GetColor("dl_modal_text"))
} else {
dlChoiceModal.SetButtonBackgroundColor(tcell.ColorWhite).
SetButtonTextColor(tcell.ColorBlack).
SetBackgroundColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
chm.SetButtonBackgroundColor(tcell.ColorWhite)
chm.SetButtonTextColor(tcell.ColorBlack)
chm.SetBackgroundColor(tcell.ColorBlack)
chm.SetTextColor(tcell.ColorWhite)
dlChoiceModal.SetBorderColor(tcell.ColorWhite)
dlChoiceModal.GetFrame().SetTitleColor(tcell.ColorWhite)
dlModal.SetButtonBackgroundColor(tcell.ColorWhite).
SetButtonTextColor(tcell.ColorBlack).
SetBackgroundColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
dlModal.GetFrame().
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
dlm.SetButtonBackgroundColor(tcell.ColorWhite)
dlm.SetButtonTextColor(tcell.ColorBlack)
dlm.SetBackgroundColor(tcell.ColorBlack)
dlm.SetTextColor(tcell.ColorWhite)
frame := dlm.GetFrame()
frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
}
dlChoiceModal.SetBorder(true)
dlChoiceModal.GetFrame().SetTitleAlign(cview.AlignCenter)
dlChoiceModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
chm.AddButtons([]string{"Download", "Open in portal", "Cancel"})
chm.SetBorder(true)
chm.GetFrame().SetTitleAlign(cview.AlignCenter)
chm.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
dlChoiceCh <- buttonLabel
})
dlModal.SetBorder(true)
dlModal.GetFrame().
SetTitleAlign(cview.AlignCenter).
SetTitle(" Download ")
dlModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
dlm.SetBorder(true)
frame := dlm.GetFrame()
frame.SetTitleAlign(cview.AlignCenter)
frame.SetTitle(" Download ")
dlm.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
if buttonLabel == "Ok" {
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
}
@ -95,14 +97,13 @@ func dlChoice(text, u string, resp *gemini.Response) {
}
dlChoiceModal.SetText(text)
tabPages.ShowPage("dlChoice")
tabPages.SendToFront("dlChoice")
panels.ShowPanel("dlChoice")
App.SetFocus(dlChoiceModal)
App.Draw()
choice := <-dlChoiceCh
if choice == "Download" {
tabPages.HidePage("dlChoice")
panels.HidePanel("dlChoice")
App.Draw()
downloadURL(u, resp)
return
@ -118,12 +119,12 @@ func dlChoice(text, u string, resp *gemini.Response) {
}
portalURL = strings.TrimPrefix(portalURL, "gemini://") + "?raw=1"
handleHTTP("https://portal.mozz.us/gemini/"+portalURL, false)
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
return
}
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
}
@ -170,15 +171,14 @@ func downloadURL(u string, resp *gemini.Response) {
// Display
dlModal.ClearButtons()
dlModal.AddButtons([]string{"Downloading..."})
tabPages.ShowPage("dl")
tabPages.SendToFront("dl")
panels.ShowPanel("dl")
App.SetFocus(dlModal)
App.Draw()
_, err = io.Copy(io.MultiWriter(f, bar), resp.Body)
done = true
if err != nil {
tabPages.HidePage("dl")
panels.HidePanel("dl")
Error("Download Error", err.Error())
f.Close()
os.Remove(savePath) // Remove partial file

View File

@ -1,10 +1,13 @@
package display
import (
"fmt"
"strconv"
"strings"
"text/tabwriter"
"github.com/gdamore/tcell/v2"
"github.com/makeworld-the-better-one/amfora/config"
"gitlab.com/tslocum/cview"
)
@ -47,56 +50,39 @@ Ctrl-C|Hard quit. This can be used when in the middle of downloading,
|for example.
`)
var helpTable = cview.NewTable().
SetSelectable(false, false).
SetBorders(false).
SetScrollBarVisibility(cview.ScrollBarNever)
var helpTable = cview.NewTextView()
// Help displays the help and keybindings.
func Help() {
helpTable.ScrollToBeginning()
tabPages.SwitchToPage("help")
if !browser.HasTab("help") {
browser.AddTab("help", "Help", helpTable)
}
browser.SetCurrentTab("help")
App.SetFocus(helpTable)
App.Draw()
}
func helpInit() {
// Populate help table
helpTable.SetBackgroundColor(config.GetColor("bg"))
helpTable.SetPadding(0, 0, 1, 1)
helpTable.SetDoneFunc(func(key tcell.Key) {
if key == tcell.KeyEsc || key == tcell.KeyEnter {
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
}
})
rows := strings.Count(helpCells, "\n") + 1
cells := strings.Split(
strings.ReplaceAll(helpCells, "\n", "|"),
"|")
cell := 0
extraRows := 0 // Rows continued from the previous, without spacing
for r := 0; r < rows; r++ {
for c := 0; c < 2; c++ {
var tableCell *cview.TableCell
if c == 0 {
// First column, the keybinding
tableCell = cview.NewTableCell(" " + cells[cell]).
SetAttributes(tcell.AttrBold).
SetAlign(cview.AlignLeft)
} else {
tableCell = cview.NewTableCell(" " + cells[cell])
lines := strings.Split(helpCells, "\n")
w := tabwriter.NewWriter(helpTable, 0, 8, 2, ' ', 0)
for i, line := range lines {
cells := strings.Split(line, "|")
if i > 0 && len(cells[0]) > 0 {
fmt.Fprintln(w, "\t")
}
if c == 0 && cells[cell] == "" || (cell > 0 && cells[cell-1] == "" && c == 1) {
// The keybinding column for this row was blank, meaning the explanation
// column is continued from the previous row.
// The row should be added without any spacing rows
helpTable.SetCell(((2*r)-extraRows/2)-1, c, tableCell)
extraRows++
} else {
helpTable.SetCell((2*r)-extraRows/2, c, tableCell) // Every other row, for readability
fmt.Fprintf(w, "%s\t%s\n", cells[0], cells[1])
}
cell++
}
}
tabPages.AddPage("help", helpTable, true, false)
w.Flush()
browser.AddTab("help", "Help", helpTable)
}

View File

@ -16,103 +16,114 @@ import (
// This file contains code for the popups / modals used in the display.
// The bookmark modal is in bookmarks.go
var infoModal = cview.NewModal().
AddButtons([]string{"Ok"})
var infoModal = cview.NewModal()
var errorModal = cview.NewModal().
AddButtons([]string{"Ok"})
var errorModal = cview.NewModal()
var inputModal = cview.NewModal()
var inputCh = make(chan string)
var inputModalText string // The current text of the input field in the modal
var yesNoModal = cview.NewModal().
AddButtons([]string{"Yes", "No"})
var yesNoModal = cview.NewModal()
// Channel to receive yesNo answer on
var yesNoCh = make(chan bool)
func modalInit() {
tabPages.AddPage("info", infoModal, false, false).
AddPage("error", errorModal, false, false).
AddPage("input", inputModal, false, false).
AddPage("yesno", yesNoModal, false, false).
AddPage("bkmk", bkmkModal, false, false).
AddPage("dlChoice", dlChoiceModal, false, false).
AddPage("dl", dlModal, false, false)
infoModal.AddButtons([]string{"Ok"})
errorModal.AddButtons([]string{"Ok"})
yesNoModal.AddButtons([]string{"Yes", "No"})
panels.AddPanel("info", infoModal, false, false)
panels.AddPanel("error", errorModal, false, false)
panels.AddPanel("input", inputModal, false, false)
panels.AddPanel("yesno", yesNoModal, false, false)
panels.AddPanel("bkmk", bkmkModal, false, false)
panels.AddPanel("dlChoice", dlChoiceModal, false, false)
panels.AddPanel("dl", dlModal, false, false)
// Color setup
if viper.GetBool("a-general.color") {
infoModal.SetBackgroundColor(config.GetColor("info_modal_bg")).
SetButtonBackgroundColor(config.GetColor("btn_bg")).
SetButtonTextColor(config.GetColor("btn_text")).
SetTextColor(config.GetColor("info_modal_text"))
infoModal.GetFrame().
SetBorderColor(config.GetColor("info_modal_text")).
SetTitleColor(config.GetColor("info_modal_text"))
m := infoModal
m.SetBackgroundColor(config.GetColor("info_modal_bg"))
m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
m.SetButtonTextColor(config.GetColor("btn_text"))
m.SetTextColor(config.GetColor("info_modal_text"))
frame := m.GetFrame()
frame.SetBorderColor(config.GetColor("info_modal_text"))
frame.SetTitleColor(config.GetColor("info_modal_text"))
errorModal.SetBackgroundColor(config.GetColor("error_modal_bg")).
SetButtonBackgroundColor(config.GetColor("btn_bg")).
SetButtonTextColor(config.GetColor("btn_text")).
SetTextColor(config.GetColor("error_modal_text"))
errorModal.GetFrame().
SetBorderColor(config.GetColor("error_modal_text")).
SetTitleColor(config.GetColor("error_modal_text"))
m = errorModal
m.SetBackgroundColor(config.GetColor("error_modal_bg"))
m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
m.SetButtonTextColor(config.GetColor("btn_text"))
m.SetTextColor(config.GetColor("error_modal_text"))
frame = errorModal.GetFrame()
frame.SetBorderColor(config.GetColor("error_modal_text"))
frame.SetTitleColor(config.GetColor("error_modal_text"))
inputModal.SetBackgroundColor(config.GetColor("input_modal_bg")).
SetButtonBackgroundColor(config.GetColor("btn_bg")).
SetButtonTextColor(config.GetColor("btn_text")).
SetTextColor(config.GetColor("input_modal_text"))
inputModal.GetFrame().
SetBorderColor(config.GetColor("input_modal_text")).
SetTitleColor(config.GetColor("input_modal_text"))
inputModal.GetForm().
SetFieldBackgroundColor(config.GetColor("input_modal_field_bg")).
SetFieldTextColor(config.GetColor("input_modal_field_text"))
m = inputModal
m.SetBackgroundColor(config.GetColor("input_modal_bg"))
m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
m.SetButtonTextColor(config.GetColor("btn_text"))
m.SetTextColor(config.GetColor("input_modal_text"))
frame = inputModal.GetFrame()
frame.SetBorderColor(config.GetColor("input_modal_text"))
frame.SetTitleColor(config.GetColor("input_modal_text"))
form := inputModal.GetForm()
form.SetFieldBackgroundColor(config.GetColor("input_modal_field_bg"))
form.SetFieldTextColor(config.GetColor("input_modal_field_text"))
yesNoModal.SetButtonBackgroundColor(config.GetColor("btn_bg")).
SetButtonTextColor(config.GetColor("btn_text"))
m = yesNoModal
m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
m.SetButtonTextColor(config.GetColor("btn_text"))
} else {
infoModal.SetBackgroundColor(tcell.ColorBlack).
SetButtonBackgroundColor(tcell.ColorWhite).
SetButtonTextColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
infoModal.GetFrame().
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
m := infoModal
m.SetBackgroundColor(tcell.ColorBlack)
m.SetButtonBackgroundColor(tcell.ColorWhite)
m.SetButtonTextColor(tcell.ColorBlack)
m.SetTextColor(tcell.ColorWhite)
frame := infoModal.GetFrame()
frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
errorModal.SetBackgroundColor(tcell.ColorBlack).
SetButtonBackgroundColor(tcell.ColorWhite).
SetButtonTextColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
errorModal.GetFrame().
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
m = errorModal
m.SetBackgroundColor(tcell.ColorBlack)
m.SetButtonBackgroundColor(tcell.ColorWhite)
m.SetButtonTextColor(tcell.ColorBlack)
m.SetTextColor(tcell.ColorWhite)
frame = errorModal.GetFrame()
frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
inputModal.SetBackgroundColor(tcell.ColorBlack).
SetButtonBackgroundColor(tcell.ColorWhite).
SetButtonTextColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
inputModal.GetFrame().
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
inputModal.GetForm().
SetFieldBackgroundColor(tcell.ColorWhite).
SetFieldTextColor(tcell.ColorBlack)
m = inputModal
m.SetBackgroundColor(tcell.ColorBlack)
m.SetButtonBackgroundColor(tcell.ColorWhite)
m.SetButtonTextColor(tcell.ColorBlack)
m.SetTextColor(tcell.ColorWhite)
frame = inputModal.GetFrame()
frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
form := inputModal.GetForm()
form.SetFieldBackgroundColor(tcell.ColorWhite)
form.SetFieldTextColor(tcell.ColorBlack)
// YesNo background color is changed in funcs
yesNoModal.SetButtonBackgroundColor(tcell.ColorWhite).
SetButtonTextColor(tcell.ColorBlack)
m = yesNoModal
m.SetButtonBackgroundColor(tcell.ColorWhite)
m.SetButtonTextColor(tcell.ColorBlack)
}
// Modal functions that can't be added up above, because they return the wrong type
infoModal.SetBorder(true)
infoModal.GetFrame().
SetTitleAlign(cview.AlignCenter).
SetTitle(" Info ")
frame := infoModal.GetFrame()
frame.SetTitleAlign(cview.AlignCenter)
frame.SetTitle(" Info ")
infoModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
})
@ -120,15 +131,15 @@ func modalInit() {
errorModal.SetBorder(true)
errorModal.GetFrame().SetTitleAlign(cview.AlignCenter)
errorModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
})
inputModal.SetBorder(true)
inputModal.GetFrame().
SetTitleAlign(cview.AlignCenter).
SetTitle(" Input ")
frame = inputModal.GetFrame()
frame.SetTitleAlign(cview.AlignCenter)
frame.SetTitle(" Input ")
inputModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
if buttonLabel == "Send" {
inputCh <- inputModalText
@ -167,8 +178,8 @@ func Error(title, text string) {
errorModal.GetFrame().SetTitle(title)
errorModal.SetText(text)
tabPages.ShowPage("error")
tabPages.SendToFront("error")
panels.ShowPanel("error")
panels.SendToFront("error")
App.SetFocus(errorModal)
App.Draw()
}
@ -176,8 +187,8 @@ func Error(title, text string) {
// Info displays some info on the screen in a modal.
func Info(s string) {
infoModal.SetText(s)
tabPages.ShowPage("info")
tabPages.SendToFront("info")
panels.ShowPanel("info")
panels.SendToFront("info")
App.SetFocus(infoModal)
App.Draw()
}
@ -198,14 +209,14 @@ func Input(prompt string) (string, bool) {
})
inputModal.SetText(prompt + " ")
tabPages.ShowPage("input")
tabPages.SendToFront("input")
panels.ShowPanel("input")
panels.SendToFront("input")
App.SetFocus(inputModal)
App.Draw()
resp := <-inputCh
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
@ -218,29 +229,29 @@ func Input(prompt string) (string, bool) {
// YesNo displays a modal asking a yes-or-no question.
func YesNo(prompt string) bool {
if viper.GetBool("a-general.color") {
yesNoModal.
SetBackgroundColor(config.GetColor("yesno_modal_bg")).
SetTextColor(config.GetColor("yesno_modal_text"))
yesNoModal.GetFrame().
SetBorderColor(config.GetColor("yesno_modal_text")).
SetTitleColor(config.GetColor("yesno_modal_text"))
m := yesNoModal
m.SetBackgroundColor(config.GetColor("yesno_modal_bg"))
m.SetTextColor(config.GetColor("yesno_modal_text"))
frame := yesNoModal.GetFrame()
frame.SetBorderColor(config.GetColor("yesno_modal_text"))
frame.SetTitleColor(config.GetColor("yesno_modal_text"))
} else {
yesNoModal.
SetBackgroundColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
yesNoModal.GetFrame().
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
m := yesNoModal
m.SetBackgroundColor(tcell.ColorBlack)
m.SetTextColor(tcell.ColorWhite)
frame := yesNoModal.GetFrame()
frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
}
yesNoModal.GetFrame().SetTitle("")
yesNoModal.SetText(prompt)
tabPages.ShowPage("yesno")
tabPages.SendToFront("yesno")
panels.ShowPanel("yesno")
panels.SendToFront("yesno")
App.SetFocus(yesNoModal)
App.Draw()
resp := <-yesNoCh
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
return resp
@ -251,36 +262,34 @@ func YesNo(prompt string) bool {
func Tofu(host string, expiry time.Time) bool {
// Reuses yesNoModal, with error color
m := yesNoModal
frame := yesNoModal.GetFrame()
if viper.GetBool("a-general.color") {
yesNoModal.
SetBackgroundColor(config.GetColor("tofu_modal_bg")).
SetTextColor(config.GetColor("tofu_modal_text"))
yesNoModal.GetFrame().
SetBorderColor(config.GetColor("tofu_modal_text")).
SetTitleColor(config.GetColor("tofu_modal_text"))
m.SetBackgroundColor(config.GetColor("tofu_modal_bg"))
m.SetTextColor(config.GetColor("tofu_modal_text"))
frame.SetBorderColor(config.GetColor("tofu_modal_text"))
frame.SetTitleColor(config.GetColor("tofu_modal_text"))
} else {
yesNoModal.
SetBackgroundColor(tcell.ColorBlack).
SetTextColor(tcell.ColorWhite)
yesNoModal.
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
m.SetBackgroundColor(tcell.ColorBlack)
m.SetTextColor(tcell.ColorWhite)
m.SetBorderColor(tcell.ColorWhite)
m.SetTitleColor(tcell.ColorWhite)
}
yesNoModal.GetFrame().SetTitle(" TOFU ")
yesNoModal.SetText(
frame.SetTitle(" TOFU ")
m.SetText(
//nolint:lll
fmt.Sprintf("%s's certificate has changed, possibly indicating an security issue. The certificate would have expired %s. Are you sure you want to continue? ",
host,
humanize.Time(expiry),
),
)
tabPages.ShowPage("yesno")
tabPages.SendToFront("yesno")
panels.ShowPanel("yesno")
panels.SendToFront("yesno")
App.SetFocus(yesNoModal)
App.Draw()
resp := <-yesNoCh
tabPages.SwitchToPage(strconv.Itoa(curTab))
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view)
App.Draw()
return resp

View File

@ -3,17 +3,14 @@ package display
import (
"bytes"
"errors"
"fmt"
"io"
"net"
"net/url"
"os/exec"
"strconv"
"strings"
"github.com/makeworld-the-better-one/amfora/cache"
"github.com/makeworld-the-better-one/amfora/client"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/makeworld-the-better-one/amfora/renderer"
"github.com/makeworld-the-better-one/amfora/structs"
"github.com/makeworld-the-better-one/amfora/webbrowser"
@ -198,7 +195,7 @@ func handleFavicon(t *tab, host, old string) {
defer func() {
// Update display if needed
if t.page.Favicon != old && isValidTab(t) {
rewriteTabRow()
// TODO update browser tab label
}
}()
@ -220,7 +217,7 @@ func handleFavicon(t *tab, host, old string) {
}
if fav != "" {
t.page.Favicon = fav
rewriteTabRow()
// TODO update browser tab label
return
}
@ -510,32 +507,3 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
go dlChoice("That file could not be displayed. What would you like to do?", u, res)
return ret("", false)
}
// rewriteTabRow clears the tabRow and writes all the tabs number/favicons into it.
func rewriteTabRow() {
tabRow.Clear()
if viper.GetBool("a-general.color") {
for i := 0; i < NumTabs(); i++ {
char := strconv.Itoa(i + 1)
if tabs[i].page.Favicon != "" {
char = tabs[i].page.Favicon
}
fmt.Fprintf(tabRow, `["%d"][%s] %s [%s][""]|`,
i,
config.GetColorString("tab_num"),
char,
config.GetColorString("tab_divider"),
)
}
} else {
for i := 0; i < NumTabs(); i++ {
char := strconv.Itoa(i + 1)
if tabs[i].page.Favicon != "" {
char = tabs[i].page.Favicon
}
fmt.Fprintf(tabRow, `["%d"] %s [""]|`, i, char)
}
}
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
App.Draw()
}

View File

@ -37,18 +37,18 @@ type tab struct {
func makeNewTab() *tab {
t := tab{
page: &structs.Page{Mode: structs.ModeOff},
view: cview.NewTextView().
SetDynamicColors(true).
SetRegions(true).
SetScrollable(true).
SetWrap(false).
SetChangedFunc(func() {
App.Draw()
}),
view: cview.NewTextView(),
history: &tabHistory{},
reformatMu: &sync.Mutex{},
mode: tabModeDone,
}
t.view.SetDynamicColors(true)
t.view.SetRegions(true)
t.view.SetScrollable(true)
t.view.SetWrap(false)
t.view.SetChangedFunc(func() {
App.Draw()
})
t.view.SetDoneFunc(func(key tcell.Key) {
// Altered from: https://gitlab.com/tslocum/cview/-/blob/master/demos/textview/main.go
// Handles being able to select and "click" links with the enter and tab keys
@ -89,7 +89,8 @@ func makeNewTab() *tab {
// They've started link highlighting
tabs[tab].page.Mode = structs.ModeLinkSelect
tabs[tab].view.Highlight("0").ScrollToHighlight()
tabs[tab].view.Highlight("0")
tabs[tab].view.ScrollToHighlight()
// Display link URL in bottomBar
bottomBar.SetLabel("[::b]Link: [::-]")
bottomBar.SetText(tabs[tab].page.Links[0])
@ -109,7 +110,8 @@ func makeNewTab() *tab {
} else {
return
}
tabs[tab].view.Highlight(strconv.Itoa(index)).ScrollToHighlight()
tabs[tab].view.Highlight(strconv.Itoa(index))
tabs[tab].view.ScrollToHighlight()
// Display link URL in bottomBar
bottomBar.SetLabel("[::b]Link: [::-]")
bottomBar.SetText(tabs[tab].page.Links[index])

19
go.mod
View File

@ -5,23 +5,26 @@ go 1.14
require (
github.com/dustin/go-humanize v1.0.0
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gdamore/tcell/v2 v2.0.0-dev.0.20200926152101-0fb77ddaa5b4
github.com/gdamore/tcell/v2 v2.0.1-0.20201019142633-1057d5591ed1
github.com/google/go-cmp v0.5.0 // indirect
github.com/makeworld-the-better-one/go-gemini v0.8.4
github.com/magiconair/properties v1.8.4 // indirect
github.com/makeworld-the-better-one/go-gemini v0.9.0
github.com/makeworld-the-better-one/go-isemoji v1.1.0
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.3.1 // indirect
github.com/pelletier/go-toml v1.8.0 // indirect
github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/rkoesters/xdg v0.0.0-20181125232953-edd15b846f9b
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/afero v1.4.1 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.0
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.6.1
gitlab.com/tslocum/cview v1.5.1-0.20201012001533-298510a6852b
gitlab.com/tslocum/cview v1.5.1-0.20201026174147-36671ba7d31c
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 // indirect
golang.org/x/text v0.3.3
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.57.0 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)

51
go.sum
View File

@ -45,8 +45,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.0.0-dev/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA=
github.com/gdamore/tcell/v2 v2.0.0-dev.0.20200926152101-0fb77ddaa5b4 h1:9WLVV5c2UI2qvgROlgzLgCuK5gi7igcU5LNsPXCSFB8=
github.com/gdamore/tcell/v2 v2.0.0-dev.0.20200926152101-0fb77ddaa5b4/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA=
github.com/gdamore/tcell/v2 v2.0.1-0.20201019142633-1057d5591ed1 h1:gp9ujdOQmQf1gMvqOYYgxdMS5tRpRGE3HAgRH4Hgzd4=
github.com/gdamore/tcell/v2 v2.0.1-0.20201019142633-1057d5591ed1/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@ -113,6 +113,7 @@ github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@ -123,8 +124,10 @@ github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tW
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/makeworld-the-better-one/go-gemini v0.8.4 h1:ntsQ9HnlJCmC9PDqXp/f1SCALjBMwh69BbT4BhFRFaw=
github.com/makeworld-the-better-one/go-gemini v0.8.4/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4=
github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/makeworld-the-better-one/go-gemini v0.9.0 h1:Iz4ywRDrfsyoR8xZOkSKGXXftMR2spIV6ibVuhrKvSw=
github.com/makeworld-the-better-one/go-gemini v0.9.0/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4=
github.com/makeworld-the-better-one/go-isemoji v1.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g=
github.com/makeworld-the-better-one/go-isemoji v1.1.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI=
@ -147,18 +150,19 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@ -187,8 +191,8 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.4.1 h1:asw9sl74539yqavKaglDM5hFpdJVK0Y5Dr/JOgQ89nQ=
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@ -198,23 +202,24 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
gitlab.com/tslocum/cbind v0.1.2 h1:ptDjO7WeOl1HglprsK18L8I9JeRkmtuBoBBaYw/6/Ow=
gitlab.com/tslocum/cbind v0.1.2/go.mod h1:HfB7qAhHSZbn1rFK8M9SvSN5NG6ScAg/3h3iE6xdeeI=
gitlab.com/tslocum/cview v1.5.1-0.20201012001533-298510a6852b h1:wVXKnAE2gt165dbOupmxBIcjLW7ZTRGAtUUAhyNAEHs=
gitlab.com/tslocum/cview v1.5.1-0.20201012001533-298510a6852b/go.mod h1:i9NyxtwBtkiVFrwmsh3Bv3dunvipjZrKX0TTdPHbzcw=
gitlab.com/tslocum/cbind v0.1.3 h1:FT/fTQ4Yj3eo5021lB3IbkIt8eVtYGhrw/xur+cjvUU=
gitlab.com/tslocum/cbind v0.1.3/go.mod h1:RvwYE3auSjBNlCmWeGspzn+jdLUVQ8C2QGC+0nP9ChI=
gitlab.com/tslocum/cview v1.5.1-0.20201026174147-36671ba7d31c h1:yjyZ6CMJodKSylKTyIHbCsMNNuSE26hW7PMl6TWaM4M=
gitlab.com/tslocum/cview v1.5.1-0.20201026174147-36671ba7d31c/go.mod h1:IEfcfqcDG4Tm28XM+H8TEtbrqjpieAewfcJvQ9SgcRM=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@ -226,6 +231,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -281,9 +287,11 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a h1:e3IU37lwO4aq3uoRKINC7JikojFmE5gO7xhfxs8VC34=
golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 h1:/DtoiOYKoQCcIFXQjz07RnWNPRCbqmSXSpgEzhC9ZHM=
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -339,11 +347,12 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=