commit 6f083ad
delthas
·
2022-02-10 15:09:42 +0000 UTC
parent b46a755
Fix event collapsing
2 files changed,
+93,
-73
M
app.go
M
app.go
+92,
-72
1@@ -990,7 +990,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
2 HeadColor: tcell.ColorGray,
3 Body: body.StyledString(),
4 Mergeable: true,
5- Data: []interface{}{ev},
6+ Data: []irc.Event{ev},
7 }
8 case irc.UserJoinEvent:
9 var body ui.StyledStringBuilder
10@@ -1005,7 +1005,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
11 HeadColor: tcell.ColorGray,
12 Body: body.StyledString(),
13 Mergeable: true,
14- Data: []interface{}{ev},
15+ Data: []irc.Event{ev},
16 }
17 case irc.UserPartEvent:
18 var body ui.StyledStringBuilder
19@@ -1020,7 +1020,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
20 HeadColor: tcell.ColorGray,
21 Body: body.StyledString(),
22 Mergeable: true,
23- Data: []interface{}{ev},
24+ Data: []irc.Event{ev},
25 }
26 case irc.UserQuitEvent:
27 var body ui.StyledStringBuilder
28@@ -1035,7 +1035,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
29 HeadColor: tcell.ColorGray,
30 Body: body.StyledString(),
31 Mergeable: true,
32- Data: []interface{}{ev},
33+ Data: []irc.Event{ev},
34 }
35 case irc.TopicChangeEvent:
36 topic := ui.IRCString(ev.Topic).String()
37@@ -1048,13 +1048,15 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
38 }
39 case irc.ModeChangeEvent:
40 body := fmt.Sprintf("[%s]", ev.Mode)
41+ // simple mode event: <+/-><mode> <nick>
42+ mergeable := len(strings.Split(ev.Mode, " ")) == 2
43 return ui.Line{
44 At: ev.Time,
45 Head: "--",
46 HeadColor: tcell.ColorGray,
47 Body: ui.Styled(body, tcell.StyleDefault.Foreground(tcell.ColorGray)),
48- Mergeable: true,
49- Data: []interface{}{ev},
50+ Mergeable: mergeable,
51+ Data: []irc.Event{ev},
52 }
53 default:
54 return ui.Line{}
55@@ -1139,86 +1141,104 @@ func (app *App) formatMessage(s *irc.Session, ev irc.MessageEvent) (buffer strin
56 }
57
58 func (app *App) mergeLine(former *ui.Line, addition ui.Line) {
59- partQuitUser := func(ev interface{}) string {
60- if ev, ok := ev.(irc.UserQuitEvent); ok {
61- return ev.User
62- }
63- if ev, ok := ev.(irc.UserPartEvent); ok {
64- return ev.User
65- }
66- panic("unreachable")
67+ events := append(former.Data.([]irc.Event), addition.Data.([]irc.Event)...)
68+ type flow struct {
69+ hide bool
70+ state int // -1: newly offline; 1: newly online
71 }
72+ flows := make(map[string]*flow)
73+
74+ eventFlows := make([]*flow, len(events))
75
76- changed := false
77-Outer:
78- for _, addedEvent := range addition.Data {
79- switch addedEvent := addedEvent.(type) {
80+ for i, ev := range events {
81+ switch ev := ev.(type) {
82 case irc.UserNickEvent:
83- for i := len(former.Data) - 1; i >= 0; i-- {
84- switch ev := former.Data[i].(type) {
85- case irc.UserNickEvent:
86- if ev.User == addedEvent.FormerNick && ev.FormerNick == addedEvent.User {
87- former.Data = append(former.Data[:i], former.Data[i+1:]...)
88- changed = true
89- continue Outer
90- }
91- }
92+ userCf := strings.ToLower(ev.User)
93+ f, ok := flows[strings.ToLower(ev.FormerNick)]
94+ if ok {
95+ flows[userCf] = f
96+ delete(flows, strings.ToLower(ev.FormerNick))
97+ eventFlows[i] = f
98+ } else {
99+ f = &flow{}
100+ flows[userCf] = f
101+ eventFlows[i] = f
102 }
103 case irc.UserJoinEvent:
104- for i := len(former.Data) - 1; i >= 0; i-- {
105- switch ev := former.Data[i].(type) {
106- case irc.UserPartEvent, irc.UserQuitEvent:
107- if partQuitUser(ev) == addedEvent.User {
108- former.Data = append(former.Data[:i], former.Data[i+1:]...)
109- changed = true
110- continue Outer
111- }
112+ userCf := strings.ToLower(ev.User)
113+ f, ok := flows[userCf]
114+ if ok {
115+ if f.state == -1 {
116+ f.hide = true
117+ delete(flows, userCf)
118+ }
119+ } else {
120+ f = &flow{
121+ state: 1,
122+ }
123+ flows[userCf] = f
124+ eventFlows[i] = f
125+ }
126+ case irc.UserPartEvent:
127+ userCf := strings.ToLower(ev.User)
128+ f, ok := flows[userCf]
129+ if ok {
130+ if f.state == 1 {
131+ f.hide = true
132+ delete(flows, userCf)
133 }
134+ } else {
135+ f = &flow{
136+ state: -1,
137+ }
138+ flows[userCf] = f
139+ eventFlows[i] = f
140 }
141- case irc.UserQuitEvent, irc.UserPartEvent:
142- user := partQuitUser(addedEvent)
143- var toRemove []int
144- for i := len(former.Data) - 1; i >= 0; i-- {
145- switch ev := former.Data[i].(type) {
146- case irc.UserNickEvent:
147- if ev.User == user {
148- user = ev.FormerNick
149- toRemove = append(toRemove, i)
150- }
151- case irc.UserJoinEvent:
152- if ev.User == user {
153- for _, i := range append(toRemove, i) {
154- former.Data = append(former.Data[:i], former.Data[i+1:]...)
155- }
156- changed = true
157- continue Outer
158- }
159+ case irc.UserQuitEvent:
160+ userCf := strings.ToLower(ev.User)
161+ f, ok := flows[userCf]
162+ if ok {
163+ if f.state == 1 {
164+ f.hide = true
165+ delete(flows, userCf)
166+ }
167+ } else {
168+ f = &flow{
169+ state: -1,
170 }
171+ flows[userCf] = f
172+ eventFlows[i] = f
173+ }
174+ case irc.ModeChangeEvent:
175+ userCf := strings.ToLower(strings.Split(ev.Mode, " ")[1])
176+ f, ok := flows[userCf]
177+ if ok {
178+ eventFlows[i] = f
179+ } else {
180+ f = &flow{}
181+ flows[userCf] = f
182+ eventFlows[i] = f
183 }
184 }
185- former.Data = append(former.Data, addedEvent)
186 }
187- if changed {
188- if len(former.Data) == 0 {
189- former.Body = ui.PlainString("")
190- return
191+
192+ newBody := new(ui.StyledStringBuilder)
193+ newBody.Grow(128)
194+ first := true
195+ for i, ev := range events {
196+ if f := eventFlows[i]; f == nil || f.hide {
197+ continue
198 }
199- var body ui.StyledStringBuilder
200- body.Grow(len(former.Body.String()))
201- body.WriteStyledString(app.formatEvent(former.Data[0]).Body)
202- for _, ev := range former.Data[1:] {
203- body.WriteString(" ")
204- body.WriteStyledString(app.formatEvent(ev).Body)
205+ l := app.formatEvent(ev)
206+ if first {
207+ first = false
208+ } else {
209+ newBody.WriteString(" ")
210 }
211- former.Body = body.StyledString()
212- } else {
213- var newBody ui.StyledStringBuilder
214- newBody.Grow(len(former.Body.String()) + 2 + len(addition.Body.String()))
215- newBody.WriteStyledString(former.Body)
216- newBody.WriteString(" ")
217- newBody.WriteStyledString(addition.Body)
218- former.Body = newBody.StyledString()
219+ newBody.WriteStyledString(l.Body)
220 }
221+ former.Body = newBody.StyledString()
222+ former.Data = events
223 }
224
225 // updatePrompt changes the prompt text according to the application context.
+1,
-1
1@@ -33,7 +33,7 @@ type Line struct {
2 HeadColor tcell.Color
3 Highlight bool
4 Mergeable bool
5- Data []interface{}
6+ Data interface{}
7
8 splitPoints []point
9 width int