commit 206be65

delthas  ·  2024-04-25 23:50:39 +0000 UTC
parent 021f76e
Add a simple Help in the network vertical "member" sidebar

Since networks do not have any members, we can reuse this sidebar
to add a few Help commands (that literally write commands to the
text input).

We're assuming that advanced users that hide the sidebar will know
how to join a channel.
6 files changed,  +105, -32
M app.go
M app.go
+51, -11
 1@@ -538,17 +538,57 @@ func (app *App) handleMouseEvent(ev *tcell.EventMouse) {
 2 		} else if x > w-app.win.MemberWidth() {
 3 			if i := y - 2 + app.win.MemberOffset(); i >= 0 && i == app.win.ClickedMember() {
 4 				netID, target := app.win.CurrentBuffer()
 5-				s := app.sessions[netID]
 6-				if s != nil && target != "" {
 7-					members := s.Names(target)
 8-					if i < len(members) {
 9-						buffer := members[i].Name.Name
10-						i, added := app.win.AddBuffer(netID, "", buffer)
11-						app.win.JumpBufferIndex(i)
12-						if added {
13-							s.MonitorAdd(buffer)
14-							s.ReadGet(buffer)
15-							s.NewHistoryRequest(buffer).WithLimit(500).Latest()
16+				if target == "" {
17+					switch y {
18+					case 2:
19+						if _, err := getBouncerService(app); err != nil {
20+							app.win.AddLine(netID, target, ui.Line{
21+								At:        time.Now(),
22+								Head:      "--",
23+								HeadColor: tcell.ColorRed,
24+								Body:      ui.PlainSprintf("Adding networks is not available: %v", err),
25+							})
26+						} else {
27+							app.win.AddLine(netID, target, ui.Line{
28+								At:   time.Now(),
29+								Head: "--",
30+								Body: ui.PlainString("To join a network/server, use /bouncer network create -addr <address> [-name <name>]"),
31+							})
32+							app.win.AddLine(netID, target, ui.Line{
33+								At:   time.Now(),
34+								Head: "--",
35+								Body: ui.PlainString("For details, see /bouncer help network create"),
36+							})
37+							app.win.InputSet("/bouncer network create -addr ")
38+						}
39+					case 4:
40+						app.win.AddLine(netID, target, ui.Line{
41+							At:   time.Now(),
42+							Head: "--",
43+							Body: ui.PlainString("To join a channel, use /join <#channel> [<password>]"),
44+						})
45+						app.win.InputSet("/join ")
46+					case 6:
47+						app.win.AddLine(netID, target, ui.Line{
48+							At:   time.Now(),
49+							Head: "--",
50+							Body: ui.PlainString("To message a user, use /query <user> [<message>]"),
51+						})
52+						app.win.InputSet("/query ")
53+					}
54+				} else {
55+					s := app.sessions[netID]
56+					if s != nil && target != "" {
57+						members := s.Names(target)
58+						if i < len(members) {
59+							buffer := members[i].Name.Name
60+							i, added := app.win.AddBuffer(netID, "", buffer)
61+							app.win.JumpBufferIndex(i)
62+							if added {
63+								s.MonitorAdd(buffer)
64+								s.ReadGet(buffer)
65+								s.NewHistoryRequest(buffer).WithLimit(500).Latest()
66+							}
67 						}
68 					}
69 				}
+18, -6
 1@@ -618,17 +618,14 @@ func commandDoQuit(app *App, args []string) (err error) {
 2 }
 3 
 4 func commandDoBouncer(app *App, args []string) (err error) {
 5-	if app.cfg.Transient {
 6-		return fmt.Errorf("usage of BOUNCER is disabled")
 7+	b, err := getBouncerService(app)
 8+	if err != nil {
 9+		return err
10 	}
11 	s := app.CurrentSession()
12 	if s == nil {
13 		return errOffline
14 	}
15-	b := s.BouncerService()
16-	if b == "" {
17-		return fmt.Errorf("no bouncer service found on this server")
18-	}
19 	s.PrivMsg(b, args[0])
20 	return nil
21 }
22@@ -1061,3 +1058,18 @@ func getSong() (string, error) {
23 	}
24 	return sb.String(), nil
25 }
26+
27+func getBouncerService(app *App) (service string, err error) {
28+	if app.cfg.Transient {
29+		return "", fmt.Errorf("usage of BOUNCER is disabled")
30+	}
31+	s := app.CurrentSession()
32+	if s == nil {
33+		return "", errOffline
34+	}
35+	b := s.BouncerService()
36+	if b == "" {
37+		return "", fmt.Errorf("no bouncer service found on this server; try using soju")
38+	}
39+	return b, nil
40+}
+2, -7
 1@@ -841,10 +841,7 @@ func (bs *BufferList) DrawTimeline(screen tcell.Screen, x0, y0, nickColWidth int
 2 	xTopic := x0
 3 	printString(screen, &xTopic, y0, Styled(b.topic, tcell.StyleDefault))
 4 	y0++
 5-	for x := x0; x < x0+bs.tlInnerWidth+nickColWidth+9; x++ {
 6-		st := tcell.StyleDefault.Foreground(tcell.ColorGray)
 7-		screen.SetContent(x, y0, 0x2500, nil, st)
 8-	}
 9+	drawHorizontalLine(screen, x0, y0, bs.tlInnerWidth+nickColWidth+9)
10 	y0++
11 
12 	if bs.textWidth < bs.tlInnerWidth {
13@@ -869,9 +866,7 @@ func (bs *BufferList) DrawTimeline(screen tcell.Screen, x0, y0, nickColWidth int
14 				yi--
15 				st := tcell.StyleDefault.Foreground(tcell.ColorGray)
16 				printIdent(screen, x0+7, yi, nickColWidth, Styled("--", st))
17-				for x := x0 + 9 + nickColWidth; x < x0+9+nickColWidth+bs.tlInnerWidth; x++ {
18-					screen.SetContent(x, yi, 0x2500, nil, st)
19-				}
20+				drawHorizontalLine(screen, x0, yi, 9+nickColWidth+bs.tlInnerWidth)
21 				rulerDrawn = true
22 			}
23 		}
+7, -0
 1@@ -124,6 +124,13 @@ func clearArea(screen tcell.Screen, x0, y0, width, height int) {
 2 	}
 3 }
 4 
 5+func drawHorizontalLine(screen tcell.Screen, x0, y, width int) {
 6+	st := tcell.StyleDefault.Foreground(tcell.ColorGray)
 7+	for x := x0; x < x0+width; x++ {
 8+		screen.SetContent(x, y, 0x2500, nil, st)
 9+	}
10+}
11+
12 func drawVerticalLine(screen tcell.Screen, x, y0, height int) {
13 	for y := y0; y < y0+height; y++ {
14 		screen.SetContent(x, y, 0x2502, nil, tcell.StyleDefault)
+26, -7
 1@@ -568,15 +568,37 @@ func (ui *UI) drawVerticalMemberList(screen tcell.Screen, x0, y0, width, height
 2 			*offset = 0
 3 		}
 4 	}
 5-	if ui.memberClicked >= len(members) {
 6-		ui.memberClicked = len(members) - 1
 7-	}
 8 
 9 	drawVerticalLine(screen, x0, y0, height)
10 	x0++
11 	width--
12 	clearArea(screen, x0, y0, width, height)
13 
14+	if _, channel := ui.bs.Current(); channel == "" {
15+		x := x0 + 1
16+		printString(screen, &x, y0, Styled("Help", tcell.StyleDefault.Foreground(ui.config.Colors.Status)))
17+		drawHorizontalLine(screen, x0, y0+1, width)
18+		y0 += 2
19+
20+		lines := []string{
21+			"→Add network",
22+			"→Join channel",
23+			"→Message user",
24+		}
25+		for i, line := range lines {
26+			reverse := i*2 == ui.memberClicked
27+			x := x0
28+			printString(screen, &x, y0, Styled(line, tcell.StyleDefault.Reverse(reverse)))
29+			drawHorizontalLine(screen, x0, y0+1, width)
30+			y0 += 2
31+		}
32+		return
33+	}
34+
35+	if ui.memberClicked >= len(members) {
36+		ui.memberClicked = len(members) - 1
37+	}
38+
39 	if len(members) > 0 {
40 		var memberString string
41 		if len(members) > 1 {
42@@ -590,10 +612,7 @@ func (ui *UI) drawVerticalMemberList(screen tcell.Screen, x0, y0, width, height
43 	}
44 	y0++
45 	height--
46-	for x := x0; x < x0+width; x++ {
47-		st := tcell.StyleDefault.Foreground(tcell.ColorGray)
48-		screen.SetContent(x, y0, 0x2500, nil, st)
49-	}
50+	drawHorizontalLine(screen, x0, y0, width)
51 	y0++
52 	height--
53 
+1, -1
1@@ -7,7 +7,7 @@ import (
2 	"git.sr.ht/~delthas/senpai/ui"
3 )
4 
5-const welcomeMessage = "senpai dev build. Enter /help for a list of commands."
6+const welcomeMessage = "Welcome to senpai! To get started, use the Help buttons, or enter /help for a list of commands."
7 
8 func (app *App) initWindow() {
9 	app.win.AddBuffer("", "(home)", "")