commit 17e7f7b

Hubert Hirtz  ·  2021-04-27 13:56:26 +0000 UTC
parent ef1ca1c
Fix duplicate lines when scrolling up
2 files changed,  +30, -1
+9, -0
 1@@ -183,6 +183,7 @@ type Session struct {
 2 	users     map[string]*User        // known users.
 3 	channels  map[string]Channel      // joined channels.
 4 	chBatches map[string]HistoryEvent // channel history batches being processed.
 5+	chReqs    map[string]struct{}     // set of targets for which history is currently requested.
 6 }
 7 
 8 // NewSession starts an IRC session from the given connection and session
 9@@ -212,6 +213,7 @@ func NewSession(conn net.Conn, params SessionParams) (*Session, error) {
10 		users:         map[string]*User{},
11 		channels:      map[string]Channel{},
12 		chBatches:     map[string]HistoryEvent{},
13+		chReqs:        map[string]struct{}{},
14 	}
15 
16 	s.running.Store(true)
17@@ -493,6 +495,12 @@ func (s *Session) requestHistory(act actionRequestHistory) (err error) {
18 		return
19 	}
20 
21+	target := s.Casemap(act.Target)
22+	if _, ok := s.chReqs[target]; ok {
23+		return
24+	}
25+	s.chReqs[target] = struct{}{}
26+
27 	t := act.Before.UTC().Add(1 * time.Second)
28 	err = s.send("CHATHISTORY BEFORE %s timestamp=%04d-%02d-%02dT%02d:%02d:%02d.%03dZ 100\r\n", act.Target, t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond()/1e6)
29 
30@@ -980,6 +988,7 @@ func (s *Session) handle(msg Message) (err error) {
31 		} else if b, ok := s.chBatches[id]; ok {
32 			s.evts <- b
33 			delete(s.chBatches, id)
34+			delete(s.chReqs, s.Casemap(b.Target))
35 		}
36 	case "NICK":
37 		nickCf := s.Casemap(msg.Prefix.Name)
+21, -1
 1@@ -279,6 +279,7 @@ func (bs *BufferList) AddLine(title string, highlight bool, line Line) {
 2 	}
 3 }
 4 
 5+// "lines" needs to be sorted by their "At" field.
 6 func (bs *BufferList) AddLines(title string, lines []Line) {
 7 	idx := bs.idx(title)
 8 	if idx < 0 {
 9@@ -289,9 +290,28 @@ func (bs *BufferList) AddLines(title string, lines []Line) {
10 	limit := len(lines)
11 
12 	if 0 < len(b.lines) {
13+		// Compute "limit", the index first line of "lines" that should
14+		// not be added to the buffer.
15 		firstLineTime := b.lines[0].At.Unix()
16+		firstLineBody := b.lines[0].Body
17 		for i, l := range lines {
18-			if firstLineTime < l.At.Unix() {
19+			historyLineTime := l.At.Unix()
20+			if historyLineTime < firstLineTime {
21+				// This line is behind the first line of the
22+				// buffer.
23+				continue
24+			}
25+			if historyLineTime > firstLineTime {
26+				// This line happened after the first line of
27+				// the buffer.
28+				limit = i
29+				break
30+			}
31+			if l.Body == firstLineBody {
32+				// This line happened at the same millisecond
33+				// as the first line of the buffer, and has the
34+				// same contents. Heuristic: it's the same
35+				// message.
36 				limit = i
37 				break
38 			}