mirror of
https://github.com/makew0rld/amfora.git
synced 2024-12-04 14:46:29 -05:00
🚧 Initial work on tab struct
This commit is contained in:
parent
518c35453a
commit
44bf54c12f
4
NOTES.md
4
NOTES.md
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
121
display/tab.go
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user