From c5740bd387b9847894d4ab2dba49f5ae44864fc9 Mon Sep 17 00:00:00 2001 From: nbsp Date: Mon, 6 Jan 2025 17:30:08 +0200 Subject: [PATCH] add config file parsing and changing still kinda broken on resize --- app/config.go | 169 +++++++++++++++++++++++++++++++++++++++++++++++ app/menu.go | 6 +- config/config.go | 49 ++++++++++++++ go.mod | 1 + go.sum | 10 +++ ui/list.go | 4 ++ 6 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 app/config.go create mode 100644 config/config.go diff --git a/app/config.go b/app/config.go new file mode 100644 index 0000000..67adda3 --- /dev/null +++ b/app/config.go @@ -0,0 +1,169 @@ +package app + +import ( + "fmt" + "strconv" + + "git.sr.ht/~rockorager/vaxis" + "git.sr.ht/~rockorager/vaxis/widgets/textinput" + "git.tilde.town/nbsp/neofeels/config" + "git.tilde.town/nbsp/neofeels/ui" +) + +type Config struct { + title string + list ui.List + help string + config *config.Config + descriptions []string +} + +var configList = []string{ + "publish to html", + "publish to gopher", + "default to nopub", +} + +func NewConfig() *Config { + cfg, err := config.Read() + if err != nil { + cfg = config.Default + } + return &Config{ + title, + ui.NewList(configList), + "↑↓/kj move ↵ enter q return", + cfg, + []string{ + `do you want to publish your feels online? + +if yes, your feels will be published to a directory of your choice in your +public_html. if not, your feels will only be readable from within the tilde.town +network. if you already have a publishing directory, i'll remove it for you +(don't worry, your written entries will still be saved!)`, + `gopher is a pre-web technology that is text-oriented and primarily used to +share folders of your files with the world. + +would you like to publish your feels to gopher? + +entries you write will automatically get linked to ~/public_gopher/feels/, +including gophermap generation. files you manually delete will no longer be +visible from your gopherhole, and will be purged from your gophermap on your +next entry update.`, + `in which directory under public_html should your blog reside? for example, +"blog" will make it visible under https://tilde.town/~you/blog.`, + `should your posts automatically show up on your world-visible pages, such as +html and gopher? you can change this behaviour on a per-post basis after the +fact. changes to this setting will not be made retroactively.`, + }, + } +} + +func (config *Config) Event(state *ui.State, event vaxis.Event) (processed bool) { + if key, ok := event.(vaxis.Key); ok && key.EventType == vaxis.EventPress { + switch key.String() { + case "Ctrl+c", "Ctrl+d": + close(ui.Quit) + case "Down", "j": + config.list.Down() + case "Up", "k": + config.list.Up() + case "End", "Shift+g": + config.list.End() + case "Home", "g": + config.list.Home() + case "0", "1": + i, _ := strconv.Atoi(key.String()) + config.list.SetIndex(i) + case "2", "3": + if config.config.Publishing { + + i, _ := strconv.Atoi(key.String()) + config.list.SetIndex(i) + } + case "q", "h", "Left": + ui.ViewChange <- NewMainMenu() + case "Enter", "l", "Right", "Space": + switch config.list.Index() { + case 0: + config.config.Publishing = !config.config.Publishing + case 1: + config.config.Gopher = !config.config.Gopher + case 2: + config.config.Nopub = !config.config.Nopub + case 3: + config.config.PublishDir = config.changePublishDir(state) + } + config.config.Write() + } + processed = true + } + config.Draw(state) + return +} + +func (config *Config) Draw(state *ui.State) { + if config.config.Publishing { + config.list.SetItems(append(configList, "html publish directory")) + } else { + config.list.SetItems(configList) + } + win := state.Window() + win.New(win.Width/2-10, win.Height/2-8, 20, 5).Print(vaxis.Segment{Text: config.title}) + config.list.Draw(vaxis.Window{ + Vx: win.Vx, + Parent: nil, + Column: win.Width/2 - 21, + Row: win.Height/2 - 2, + Width: 28, + Height: 4, + }) + win.New(win.Width/2-40, win.Height/2+3, 80, 10).Print(vaxis.Segment{Text: config.descriptions[config.list.Index()]}) + win.New(win.Width/2-15, win.Height/2+13, 30, 1).Print(vaxis.Segment{Text: config.help}) + + // drawing the current selected options + win.New(win.Width/2+7, win.Height/2-2, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Publishing)}) + win.New(win.Width/2+7, win.Height/2-1, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Gopher)}) + win.New(win.Width/2+7, win.Height/2, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Nopub)}) + if config.config.Publishing { + win.New(win.Width/2+7, win.Height/2+1, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.PublishDir)}) + } +} + +func (config *Config) changePublishDir(state *ui.State) string { + ti := textinput.New() + ti.SetContent(config.config.PublishDir) + config.Draw(state) + win := state.Window() + ti.Draw(vaxis.Window{ + Vx: win.Vx, + Parent: &win, + Column: win.Width/2 + 9, + Row: win.Height/2 + 1, + Width: 12, + Height: 1, + }) + for ev := range win.Vx.Events() { + switch ev := ev.(type) { + case vaxis.Key: + switch ev.String() { + case "Ctrl+c", "Esc", "Enter": + state.HideCursor() + return ti.String() + } + } + ti.Update(ev) + config.Draw(state) + ti.Draw(vaxis.Window{ + Vx: win.Vx, + Parent: nil, + Column: win.Width/2 + 9, + Row: win.Height/2 + 1, + Width: 12, + Height: 1, + }) + state.Render() + } + + return "" +} diff --git a/app/menu.go b/app/menu.go index 20d6c27..341071e 100644 --- a/app/menu.go +++ b/app/menu.go @@ -34,8 +34,8 @@ func NewMainMenu() *MainMenu { "browse global feels", // TODO "visit your subscriptions", // TODO "scribble some graffiti", // TODO - "change your settings", // TODO - "send some feedback", // TODO + "change your settings", + "send some feedback", // TODO "see credits", "read documentation", }), @@ -65,6 +65,8 @@ func (menu *MainMenu) Event(state *ui.State, event vaxis.Event) (processed bool) newFeels(state) case 1: ui.ViewChange <- NewManagement() + case 6: + ui.ViewChange <- NewConfig() case 8: ui.ViewChange <- NewCredits() case 9: diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..bb10526 --- /dev/null +++ b/config/config.go @@ -0,0 +1,49 @@ +package config + +import ( + "encoding/json" + "os" + "path" +) + +type Config struct { + Editor string `json:"editor"` // we don't care about this + Gopher bool `json:"gopher"` + Nopub bool `json:"post as nopub"` + PublishDir string `json:"publish dir"` + Publishing bool `json:"publishing"` + Rainbows bool `json:"rainbows"` // we don't care about this +} + +var Default = &Config{ + Editor: "nano", + Gopher: false, + Nopub: false, + PublishDir: "blog", + Publishing: false, + Rainbows: false, +} + +func Read() (config *Config, err error) { + file, err := os.Open(path.Join(os.Getenv("HOME"), ".ttbp/config/ttbprc")) + if err != nil { + return + } + defer file.Close() + + decoder := json.NewDecoder(file) + err = decoder.Decode(&config) + return +} + +func (config *Config) Write() (err error) { + file, err := os.Create(path.Join(os.Getenv("HOME"), ".ttbp/config/ttbprc")) + if err != nil { + return + } + defer file.Close() + + encoder := json.NewEncoder(file) + err = encoder.Encode(config) + return +} diff --git a/go.mod b/go.mod index 8122db5..62fabe3 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/mattn/go-sixel v0.0.5 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/soniakeys/quant v1.0.0 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/image v0.9.0 // indirect golang.org/x/sys v0.10.0 // indirect ) diff --git a/go.sum b/go.sum index 4c399c7..9d5dea7 100644 --- a/go.sum +++ b/go.sum @@ -4,18 +4,26 @@ github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARu github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sixel v0.0.5 h1:55w2FR5ncuhKhXrM5ly1eiqMQfZsnAHIpYNGZX03Cv8= github.com/mattn/go-sixel v0.0.5/go.mod h1:h2Sss+DiUEHy0pUqcIB6PFXo5Cy8sTQEFr3a9/5ZLNw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/soniakeys/quant v1.0.0 h1:N1um9ktjbkZVcywBVAAYpZYSHxEfJGzshHCxx/DaI0Y= github.com/soniakeys/quant v1.0.0/go.mod h1:HI1k023QuVbD4H8i9YdfZP2munIHU4QpjsImz6Y6zds= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.9.0 h1:QrzfX26snvCM20hIhBwuHI/ThTg18b/+kcKdXHvnR+g= golang.org/x/image v0.9.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -49,3 +57,5 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/ui/list.go b/ui/list.go index 901d179..0a83f1f 100644 --- a/ui/list.go +++ b/ui/list.go @@ -81,6 +81,10 @@ func (m *List) PageUp(win vaxis.Window) { m.index = max(0, m.index-height) } +func (m *List) Items() []string { + return m.items +} + func (m *List) SetItems(items []string) { m.items = items m.index = min(len(items)-1, m.index)