]> Sergey Matveev's repositories - vors.git/blob - cmd/client/gui.go
Chatting ability
[vors.git] / cmd / client / gui.go
1 // VoRS -- Vo(IP) Really Simple
2 // Copyright (C) 2024 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU Affero General Public License for more details.
12 //
13 // You should have received a copy of the GNU Affero General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package main
17
18 import (
19         "fmt"
20         "log"
21         "sort"
22
23         "github.com/jroimartin/gocui"
24         vors "go.stargrave.org/vors/v3/internal"
25 )
26
27 var (
28         GUI         *gocui.Gui
29         GUIReady    bool
30         GUIReadyC   = make(chan struct{})
31         GUIMaxY     int
32         CurrentView = 0
33 )
34
35 func guiQuit(gui *gocui.Gui, v *gocui.View) error {
36         Finish <- struct{}{}
37         return gocui.ErrQuit
38 }
39
40 func mute(gui *gocui.Gui, v *gocui.View) error {
41         muteToggle()
42         return nil
43 }
44
45 func tabHandle(gui *gocui.Gui, v *gocui.View) error {
46         sids := make([]int, 0, len(Streams)+1)
47         sids = append(sids, -1)
48         for sid := range Streams {
49                 sids = append(sids, int(sid))
50         }
51         sort.Ints(sids)
52         if CurrentView+1 >= len(sids) {
53                 CurrentView = 0
54         } else {
55                 CurrentView++
56         }
57         if CurrentView == 0 {
58                 gui.SetCurrentView("chat")
59         } else {
60                 gui.SetCurrentView(Streams[byte(sids[CurrentView])].name)
61         }
62         return nil
63 }
64
65 func chatEnter(gui *gocui.Gui, v *gocui.View) error {
66         msg := v.Buffer()
67         if len(msg) > 1 {
68                 Ctrl <- vors.ArgsEncode([]byte(vors.CmdChat), []byte(msg[:len(msg)-1]))
69                 log.Println("me:", msg[:len(msg)-1])
70         }
71         v.Clear()
72         v.SetCursor(0, 0)
73         return nil
74 }
75
76 func guiLayout(gui *gocui.Gui) error {
77         var maxX int
78         maxX, GUIMaxY = gui.Size()
79         prevY := 0
80         v, err := gui.SetView("logs", 0, prevY, maxX-1, prevY+7+2)
81         prevY += 7 + 2
82         if err != nil {
83                 if err != gocui.ErrUnknownView {
84                         return err
85                 }
86                 v.Title = fmt.Sprintf("Logs room=%s", *Room)
87                 v.Autoscroll = true
88                 v.Wrap = true
89         }
90         v, err = gui.SetView("chat", 0, prevY, maxX-1, prevY+2)
91         if err != nil {
92                 if err != gocui.ErrUnknownView {
93                         return err
94                 }
95                 v.Title = "chat"
96                 v.Editable = true
97                 if err := GUI.SetKeybinding(
98                         "chat", gocui.KeyEnter, gocui.ModNone, chatEnter,
99                 ); err != nil {
100                         return err
101                 }
102         }
103         prevY += 3
104         sids := make([]int, 0, len(Streams))
105         for sid := range Streams {
106                 sids = append(sids, int(sid))
107         }
108         sort.Ints(sids)
109         var stream *Stream
110         for _, sid := range sids {
111                 stream = Streams[byte(sid)]
112                 v, err = gui.SetView(stream.name, 0, prevY, maxX/2-1, prevY+2)
113                 if err != nil {
114                         if err != gocui.ErrUnknownView {
115                                 return err
116                         }
117                         if stream.name == *Name {
118                                 v.Title = ">" + stream.name + "<"
119                         } else {
120                                 v.Title = stream.name
121                         }
122                 }
123                 _, err = gui.SetView(stream.name+"-vol", maxX/2, prevY, maxX-1, prevY+2)
124                 prevY += 3
125                 if err != nil {
126                         if err != gocui.ErrUnknownView {
127                                 return err
128                         }
129                 }
130         }
131         if !GUIReady {
132                 close(GUIReadyC)
133                 GUIReady = true
134                 gui.SetCurrentView("chat")
135         }
136         return nil
137 }