summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/application.go12
-rw-r--r--client/channel_list.go99
-rw-r--r--client/channel_window.go1
-rw-r--r--client/ui.go29
4 files changed, 134 insertions, 7 deletions
diff --git a/client/application.go b/client/application.go
index 35f38c8..2d16591 100644
--- a/client/application.go
+++ b/client/application.go
@@ -18,6 +18,7 @@ type application struct {
windowCache window.WindowCache
currentWindow window.Location
windowHist []window.Location
+ channelList channelList
cmdWindow cmdWindow
prompts []window.Prompt
}
@@ -121,6 +122,7 @@ func (a *application) auth(name string, authCallback func(success bool)) {
a.authenticated = true
a.uid = me.Id
a.cache.Watch(a.uid)
+ a.onAuth()
if authCallback != nil {
authCallback(true)
}
@@ -138,6 +140,14 @@ func (a *application) auth(name string, authCallback func(success bool)) {
}), callback)
}
+func (a *application) onAuth() {
+ a.Request(proto.NewCmd("channels", ""), func(response proto.Command) {
+ if response.Kind == "channels" {
+ a.channelList.setChannels(response.Args)
+ }
+ })
+}
+
func (a *application) sendUpdate(o proto.Object, cb func(proto.Command)) {
a.Request(proto.NewCmd("update", o.Id, o), cb)
}
@@ -170,6 +180,7 @@ func (a *application) join(channelName string) {
a.Request(proto.NewCmd("join", ch.Id), func(response proto.Command) {
switch response.Kind {
case "ok":
+ a.channelList.add(channelName, channelLocation {id: ch.Id})
a.goTo(channelLocation {id: ch.Id})
case "fail":
if len(response.Args) > 0 {
@@ -188,6 +199,7 @@ func (a *application) createChannel(name string) {
case "create":
if len(response.Args) > 0 {
ch := response.Args[0]
+ a.channelList.add(ch.Fields[""], channelLocation {id: ch.Id})
a.goTo(channelLocation {id: ch.Id})
}
case "fail":
diff --git a/client/channel_list.go b/client/channel_list.go
new file mode 100644
index 0000000..5903792
--- /dev/null
+++ b/client/channel_list.go
@@ -0,0 +1,99 @@
+package main
+
+import (
+ "citrons.xyz/talk/proto"
+ "citrons.xyz/talk/tui"
+ "sort"
+)
+
+type channelList []channelListEntry
+
+type channelListEntry struct {
+ name string
+ location channelLocation
+}
+
+func (cl *channelList) Len() int {
+ return len(*cl)
+}
+
+func (cl *channelList) Less(i, j int) bool {
+ return (*cl)[i].name < (*cl)[j].name
+}
+
+func (cl *channelList) Swap(i, j int) {
+ x := (*cl)[i]
+ (*cl)[i] = (*cl)[j]
+ (*cl)[j] = x
+}
+
+func (cl *channelList) setChannels(cs []proto.Object) {
+ *cl = nil
+ for _, c := range cs {
+ *cl = append(*cl, channelListEntry {
+ c.Fields[""], channelLocation {c.Id},
+ })
+ }
+ sort.Sort(cl)
+}
+
+func (cl *channelList) remove(location channelLocation) {
+ for i := len(*cl) - 1; i >= 0; i-- {
+ if (*cl)[i].location != location {
+ continue
+ }
+ if i < len(*cl) - 1 {
+ *cl = append((*cl)[:i], (*cl)[i + 1:]...)
+ } else {
+ *cl = (*cl)[:i]
+ }
+ break
+ }
+}
+
+func (cl *channelList) traverse(direction int) {
+ var i int
+ for i = 0; i < len(*cl); i++ {
+ if (*cl)[i].location == globalApp.currentWindow {
+ break
+ }
+ }
+ if i == len(*cl) {
+ i = 0
+ } else {
+ i += direction
+ i %= len(*cl)
+ if i < 0 {
+ i = len(*cl) + i
+ }
+ }
+ globalApp.goTo((*cl)[i].location)
+}
+
+func (cl *channelList) add(name string, location channelLocation) {
+ cl.remove(location)
+ entry := channelListEntry {name, location}
+ *cl = append([]channelListEntry {entry}, *cl...)
+}
+
+func (cl *channelList) show() {
+ tui.Push("channel list", tui.Box {Width: 12, Height: tui.Fill})
+ for i, entry := range *cl {
+ var style *tui.Style
+ if entry.location == globalApp.currentWindow {
+ style = &tui.Style {Fg: tui.Black, Bg: tui.White}
+ }
+
+ tui.Push("channel list." + entry.location.id, tui.Box {
+ Width: tui.Fill, Height: 1, NoWrap: true, Style: style,
+ })
+ ch := globalApp.cache.Get(entry.location.id)
+ if ch != nil {
+ entry.name = ch.Fields[""]
+ (*cl)[i] = entry
+ }
+ tui.Text(entry.name, nil)
+ tui.Pop()
+ }
+ tui.Pop()
+}
diff --git a/client/channel_window.go b/client/channel_window.go
index 6ec9ea0..b3788da 100644
--- a/client/channel_window.go
+++ b/client/channel_window.go
@@ -111,6 +111,7 @@ func (cw *channelWindow) leaveChannel() {
globalApp.Request(proto.NewCmd("leave", cw.location.id), nil)
globalApp.windowCache.Evict(cw.location)
globalApp.removeFromHistory(cw.location)
+ globalApp.channelList.remove(cw.location)
}
func (cw *channelWindow) renameChannel(newName string) {
diff --git a/client/ui.go b/client/ui.go
index 014c7e9..87edea8 100644
--- a/client/ui.go
+++ b/client/ui.go
@@ -67,6 +67,10 @@ func (a *application) onInput(ev tui.Event) {
input.SetText("")
}
}
+ case keys.Up | keys.Alt:
+ a.channelList.traverse(-1)
+ case keys.Down | keys.Alt:
+ a.channelList.traverse(1)
case 'p' | keys.Ctrl:
a.traverseHistory(-1)
case 'n' | keys.Ctrl:
@@ -106,13 +110,8 @@ func (a *application) showNickBox() {
tui.Pop()
}
-func (a *application) show() {
- tui.Clear()
- s := tui.Size()
- tui.Push("", tui.Box {
- Width: tui.BoxSize(s.Width), Height: tui.BoxSize(s.Height),
- Style: &tui.Style {Fg: tui.White, Bg: colorDefault[false]},
- })
+func (a *application) showWindow() {
+ tui.Push("window", tui.Box {Width: tui.Fill, Height: tui.Fill})
if a.currentWindow != (cmdWindowLocation{}) {
a.cmdWindow.showPreview()
@@ -153,6 +152,22 @@ func (a *application) show() {
tui.Pop()
tui.Pop()
+}
+
+func (a *application) show() {
+ tui.Clear()
+ s := tui.Size()
+ tui.Push("", tui.Box {
+ Width: tui.BoxSize(s.Width), Height: tui.BoxSize(s.Height),
+ Dir: tui.Right,
+ })
+
+ a.channelList.show()
+ tui.Push("border", tui.Box {Width: 1, Height: tui.Fill})
+ tui.Text(strings.Repeat("│", s.Height), nil)
+ tui.Pop()
+ a.showWindow()
+
tui.DrawLayout()
if tui.Present() != nil {
os.Exit(-1)