1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-06-19 19:25:24 +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
- Simplify into one struct
- All the maps and stuff could be replaced with a `Tab` struct
- And then just one single map of tab number to `Tab`
- All the maps and stuff could be replaced with a `tab` struct
- 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
## Upstream Bugs

View File

@ -172,7 +172,7 @@ func Init() {
// It's a full URL or search term
// Detect if it's a search or URL
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
URL(u)
} else {

View File

@ -54,8 +54,9 @@ func textWidth() int {
return viper.GetInt("a-general.max_width")
}
// pathEscape is the same as url.PathEscape, but it also replaces the +.
func pathEscape(path string) string {
// queryEscape is the same as url.PathEscape, but it also replaces the +.
// This is because Gemini requires percent-escaping for queries.
func queryEscape(path string) string {
return strings.ReplaceAll(url.PathEscape(path), "+", "%2B")
}
@ -220,6 +221,10 @@ func setPage(p *structs.Page) {
// If there is some error, it will return "".
// The second returned item is a bool indicating if page content was displayed.
// 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) {
defer App.Draw() // Just in case
@ -324,7 +329,7 @@ func handleURL(u string) (string, bool) {
if ok {
// Make another request with the query string added
// + chars are replaced because PathEscape doesn't do that
parsed.RawQuery = pathEscape(userInput)
parsed.RawQuery = queryEscape(userInput)
if len(parsed.String()) > 1024 {
// 1024 is the max size for URLs in the spec
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)
}