~adnano/astronaut

72319c47d4e32cc4a15ff6030d55829d0160bd09 — Adnan Maolood 2 months ago 913d8e0 master
browser: Rework input channels
2 files changed, 24 insertions(+), 14 deletions(-)

M browser.go
M tab.go
M browser.go => browser.go +8 -5
@@ 10,6 10,7 @@ import (
	"os"
	"path/filepath"
	"strings"
	"sync"

	"git.sr.ht/~adnano/go-gemini"
	"git.sr.ht/~adnano/go-gemini/certificate"


@@ 43,6 44,8 @@ type Browser struct {
	status    ui.StatusLine
	input     ui.Input
	mode      Mode
	mu        sync.Mutex
	inputch   chan string
}

// init initializes the browser.


@@ 87,14 90,13 @@ func (b *Browser) onInput(input string, ok bool) {
			return
		}
		b.RunCommand(input)
	} else if tab := b.tabs[b.tab]; tab.inputc != nil {
		// XXX: This doesn't work well with multiple tabs.
	} else if b.inputch != nil {
		if ok {
			tab.inputc <- input
			b.inputch <- input
		} else {
			close(tab.inputc)
			close(b.inputch)
		}
		tab.inputc = nil
		b.inputch = nil
		b.status.Clear()
		b.view.Invalidate()
	}


@@ 409,6 411,7 @@ func (b *Browser) NewTab() *Tab {
		Settings:     b.settings,
		status:       &b.status,
		input:        &b.input,
		browser:      b,
	}
}


M tab.go => tab.go +16 -9
@@ 31,7 31,8 @@ type Tab struct {
	cancel func()
	status *ui.StatusLine
	input  *ui.Input
	inputc chan string

	browser *Browser

	URL    string // current URL
	Media  string // media type


@@ 77,6 78,7 @@ func (t *Tab) Clone() *Tab {
	clone.HostsFile = t.HostsFile
	clone.Certificates = t.Certificates
	clone.Settings = t.Settings
	clone.browser = t.browser
	return clone
}



@@ 454,7 456,14 @@ func (t *Tab) do(ctx context.Context, req *gemini.Request, via []*gemini.Request
		// TODO: Allow piping response somewhere else
		resp.Body.Close()
	}
}

func (t *Tab) inputch() chan string {
	ch := make(chan string)
	t.browser.mu.Lock()
	defer t.browser.mu.Unlock()
	t.browser.inputch = ch
	return ch
}

// getInput is called to retrieve input when a server requests it.


@@ 462,9 471,9 @@ func (t *Tab) getInput(prompt string, sensitive bool) (string, bool) {
	t.mu.Lock()
	t.input.Prompt(prompt + " ")
	t.input.Sensitive(sensitive)
	ch := make(chan string)
	t.inputc = ch
	t.mu.Unlock()

	ch := t.inputch()
	input, ok := <-ch
	if ok {
		return input, true


@@ 488,10 497,9 @@ func (t *Tab) shouldRedirect(req *gemini.Request, via []*gemini.Request) bool {
		t.mu.Lock()
		t.status.Warn(fmt.Sprintf("Redirecting to %s", req.URL))
		t.input.Confirm("Proceed?")
		ch := make(chan string)
		t.inputc = ch
		t.mu.Unlock()

		ch := t.inputch()
		if _, ok := <-ch; !ok {
			return false
		}


@@ 525,9 533,9 @@ func (t *Tab) createCertificate(hostname string) (tls.Certificate, bool) {
	t.mu.Lock()
	t.status.Info("Creating a certificate for " + hostname)
	t.input.Prompt("Duration: ")
	ch := make(chan string)
	t.inputc = ch
	t.mu.Unlock()

	ch := t.inputch()
	input, ok := <-ch
	if !ok {
		return tls.Certificate{}, false


@@ 571,10 579,9 @@ func (t *Tab) trustCertificate(hostname string, cert *x509.Certificate) error {
	t.mu.Lock()
	t.status.Warn(fmt.Sprintf(trustInfo, hostname))
	t.input.Prompt(trustPrompt)
	ch := make(chan string)
	t.inputc = ch
	t.mu.Unlock()

	ch := t.inputch()
	if input, ok := <-ch; ok {
		switch input {
		case "":