~adnano/astronaut

f4e5bba01d1f0ed757a9b61382438906bf566923 — Adnan Maolood 5 months ago c79219e
browser: Remove save mode
4 files changed, 20 insertions(+), 110 deletions(-)

D about/open.tmpl
M browser.go
M command.go
M tab.go
D about/open.tmpl => about/open.tmpl +0 -7
@@ 1,7 0,0 @@
# Opening {{.Filename}}

You have chosen to open {{.Filename}} which is {{.MediaType}} from {{.Hostname}}.

=> save Save file
=> open Open in external program
=> abort Abort

M browser.go => browser.go +1 -45
@@ 3,9 3,7 @@ package main
import (
	"astronaut/styles"
	"astronaut/ui"
	"bufio"
	"fmt"
	"io"
	"log"
	"math"
	"math/rand"


@@ 30,7 28,6 @@ const (
	ModeNormal Mode = iota
	ModeCommand
	ModeInput
	ModeSave
	ModeFollow
)



@@ 59,9 56,6 @@ type Browser struct {

	input ui.Input

	// save mode
	data io.ReadCloser

	// follow mode
	hint    string
	hints   []Hint


@@ 191,7 185,7 @@ func (b *Browser) Draw() {
			b.statusView.DrawText(0, 0, b.message.text, style)
		}

	case ModeCommand, ModeInput, ModeSave:
	case ModeCommand, ModeInput:
		b.input.Draw()

	case ModeFollow:


@@ 290,31 284,6 @@ func (b *Browser) Event(event tcell.Event) {
			tab.DoBackground(req)
		}

	case ModeSave:
		switch event := event.(type) {
		case *ui.EventTextInput:
			b.mode = ModeNormal
			data := b.data
			defer data.Close()
			b.data = nil
			if event.NoInput() {
				return
			}
			// TODO: Avoid overwriting files
			// TODO: Download directory?
			f, err := os.Create(event.Text())
			if err != nil {
				tab.Error(err)
				return
			}
			defer f.Close()
			_, err = io.Copy(bufio.NewWriter(f), data)
			if err != nil {
				tab.Error(err)
				return
			}
		}

	case ModeFollow:
		text := tab.Text()
		if text == nil {


@@ 705,19 674,6 @@ func (b *Browser) InputMode(prompt string, sensitive bool) {
	b.input.Sensitive(sensitive)
}

func (b *Browser) SaveMode(data io.ReadCloser, name string) {
	b.mu.Lock()
	defer b.mu.Unlock()
	b.saveMode(data, name)
}

func (b *Browser) saveMode(data io.ReadCloser, name string) {
	b.mode = ModeSave
	b.data = data
	b.input.Prompt("Save as ")
	b.input.SetInput(name)
}

func (b *Browser) FollowMode() error {
	text := b.tabs[b.tab].Text()
	if text == nil {

M command.go => command.go +16 -3
@@ 1,10 1,11 @@
package main

import (
	"bufio"
	"errors"
	"io"
	"net/url"
	"path"
	"os"
	"strconv"
	"strings"



@@ 264,9 265,21 @@ func cmdScroll(b *Browser, args ...string) error {
}

func cmdSave(b *Browser, args ...string) error {
	if len(args) < 1 {
		return errors.New("usage: save <path>")
	}
	tab := b.tabs[b.tab]
	name := path.Base(tab.URL())
	b.saveMode(io.NopCloser(&tab.buf), name)
	name := args[0]

	f, err := os.OpenFile(name, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = io.Copy(bufio.NewWriter(f), &tab.buf)
	if err != nil {
		return err
	}
	return nil
}


M tab.go => tab.go +3 -55
@@ 634,7 634,7 @@ func (t *Tab) handle(req *gemini.Request, resp *gemini.Response) error {
		defer resp.Body.Close()
		return t.handleText(resp, mediatype, params)
	}
	return t.handleDownload(req, resp, mediatype)
	return t.openResponse(req, resp, mediatype)
}

func (t *Tab) handleText(resp *gemini.Response, mediatype string, params map[string]string) error {


@@ 655,60 655,9 @@ func (t *Tab) handleText(resp *gemini.Response, mediatype string, params map[str
	return err
}

func (t *Tab) handleDownload(req *gemini.Request, resp *gemini.Response, mediatype string) error {
func (t *Tab) openResponse(req *gemini.Request, resp *gemini.Response, mediatype string) error {
	filename := path.Base(req.URL.Path)

	ch := make(chan int)
	const (
		save = iota + 1
		open
	)

	{
		t.setStyle(styles.Warning)
		defer t.setStyle(tcell.StyleDefault)

		ctx := struct {
			Hostname  string
			Filename  string
			MediaType string
		}{
			req.URL.Hostname(),
			filename,
			mediatype,
		}
		var buf bytes.Buffer
		templates.ExecuteTemplate(&buf, "open.tmpl", ctx)
		gem := NewParsedGemText(t.view, t, io.NopCloser(&buf))
		gem.action = func(action string) {
			switch action {
			case "save":
				ch <- save
			case "open":
				ch <- open
			default:
				close(ch)
			}
		}
		t.setText(gem)
		defer t.setText(nil)
	}

	select {
	case choice := <-ch:
		switch choice {
		case save:
			t.browser.SaveMode(resp.Body, filename)
			return nil
		case open:
			defer resp.Body.Close()
			return t.openResponse(resp, filename)
		}
	}
	return nil
}

func (t *Tab) openResponse(resp *gemini.Response, filename string) error {
	f, err := os.CreateTemp("", "astronaut-*-"+filename)
	if err != nil {
		return err


@@ 721,8 670,7 @@ func (t *Tab) openResponse(resp *gemini.Response, filename string) error {

	// TODO: Configurable open command?
	cmd := exec.Command("xdg-open", f.Name())
	cmd.Stderr = os.Stderr
	if err := cmd.Start(); err != nil {
	if err := cmd.Run(); err != nil {
		return err
	}
	return nil