summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-06-17 09:29:40 +0300
committerPaul Buetow <paul@buetow.org>2024-06-17 09:29:40 +0300
commit2f353f6d9aee9d9a989d11757289c11679752789 (patch)
tree68ff89aa37c661ad6de00c3774ce45b31591a4e0
parent4867c040ffddfc18b235e1950f44870c99acf096 (diff)
initial TUI for the client
-rw-r--r--cmd/gos/main.go3
-rw-r--r--go.mod18
-rw-r--r--go.sum32
-rw-r--r--internal/client/tui/tui.go81
4 files changed, 133 insertions, 1 deletions
diff --git a/cmd/gos/main.go b/cmd/gos/main.go
index 2f2ac89..a313b6f 100644
--- a/cmd/gos/main.go
+++ b/cmd/gos/main.go
@@ -4,6 +4,7 @@ import (
"flag"
"log"
+ "codeberg.org/snonux/gos/internal/client/tui"
config "codeberg.org/snonux/gos/internal/config/client"
)
@@ -15,5 +16,5 @@ func main() {
log.Fatal("error building config:", err)
}
- log.Println(conf)
+ tui.Run(conf)
}
diff --git a/go.mod b/go.mod
index fd9a54a..701650f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,21 @@
module codeberg.org/snonux/gos
go 1.22.2
+
+require (
+ github.com/charmbracelet/bubbletea v0.26.4 // indirect
+ github.com/charmbracelet/x/ansi v0.1.2 // indirect
+ github.com/charmbracelet/x/input v0.1.0 // indirect
+ github.com/charmbracelet/x/term v0.1.1 // indirect
+ github.com/charmbracelet/x/windows v0.1.0 // indirect
+ github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
+ github.com/mattn/go-localereader v0.0.1 // indirect
+ github.com/mattn/go-runewidth v0.0.15 // indirect
+ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
+ github.com/muesli/cancelreader v0.2.2 // indirect
+ github.com/rivo/uniseg v0.4.7 // indirect
+ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
+ golang.org/x/sync v0.7.0 // indirect
+ golang.org/x/sys v0.20.0 // indirect
+ golang.org/x/text v0.3.8 // indirect
+)
diff --git a/go.sum b/go.sum
index e69de29..9ac6c71 100644
--- a/go.sum
+++ b/go.sum
@@ -0,0 +1,32 @@
+github.com/charmbracelet/bubbletea v0.26.4 h1:2gDkkzLZaTjMl/dQBpNVtnvcCxsh/FCkimep7FC9c40=
+github.com/charmbracelet/bubbletea v0.26.4/go.mod h1:P+r+RRA5qtI1DOHNFn0otoNwB4rn+zNAzSj/EXz6xU0=
+github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
+github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
+github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ=
+github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28=
+github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
+github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw=
+github.com/charmbracelet/x/windows v0.1.0 h1:gTaxdvzDM5oMa/I2ZNF7wN78X/atWemG9Wph7Ika2k4=
+github.com/charmbracelet/x/windows v0.1.0/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
+github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
+github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
+github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
+github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
+github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
+github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
+github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
diff --git a/internal/client/tui/tui.go b/internal/client/tui/tui.go
new file mode 100644
index 0000000..6486ff2
--- /dev/null
+++ b/internal/client/tui/tui.go
@@ -0,0 +1,81 @@
+package tui
+
+import (
+ "fmt"
+ "log"
+
+ config "codeberg.org/snonux/gos/internal/config/client"
+ tea "github.com/charmbracelet/bubbletea"
+)
+
+func Run(config config.ClientConfig) {
+ p := tea.NewProgram(initModel())
+ if _, err := p.Run(); err != nil {
+ log.Fatal("error starting TUI:", err)
+ }
+}
+
+type model struct {
+ choices []string
+ cursor int
+ selected map[int]struct{}
+}
+
+func initModel() model {
+ return model{
+ choices: []string{"Compose post", "Schedule post"},
+ selected: make(map[int]struct{}),
+ }
+}
+
+func (m model) Init() tea.Cmd {
+ return nil
+}
+
+func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ switch msg := msg.(type) {
+ case tea.KeyMsg:
+ switch msg.String() {
+ case "ctrl+c", "q":
+ return m, tea.Quit
+ case "up", "k":
+ if m.cursor > 0 {
+ m.cursor--
+ }
+ case "down", "j":
+ if m.cursor < len(m.choices)-1 {
+ m.cursor++
+ }
+ case "enter", " ":
+ _, ok := m.selected[m.cursor]
+ if ok {
+ delete(m.selected, m.cursor)
+ } else {
+ m.selected[m.cursor] = struct{}{}
+ }
+ }
+ }
+
+ return m, nil
+}
+
+func (m model) View() string {
+ s := "Please choose your destiny\n\n"
+
+ for i, choice := range m.choices {
+ cursor := " " // no cursor
+ if m.cursor == i {
+ cursor = "==>"
+ }
+
+ checked := " "
+ if _, ok := m.selected[i]; ok {
+ checked = "x"
+ }
+
+ s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
+ }
+
+ s += "\nPress q to quiet.\n"
+ return s
+}