1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-06-15 19:15:24 +00:00

Modal fixes (#281) (#284)

This commit is contained in:
mooff 2021-12-22 22:09:47 +00:00 committed by GitHub
parent 0deee6d573
commit baebc86c09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 40 deletions

View File

@ -241,7 +241,7 @@ func Init(version, commit, builtBy string) {
} }
if i <= len(tabs[tab].page.Links) && i > 0 { if i <= len(tabs[tab].page.Links) && i > 0 {
// It's a valid link number // It's a valid link number
followLink(tabs[tab], tabs[tab].page.URL, tabs[tab].page.Links[i-1]) go followLink(tabs[tab], tabs[tab].page.URL, tabs[tab].page.Links[i-1])
return return
} }
// Invalid link number, don't do anything // Invalid link number, don't do anything

View File

@ -352,7 +352,7 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
// Disable read timeout and go back to start // Disable read timeout and go back to start
res.SetReadTimeout(0) //nolint: errcheck res.SetReadTimeout(0) //nolint: errcheck
res.Body.(*rr.RestartReader).Restart() res.Body.(*rr.RestartReader).Restart()
go dlChoice("That page is too large. What would you like to do?", u, res) dlChoice("That page is too large. What would you like to do?", u, res)
return ret("", false) return ret("", false)
} }
if errors.Is(err, renderer.ErrTimedOut) { if errors.Is(err, renderer.ErrTimedOut) {
@ -360,7 +360,7 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
// Disable read timeout and go back to start // Disable read timeout and go back to start
res.SetReadTimeout(0) //nolint: errcheck res.SetReadTimeout(0) //nolint: errcheck
res.Body.(*rr.RestartReader).Restart() res.Body.(*rr.RestartReader).Restart()
go dlChoice("Loading that page timed out. What would you like to do?", u, res) dlChoice("Loading that page timed out. What would you like to do?", u, res)
return ret("", false) return ret("", false)
} }
if err != nil { if err != nil {
@ -493,7 +493,7 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
// Disable read timeout and go back to start // Disable read timeout and go back to start
res.SetReadTimeout(0) //nolint: errcheck res.SetReadTimeout(0) //nolint: errcheck
res.Body.(*rr.RestartReader).Restart() res.Body.(*rr.RestartReader).Restart()
go dlChoice("That file could not be displayed. What would you like to do?", u, res) dlChoice("That file could not be displayed. What would you like to do?", u, res)
} }
}() }()
return ret("", false) return ret("", false)
@ -503,6 +503,6 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
// Disable read timeout and go back to start // Disable read timeout and go back to start
res.SetReadTimeout(0) //nolint: errcheck res.SetReadTimeout(0) //nolint: errcheck
res.Body.(*rr.RestartReader).Restart() res.Body.(*rr.RestartReader).Restart()
go dlChoice("That file could not be displayed. What would you like to do?", u, res) dlChoice("That file could not be displayed. What would you like to do?", u, res)
return ret("", false) return ret("", false)
} }

View File

@ -16,24 +16,21 @@ import (
// The bookmark modal is in bookmarks.go // The bookmark modal is in bookmarks.go
var infoModal = cview.NewModal() var infoModal = cview.NewModal()
var errorModal = cview.NewModal() var errorModal = cview.NewModal()
var errorModalDone = make(chan struct{})
var inputModal = 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() var yesNoModal = cview.NewModal()
// Channel to receive yesNo answer on var inputCh = make(chan string)
var yesNoCh = make(chan bool) var yesNoCh = make(chan bool)
var inputModalText string // The current text of the input field in the modal
// Internal channel used to know when a modal has been dismissed
var modalDone = make(chan struct{})
func modalInit() { func modalInit() {
infoModal.AddButtons([]string{"Ok"}) infoModal.AddButtons([]string{"Ok"})
errorModal.AddButtons([]string{"Ok"}) errorModal.AddButtons([]string{"Ok"})
yesNoModal.AddButtons([]string{"Yes", "No"}) yesNoModal.AddButtons([]string{"Yes", "No"})
panels.AddPanel(PanelInfoModal, infoModal, false, false) panels.AddPanel(PanelInfoModal, infoModal, false, false)
@ -145,6 +142,7 @@ func modalInit() {
panels.HidePanel(PanelInfoModal) panels.HidePanel(PanelInfoModal)
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
modalDone <- struct{}{}
}) })
errorModal.SetBorder(true) errorModal.SetBorder(true)
@ -153,7 +151,7 @@ func modalInit() {
panels.HidePanel(PanelErrorModal) panels.HidePanel(PanelErrorModal)
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
errorModalDone <- struct{}{} modalDone <- struct{}{}
}) })
inputModal.SetBorder(true) inputModal.SetBorder(true)
@ -183,7 +181,7 @@ func modalInit() {
dlInit() dlInit()
} }
// Error displays an error on the screen in a modal. // Error displays an error on the screen in a modal, and blocks until dismissed by the user.
func Error(title, text string) { func Error(title, text string) {
if text == "" { if text == "" {
text = "No additional information." text = "No additional information."
@ -203,19 +201,21 @@ func Error(title, text string) {
App.SetFocus(errorModal) App.SetFocus(errorModal)
App.Draw() App.Draw()
<-errorModalDone <-modalDone
} }
// Info displays some info on the screen in a modal. // Info displays some info on the screen in a modal, and blocks until dismissed by the user.
func Info(s string) { func Info(s string) {
infoModal.SetText(s) infoModal.SetText(s)
panels.ShowPanel(PanelInfoModal) panels.ShowPanel(PanelInfoModal)
panels.SendToFront(PanelInfoModal) panels.SendToFront(PanelInfoModal)
App.SetFocus(infoModal) App.SetFocus(infoModal)
App.Draw() App.Draw()
<-modalDone
} }
// Input pulls up a modal that asks for input, and returns the user's input. // Input pulls up a modal that asks for input, waits for that input, and returns it.
// It returns an bool indicating if the user chose to send input or not. // It returns an bool indicating if the user chose to send input or not.
func Input(prompt string, sensitive bool) (string, bool) { func Input(prompt string, sensitive bool) (string, bool) {
// Remove elements and re-add them - to clear input text and keep input in focus // Remove elements and re-add them - to clear input text and keep input in focus
@ -257,7 +257,7 @@ func Input(prompt string, sensitive bool) (string, bool) {
return resp, true return resp, true
} }
// YesNo displays a modal asking a yes-or-no question. // YesNo displays a modal asking a yes-or-no question, waits for an answer, then returns it as a bool.
func YesNo(prompt string) bool { func YesNo(prompt string) bool {
if viper.GetBool("a-general.color") { if viper.GetBool("a-general.color") {
m := yesNoModal m := yesNoModal
@ -289,7 +289,7 @@ func YesNo(prompt string) bool {
} }
// Tofu displays the TOFU warning modal. // Tofu displays the TOFU warning modal.
// It returns a bool indicating whether the user wants to continue. // It blocks then returns a bool indicating whether the user wants to continue.
func Tofu(host string, expiry time.Time) bool { func Tofu(host string, expiry time.Time) bool {
// Reuses yesNoModal, with error color // Reuses yesNoModal, with error color

View File

@ -1,5 +1,8 @@
package display package display
// This file contains the functions that aren't part of the public API.
// The funcs are for network and displaying.
import ( import (
"net/url" "net/url"
"strconv" "strconv"
@ -9,17 +12,20 @@ import (
"github.com/makeworld-the-better-one/amfora/structs" "github.com/makeworld-the-better-one/amfora/structs"
) )
// This file contains the functions that aren't part of the public API. // followLink should be used when the user "clicks" a link on a page,
// The funcs are for network and displaying. // but not when a URL is opened on a new tab for the first time.
//
// followLink should be used when the user "clicks" a link on a page. // It will handle updating the bottomBar.
// Not when a URL is opened on a new tab for the first time. //
// It will handle setting the bottomBar. // It should be called with the `go` keyword to spawn a new goroutine if
// it would otherwise block the UI loop, such as when called from an input
// handler.
//
// It blocks until navigation is finished, and we've completed any user
// interaction related to loading the URL (such as info, error modals)
func followLink(t *tab, prev, next string) { func followLink(t *tab, prev, next string) {
if strings.HasPrefix(next, "about:") { if strings.HasPrefix(next, "about:") {
if final, ok := handleAbout(t, next); ok { goURL(t, next)
t.addToHistory(final)
}
return return
} }
@ -29,7 +35,7 @@ func followLink(t *tab, prev, next string) {
Error("URL Error", err.Error()) Error("URL Error", err.Error())
return return
} }
go goURL(t, nextURL) goURL(t, nextURL)
return return
} }
// No content on current tab, so the "prev" URL is not valid. // No content on current tab, so the "prev" URL is not valid.
@ -39,7 +45,7 @@ func followLink(t *tab, prev, next string) {
Error("URL Error", "Link URL could not be parsed") Error("URL Error", "Link URL could not be parsed")
return return
} }
go goURL(t, next) goURL(t, next)
} }
// reformatPage will take the raw page content and reformat it according to the current terminal dimensions. // reformatPage will take the raw page content and reformat it according to the current terminal dimensions.

View File

@ -86,7 +86,7 @@ func makeNewTab() *tab {
linkN, _ := strconv.Atoi(currentSelection[0]) linkN, _ := strconv.Atoi(currentSelection[0])
tabs[tab].page.Selected = tabs[tab].page.Links[linkN] tabs[tab].page.Selected = tabs[tab].page.Links[linkN]
tabs[tab].page.SelectedID = currentSelection[0] tabs[tab].page.SelectedID = currentSelection[0]
followLink(tabs[tab], tabs[tab].page.URL, tabs[tab].page.Links[linkN]) go followLink(tabs[tab], tabs[tab].page.URL, tabs[tab].page.Links[linkN])
return return
} }
if len(currentSelection) == 0 && (key == tcell.KeyEnter || key == tcell.KeyTab) { if len(currentSelection) == 0 && (key == tcell.KeyEnter || key == tcell.KeyTab) {
@ -156,12 +156,12 @@ func makeNewTab() *tab {
if t.hasContent() { if t.hasContent() {
savePath, err := downloadPage(t.page) savePath, err := downloadPage(t.page)
if err != nil { if err != nil {
Error("Download Error", fmt.Sprintf("Error saving page content: %v", err)) go Error("Download Error", fmt.Sprintf("Error saving page content: %v", err))
} else { } else {
Info(fmt.Sprintf("Page content saved to %s. ", savePath)) go Info(fmt.Sprintf("Page content saved to %s. ", savePath))
} }
} else { } else {
Info("The current page has no content, so it couldn't be downloaded.") go Info("The current page has no content, so it couldn't be downloaded.")
} }
return nil return nil
case config.CmdBack: case config.CmdBack:
@ -178,7 +178,7 @@ func makeNewTab() *tab {
currentURL := tabs[curTab].page.URL currentURL := tabs[curTab].page.URL
err := clipboard.WriteAll(currentURL) err := clipboard.WriteAll(currentURL)
if err != nil { if err != nil {
Error("Copy Error", err.Error()) go Error("Copy Error", err.Error())
return nil return nil
} }
return nil return nil
@ -193,14 +193,14 @@ func makeNewTab() *tab {
if err != nil { if err != nil {
err := clipboard.WriteAll(selectedURL) err := clipboard.WriteAll(selectedURL)
if err != nil { if err != nil {
Error("Copy Error", err.Error()) go Error("Copy Error", err.Error())
return nil return nil
} }
return nil return nil
} }
err = clipboard.WriteAll(copiedURL.String()) err = clipboard.WriteAll(copiedURL.String())
if err != nil { if err != nil {
Error("Copy Error", err.Error()) go Error("Copy Error", err.Error())
return nil return nil
} }
return nil return nil
@ -209,7 +209,7 @@ func makeNewTab() *tab {
if cmd >= config.CmdLink1 && cmd <= config.CmdLink0 { if cmd >= config.CmdLink1 && cmd <= config.CmdLink0 {
if int(cmd) <= len(t.page.Links) { if int(cmd) <= len(t.page.Links) {
// It's a valid link number // It's a valid link number
followLink(&t, t.page.URL, t.page.Links[cmd-1]) go followLink(&t, t.page.URL, t.page.Links[cmd-1])
return nil return nil
} }
} }