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
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 }
+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++ {