forked from tildetown/town
		
	WIP
This commit is contained in:
		
							parent
							
								
									6b86087c0e
								
							
						
					
					
						commit
						d7adcbf11f
					
				| @ -1,16 +1,13 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 	"unicode/utf8" | ||||
| 
 | ||||
| 	"github.com/MakeNowJust/heredoc/v2" | ||||
| 	"github.com/gdamore/tcell/v2" | ||||
| 	"github.com/rivo/tview" | ||||
| ) | ||||
| 
 | ||||
| @ -61,7 +58,19 @@ func cli(s *streams) error { | ||||
| 	sidebar := tview.NewTextView() | ||||
| 	sidebar.SetBorder(true) | ||||
| 	sidebar.SetDynamicColors(true) | ||||
| 	sidebar.SetText("[-:-:b]pbbt[-:-:-]") | ||||
| 	sidebar.SetText(heredoc.Doc(` | ||||
| 		[-:-:b]hey here are some hints[-:-:-] | ||||
| 
 | ||||
| 		quit by pressing [-:-:b]ctrl-c[-:-:-] | ||||
| 		(your responses won't be saved) | ||||
| 
 | ||||
| 		type stuff. send it with [-:-:b]ctrl+d[-:-:-] | ||||
| 
 | ||||
| 		try a [-:-:b]verb[-:-:-] using [-:-:b]/[-:-:-] like: | ||||
| 
 | ||||
| 		[-:-:b]/go north[-:-:-] | ||||
| 
 | ||||
| 	`)) | ||||
| 
 | ||||
| 	innerFlex.SetDirection(tview.FlexColumn) | ||||
| 	innerFlex.AddItem(msgScroll, 0, 2, false) | ||||
| @ -77,9 +86,52 @@ func cli(s *streams) error { | ||||
| 	app := tview.NewApplication() | ||||
| 	app.SetRoot(pages, true) | ||||
| 
 | ||||
| 	player := newCharacter("you", "TODO") | ||||
| 
 | ||||
| 	handleInput := func(msg string) { | ||||
| 		if strings.HasPrefix(msg, "/") { | ||||
| 			// TODO handle command | ||||
| 		} | ||||
| 		fmt.Fprintln(msgScroll, player.Say(msg)) | ||||
| 	} | ||||
| 
 | ||||
| 	app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { | ||||
| 		switch event.Key() { | ||||
| 		case tcell.KeyCtrlD: | ||||
| 			handleInput(input.GetText()) | ||||
| 			input.SetText("", false) | ||||
| 			return nil | ||||
| 		} | ||||
| 
 | ||||
| 		return event | ||||
| 	}) | ||||
| 
 | ||||
| 	return app.Run() | ||||
| } | ||||
| 
 | ||||
| type character struct { | ||||
| 	Name        string | ||||
| 	Description string | ||||
| } | ||||
| 
 | ||||
| func newCharacter(name, description string) *character { | ||||
| 	return &character{ | ||||
| 		Name:        name, | ||||
| 		Description: description, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (c *character) Say(msg string) string { | ||||
| 	verb := "says" | ||||
| 	if c.Name == "you" { | ||||
| 		verb = "say" | ||||
| 	} | ||||
| 	return fmt.Sprintf("[-:-:b]%s[-:-:-] %s: '%s'", | ||||
| 		c.Name, | ||||
| 		verb, | ||||
| 		strings.TrimSpace(msg)) | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	s := &streams{ | ||||
| 		In:  os.Stdin, | ||||
| @ -93,141 +145,7 @@ func main() { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type Prompter struct { | ||||
| 	in    io.Reader | ||||
| 	out   io.Writer | ||||
| 	width int | ||||
| } | ||||
| 
 | ||||
| func (p *Prompter) Say(m string) { | ||||
| 	for _, line := range wrap(m, p.width) { | ||||
| 		fmt.Fprintln(p.out, line) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *Prompter) CharSay(c, m string) { | ||||
| 	sayPrefix := fmt.Sprintf("%s says: ", c) | ||||
| 	prefixWidth := utf8.RuneCountInString(sayPrefix) | ||||
| 	width := p.width - prefixWidth | ||||
| 	indent := "" | ||||
| 	for x := 0; x < utf8.RuneCountInString(sayPrefix); x++ { | ||||
| 		indent += " " | ||||
| 	} | ||||
| 	for i, line := range wrap(m, width) { | ||||
| 		if i == 0 { | ||||
| 			fmt.Fprintln(p.out, sayPrefix+line) | ||||
| 		} else { | ||||
| 			fmt.Fprintln(p.out, indent+line) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type InputAnswer struct { | ||||
| 	Value string | ||||
| } | ||||
| 
 | ||||
| func runeLen(s string) int { | ||||
| 	return utf8.RuneCountInString(s) | ||||
| } | ||||
| 
 | ||||
| func wrap(s string, width int) []string { | ||||
| 	fielded := strings.Fields(s) | ||||
| 	out := []string{} | ||||
| 	line := "" | ||||
| 	for i, field := range fielded { | ||||
| 		if runeLen(field)+runeLen(line)+1 < width { | ||||
| 			line += field + " " | ||||
| 		} else { | ||||
| 			out = append(out, line) | ||||
| 			line = field + " " | ||||
| 			continue | ||||
| 		} | ||||
| 		if i == len(fielded)-1 { | ||||
| 			out = append(out, line) | ||||
| 		} | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
| 
 | ||||
| func (p *Prompter) Confirm(m string) (bool, error) { | ||||
| 	result := InputAnswer{} | ||||
| 
 | ||||
| 	for { | ||||
| 		err := p.Ask(m, &result) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| 
 | ||||
| 		val := strings.TrimSpace(result.Value) | ||||
| 
 | ||||
| 		switch val { | ||||
| 		case "yes", "y": | ||||
| 			return true, nil | ||||
| 		case "no", "n": | ||||
| 			return false, nil | ||||
| 		default: | ||||
| 			p.Say("sorry, please say y or n") | ||||
| 			p.Pause() | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *Prompter) Ask(m string, result *InputAnswer) error { | ||||
| 	fmt.Fprintf(p.out, "%s ", m) | ||||
| 	var val string | ||||
| 	var err error | ||||
| 
 | ||||
| 	reader := bufio.NewReader(p.in) | ||||
| 	for val == "" { | ||||
| 		val, err = reader.ReadString('\n') | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if val == "" { | ||||
| 			p.Say("hmm, what was that?") | ||||
| 			p.Pause() | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	result.Value = val | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *Prompter) AskLong(m string, result *InputAnswer) error { | ||||
| 	fmt.Fprintf(p.out, "%s\n", m) | ||||
| 	var val []byte | ||||
| 	var err error | ||||
| 
 | ||||
| 	reader := bufio.NewReader(p.in) | ||||
| 	for len(val) == 0 { | ||||
| 		val, err = ioutil.ReadAll(reader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if len(val) == 0 { | ||||
| 			fmt.Fprintf(p.out, "%s\n", m) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	result.Value = string(val) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *Prompter) Pause() { | ||||
| 	fmt.Fprintln(p.out) | ||||
| 	time.Sleep(1 * time.Second) | ||||
| } | ||||
| 
 | ||||
| func NewPrompter(width int, s *streams) Prompter { | ||||
| 	return Prompter{ | ||||
| 		in:    s.In, | ||||
| 		out:   s.Out, | ||||
| 		width: width, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| type answers struct { | ||||
| 	username string | ||||
| 	email    string | ||||
| @ -242,29 +160,6 @@ type answers struct { | ||||
| } | ||||
| 
 | ||||
| func _main(args []string, s *streams) error { | ||||
| 	a := answers{} | ||||
| 
 | ||||
| 	p := NewPrompter(80, s) | ||||
| 
 | ||||
| 	// disable input buffering | ||||
| 	exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run() | ||||
| 
 | ||||
| 	// LOL i don't think this will work | ||||
| 	//reader := bufio.NewReader(p.in) | ||||
| 	//s, _ := reader.ReadString(4) | ||||
| 	fmt.Printf("DBG %#v\n", s) | ||||
| 	//var b []byte = make([]byte, 100) | ||||
| 	//for { | ||||
| 	//	os.Stdin.Read(b) | ||||
| 	//	fmt.Println("I got the byte", b, "("+string(b)+")") | ||||
| 	//} | ||||
| 
 | ||||
| 	var ia InputAnswer | ||||
| 	if err := p.AskLong("lol give me stuff hit ctrl+d", &ia); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	fmt.Printf("DBG %#v\n", ia.Value) | ||||
| 
 | ||||
| 	p.Say("you are standing in a field.") | ||||
| 	p.Pause() | ||||
| 	p.Say("there are flowers around you. you are standing in a slight depression and before you is grass touching a purple sky.") | ||||
| @ -345,54 +240,5 @@ func _main(args []string, s *streams) error { | ||||
| 
 | ||||
| 	p.CharSay("cube", "i know that was a lot so i appreciate it. i've got everything written down here. before i carry it off, do you want to review and edit what you wrote?") | ||||
| 
 | ||||
| 	confirmed, err := p.Confirm("type y or n: ") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if confirmed { | ||||
| 		err := edit(s, &a) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Printf("DBG %#v\n", confirmed) | ||||
| 
 | ||||
| 	fmt.Printf("DBG %#v\n", a) | ||||
| 
 | ||||
| 	// TODO allow for editing | ||||
| 	// TODO write answers to disk | ||||
| 	// TODO add a log | ||||
| 	// TODO pretty colors | ||||
| 	// TODO ascii art | ||||
| 	// TODO IP throttling? | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func edit(s *streams, a *answers) error { | ||||
| 	// TODO make more real | ||||
| 	/* | ||||
| 		username string | ||||
| 		email    string | ||||
| 		applied  time.Time | ||||
| 
 | ||||
| 		howDay   string | ||||
| 		howHeard string | ||||
| 		reasons  string | ||||
| 		plans    string | ||||
| 		socials  string | ||||
| 		sshKey   string | ||||
| 	*/ | ||||
| 	// TODO add note about tabbing around | ||||
| 
 | ||||
| 	app := tview.NewApplication() | ||||
| 	form := tview.NewForm(). | ||||
| 		AddInputField("how did you hear about the town?", a.howHeard, 0, nil, nil). | ||||
| 		AddButton("cool i'm good", nil). | ||||
| 		AddButton("cancel and discard all this please", func() { app.Stop() }) | ||||
| 	form.SetBorder(true).SetTitle("edit your stuff").SetTitleAlign(tview.AlignCenter) | ||||
| 
 | ||||
| 	return app.SetRoot(form, true).EnableMouse(true).Run() | ||||
| } | ||||
| */ | ||||
|  | ||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @ -4,6 +4,7 @@ go 1.18 | ||||
| 
 | ||||
| require ( | ||||
| 	github.com/AlecAivazis/survey/v2 v2.3.5 | ||||
| 	github.com/MakeNowJust/heredoc/v2 v2.0.1 | ||||
| 	github.com/charmbracelet/glamour v0.5.0 | ||||
| 	github.com/rivo/tview v0.0.0-20230130130022-4a1b7a76c01c | ||||
| 	github.com/spf13/cobra v1.5.0 | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @ -1,5 +1,7 @@ | ||||
| github.com/AlecAivazis/survey/v2 v2.3.5 h1:A8cYupsAZkjaUmhtTYv3sSqc7LO5mp1XDfqe5E/9wRQ= | ||||
| github.com/AlecAivazis/survey/v2 v2.3.5/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= | ||||
| github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A= | ||||
| github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM= | ||||
| github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= | ||||
| github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= | ||||
| github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user