summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--irc/states.go9
-rw-r--r--ui/buffers.go22
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
}