summaryrefslogtreecommitdiff
path: root/client/application.go
diff options
context:
space:
mode:
Diffstat (limited to 'client/application.go')
-rw-r--r--client/application.go159
1 files changed, 118 insertions, 41 deletions
diff --git a/client/application.go b/client/application.go
index 72ec078..b1c5865 100644
--- a/client/application.go
+++ b/client/application.go
@@ -3,45 +3,49 @@ package main
import (
"citrons.xyz/talk/client/client"
"citrons.xyz/talk/client/object"
- "citrons.xyz/talk/client/buffer"
+ "citrons.xyz/talk/client/window"
"citrons.xyz/talk/proto"
- "citrons.xyz/talk/tui"
- "zgo.at/termfo/keys"
- "os"
)
type application struct {
client.Client
+ quit bool
+ connected bool
reconnecting bool
authenticated bool
uid string
cache object.ObjCache
- currentBuffer *buffer.Buffer
- cmdBuffer cmdBuffer
+ windowCache window.WindowCache
+ currentWindow window.Location
+ cmdWindow cmdWindow
}
func newApplication(serverAddress string) *application {
var app application
app.Client = client.New(serverAddress)
+ app.currentWindow = app.cmdWindow.Location()
app.cache = object.NewCache(&app)
- app.currentBuffer = &app.cmdBuffer.Buffer
+ app.windowCache = window.NewCache()
- app.cmdBuffer.info("connecting to %s", app.Client.Address)
+ app.cmdWindow.info("connecting to %s", app.Client.Address)
return &app
}
func (a *application) OnConnect() {
+ a.connected = true
a.reconnecting = false
- a.cmdBuffer.info("connected to %s", a.Client.Address)
-
- a.auth("test user")
+ a.cache = object.NewCache(a)
+ a.windowCache = window.NewCache()
+ a.cmdWindow.info("connected to %s", a.Client.Address)
+ a.cmdWindow.loginMode()
}
func (a *application) OnDisconnect(err error) {
+ a.connected = false
a.authenticated = false
a.uid = ""
if !a.reconnecting {
- a.cmdBuffer.err(
+ a.cmdWindow.err(
"disconnected from %s: %s\nreconnecting...", a.Client.Address, err,
)
a.reconnecting = true
@@ -50,6 +54,11 @@ func (a *application) OnDisconnect(err error) {
func (a *application) OnEvent(cmd proto.Command) {
switch cmd.Kind {
+ case "p":
+ cw := a.windowCache.Get(channelLocation {cmd.Target}).(*channelWindow)
+ if cw != nil && len(cmd.Args) > 0 {
+ cw.put(cmd.Args[0])
+ }
case "update":
if len(cmd.Args) > 0 {
a.cache.Update(cmd.Target, cmd.Args[0])
@@ -63,7 +72,7 @@ func (a *application) OnResponse(requestId string, cmd proto.Command) {
switch cmd.Kind {
case "you-are":
if len(cmd.Args) > 0 {
- a.cmdBuffer.info("your name is: %s", cmd.Args[0].Fields[""])
+ a.cmdWindow.info("your name is: %s", cmd.Args[0].Fields[""])
}
}
}
@@ -84,19 +93,28 @@ func (a *application) GetInfo(id string, callback func(proto.Command)) {
a.Request(proto.NewCmd("i", id), callback)
}
-func (a *application) auth(name string) {
+func (a *application) auth(name string, authCallback func(success bool)) {
callback := func(response proto.Command) {
switch response.Kind {
case "you-are":
if len(response.Args) == 0 {
+ authCallback(false)
break
}
me := response.Args[0]
a.authenticated = true
a.uid = me.Id
a.cache.Watch(a.uid)
+ if authCallback != nil {
+ authCallback(true)
+ }
case "fail":
- // todo
+ if len(response.Args) != 0 {
+ a.cmdWindow.err(proto.Strfail(response.Args[0]))
+ }
+ if authCallback != nil {
+ authCallback(false)
+ }
}
}
a.Request(proto.NewCmd("auth", "", proto.Object {
@@ -104,39 +122,98 @@ func (a *application) auth(name string) {
}), callback)
}
-func (a *application) onInput(ev tui.Event) {
- tui.Selected = "input"
+func (a *application) sendUpdate(o proto.Object, cb func(proto.Command)) {
+ a.Request(proto.NewCmd("update", o.Id, o), func(response proto.Command) {
+ if response.Kind == "ok" {
+ a.cache.Update(o.Id, o)
+ }
+ cb(response)
+ })
+}
- a.currentBuffer.Scroll(-ev.Mouse.Scroll * 2)
- scroll := tui.Size().Height - 5
- switch ev.Key {
- case keys.PageUp:
- a.currentBuffer.Scroll(scroll)
- case keys.PageDown:
- a.currentBuffer.Scroll(-scroll)
+func (a *application) lookup(
+ name string, kind string, callback func(*proto.Object, *proto.Fail)) {
+ cb := func(response proto.Command) {
+ switch response.Kind {
+ case "i":
+ if len(response.Args) > 0 {
+ callback(&response.Args[0], nil)
+ }
+ case "fail":
+ if len(response.Args) > 0 {
+ f := proto.Fail(response.Args[0])
+ callback(nil, &f)
+ }
+ }
}
-
- a.currentBuffer.TextInput.Update(ev)
+ o := proto.Object {kind, "", map[string]string {"": name}}
+ a.Request(proto.NewCmd("lookup", "", o), cb)
}
-func (a *application) show() {
- tui.Clear()
- s := tui.Size()
- tui.Push("", tui.Box {
- Width: tui.BoxSize(s.Width), Height: tui.BoxSize(s.Height),
+func (a *application) join(channelName string) {
+ a.lookup(channelName, "channel", func(ch *proto.Object, f *proto.Fail) {
+ if f != nil {
+ a.cmdWindow.err(f.Error())
+ return
+ }
+ a.Request(proto.NewCmd("join", ch.Id), func(response proto.Command) {
+ switch response.Kind {
+ case "ok":
+ a.currentWindow = channelLocation {id: ch.Id}
+ case "fail":
+ if len(response.Args) > 0 {
+ f := proto.Fail(response.Args[0])
+ a.cmdWindow.err(f.Error())
+ }
+ }
+ })
})
+}
- a.currentBuffer.Show("buffer")
- tui.Push("status", tui.Box {
- Width: tui.Fill, Height: tui.BoxSize(1), Dir: tui.Right,
- Style: &tui.Style {Bg: tui.White, Fg: tui.Black},
+func (a *application) createChannel(name string) {
+ ch := proto.Object {"channel", "", map[string]string {"": name}}
+ a.Request(proto.NewCmd("create", "", ch), func(response proto.Command) {
+ switch response.Kind {
+ case "create":
+ if len(response.Args) > 0 {
+ ch := response.Args[0]
+ a.currentWindow = channelLocation {id: ch.Id}
+ }
+ case "fail":
+ if len(response.Args) > 0 {
+ f := proto.Fail(response.Args[0])
+ a.cmdWindow.err(f.Error())
+ }
+ }
})
- tui.Pop()
- a.currentBuffer.TextInput.Show("input")
+}
+
+func (a *application) getNick() string {
+ if !a.authenticated {
+ return ""
+ }
+ u := a.cache.Get(a.uid)
+ if u != nil {
+ return u.Fields[""]
+ }
+ return ""
+}
- tui.Pop()
- tui.DrawLayout()
- if tui.Present() != nil {
- os.Exit(-1)
+func (a *application) setNick(newName string) {
+ if !a.authenticated {
+ return
+ }
+ callback := func(response proto.Command) {
+ switch response.Kind {
+ case "fail":
+ if len(response.Args) != 0 {
+ a.cmdWindow.err(proto.Strfail(response.Args[0]))
+ }
+ case "ok":
+ a.cmdWindow.info("your name is: %s", newName)
+ }
}
+ a.sendUpdate(
+ proto.Object {"u", a.uid, map[string]string {"": newName}}, callback,
+ )
}