commit b680d6c
delthas
·
2021-07-13 22:03:27 +0000 UTC
parent 2c5872f
ui: Introduce a vertical member list on channels Also, fix the UI timeline clearing too much, as well as the status line. Also, remove the width in the editor and buffer list constructors. We were initializing them with wrong values, only to overwrite these values with correct ones later in Resize().
6 files changed,
+81,
-39
M
app.go
+8,
-3
1@@ -60,8 +60,9 @@ func NewApp(cfg Config) (app *App, err error) {
2 }
3
4 app.win, err = ui.New(ui.Config{
5- NickColWidth: cfg.NickColWidth,
6- ChanColWidth: cfg.ChanColWidth,
7+ NickColWidth: cfg.NickColWidth,
8+ ChanColWidth: cfg.ChanColWidth,
9+ MemberColWidth: cfg.MemberColWidth,
10 AutoComplete: func(cursorIdx int, text []rune) []ui.Completion {
11 return app.completions(cursorIdx, text)
12 },
13@@ -116,7 +117,11 @@ func (app *App) eventLoop() {
14 if !app.pasting {
15 app.setStatus()
16 app.updatePrompt()
17- app.win.Draw()
18+ var currentMembers []irc.Member
19+ if app.s != nil {
20+ currentMembers = app.s.Names(app.win.CurrentBuffer())
21+ }
22+ app.win.Draw(currentMembers)
23 }
24 }
25 }
+8,
-4
1@@ -58,10 +58,11 @@ type Config struct {
2 NoTypings bool `yaml:"no-typings"`
3 Mouse *bool
4
5- Highlights []string
6- OnHighlight string `yaml:"on-highlight"`
7- NickColWidth int `yaml:"nick-column-width"`
8- ChanColWidth int `yaml:"chan-column-width"`
9+ Highlights []string
10+ OnHighlight string `yaml:"on-highlight"`
11+ NickColWidth int `yaml:"nick-column-width"`
12+ ChanColWidth int `yaml:"chan-column-width"`
13+ MemberColWidth int `yaml:"member-column-width"`
14
15 Colors struct {
16 Prompt Color
17@@ -93,6 +94,9 @@ func ParseConfig(buf []byte) (cfg Config, err error) {
18 if cfg.ChanColWidth <= 0 {
19 cfg.ChanColWidth = 16
20 }
21+ if cfg.MemberColWidth <= 0 {
22+ cfg.MemberColWidth = 16
23+ }
24 return
25 }
26
+5,
-2
1@@ -72,11 +72,14 @@ on-highlight: |
2 ```
3
4 *nick-column-width*
5- The number of cell that the column for nicknames occupies in the timeline.
6+ The number of cells that the column for nicknames occupies in the timeline.
7 By default, 16.
8
9 *chan-column-width*
10- The number of cell that the column for channels occupies. By default, 16.
11+ The number of cells that the column for channels occupies. By default, 16.
12+
13+*member-column-width*
14+ The number of cells that the column for members occupies. By default, 16.
15
16 *no-tls*
17 Disable TLS encryption. Defaults to false.
+39,
-17
1@@ -4,6 +4,8 @@ import (
2 "strings"
3 "time"
4
5+ "git.sr.ht/~taiite/senpai/irc"
6+
7 "github.com/gdamore/tcell/v2"
8 )
9
10@@ -185,30 +187,24 @@ type BufferList struct {
11 current int
12 clicked int
13
14- tlWidth int
15+ tlInnerWidth int
16 tlHeight int
17- nickColWidth int
18 }
19
20-func NewBufferList(tlWidth, tlHeight, nickColWidth int) BufferList {
21+// NewBufferList returns a new BufferList.
22+// Call Resize() once before using it.
23+func NewBufferList() BufferList {
24 return BufferList{
25- list: []buffer{},
26- clicked: -1,
27- tlWidth: tlWidth,
28- tlHeight: tlHeight,
29- nickColWidth: nickColWidth,
30+ list: []buffer{},
31+ clicked: -1,
32 }
33 }
34
35-func (bs *BufferList) ResizeTimeline(tlWidth, tlHeight, nickColWidth int) {
36- bs.tlWidth = tlWidth
37+func (bs *BufferList) ResizeTimeline(tlInnerWidth, tlHeight int) {
38+ bs.tlInnerWidth = tlInnerWidth
39 bs.tlHeight = tlHeight
40 }
41
42-func (bs *BufferList) tlInnerWidth() int {
43- return bs.tlWidth - bs.nickColWidth - 9
44-}
45-
46 func (bs *BufferList) To(i int) {
47 if 0 <= i {
48 bs.current = i
49@@ -284,7 +280,7 @@ func (bs *BufferList) AddLine(title string, notify NotifyType, line Line) {
50 line.computeSplitPoints()
51 b.lines = append(b.lines, line)
52 if idx == bs.current && 0 < b.scrollAmt {
53- b.scrollAmt += len(line.NewLines(bs.tlInnerWidth())) + 1
54+ b.scrollAmt += len(line.NewLines(bs.tlInnerWidth)) + 1
55 }
56 }
57
58@@ -433,8 +429,34 @@ func (bs *BufferList) DrawVerticalBufferList(screen tcell.Screen, x0, y0, width,
59 }
60 }
61
62+func (bs *BufferList) DrawVerticalMemberList(screen tcell.Screen, x0, y0, width, height int, members []irc.Member) {
63+ st := tcell.StyleDefault
64+
65+ for y := y0; y < y0+height; y++ {
66+ screen.SetContent(x0, y, 0x2502, nil, st)
67+ for x := x0 + 1; x < x0+width; x++ {
68+ screen.SetContent(x, y, ' ', nil, st)
69+ }
70+ }
71+
72+ for i, m := range members {
73+ st = tcell.StyleDefault
74+ x := x0 + 1
75+ y := y0 + i
76+
77+ if m.PowerLevel != "" {
78+ printString(screen, &x, y, Styled(string([]rune(m.PowerLevel)[0]), st.Foreground(tcell.ColorGreen)))
79+ } else {
80+ x += 1
81+ }
82+ name := truncate(m.Name.Name, width-(x-x0), "\u2026")
83+ printString(screen, &x, y, Styled(name, st))
84+ y++
85+ }
86+}
87+
88 func (bs *BufferList) DrawTimeline(screen tcell.Screen, x0, y0, nickColWidth int) {
89- for x := x0; x < x0+bs.tlWidth; x++ {
90+ for x := x0; x < x0+bs.tlInnerWidth+nickColWidth+9; x++ {
91 for y := y0; y < y0+bs.tlHeight; y++ {
92 screen.SetContent(x, y, ' ', nil, tcell.StyleDefault)
93 }
94@@ -450,7 +472,7 @@ func (bs *BufferList) DrawTimeline(screen tcell.Screen, x0, y0, nickColWidth int
95 x1 := x0 + 9 + nickColWidth
96
97 line := &b.lines[i]
98- nls := line.NewLines(bs.tlInnerWidth())
99+ nls := line.NewLines(bs.tlInnerWidth)
100 yi -= len(nls) + 1
101 if y0+bs.tlHeight <= yi {
102 continue
+3,
-2
1@@ -37,11 +37,12 @@ type Editor struct {
2 autoCacheIdx int
3 }
4
5-func NewEditor(width int, autoComplete func(cursorIdx int, text []rune) []Completion) Editor {
6+// NewEditor returns a new Editor.
7+// Call Resize() once before using it.
8+func NewEditor(autoComplete func(cursorIdx int, text []rune) []Completion) Editor {
9 return Editor{
10 text: [][]rune{{}},
11 textWidth: []int{0},
12- width: width,
13 autoComplete: autoComplete,
14 }
15 }
M
ui/ui.go
+18,
-11
1@@ -5,14 +5,17 @@ import (
2 "sync/atomic"
3 "time"
4
5+ "git.sr.ht/~taiite/senpai/irc"
6+
7 "github.com/gdamore/tcell/v2"
8 )
9
10 type Config struct {
11- NickColWidth int
12- ChanColWidth int
13- AutoComplete func(cursorIdx int, text []rune) []Completion
14- Mouse bool
15+ NickColWidth int
16+ ChanColWidth int
17+ MemberColWidth int
18+ AutoComplete func(cursorIdx int, text []rune) []Completion
19+ Mouse bool
20 }
21
22 type UI struct {
23@@ -46,7 +49,7 @@ func New(config Config) (ui *UI, err error) {
24 }
25 ui.screen.EnablePaste()
26
27- w, h := ui.screen.Size()
28+ _, h := ui.screen.Size()
29 ui.screen.Clear()
30 ui.screen.ShowCursor(0, h-2)
31
32@@ -59,8 +62,8 @@ func New(config Config) (ui *UI, err error) {
33 }
34 }()
35
36- ui.bs = NewBufferList(w, h, ui.config.NickColWidth)
37- ui.e = NewEditor(w, ui.config.AutoComplete)
38+ ui.bs = NewBufferList()
39+ ui.e = NewEditor(ui.config.AutoComplete)
40 ui.Resize()
41
42 return
43@@ -242,18 +245,20 @@ func (ui *UI) InputClear() bool {
44
45 func (ui *UI) Resize() {
46 w, h := ui.screen.Size()
47- ui.e.Resize(w - 9 - ui.config.ChanColWidth - ui.config.NickColWidth)
48- ui.bs.ResizeTimeline(w-ui.config.ChanColWidth, h-2, ui.config.NickColWidth)
49+ innerWidth := w - 9 - ui.config.ChanColWidth - ui.config.NickColWidth - ui.config.MemberColWidth
50+ ui.e.Resize(innerWidth)
51+ ui.bs.ResizeTimeline(innerWidth, h-2)
52 }
53
54-func (ui *UI) Draw() {
55+func (ui *UI) Draw(members []irc.Member) {
56 w, h := ui.screen.Size()
57
58 ui.e.Draw(ui.screen, 9+ui.config.ChanColWidth+ui.config.NickColWidth, h-1)
59
60 ui.bs.DrawTimeline(ui.screen, ui.config.ChanColWidth, 0, ui.config.NickColWidth)
61 ui.bs.DrawVerticalBufferList(ui.screen, 0, 0, ui.config.ChanColWidth, h)
62- ui.drawStatusBar(ui.config.ChanColWidth, h-2, w-ui.config.ChanColWidth)
63+ ui.bs.DrawVerticalMemberList(ui.screen, w-ui.config.MemberColWidth, 0, ui.config.MemberColWidth, h, members)
64+ ui.drawStatusBar(ui.config.ChanColWidth, h-2, w-ui.config.ChanColWidth-ui.config.MemberColWidth)
65
66 for x := ui.config.ChanColWidth; x < 9+ui.config.ChanColWidth+ui.config.NickColWidth; x++ {
67 ui.screen.SetContent(x, h-1, ' ', nil, tcell.StyleDefault)
68@@ -264,6 +269,8 @@ func (ui *UI) Draw() {
69 }
70
71 func (ui *UI) drawStatusBar(x0, y, width int) {
72+ width--
73+
74 st := tcell.StyleDefault.Dim(true)
75
76 for x := x0; x < x0+width; x++ {