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() } }