summaryrefslogtreecommitdiff
path: root/client/channel_window.go
diff options
context:
space:
mode:
authorcitrons <citrons@mondecitronne.com>2025-06-09 14:45:51 -0500
committercitrons <citrons@mondecitronne.com>2025-06-09 14:46:11 -0500
commitcd06a27e20717cdfbcc6840328f67405acc7c9e7 (patch)
tree9cc2e9c67c749f4a9e263d586a244b7e7746b5fd /client/channel_window.go
parentdc957f6bb77c9d89b52f22b605f79f7be110f546 (diff)
jump to message
Diffstat (limited to 'client/channel_window.go')
-rw-r--r--client/channel_window.go142
1 files changed, 119 insertions, 23 deletions
diff --git a/client/channel_window.go b/client/channel_window.go
index 3239b47..3dc208d 100644
--- a/client/channel_window.go
+++ b/client/channel_window.go
@@ -15,6 +15,7 @@ import (
type channelLocation struct {
id string
+ jumpTo string
}
type channelWindow struct {
@@ -25,6 +26,8 @@ type channelWindow struct {
replyingTo string
loadingHistory bool
endOfHistory bool
+ startOfHistory bool
+ jumpedTo buffer.Message
}
type channelMsg struct {
@@ -41,7 +44,11 @@ func (cl channelLocation) CreateWindow() window.Window {
}
cw.messageCache = object.NewCache(cw)
globalApp.cache.Watch(cl.id)
- cw.loadMoreHistory()
+ if cl.jumpTo == "" {
+ cw.startOfHistory = true
+ }
+ cw.Buf.SetSnap(cw.startOfHistory)
+ cw.loadMoreHistory(false)
return cw
}
@@ -72,14 +79,16 @@ func (cw *channelWindow) isGone(uid string) bool {
}
func (cw *channelWindow) put(msg proto.Object) {
+ if !cw.startOfHistory {
+ return
+ }
if msg.Kind == "membership" {
cw.endOfHistory = false
+ if cw.location.jumpTo != "" {
+ cw.startOfHistory = false
+ }
}
- cw.messageCache.Update(msg.Id, msg)
- if !cw.messageCache.IsWatched(msg.Id) {
- cw.messageCache.Watch(msg.Id)
- }
- cw.Buf.Add(channelMsg {msg, cw})
+ cw.addMessage(msg, true)
}
func (cw *channelWindow) Location() window.Location {
@@ -95,8 +104,12 @@ func (cw *channelWindow) Kill() {
func (cw *channelWindow) Buffer() *buffer.Buffer {
if cw.Buf.AtTop() {
- cw.loadMoreHistory()
+ cw.loadMoreHistory(false)
+ }
+ if cw.Buf.AtBottom() {
+ cw.loadMoreHistory(true)
}
+ cw.Buf.SetSnap(cw.startOfHistory)
return &cw.Buf
}
@@ -124,6 +137,11 @@ func (cw *channelWindow) Send(text string) {
msg := proto.Object {"m", "", fields}
globalApp.Request(proto.NewCmd("p", cw.location.id, msg), cb)
cw.In.SetText("")
+ if cw.location.jumpTo == "" {
+ cw.Buf.ScrollBottom()
+ } else {
+ globalApp.goTo(channelLocation {id: cw.location.id})
+ }
}
func (cw *channelWindow) replyTo(id string) {
@@ -151,37 +169,87 @@ func (cw *channelWindow) renameChannel(newName string) {
})
}
-func (cw *channelWindow) loadMoreHistory() {
- if cw.loadingHistory || cw.endOfHistory {
+func (cw *channelWindow) addMessage(m proto.Object, after bool) {
+ cw.messageCache.Update(m.Id, m)
+ if !cw.messageCache.IsWatched(m.Id) {
+ cw.messageCache.Watch(m.Id)
+ }
+ cmsg := channelMsg {m, cw}
+ if after {
+ cw.Buf.Add(cmsg)
+ } else {
+ cw.Buf.AddTop(cmsg)
+ }
+ if m.Id == cw.location.jumpTo {
+ cw.jumpedTo = cmsg
+ cw.Buf.ScrollTo(cmsg.Id())
+ }
+}
+
+func (cw *channelWindow) loadMoreHistory(after bool) {
+ if cw.loadingHistory {
+ return
+ }
+ if !after && cw.endOfHistory {
+ return
+ }
+ if after && cw.startOfHistory {
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
+ var last *buffer.List
+ if !after {
+ last = cw.Buf.Top()
} else {
+ last = cw.Buf.Bottom()
+ }
+ var lastId string
+ if last != nil {
+ lastId = last.Msg().(channelMsg).Object.Id
+ }
+
+ switch {
+ case last == nil && cw.location.jumpTo != "":
+ rq.Kind = "around"
+ rq.Fields[""] = cw.location.jumpTo
+ case last == nil:
rq.Kind = "latest"
+ case !after:
+ rq.Kind = "before"
+ rq.Fields[""] = lastId
+ case after:
+ rq.Kind = "after"
+ rq.Fields[""] = lastId
}
+
cb := func(response proto.Command) {
cw.loadingHistory = false
switch response.Kind {
case "history":
if len(response.Args) == 0 {
- cw.endOfHistory = true
+ if !after {
+ cw.endOfHistory = true
+ } else {
+ cw.startOfHistory = true
+ }
}
- for i := len(response.Args) - 1; i >= 0; i-- {
- m := response.Args[i]
- cw.messageCache.Update(m.Id, m)
- if !cw.messageCache.IsWatched(m.Id) {
- cw.messageCache.Watch(m.Id)
+ if !after {
+ for i := len(response.Args) - 1; i >= 0; i-- {
+ cw.addMessage(response.Args[i], after)
+ }
+ } else {
+ for i := 0; i < len(response.Args); i++ {
+ cw.addMessage(response.Args[i], after)
}
- cw.Buf.AddTop(channelMsg {m, cw})
}
case "fail":
- cw.endOfHistory = true
+ if !after {
+ cw.endOfHistory = true
+ } else {
+ cw.startOfHistory = true
+ }
}
}
globalApp.Request(proto.NewCmd("history", cw.location.id, rq), cb)
@@ -277,6 +345,12 @@ func (cw *channelWindow) userList(callback func(userListMsg)) {
}
func (cw *channelWindow) ShowStatusLine() {
+ if cw.location.jumpTo != "" {
+ tui.Text("viewing history", &tui.Style {
+ Fg: tui.Black, Bg: tui.White, Italic: true,
+ })
+ tui.Text(": ", nil)
+ }
ch := cw.getChannel()
if ch == nil {
return
@@ -295,7 +369,7 @@ func (cw *channelWindow) ShowComposingReply() {
Style: &tui.Style {Fg: 248, Bg: tui.Black},
})
tui.Text("> ", nil)
- tui.Text(msg.Fields[""], nil)
+ tui.Text(strings.TrimSpace(msg.Fields[""]), nil)
tui.Pop()
if mouse.Pressed && mouse.Button == 0 {
cw.replyingTo = ""
@@ -304,6 +378,12 @@ func (cw *channelWindow) ShowComposingReply() {
}
}
+func (cw *channelWindow) OnNavigate() {
+ if cw.jumpedTo != nil {
+ cw.Buf.ScrollTo(cw.jumpedTo.Id())
+ }
+}
+
func (m channelMsg) Id() string {
return "buffer." + m.Object.Id
}
@@ -365,10 +445,17 @@ func (m channelMsg) showName(bg int32, uid string, abbreviate bool) {
}
func (m channelMsg) showReply(bg int32, replyTo *proto.Object) {
- tui.Push(m.Id() + ".reply message", tui.Box {
+ mouse := tui.Push(m.Id() + ".reply message", tui.Box {
Width: tui.Children, Height: 1, Dir: tui.Right,
})
+ if replyTo != nil && mouse.Button == 0 && mouse.Pressed {
+ globalApp.goTo(channelLocation {
+ id: m.window.location.id, jumpTo: replyTo.Id,
+ })
+ globalApp.redraw = true
+ }
+
tui.Push("", tui.Box {
Width: tui.TextSize, Height: 1, NoWrap: true,
})
@@ -402,6 +489,13 @@ func (m channelMsg) showReply(bg int32, replyTo *proto.Object) {
func (m channelMsg) Show(odd bool) {
var bg int32 = colorDefault[odd]
+ if m.Object.Id == m.window.location.jumpTo {
+ bg = 17
+ }
+ tui.Push("", tui.Box {
+ Width: tui.Fill, Height: tui.Children,
+ Style: &tui.Style {Bg: bg, Fg: tui.White},
+ })
var (
isReply bool
@@ -472,4 +566,6 @@ func (m channelMsg) Show(odd bool) {
tui.Text("]", nil)
tui.Pop()
}
+
+ tui.Pop()
}