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

🚧 Initial work on tab struct

This commit is contained in:
makeworld 2020-07-04 13:24:49 -04:00
parent 518c35453a
commit 44bf54c12f
4 changed files with 132 additions and 6 deletions

View File

@ -1,8 +1,8 @@
# Notes # Notes
- Simplify into one struct - Simplify into one struct
- All the maps and stuff could be replaced with a `Tab` struct - All the maps and stuff could be replaced with a `tab` struct
- And then just one single map of tab number to `Tab` - And then just one single map of tab number to `tab`
- URL for each tab should not be stored as a string - in the current code there's lots of reparsing the URL - URL for each tab should not be stored as a string - in the current code there's lots of reparsing the URL
## Upstream Bugs ## Upstream Bugs

View File

@ -172,7 +172,7 @@ func Init() {
// It's a full URL or search term // It's a full URL or search term
// Detect if it's a search or URL // Detect if it's a search or URL
if strings.Contains(query, " ") || (!strings.Contains(query, "//") && !strings.Contains(query, ".") && !strings.HasPrefix(query, "about:")) { if strings.Contains(query, " ") || (!strings.Contains(query, "//") && !strings.Contains(query, ".") && !strings.HasPrefix(query, "about:")) {
u := viper.GetString("a-general.search") + "?" + pathEscape(query) u := viper.GetString("a-general.search") + "?" + queryEscape(query)
cache.Remove(u) // Don't use the cached version of the search cache.Remove(u) // Don't use the cached version of the search
URL(u) URL(u)
} else { } else {

View File

@ -54,8 +54,9 @@ func textWidth() int {
return viper.GetInt("a-general.max_width") return viper.GetInt("a-general.max_width")
} }
// pathEscape is the same as url.PathEscape, but it also replaces the +. // queryEscape is the same as url.PathEscape, but it also replaces the +.
func pathEscape(path string) string { // This is because Gemini requires percent-escaping for queries.
func queryEscape(path string) string {
return strings.ReplaceAll(url.PathEscape(path), "+", "%2B") return strings.ReplaceAll(url.PathEscape(path), "+", "%2B")
} }
@ -220,6 +221,10 @@ func setPage(p *structs.Page) {
// If there is some error, it will return "". // If there is some error, it will return "".
// The second returned item is a bool indicating if page content was displayed. // The second returned item is a bool indicating if page content was displayed.
// It returns false for Errors, other protocols, etc. // It returns false for Errors, other protocols, etc.
//
// TODO: Add tab number param - now the func only saves the values like the content
// and bottom bar.
// TODO: Some other func that constantly updates bottom bar values
func handleURL(u string) (string, bool) { func handleURL(u string) (string, bool) {
defer App.Draw() // Just in case defer App.Draw() // Just in case
@ -324,7 +329,7 @@ func handleURL(u string) (string, bool) {
if ok { if ok {
// Make another request with the query string added // Make another request with the query string added
// + chars are replaced because PathEscape doesn't do that // + chars are replaced because PathEscape doesn't do that
parsed.RawQuery = pathEscape(userInput) parsed.RawQuery = queryEscape(userInput)
if len(parsed.String()) > 1024 { if len(parsed.String()) > 1024 {
// 1024 is the max size for URLs in the spec // 1024 is the max size for URLs in the spec
Error("Input Error", "URL for that input would be too long.") Error("Input Error", "URL for that input would be too long.")

121
display/tab.go Normal file
View File

@ -0,0 +1,121 @@
package display
import (
"strings"
"sync"
"github.com/makeworld-the-better-one/amfora/structs"
"gitlab.com/tslocum/cview"
)
type tabMode int
const (
modeOff tabMode = iota // Regular mode
modeLinkSelect // When the enter key is pressed, allow for tab-based link navigation
)
// tabHist holds the history for a tab.
type tabHistory struct {
urls []string
pos int // Position: where in the list of URLs we are
}
// tab hold the information needed for each browser tab.
type tab struct {
page *structs.Page
view *cview.TextView
mode tabMode
history *tabHistory
reformatMut *sync.Mutex // Mutex for reformatting, so there's only one reformat job at once
selected string // The current text or link selected
barLabel string // The bottomBar label for the tab
barText string // The bottomBar text for the tab
}
// makeNewTab initializes an tab struct with no content.
func makeNewTab() *tab {
return &tab{
page: &structs.Page{},
view: cview.NewTextView().
SetDynamicColors(true).
SetRegions(true).
SetScrollable(true).
SetWrap(false).
SetChangedFunc(func() {
App.Draw()
}),
mode: modeOff,
reformatMut: &sync.Mutex{},
}
}
// addToHistory adds the given URL to history.
// It assumes the URL is currently being loaded and displayed on the page.
func (t *tab) addToHistory(u string) {
if t.history.pos < len(t.history.urls)-1 {
// We're somewhere in the middle of the history instead, with URLs ahead and behind.
// The URLs ahead need to be removed so this new URL is the most recent item in the history
t.history.urls = t.history.urls[:t.history.pos+1]
}
t.history.urls = append(t.history.urls, u)
t.history.pos++
}
// pageUp scrolls up 75% of the height of the terminal, like Bombadillo.
func (t *tab) pageUp() {
row, col := t.view.GetScrollOffset()
t.view.ScrollTo(row-(termH/4)*3, col)
}
// pageDown scrolls down 75% of the height of the terminal, like Bombadillo.
func (t *tab) pageDown() {
row, col := t.view.GetScrollOffset()
t.view.ScrollTo(row+(termH/4)*3, col)
}
// hasContent returns true when the tab has a page that could be displayed.
// The most likely situation where false would be returned is when the default
// new tab content is being displayed.
func (t *tab) hasContent() bool {
if t.page == nil || t.view == nil {
return false
}
if t.page.Url == "" {
return false
}
if strings.HasPrefix(t.page.Url, "about:") {
return false
}
if t.page.Content == "" {
return false
}
return true
}
// saveScroll saves where in the page the user was.
// It should be used whenever moving from one page to another.
func (t *tab) saveScroll() {
// It will also be saved in the cache because the cache uses the same pointer
row, col := t.view.GetScrollOffset()
t.page.Row = row
t.page.Column = col
}
// applyScroll applies the saved scroll values to the page and tab.
// It should only be used when going backward and forward.
func (t *tab) applyScroll() {
t.view.ScrollTo(t.page.Row, t.page.Column)
}
// saveBottomBar saves the current bottomBar values in the tab.
func (t *tab) saveBottomBar() {
t.barLabel = bottomBar.GetLabel()
t.barText = bottomBar.GetText()
}
// applyBottomBar sets the bottomBar using the stored tab values
func (t *tab) applyBottomBar() {
bottomBar.SetLabel(t.barLabel)
bottomBar.SetText(t.barText)
}