summaryrefslogtreecommitdiff
path: root/client/channel_window.go
diff options
context:
space:
mode:
Diffstat (limited to 'client/channel_window.go')
-rw-r--r--client/channel_window.go189
1 files changed, 189 insertions, 0 deletions
diff --git a/client/channel_window.go b/client/channel_window.go
new file mode 100644
index 0000000..abeaa77
--- /dev/null
+++ b/client/channel_window.go
@@ -0,0 +1,189 @@
+package main
+
+import (
+ "citrons.xyz/talk/client/buffer"
+ "citrons.xyz/talk/client/window"
+ "citrons.xyz/talk/proto"
+ "citrons.xyz/talk/tui"
+ "strconv"
+ "time"
+)
+
+type channelLocation struct {
+ id string
+}
+
+type channelWindow struct {
+ location channelLocation
+ buf buffer.Buffer
+ input tui.TextInput
+ watchedUsers map[string]bool
+ loadingHistory bool
+}
+
+type channelMsg struct {
+ proto.Object
+ window *channelWindow
+}
+
+func (cl channelLocation) CreateWindow() window.Window {
+ if !globalApp.connected {
+ return nil
+ }
+ cw := &channelWindow {
+ location: cl, watchedUsers: make(map[string]bool),
+ }
+ globalApp.cache.Watch(cl.id)
+ return cw
+}
+
+func (cw *channelWindow) getChannel() *proto.Object {
+ return globalApp.cache.Get(cw.location.id)
+}
+
+func (cw *channelWindow) watchUser(uid string) {
+ if !cw.watchedUsers[uid] {
+ globalApp.cache.Watch(uid)
+ cw.watchedUsers[uid] = true
+ }
+}
+
+func (cw *channelWindow) username(uid string) string {
+ cw.watchUser(uid)
+ u := globalApp.cache.Get(uid)
+ if u != nil {
+ return u.Fields[""]
+ }
+ return "..."
+}
+
+func (cw *channelWindow) put(msg proto.Object) {
+ cw.buf.Add(channelMsg {msg, cw})
+}
+
+func (cw *channelWindow) Location() window.Location {
+ return cw.location
+}
+
+func (cw *channelWindow) Kill() {
+ globalApp.cache.Unwatch(cw.location.id)
+ for u := range cw.watchedUsers {
+ globalApp.cache.Watch(u)
+ }
+}
+
+func (cw *channelWindow) Buffer() *buffer.Buffer {
+ return &cw.buf
+}
+
+func (cw *channelWindow) Input() *tui.TextInput {
+ return &cw.input
+}
+
+func (cw *channelWindow) Send(text string) {
+ if !globalApp.connected || !globalApp.authenticated {
+ return
+ }
+ cb := func(response proto.Command) {
+ switch response.Kind {
+ case "p":
+ if len(response.Args) > 0 {
+ cw.put(response.Args[0])
+ }
+ case "fail":
+ if len(response.Args) > 0 {
+ f := proto.Fail(response.Args[0])
+ globalApp.cmdWindow.err(f.Error())
+ }
+ }
+ }
+ msg := proto.Object {"m", "", map[string]string {"": text}}
+ globalApp.Request(proto.NewCmd("p", cw.location.id, msg), cb)
+ cw.input.SetText("")
+}
+
+func (cw *channelWindow) ShowStatusLine() {
+ ch := cw.getChannel()
+ if ch == nil {
+ return
+ }
+ tui.Text(ch.Fields[""], nil)
+ if cw.loadingHistory {
+ tui.Text("...", nil)
+ }
+}
+
+func (m channelMsg) Id() string {
+ return m.Object.Id
+}
+
+func (m channelMsg) showDate(bg int32) {
+ unix, _ := strconv.Atoi(m.Fields["t"])
+ time := time.Unix(int64(unix), 0).Format(time.DateTime)
+ tui.Push("", tui.Box {Width: tui.TextSize, Height: 1, NoWrap: true})
+ tui.Text(" " + time, &tui.Style {Fg: tui.BrightBlack, Bg: bg})
+ tui.Pop()
+ tui.Push("", tui.Box {Width: tui.Fill, Height: 1})
+ tui.Pop()
+}
+
+func (m channelMsg) Show(odd bool) {
+ var bg int32 = tui.Black
+ if odd {
+ bg = 236
+ }
+
+ switch m.Kind {
+ case "join":
+ tui.Push("", tui.Box {
+ Width: tui.Fill, Height: tui.Children, Dir: tui.Left,
+ })
+ m.showDate(bg)
+ tui.Push("", tui.Box {Width: tui.TextSize, Height: tui.TextSize})
+ tui.Text("-> ", &tui.Style {Fg: tui.BrightBlack, Bg: bg})
+ tui.Text("join", &tui.Style {Fg: tui.Blue, Bg: bg, Bold: true})
+ tui.Text(": ", &tui.Style {Fg: tui.BrightBlack, Bg: bg})
+ tui.Text(m.window.username(m.Fields[""]), nil)
+ tui.Pop()
+ tui.Pop()
+ case "leave":
+ tui.Push("", tui.Box {
+ Width: tui.Fill, Height: tui.Children, Dir: tui.Left,
+ })
+ m.showDate(bg)
+ tui.Push("", tui.Box {Width: tui.TextSize, Height: tui.TextSize})
+ tui.Text("<- ", &tui.Style {Fg: tui.BrightBlack, Bg: bg})
+ tui.Text("leave", &tui.Style {Fg: tui.Blue, Bg: bg, Bold: true})
+ tui.Text(": ", &tui.Style {Fg: tui.BrightBlack, Bg: bg})
+ tui.Text(m.window.username(m.Fields[""]), nil)
+ tui.Pop()
+ tui.Pop()
+ case "m":
+ var usernameFg int32 = tui.White
+ if m.Fields["f"] == globalApp.uid {
+ usernameFg = tui.Cyan
+ }
+
+ tui.Push("", tui.Box {Width: tui.Fill, Height: 1, Dir: tui.Left})
+ m.showDate(bg)
+ tui.Push("", tui.Box {Width: tui.TextSize, Height: 1, NoWrap: true})
+ tui.Text(m.window.username(m.Fields["f"]), &tui.Style {
+ Fg: usernameFg, Bg: bg, Bold: true,
+ })
+ tui.Pop()
+ tui.Pop()
+
+ tui.Push("", tui.Box {
+ Width: tui.TextSize, Height: tui.TextSize,
+ Margins: [4]int {1, 0, 0, 0},
+ })
+ tui.Text(m.Fields[""], nil)
+ tui.Pop()
+ default:
+ tui.Push("", tui.Box {Width: tui.Fill, Height: tui.TextSize})
+ tui.Text("[", nil)
+ tui.Text(m.Kind, &tui.Style {Fg: tui.White, Bg: bg, Italic: true})
+ tui.Text("]", nil)
+ tui.Pop()
+ }
+}