From 335f57fbc8403b32b5e3d8ea1cb1b713cdacb5fc Mon Sep 17 00:00:00 2001 From: citrons Date: Sun, 1 Jun 2025 19:10:35 -0500 Subject: message history --- client/buffer/buffer.go | 6 +++++- client/channel_window.go | 38 +++++++++++++++++++++++++++++++++++++- tui/layout.go | 14 ++++++-------- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/client/buffer/buffer.go b/client/buffer/buffer.go index b57ec26..921ad00 100644 --- a/client/buffer/buffer.go +++ b/client/buffer/buffer.go @@ -31,6 +31,10 @@ func (l List) Next() *List { return l.next } +func (l List) Msg() Message { + return l.msg +} + func (b *Buffer) Top() *List { return b.top } @@ -57,7 +61,7 @@ func (b *Buffer) AddTop(msg Message) { if b.top != nil { b.top.prev = &l l.next = b.top - l.odd = !b.bottom.odd + l.odd = !b.top.odd } b.top = &l if b.bottom == nil { diff --git a/client/channel_window.go b/client/channel_window.go index 43ce83f..b4c9b9f 100644 --- a/client/channel_window.go +++ b/client/channel_window.go @@ -19,6 +19,7 @@ type channelWindow struct { input tui.TextInput watchedUsers map[string]bool loadingHistory bool + endOfHistory bool } type channelMsg struct { @@ -34,6 +35,7 @@ func (cl channelLocation) CreateWindow() window.Window { location: cl, watchedUsers: make(map[string]bool), } globalApp.cache.Watch(cl.id) + cw.loadMoreHistory() return cw } @@ -73,6 +75,9 @@ func (cw *channelWindow) Kill() { } func (cw *channelWindow) Buffer() *buffer.Buffer { + if cw.buf.AtTop() { + cw.loadMoreHistory() + } return &cw.buf } @@ -107,6 +112,37 @@ func (cw *channelWindow) leaveChannel() { globalApp.windowCache.Evict(cw.location) } +func (cw *channelWindow) loadMoreHistory() { + if cw.loadingHistory || cw.endOfHistory { + return + } + cw.loadingHistory = true + + rq := proto.Object {Fields: make(map[string]string)} + top := cw.buf.Top() + if top != nil { + rq.Kind = "before" + rq.Fields[""] = top.Msg().(channelMsg).Object.Id + } else { + rq.Kind = "latest" + } + cb := func(response proto.Command) { + cw.loadingHistory = false + switch response.Kind { + case "history": + if len(response.Args) == 0 { + cw.endOfHistory = true + } + for i := len(response.Args) - 1; i >= 0; i-- { + cw.buf.AddTop(channelMsg {response.Args[i], cw}) + } + case "fail": + cw.endOfHistory = true + } + } + globalApp.Request(proto.NewCmd("history", cw.location.id, rq), cb) +} + type userListMsg struct { index int channelName string @@ -177,7 +213,7 @@ func (cw *channelWindow) ShowStatusLine() { } tui.Text(ch.Fields[""], nil) if cw.loadingHistory { - tui.Text("...", nil) + tui.Text(" ...", nil) } } diff --git a/tui/layout.go b/tui/layout.go index 5811f4e..480f3cc 100644 --- a/tui/layout.go +++ b/tui/layout.go @@ -285,9 +285,10 @@ func (b *Box) computePositions(axis int) { if last != nil { lastPos := last.computedPosition - lastPos += last.computedSize[axis] if b.Dir.reverse() { lastPos = b.computedSize[axis] - lastPos + } else { + lastPos += last.computedSize[axis] } b.Scroll.absolute = min(b.Scroll.absolute, lastPos - b.computedSize[axis]) } @@ -300,7 +301,7 @@ func (b *Box) computePositions(axis int) { } else { c.computedPosition += b.Scroll.absolute } - if c.computedPosition > b.computedRect.min[axis] && + if c.computedPosition >= b.computedRect.min[axis] && c.computedPosition < b.computedRect.max[axis] { if firstShown == nil { firstShown = c @@ -308,12 +309,9 @@ func (b *Box) computePositions(axis int) { lastShown = c } } - if firstShown == first { - b.Scroll.atFirst = true - } - if lastShown == last { - b.Scroll.atLast = true - } + b.Scroll.atFirst = firstShown == first + b.Scroll.atLast = lastShown == last + if firstShown != nil { p := first.computedPosition if b.Dir.reverse() { -- cgit v1.2.3