mirror of
https://github.com/makew0rld/amfora.git
synced 2024-12-04 14:46:29 -05:00
🚧 Fixed some bugs, major ones remain
This commit is contained in:
parent
d3d47a344d
commit
ef8ab3da39
@ -9,12 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Link and heading lines are wrapped just like regular text lines
|
- Link and heading lines are wrapped just like regular text lines
|
||||||
- Wrapped list items are indented to stay behind the bullet (#35)
|
- Wrapped list items are indented to stay behind the bullet (#35)
|
||||||
- Certificate expiry date is stored when the cert IDs match (#39)
|
- Certificate expiry date is stored when the cert IDs match (#39)
|
||||||
|
- What link was selected is remembered as you browse through history
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Pages are rewrapped dynamically, whenever the terminal size changes (#33)
|
- Pages are rewrapped dynamically, whenever the terminal size changes (#33)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Many potential loading race conditions eliminated
|
- Many potential network and display race conditions eliminated
|
||||||
|
- Whether a tab is loading stays indicated when you switch away from it and go back
|
||||||
|
|
||||||
## [1.2.0] - 2020-07-02
|
## [1.2.0] - 2020-07-02
|
||||||
### Added
|
### Added
|
||||||
|
6
NOTES.md
6
NOTES.md
@ -1,6 +1,12 @@
|
|||||||
# Notes
|
# Notes
|
||||||
|
|
||||||
- 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
|
||||||
|
- Switch to UUIDs for each tab maybe? So that if `handleURL` completes after the tab is closed (and reopened) it doesn't go anywhere
|
||||||
|
- New UUID every time a new page is loaded?
|
||||||
|
|
||||||
|
## Bugs
|
||||||
|
- Can't go back or do other things while page is loading - need a way to stop `handleURL`
|
||||||
|
- `handleURL` will reference a tab that doesn't exist and cause a panic if the tab is closed
|
||||||
|
|
||||||
## Upstream Bugs
|
## Upstream Bugs
|
||||||
- Wrapping messes up on brackets
|
- Wrapping messes up on brackets
|
||||||
|
2
cache/cache.go
vendored
2
cache/cache.go
vendored
@ -111,7 +111,7 @@ func NumPages() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the page struct, and a bool indicating if the page was in the cache or not.
|
// Get returns the page struct, and a bool indicating if the page was in the cache or not.
|
||||||
// An empty page struct is returned if the page isn't in the cache
|
// An empty page struct is returned if the page isn't in the cache.
|
||||||
func Get(url string) (*structs.Page, bool) {
|
func Get(url string) (*structs.Page, bool) {
|
||||||
lock.RLock()
|
lock.RLock()
|
||||||
defer lock.RUnlock()
|
defer lock.RUnlock()
|
||||||
|
@ -96,7 +96,7 @@ func openBkmkModal(name string, exists bool) (string, int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bookmarks displays the bookmarks page on the current tab.
|
// Bookmarks displays the bookmarks page on the current tab.
|
||||||
func Bookmarks() {
|
func Bookmarks(tab int) {
|
||||||
// Gather bookmarks
|
// Gather bookmarks
|
||||||
rawContent := "# Bookmarks\r\n\r\n"
|
rawContent := "# Bookmarks\r\n\r\n"
|
||||||
m, keys := bookmarks.All()
|
m, keys := bookmarks.All()
|
||||||
@ -114,6 +114,7 @@ func Bookmarks() {
|
|||||||
Mediatype: structs.TextGemini,
|
Mediatype: structs.TextGemini,
|
||||||
}
|
}
|
||||||
setPage(curTab, &page)
|
setPage(curTab, &page)
|
||||||
|
tabs[tab].applyBottomBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
// addBookmark goes through the process of adding a bookmark for the current page.
|
// addBookmark goes through the process of adding a bookmark for the current page.
|
||||||
|
@ -224,6 +224,9 @@ func Init() {
|
|||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tabs[curTab].mode == tabModeDone {
|
||||||
|
// All the keys and operations that can only work while NOT loading
|
||||||
|
|
||||||
// History arrow keys
|
// History arrow keys
|
||||||
if event.Modifiers() == tcell.ModAlt {
|
if event.Modifiers() == tcell.ModAlt {
|
||||||
if event.Key() == tcell.KeyLeft {
|
if event.Key() == tcell.KeyLeft {
|
||||||
@ -238,8 +241,8 @@ func Init() {
|
|||||||
|
|
||||||
switch event.Key() {
|
switch event.Key() {
|
||||||
case tcell.KeyCtrlT:
|
case tcell.KeyCtrlT:
|
||||||
if tabs[curTab].mode == modeLinkSelect {
|
if tabs[curTab].page.Mode == structs.ModeLinkSelect {
|
||||||
next, err := resolveRelLink(curTab, tabs[curTab].page.Url, tabs[curTab].selected)
|
next, err := resolveRelLink(curTab, tabs[curTab].page.Url, tabs[curTab].page.Selected)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Error("URL Error", err.Error())
|
Error("URL Error", err.Error())
|
||||||
return nil
|
return nil
|
||||||
@ -250,20 +253,14 @@ func Init() {
|
|||||||
NewTab()
|
NewTab()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case tcell.KeyCtrlW:
|
|
||||||
CloseTab()
|
|
||||||
return nil
|
|
||||||
case tcell.KeyCtrlR:
|
case tcell.KeyCtrlR:
|
||||||
Reload()
|
Reload()
|
||||||
return nil
|
return nil
|
||||||
case tcell.KeyCtrlH:
|
case tcell.KeyCtrlH:
|
||||||
URL(viper.GetString("a-general.home"))
|
URL(viper.GetString("a-general.home"))
|
||||||
return nil
|
return nil
|
||||||
case tcell.KeyCtrlQ:
|
|
||||||
Stop()
|
|
||||||
return nil
|
|
||||||
case tcell.KeyCtrlB:
|
case tcell.KeyCtrlB:
|
||||||
Bookmarks()
|
Bookmarks(curTab)
|
||||||
tabs[curTab].addToHistory("about:bookmarks")
|
tabs[curTab].addToHistory("about:bookmarks")
|
||||||
return nil
|
return nil
|
||||||
case tcell.KeyCtrlD:
|
case tcell.KeyCtrlD:
|
||||||
@ -285,9 +282,6 @@ func Init() {
|
|||||||
// Don't save bottom bar, so that whenever you switch tabs, it's not in that mode
|
// Don't save bottom bar, so that whenever you switch tabs, it's not in that mode
|
||||||
App.SetFocus(bottomBar)
|
App.SetFocus(bottomBar)
|
||||||
return nil
|
return nil
|
||||||
case "q":
|
|
||||||
Stop()
|
|
||||||
return nil
|
|
||||||
case "R":
|
case "R":
|
||||||
Reload()
|
Reload()
|
||||||
return nil
|
return nil
|
||||||
@ -297,15 +291,33 @@ func Init() {
|
|||||||
case "f":
|
case "f":
|
||||||
histForward()
|
histForward()
|
||||||
return nil
|
return nil
|
||||||
case "?":
|
|
||||||
Help()
|
|
||||||
return nil
|
|
||||||
case "u":
|
case "u":
|
||||||
tabs[curTab].pageUp()
|
tabs[curTab].pageUp()
|
||||||
return nil
|
return nil
|
||||||
case "d":
|
case "d":
|
||||||
tabs[curTab].pageDown()
|
tabs[curTab].pageDown()
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All the keys and operations that can work while a tab IS loading
|
||||||
|
|
||||||
|
switch event.Key() {
|
||||||
|
case tcell.KeyCtrlW:
|
||||||
|
CloseTab()
|
||||||
|
return nil
|
||||||
|
case tcell.KeyCtrlQ:
|
||||||
|
Stop()
|
||||||
|
return nil
|
||||||
|
case tcell.KeyRune:
|
||||||
|
// Regular key was sent
|
||||||
|
switch string(event.Rune()) {
|
||||||
|
case "q":
|
||||||
|
Stop()
|
||||||
|
return nil
|
||||||
|
case "?":
|
||||||
|
Help()
|
||||||
|
return nil
|
||||||
|
|
||||||
// Shift+NUMBER keys, for switching to a specific tab
|
// Shift+NUMBER keys, for switching to a specific tab
|
||||||
case "!":
|
case "!":
|
||||||
@ -340,6 +352,8 @@ func Init() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Let another element handle the event, it's not a special global key
|
||||||
return event
|
return event
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -367,10 +381,9 @@ func NewTab() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
curTab = NumTabs()
|
curTab = NumTabs()
|
||||||
reformatPage(newTabPage)
|
|
||||||
|
|
||||||
tabs[curTab] = makeNewTab()
|
tabs = append(tabs, makeNewTab())
|
||||||
tabs[curTab].page = newTabPage
|
setPage(curTab, newTabPage)
|
||||||
|
|
||||||
// Can't go backwards, but this isn't the first page either.
|
// Can't go backwards, but this isn't the first page either.
|
||||||
// The first page will be the next one the user goes to.
|
// The first page will be the next one the user goes to.
|
||||||
@ -436,9 +449,12 @@ func CloseTab() {
|
|||||||
}
|
}
|
||||||
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
|
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
|
||||||
|
|
||||||
// Set previous tab's bottomBar state
|
// Restore previous tab's state
|
||||||
|
tabs[curTab].applySelected()
|
||||||
tabs[curTab].applyBottomBar()
|
tabs[curTab].applyBottomBar()
|
||||||
|
|
||||||
|
App.SetFocus(tabs[curTab].view)
|
||||||
|
|
||||||
// Just in case
|
// Just in case
|
||||||
App.Draw()
|
App.Draw()
|
||||||
}
|
}
|
||||||
@ -466,8 +482,11 @@ func SwitchTab(tab int) {
|
|||||||
reformatPageAndSetView(curTab, tabs[curTab].page)
|
reformatPageAndSetView(curTab, tabs[curTab].page)
|
||||||
tabPages.SwitchToPage(strconv.Itoa(curTab))
|
tabPages.SwitchToPage(strconv.Itoa(curTab))
|
||||||
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
|
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
|
||||||
|
tabs[curTab].applySelected()
|
||||||
tabs[curTab].applyBottomBar()
|
tabs[curTab].applyBottomBar()
|
||||||
|
|
||||||
|
App.SetFocus(tabs[curTab].view)
|
||||||
|
|
||||||
// Just in case
|
// Just in case
|
||||||
App.Draw()
|
App.Draw()
|
||||||
}
|
}
|
||||||
@ -493,7 +512,7 @@ func URL(u string) {
|
|||||||
// Some code is copied in followLink()
|
// Some code is copied in followLink()
|
||||||
|
|
||||||
if u == "about:bookmarks" {
|
if u == "about:bookmarks" {
|
||||||
Bookmarks()
|
Bookmarks(curTab)
|
||||||
tabs[curTab].addToHistory("about:bookmarks")
|
tabs[curTab].addToHistory("about:bookmarks")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ func histForward() {
|
|||||||
go func(tab int) {
|
go func(tab int) {
|
||||||
handleURL(tab, tabs[tab].history.urls[tabs[tab].history.pos]) // Load that position in history
|
handleURL(tab, tabs[tab].history.urls[tabs[tab].history.pos]) // Load that position in history
|
||||||
tabs[tab].applyScroll()
|
tabs[tab].applyScroll()
|
||||||
|
tabs[tab].applySelected()
|
||||||
if tab == curTab {
|
if tab == curTab {
|
||||||
// Display the bottomBar state that handleURL set
|
// Display the bottomBar state that handleURL set
|
||||||
tabs[tab].applyBottomBar()
|
tabs[tab].applyBottomBar()
|
||||||
@ -25,6 +26,7 @@ func histBack() {
|
|||||||
go func(tab int) {
|
go func(tab int) {
|
||||||
handleURL(tab, tabs[tab].history.urls[tabs[tab].history.pos]) // Load that position in history
|
handleURL(tab, tabs[tab].history.urls[tabs[tab].history.pos]) // Load that position in history
|
||||||
tabs[tab].applyScroll()
|
tabs[tab].applyScroll()
|
||||||
|
tabs[tab].applySelected()
|
||||||
if tab == curTab {
|
if tab == curTab {
|
||||||
// Display the bottomBar state that handleURL set
|
// Display the bottomBar state that handleURL set
|
||||||
tabs[tab].applyBottomBar()
|
tabs[tab].applyBottomBar()
|
||||||
|
@ -71,7 +71,7 @@ func followLink(tab int, prev, next string) {
|
|||||||
|
|
||||||
// Copied from URL()
|
// Copied from URL()
|
||||||
if next == "about:bookmarks" {
|
if next == "about:bookmarks" {
|
||||||
Bookmarks()
|
Bookmarks(tab)
|
||||||
tabs[tab].addToHistory("about:bookmarks")
|
tabs[tab].addToHistory("about:bookmarks")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ func handleURL(tab int, u string) (string, bool) {
|
|||||||
|
|
||||||
// To allow linking to the bookmarks page, and history browsing
|
// To allow linking to the bookmarks page, and history browsing
|
||||||
if u == "about:bookmarks" {
|
if u == "about:bookmarks" {
|
||||||
Bookmarks()
|
Bookmarks(tab)
|
||||||
return "about:bookmarks", true
|
return "about:bookmarks", true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,9 +241,14 @@ func handleURL(tab int, u string) (string, bool) {
|
|||||||
// Otherwise download it
|
// Otherwise download it
|
||||||
bottomBar.SetText("Loading...")
|
bottomBar.SetText("Loading...")
|
||||||
tabs[tab].barText = "Loading..." // Save it too, in case the tab switches during loading
|
tabs[tab].barText = "Loading..." // Save it too, in case the tab switches during loading
|
||||||
|
tabs[tab].mode = tabModeLoading
|
||||||
|
defer func(t int) {
|
||||||
|
tabs[t].mode = tabModeDone
|
||||||
|
}(tab)
|
||||||
App.Draw()
|
App.Draw()
|
||||||
|
|
||||||
res, err := client.Fetch(u)
|
res, err := client.Fetch(u)
|
||||||
|
|
||||||
if err == client.ErrTofu {
|
if err == client.ErrTofu {
|
||||||
if Tofu(parsed.Host) {
|
if Tofu(parsed.Host) {
|
||||||
// They want to continue anyway
|
// They want to continue anyway
|
||||||
@ -270,7 +275,7 @@ func handleURL(tab int, u string) (string, bool) {
|
|||||||
tabs[tab].barText = tabs[tab].page.Url
|
tabs[tab].barText = tabs[tab].page.Url
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
cache.Add(page)
|
go cache.Add(page)
|
||||||
setPage(tab, page)
|
setPage(tab, page)
|
||||||
return u, true
|
return u, true
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,10 @@ import (
|
|||||||
type tabMode int
|
type tabMode int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
modeOff tabMode = iota // Regular mode
|
tabModeDone tabMode = iota
|
||||||
modeLinkSelect // When the enter key is pressed, allow for tab-based link navigation
|
tabModeLoading
|
||||||
)
|
)
|
||||||
|
|
||||||
// tabHist holds the history for a tab.
|
|
||||||
type tabHistory struct {
|
type tabHistory struct {
|
||||||
urls []string
|
urls []string
|
||||||
pos int // Position: where in the list of URLs we are
|
pos int // Position: where in the list of URLs we are
|
||||||
@ -27,11 +26,9 @@ type tabHistory struct {
|
|||||||
type tab struct {
|
type tab struct {
|
||||||
page *structs.Page
|
page *structs.Page
|
||||||
view *cview.TextView
|
view *cview.TextView
|
||||||
mode tabMode
|
|
||||||
history *tabHistory
|
history *tabHistory
|
||||||
|
mode tabMode
|
||||||
reformatMut *sync.Mutex // Mutex for reformatting, so there's only one reformat job at once
|
reformatMut *sync.Mutex // Mutex for reformatting, so there's only one reformat job at once
|
||||||
selected string // The current text or link selected
|
|
||||||
selectedID string // The cview region ID for the selected text/link
|
|
||||||
barLabel string // The bottomBar label for the tab
|
barLabel string // The bottomBar label for the tab
|
||||||
barText string // The bottomBar text for the tab
|
barText string // The bottomBar text for the tab
|
||||||
}
|
}
|
||||||
@ -39,7 +36,7 @@ type tab struct {
|
|||||||
// makeNewTab initializes an tab struct with no content.
|
// makeNewTab initializes an tab struct with no content.
|
||||||
func makeNewTab() *tab {
|
func makeNewTab() *tab {
|
||||||
t := tab{
|
t := tab{
|
||||||
page: &structs.Page{},
|
page: &structs.Page{Mode: structs.ModeOff},
|
||||||
view: cview.NewTextView().
|
view: cview.NewTextView().
|
||||||
SetDynamicColors(true).
|
SetDynamicColors(true).
|
||||||
SetRegions(true).
|
SetRegions(true).
|
||||||
@ -48,9 +45,9 @@ func makeNewTab() *tab {
|
|||||||
SetChangedFunc(func() {
|
SetChangedFunc(func() {
|
||||||
App.Draw()
|
App.Draw()
|
||||||
}),
|
}),
|
||||||
mode: modeOff,
|
|
||||||
history: &tabHistory{},
|
history: &tabHistory{},
|
||||||
reformatMut: &sync.Mutex{},
|
reformatMut: &sync.Mutex{},
|
||||||
|
mode: tabModeDone,
|
||||||
}
|
}
|
||||||
t.view.SetDoneFunc(func(key tcell.Key) {
|
t.view.SetDoneFunc(func(key tcell.Key) {
|
||||||
// Altered from: https://gitlab.com/tslocum/cview/-/blob/master/demos/textview/main.go
|
// Altered from: https://gitlab.com/tslocum/cview/-/blob/master/demos/textview/main.go
|
||||||
@ -58,34 +55,43 @@ func makeNewTab() *tab {
|
|||||||
|
|
||||||
tab := curTab // Don't let it change in the middle of the code
|
tab := curTab // Don't let it change in the middle of the code
|
||||||
|
|
||||||
defer tabs[tab].saveBottomBar()
|
if key == tcell.KeyEsc && tabs[tab].mode == tabModeDone {
|
||||||
|
|
||||||
if key == tcell.KeyEsc {
|
|
||||||
// Stop highlighting
|
// Stop highlighting
|
||||||
tabs[tab].view.Highlight("")
|
|
||||||
bottomBar.SetLabel("")
|
bottomBar.SetLabel("")
|
||||||
bottomBar.SetText(tabs[tab].page.Url)
|
bottomBar.SetText(tabs[tab].page.Url)
|
||||||
tabs[tab].mode = modeOff
|
tabs[tab].clearSelected()
|
||||||
|
tabs[tab].saveBottomBar()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tabs[tab].page.Links) <= 0 {
|
||||||
|
// No links on page
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSelection := tabs[tab].view.GetHighlights()
|
currentSelection := tabs[tab].view.GetHighlights()
|
||||||
numSelections := len(tabs[tab].page.Links)
|
numSelections := len(tabs[tab].page.Links)
|
||||||
|
|
||||||
if key == tcell.KeyEnter {
|
if key == tcell.KeyEnter {
|
||||||
if len(currentSelection) > 0 && len(tabs[tab].page.Links) > 0 {
|
if len(currentSelection) > 0 {
|
||||||
// A link was selected, "click" it and load the page it's for
|
// A link was selected, "click" it and load the page it's for
|
||||||
bottomBar.SetLabel("")
|
bottomBar.SetLabel("")
|
||||||
tabs[tab].mode = modeOff
|
|
||||||
linkN, _ := strconv.Atoi(currentSelection[0])
|
linkN, _ := strconv.Atoi(currentSelection[0])
|
||||||
|
tabs[tab].page.Selected = tabs[tab].page.Links[linkN]
|
||||||
|
tabs[tab].page.SelectedID = currentSelection[0]
|
||||||
followLink(tab, tabs[tab].page.Url, tabs[tab].page.Links[linkN])
|
followLink(tab, tabs[tab].page.Url, tabs[tab].page.Links[linkN])
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
// They've started link highlighting
|
||||||
|
tabs[tab].page.Mode = structs.ModeLinkSelect
|
||||||
|
|
||||||
tabs[tab].view.Highlight("0").ScrollToHighlight()
|
tabs[tab].view.Highlight("0").ScrollToHighlight()
|
||||||
// Display link URL in bottomBar
|
// Display link URL in bottomBar
|
||||||
bottomBar.SetLabel("[::b]Link: [::-]")
|
bottomBar.SetLabel("[::b]Link: [::-]")
|
||||||
bottomBar.SetText(tabs[tab].page.Links[0])
|
bottomBar.SetText(tabs[tab].page.Links[0])
|
||||||
tabs[tab].selected = tabs[tab].page.Links[0]
|
tabs[tab].saveBottomBar()
|
||||||
tabs[tab].selectedID = "0"
|
tabs[tab].page.Selected = tabs[tab].page.Links[0]
|
||||||
|
tabs[tab].page.SelectedID = "0"
|
||||||
}
|
}
|
||||||
} else if len(currentSelection) > 0 {
|
} else if len(currentSelection) > 0 {
|
||||||
// There's still a selection, but a different key was pressed, not Enter
|
// There's still a selection, but a different key was pressed, not Enter
|
||||||
@ -102,8 +108,9 @@ func makeNewTab() *tab {
|
|||||||
// Display link URL in bottomBar
|
// Display link URL in bottomBar
|
||||||
bottomBar.SetLabel("[::b]Link: [::-]")
|
bottomBar.SetLabel("[::b]Link: [::-]")
|
||||||
bottomBar.SetText(tabs[tab].page.Links[index])
|
bottomBar.SetText(tabs[tab].page.Links[index])
|
||||||
tabs[tab].selected = tabs[tab].page.Links[index]
|
tabs[tab].saveBottomBar()
|
||||||
tabs[tab].selectedID = currentSelection[0]
|
tabs[tab].page.Selected = tabs[tab].page.Links[index]
|
||||||
|
tabs[tab].page.SelectedID = strconv.Itoa(index)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -179,3 +186,35 @@ func (t *tab) applyBottomBar() {
|
|||||||
bottomBar.SetLabel(t.barLabel)
|
bottomBar.SetLabel(t.barLabel)
|
||||||
bottomBar.SetText(t.barText)
|
bottomBar.SetText(t.barText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clearSelected turns off any selection that was going on.
|
||||||
|
// It does not affect the bottomBar.
|
||||||
|
func (t *tab) clearSelected() {
|
||||||
|
t.page.Mode = structs.ModeOff
|
||||||
|
t.page.Selected = ""
|
||||||
|
t.page.SelectedID = ""
|
||||||
|
t.view.Highlight("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// applySelected selects whatever is stored as the selected element in the struct,
|
||||||
|
// and sets the mode accordingly.
|
||||||
|
// It is safe to call if nothing was selected previously.
|
||||||
|
//
|
||||||
|
// applyBottomBar should be called after, as this func might set some bottomBar values.
|
||||||
|
func (t *tab) applySelected() {
|
||||||
|
if t.page.Mode == structs.ModeOff {
|
||||||
|
// Just in case
|
||||||
|
t.page.Selected = ""
|
||||||
|
t.page.SelectedID = ""
|
||||||
|
t.view.Highlight("")
|
||||||
|
return
|
||||||
|
} else if t.page.Mode == structs.ModeLinkSelect {
|
||||||
|
t.view.Highlight(t.page.SelectedID).ScrollToHighlight()
|
||||||
|
|
||||||
|
if t.mode == tabModeDone {
|
||||||
|
// Page is not loading so bottomBar can change
|
||||||
|
t.barLabel = "[::b]Link: [::-]"
|
||||||
|
t.barText = t.page.Selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,6 +7,13 @@ const (
|
|||||||
TextPlain Mediatype = "text/plain"
|
TextPlain Mediatype = "text/plain"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PageMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ModeOff PageMode = iota // Regular mode
|
||||||
|
ModeLinkSelect // When the enter key is pressed, allow for tab-based link navigation
|
||||||
|
)
|
||||||
|
|
||||||
// Page is for storing UTF-8 text/gemini pages, as well as text/plain pages.
|
// Page is for storing UTF-8 text/gemini pages, as well as text/plain pages.
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Url string
|
Url string
|
||||||
@ -17,11 +24,14 @@ type Page struct {
|
|||||||
Row int // Scroll position
|
Row int // Scroll position
|
||||||
Column int // ditto
|
Column int // ditto
|
||||||
Width int // The width of the terminal at the time when the Content was set. This is to know when reformatting should happen.
|
Width int // The width of the terminal at the time when the Content was set. This is to know when reformatting should happen.
|
||||||
|
Selected string // The current text or link selected
|
||||||
|
SelectedID string // The cview region ID for the selected text/link
|
||||||
|
Mode PageMode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns an approx. size of a Page in bytes.
|
// Size returns an approx. size of a Page in bytes.
|
||||||
func (p *Page) Size() int {
|
func (p *Page) Size() int {
|
||||||
b := len(p.Raw) + len(p.Content) + len(p.Url)
|
b := len(p.Raw) + len(p.Content) + len(p.Url) + len(p.Selected) + len(p.SelectedID)
|
||||||
for i := range p.Links {
|
for i := range p.Links {
|
||||||
b += len(p.Links[i])
|
b += len(p.Links[i])
|
||||||
}
|
}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
package structs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSize(t *testing.T) {
|
|
||||||
p := Page{
|
|
||||||
Url: "12345",
|
|
||||||
Raw: "12345",
|
|
||||||
Content: "12345",
|
|
||||||
Links: []string{"1", "2", "3", "4", "5"},
|
|
||||||
}
|
|
||||||
assert.Equal(t, 20, p.Size(), "sizes should be equal")
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user