commit ea46a8d

sewn  ·  2026-05-31 21:48:27 +0000 UTC
parent f8929cb
Implement hiding topic at runtime
3 files changed,  +79, -62
M app.go
M app.go
+3, -0
 1@@ -907,6 +907,8 @@ func (app *App) handleAction(action string, args ...string) {
 2 		}
 3 	case "close-overlay":
 4 		app.win.CloseOverlay()
 5+	case "toggle-topic":
 6+		app.win.ToggleTopic()
 7 	case "toggle-channel-list":
 8 		app.win.ToggleChannelList()
 9 	case "toggle-member-list":
10@@ -1007,6 +1009,7 @@ var defaultCommands = map[string][]string{
11 	"Control+r":       {"search-editor"},
12 	"Tab":             {"auto-complete"},
13 	"Escape":          {"close-overlay"},
14+	"F6":              {"toggle-topic"},
15 	"F7":              {"toggle-channel-list"},
16 	"F8":              {"toggle-member-list"},
17 	"\n":              {"send"},
+70, -62
  1@@ -256,7 +256,10 @@ func NewBufferList(ui *UI) BufferList {
  2 
  3 func (bs *BufferList) ResizeTimeline(tlInnerWidth, tlHeight, textWidth int) {
  4 	bs.tlInnerWidth = tlInnerWidth
  5-	bs.tlHeight = tlHeight - 2
  6+	bs.tlHeight = tlHeight
  7+	if !bs.ui.hideTopic {
  8+		bs.tlHeight -= 2
  9+	}
 10 	bs.textWidth = textWidth
 11 }
 12 
 13@@ -1084,6 +1087,67 @@ func (bs *BufferList) DrawHorizontalBufferList(vx *Vaxis, x0, y0, width int, off
 14 	}
 15 }
 16 
 17+func (bs *BufferList) DrawTopic(ui *UI, x0, y0 int) {
 18+	// TODO: factorize this (same code for drawing timeline)
 19+	vx := ui.vx
 20+	b := bs.cur()
 21+
 22+	var st vaxis.Style
 23+	nextStyles := b.topic.styles
 24+
 25+	sr := []rune(b.topic.string)
 26+	ri := 0
 27+	for i := 0; i < b.topicOffset; i++ {
 28+		s, _ := firstCluster(bs.ui.vx, sr[ri:])
 29+		ri += len([]rune(s))
 30+	}
 31+	i := len(string(sr[:ri]))
 32+	sr = sr[ri:]
 33+	for len(sr) > 0 {
 34+		if 0 < len(nextStyles) && nextStyles[0].Start == i {
 35+			st = nextStyles[0].Style
 36+			nextStyles = nextStyles[1:]
 37+
 38+			if (bs.ui.mouseLinks || st.Hyperlink == "") && st.HyperlinkParams != "" && st.UnderlineStyle == 0 {
 39+				st.UnderlineStyle = vaxis.UnderlineDotted
 40+			}
 41+		}
 42+		dx, di := printCluster(vx, x0, y0, -1, sr, st)
 43+		x0 += dx
 44+		i += len(string(sr[:di]))
 45+		sr = sr[di:]
 46+
 47+		if st.Hyperlink != "" {
 48+			ui.clickEvents = append(ui.clickEvents, clickEvent{
 49+				xb: x0 - dx,
 50+				xe: x0,
 51+				y:  y0,
 52+				event: &events.EventClickLink{
 53+					EventClick: events.EventClick{
 54+						NetID:  b.netID,
 55+						Buffer: b.title,
 56+					},
 57+					Link:  st.Hyperlink,
 58+					Mouse: ui.mouseLinks,
 59+				},
 60+			})
 61+		} else if _, channel, ok := strings.Cut(st.HyperlinkParams, "="); ok {
 62+			ui.clickEvents = append(ui.clickEvents, clickEvent{
 63+				xb: x0 - dx,
 64+				xe: x0,
 65+				y:  y0,
 66+				event: &events.EventClickChannel{
 67+					EventClick: events.EventClick{
 68+						NetID:  b.netID,
 69+						Buffer: b.title,
 70+					},
 71+					Channel: channel,
 72+				},
 73+			})
 74+		}
 75+	}
 76+}
 77+
 78 func (bs *BufferList) DrawTimeline(ui *UI, x0, y0, nickColWidth int) {
 79 	vx := ui.vx
 80 	clearArea(vx, x0, y0, bs.tlInnerWidth+nickColWidth+9, bs.tlHeight+2)
 81@@ -1114,68 +1178,12 @@ func (bs *BufferList) DrawTimeline(ui *UI, x0, y0, nickColWidth int) {
 82 		}
 83 	}
 84 
 85-	xTopic := x0
 86-	{
 87-		// TODO: factorize this (same code for drawing timeline)
 88-
 89-		var st vaxis.Style
 90-		nextStyles := b.topic.styles
 91-
 92-		sr := []rune(b.topic.string)
 93-		ri := 0
 94-		for i := 0; i < b.topicOffset; i++ {
 95-			s, _ := firstCluster(bs.ui.vx, sr[ri:])
 96-			ri += len([]rune(s))
 97-		}
 98-		i := len(string(sr[:ri]))
 99-		sr = sr[ri:]
100-		for len(sr) > 0 {
101-			if 0 < len(nextStyles) && nextStyles[0].Start == i {
102-				st = nextStyles[0].Style
103-				nextStyles = nextStyles[1:]
104-
105-				if (bs.ui.mouseLinks || st.Hyperlink == "") && st.HyperlinkParams != "" && st.UnderlineStyle == 0 {
106-					st.UnderlineStyle = vaxis.UnderlineDotted
107-				}
108-			}
109-			dx, di := printCluster(vx, xTopic, y0, -1, sr, st)
110-			xTopic += dx
111-			i += len(string(sr[:di]))
112-			sr = sr[di:]
113-
114-			if st.Hyperlink != "" {
115-				ui.clickEvents = append(ui.clickEvents, clickEvent{
116-					xb: xTopic - dx,
117-					xe: xTopic,
118-					y:  y0,
119-					event: &events.EventClickLink{
120-						EventClick: events.EventClick{
121-							NetID:  b.netID,
122-							Buffer: b.title,
123-						},
124-						Link:  st.Hyperlink,
125-						Mouse: ui.mouseLinks,
126-					},
127-				})
128-			} else if _, channel, ok := strings.Cut(st.HyperlinkParams, "="); ok {
129-				ui.clickEvents = append(ui.clickEvents, clickEvent{
130-					xb: xTopic - dx,
131-					xe: xTopic,
132-					y:  y0,
133-					event: &events.EventClickChannel{
134-						EventClick: events.EventClick{
135-							NetID:  b.netID,
136-							Buffer: b.title,
137-						},
138-						Channel: channel,
139-					},
140-				})
141-			}
142-		}
143+	if !ui.hideTopic {
144+		bs.DrawTopic(ui, x0, y0)
145+		y0++
146+		bs.ui.drawHorizontalLine(vx, x0, y0, bs.tlInnerWidth+nickColWidth+9)
147+		y0++
148 	}
149-	y0++
150-	bs.ui.drawHorizontalLine(vx, x0, y0, bs.tlInnerWidth+nickColWidth+9)
151-	y0++
152 
153 	if bs.textWidth < bs.tlInnerWidth {
154 		x0 += (bs.tlInnerWidth - bs.textWidth) / 2
+6, -0
 1@@ -80,6 +80,7 @@ type UI struct {
 2 	channelOffset int
 3 	memberClicked int
 4 	memberOffset  int
 5+	hideTopic     bool
 6 
 7 	channelWidth int
 8 	memberWidth  int
 9@@ -411,6 +412,11 @@ func (ui *UI) MemberWidth() int {
10 	return ui.memberWidth
11 }
12 
13+func (ui *UI) ToggleTopic() {
14+	ui.hideTopic = !ui.hideTopic
15+	ui.Resize()
16+}
17+
18 func (ui *UI) ToggleChannelList() {
19 	if ui.channelWidth == 0 {
20 		ui.channelWidth = ui.config.ChanColWidth