diff options
-rw-r--r-- | irc/states.go | 9 | ||||
-rw-r--r-- | ui/buffers.go | 22 |
2 files changed, 30 insertions, 1 deletions
diff --git a/irc/states.go b/irc/states.go index 50bf4a6..957286d 100644 --- a/irc/states.go +++ b/irc/states.go @@ -183,6 +183,7 @@ type Session struct { users map[string]*User // known users. channels map[string]Channel // joined channels. chBatches map[string]HistoryEvent // channel history batches being processed. + chReqs map[string]struct{} // set of targets for which history is currently requested. } // NewSession starts an IRC session from the given connection and session @@ -212,6 +213,7 @@ func NewSession(conn net.Conn, params SessionParams) (*Session, error) { users: map[string]*User{}, channels: map[string]Channel{}, chBatches: map[string]HistoryEvent{}, + chReqs: map[string]struct{}{}, } s.running.Store(true) @@ -493,6 +495,12 @@ func (s *Session) requestHistory(act actionRequestHistory) (err error) { return } + target := s.Casemap(act.Target) + if _, ok := s.chReqs[target]; ok { + return + } + s.chReqs[target] = struct{}{} + t := act.Before.UTC().Add(1 * time.Second) 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) @@ -980,6 +988,7 @@ func (s *Session) handle(msg Message) (err error) { } else if b, ok := s.chBatches[id]; ok { s.evts <- b delete(s.chBatches, id) + delete(s.chReqs, s.Casemap(b.Target)) } case "NICK": nickCf := s.Casemap(msg.Prefix.Name) diff --git a/ui/buffers.go b/ui/buffers.go index 40aa83f..b6020a8 100644 --- a/ui/buffers.go +++ b/ui/buffers.go @@ -279,6 +279,7 @@ func (bs *BufferList) AddLine(title string, highlight bool, line Line) { } } +// "lines" needs to be sorted by their "At" field. func (bs *BufferList) AddLines(title string, lines []Line) { idx := bs.idx(title) if idx < 0 { @@ -289,9 +290,28 @@ func (bs *BufferList) AddLines(title string, lines []Line) { limit := len(lines) if 0 < len(b.lines) { + // Compute "limit", the index first line of "lines" that should + // not be added to the buffer. firstLineTime := b.lines[0].At.Unix() + firstLineBody := b.lines[0].Body for i, l := range lines { - if firstLineTime < l.At.Unix() { + historyLineTime := l.At.Unix() + if historyLineTime < firstLineTime { + // This line is behind the first line of the + // buffer. + continue + } + if historyLineTime > firstLineTime { + // This line happened after the first line of + // the buffer. + limit = i + break + } + if l.Body == firstLineBody { + // This line happened at the same millisecond + // as the first line of the buffer, and has the + // same contents. Heuristic: it's the same + // message. limit = i break } |