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
+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
M
ui/ui.go
+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