diff options
| author | raven <citrons@mondecitronne.com> | 2026-02-17 15:21:17 -0600 |
|---|---|---|
| committer | raven <citrons@mondecitronne.com> | 2026-02-17 15:22:10 -0600 |
| commit | 86df926a15da7c5447788b00a34995e0512bd286 (patch) | |
| tree | 13249c0cc6c323ad91ebfc32bffec65a915da23c /client | |
| parent | 61ba037f8a70d6a842853b9f0f0b782873e0a763 (diff) | |
direct message list
Diffstat (limited to 'client')
| -rw-r--r-- | client/application.go | 24 | ||||
| -rw-r--r-- | client/channel_list.go | 46 | ||||
| -rw-r--r-- | client/channel_window.go | 1 | ||||
| -rw-r--r-- | client/ui.go | 42 |
4 files changed, 74 insertions, 39 deletions
diff --git a/client/application.go b/client/application.go index 6f7e599..304869d 100644 --- a/client/application.go +++ b/client/application.go @@ -21,6 +21,8 @@ type application struct { windowHist []window.Location channelList channelList channelScroll tui.ScrollState + dmList channelList + dmScroll tui.ScrollState redraw bool cmdWindow cmdWindow prompts []window.Prompt @@ -104,8 +106,18 @@ func (a *application) OnEvent(cmd proto.Command) { }) case "unread": a.channelList.setUnread(channelLocation {id: cmd.Target}, true) + a.cache.Fetch(cmd.Target, func(ch *proto.Object) { + if ch == nil || ch.Kind != "direct-channel" { + return + } + if !a.dmList.contains(channelLocation {id: cmd.Target}) { + a.newDirect(*ch) + } + a.dmList.setUnread(channelLocation {id: cmd.Target}, true) + }) case "read": a.channelList.setUnread(channelLocation {id: cmd.Target}, false) + a.dmList.setUnread(channelLocation {id: cmd.Target}, false) } } @@ -287,6 +299,13 @@ func (a *application) onAuth(uid string) { } } }) + a.Request(proto.NewCmd("direct-channels", ""), + func(response proto.Command) { + if response.Kind == "direct-channels" { + a.dmList.setChannels(response.Args) + } + }, + ) if !a.welcomed { a.cmdWindow.info("welcome! type /help for help. try: /join talk") a.welcomed = true @@ -395,6 +414,11 @@ func (a *application) newChannel(ch proto.Object) { a.channelScroll.Set(0) } +func (a *application) newDirect(ch proto.Object) { + a.dmList.add(ch.Fields[""], channelLocation {id: ch.Id}) + a.dmScroll.Set(0) +} + func (a *application) getNick() string { if !a.authenticated { return "" diff --git a/client/channel_list.go b/client/channel_list.go index b8bf962..2c7c51c 100644 --- a/client/channel_list.go +++ b/client/channel_list.go @@ -91,27 +91,17 @@ func (cl *channelList) remove(location channelLocation) { } func (cl *channelList) traverse(direction int) int { - if len(*cl) == 0 { - return 0 - } - - var i int - for i = 0; i < len(*cl); i++ { + next := 0 + for i := 0; i < len(*cl); i++ { if (*cl)[i].location == globalApp.currentWindow { + next = i + direction break } } - if i == len(*cl) { - i = 0 - } else { - i += direction - i %= len(*cl) - if i < 0 { - i = len(*cl) + i - } + if next >= 0 && next < len(*cl) { + globalApp.goTo((*cl)[next].location) } - globalApp.goTo((*cl)[i].location) - return i + return next } func (cl *channelList) add(name string, location channelLocation) { @@ -120,7 +110,8 @@ func (cl *channelList) add(name string, location channelLocation) { *cl = append([]channelListEntry {entry}, *cl...) } -func (cl *channelList) show(scroll *tui.ScrollState) { +func (cl *channelList) show( + scroll *tui.ScrollState, menu func(channelLocation)) { mouse := tui.Push("channel list", tui.Box { Width: 12, Height: tui.Fill, Overflow: true, Scroll: scroll, }) @@ -158,26 +149,7 @@ func (cl *channelList) show(scroll *tui.ScrollState) { } } } - - switch { - case tui.MenuOption("list"): - w := globalApp.windowCache.Open(entry.location) - switch w.(type) { - case *channelWindow: - w.(*channelWindow).userList(func(msg userListMsg) { - globalApp.cmdWindow.Buffer().Add(msg) - }) - } - case tui.MenuOption("leave"): - w := globalApp.windowCache.Open(entry.location) - switch w.(type) { - case *channelWindow: - defer w.(*channelWindow).leaveChannel() - } - if entry.location == globalApp.currentWindow { - globalApp.goTo(cmdWindowLocation {}) - } - } + menu(entry.location) ch := globalApp.cache.Get(entry.location.id) if ch != nil { diff --git a/client/channel_window.go b/client/channel_window.go index 97e86e8..ee656ca 100644 --- a/client/channel_window.go +++ b/client/channel_window.go @@ -152,6 +152,7 @@ func (cw *channelWindow) markRead() { func(response proto.Command) { if response.Kind == "ok" { globalApp.channelList.setUnread(cw.location, false) + globalApp.dmList.setUnread(cw.location, false) } }, ) diff --git a/client/ui.go b/client/ui.go index fc8d9a6..6282bc6 100644 --- a/client/ui.go +++ b/client/ui.go @@ -212,6 +212,40 @@ func (a *application) showWindow() { tui.Pop() } +func (a *application) showChannelLists() { + tui.Push("", tui.Box { + Width: tui.Children, Height: tui.Fill, Dir: tui.Down, + }) + + a.channelList.show(&a.channelScroll, func(cl channelLocation) { + switch { + case tui.MenuOption("list"): + w := globalApp.windowCache.Open(cl) + switch w.(type) { + case *channelWindow: + w.(*channelWindow).userList(func(msg userListMsg) { + globalApp.cmdWindow.Buffer().Add(msg) + }) + } + case tui.MenuOption("leave"): + w := globalApp.windowCache.Open(cl) + switch w.(type) { + case *channelWindow: + defer w.(*channelWindow).leaveChannel() + } + if cl == globalApp.currentWindow { + globalApp.goTo(cmdWindowLocation {}) + } + } + }) + tui.Push("", tui.Box {Width: 12, Height: 1}) + tui.Text(strings.Repeat("─", 12), nil) + tui.Pop() + a.dmList.show(&a.dmScroll, func(cl channelLocation) {}) + + tui.Pop() +} + func (a *application) show() { s := tui.Size() tui.Push("", tui.Box { @@ -219,9 +253,13 @@ func (a *application) show() { Dir: tui.Right, }) - a.channelList.show(&a.channelScroll) + a.showChannelLists() + tui.Push("border", tui.Box {Width: 1, Height: tui.Fill}) - tui.Text(strings.Repeat("│", s.Height), nil) + tui.Text(strings.Repeat("│", s.Height / 2), nil) + tui.Text("┤", nil) + tui.Text(strings.Repeat("│", s.Height / 2), nil) tui.Pop() + a.showWindow() }
\ No newline at end of file |
