summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/application.go18
-rw-r--r--client/channel_window.go3
-rw-r--r--client/cmd_window.go6
-rw-r--r--client/command.go16
-rw-r--r--client/ui.go20
-rw-r--r--client/user_messages.go60
-rw-r--r--proto/strfail.go2
-rw-r--r--server/channel/command.go4
-rw-r--r--server/user/command.go8
-rw-r--r--server/user/user.go8
-rw-r--r--server/validate/validate.go2
11 files changed, 132 insertions, 15 deletions
diff --git a/client/application.go b/client/application.go
index 5ac3b9d..fb12717 100644
--- a/client/application.go
+++ b/client/application.go
@@ -64,7 +64,7 @@ func (a *application) OnEvent(cmd proto.Command) {
}
case "update":
if len(cmd.Args) > 0 {
- a.cache.Update(cmd.Target, cmd.Args[0])
+ a.onUpdate(cmd.Target, cmd.Args[0])
}
case "delete":
a.cache.Gone(cmd.Target)
@@ -80,6 +80,13 @@ func (a *application) OnResponse(requestId string, cmd proto.Command) {
}
}
+func (a *application) onUpdate(target string, update proto.Object) {
+ if target == a.uid {
+ a.logUserUpdate(target, update)
+ }
+ a.cache.Update(target, update)
+}
+
func (a *application) Sub(id string) {
a.Request(proto.NewCmd("s", id), func(cmd proto.Command) {
if cmd.Kind == "i" && len(cmd.Args) > 0 {
@@ -126,12 +133,7 @@ func (a *application) auth(name string, authCallback func(success bool)) {
}
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.Request(proto.NewCmd("update", o.Id, o), cb)
}
func (a *application) lookup(
@@ -212,8 +214,6 @@ func (a *application) setNick(newName string) {
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(
diff --git a/client/channel_window.go b/client/channel_window.go
index b516775..d8f4c2c 100644
--- a/client/channel_window.go
+++ b/client/channel_window.go
@@ -98,8 +98,7 @@ func (cw *channelWindow) Send(text string) {
}
case "fail":
if len(response.Args) > 0 {
- f := proto.Fail(response.Args[0])
- globalApp.cmdWindow.err(f.Error())
+ globalApp.cmdWindow.fail(response.Args[0])
}
}
}
diff --git a/client/cmd_window.go b/client/cmd_window.go
index fe6e60a..c423b87 100644
--- a/client/cmd_window.go
+++ b/client/cmd_window.go
@@ -1,9 +1,9 @@
package main
import (
- "citrons.xyz/talk/client/buffer"
"citrons.xyz/talk/client/window"
"citrons.xyz/talk/tui"
+ "citrons.xyz/talk/proto"
"fmt"
)
@@ -119,6 +119,10 @@ func (w *cmdWindow) err(f string, a ...any) {
w.Buf.Add(logMsg {lastIndex, fmt.Sprintf(f, a...), logErr})
}
+func (w *cmdWindow) fail(o proto.Object) {
+ w.err(proto.Strfail(o))
+}
+
func (w *cmdWindow) cmd(f string, a ...any) {
lastIndex++
w.Buf.Add(logMsg {lastIndex, fmt.Sprintf(f, a...), logCmd})
diff --git a/client/command.go b/client/command.go
index 2c146e9..3122dc6 100644
--- a/client/command.go
+++ b/client/command.go
@@ -1,5 +1,9 @@
package main
+import (
+ "citrons.xyz/talk/proto"
+)
+
func isCommand(text string) (bool, string) {
if text[0] == '/' {
if len(text) > 1 && text[1] == '/' {
@@ -93,6 +97,18 @@ func (a *application) doCommand(command string, args []string, text string) {
a.cmdWindow.Buffer().Add(msg)
})
}
+ case "status":
+ if !a.authenticated {
+ break
+ }
+ cb := func(response proto.Command) {
+ if response.Kind == "fail" && len(response.Args) > 0 {
+ a.cmdWindow.fail(response.Args[0])
+ }
+ }
+ a.sendUpdate(proto.Object {
+ "u", a.uid, map[string]string {"status": text},
+ }, cb)
case "create":
if a.authenticated {
a.createChannel(text)
diff --git a/client/ui.go b/client/ui.go
index 740cc54..f3a79c6 100644
--- a/client/ui.go
+++ b/client/ui.go
@@ -3,6 +3,7 @@ package main
import (
"citrons.xyz/talk/client/window"
"citrons.xyz/talk/tui"
+ "citrons.xyz/talk/proto"
"zgo.at/termfo/keys"
"os"
)
@@ -68,6 +69,25 @@ func (a *application) onInput(ev tui.Event) {
}
+func (a *application) logUserUpdate(uid string, update proto.Object) {
+ u := a.cache.Get(uid)
+ if u == nil {
+ return
+ }
+ switch {
+ case update.Fields["status"] != "":
+ lastIndex++
+ a.cmdWindow.Buffer().Add(userStatusMsg {
+ lastIndex, uid, u.Fields[""], update.Fields["status"],
+ })
+ case update.Fields[""] != "":
+ lastIndex++
+ a.cmdWindow.Buffer().Add(nameChangeMsg {
+ lastIndex, uid, u.Fields[""], update.Fields[""],
+ })
+ }
+}
+
func (a *application) showNickBox() {
tui.Push("username", tui.Box {Width: tui.TextSize, Height: tui.TextSize})
tui.Text("[", nil)
diff --git a/client/user_messages.go b/client/user_messages.go
new file mode 100644
index 0000000..80b8fcc
--- /dev/null
+++ b/client/user_messages.go
@@ -0,0 +1,60 @@
+package main
+
+import (
+ "citrons.xyz/talk/tui"
+ "fmt"
+)
+
+type nameChangeMsg struct {
+ index int
+ uid string
+ oldName string
+ newName string
+}
+
+type userStatusMsg struct {
+ index int
+ uid string
+ username string
+ status string
+}
+
+func (m nameChangeMsg) Id() string {
+ return fmt.Sprintf("name change.%d", m.index)
+}
+
+func (m userStatusMsg) Id() string {
+ return fmt.Sprintf("user status.%d", m.index)
+}
+
+func (m nameChangeMsg) Show(odd bool) {
+ tui.Push("", tui.Box {Width: tui.Fill, Height: tui.TextSize})
+ tui.Text("nick: ", &tui.Style {
+ Fg: tui.BrightBlack, Bg: colorDefault[odd],
+ })
+ tui.Text(m.oldName, &tui.Style {
+ Fg: tui.White, Bg: colorDefault[odd], Italic: true,
+ })
+ tui.Text(" -> ", &tui.Style {
+ Fg: tui.BrightBlack, Bg: colorDefault[odd],
+ })
+ tui.Text(m.newName, &tui.Style {
+ Fg: tui.White, Bg: colorDefault[odd], Bold: true,
+ })
+ tui.Pop()
+}
+
+func (m userStatusMsg) Show(odd bool) {
+ tui.Push("", tui.Box {Width: tui.Fill, Height: tui.TextSize})
+ tui.Text("status: ", &tui.Style {
+ Fg: tui.BrightBlack, Bg: colorDefault[odd],
+ })
+ tui.Text(m.username, &tui.Style {
+ Fg: tui.White, Bg: colorDefault[odd], Bold: true,
+ })
+ tui.Text(" : ", &tui.Style {
+ Fg: tui.BrightBlack, Bg: colorDefault[odd],
+ })
+ tui.Text(m.status, nil)
+ tui.Pop()
+}
diff --git a/proto/strfail.go b/proto/strfail.go
index 83f314b..eb3d1c6 100644
--- a/proto/strfail.go
+++ b/proto/strfail.go
@@ -14,6 +14,8 @@ func Strfail(fail Object) string {
return "name is in use: " + fail.Fields[""]
case "invalid-name":
return "name is too long or contains invalid characters: " + fail.Fields[""]
+ case "too-long":
+ return "message or status is too long"
case "not-in-channel":
return "you are not a member of this channel: " + fail.Fields[""]
default:
diff --git a/server/channel/command.go b/server/channel/command.go
index af5ff16..e645055 100644
--- a/server/channel/command.go
+++ b/server/channel/command.go
@@ -25,6 +25,10 @@ func (c *Channel) SendRequest(r session.Request) {
return
}
}
+ if len(m.Fields[""]) > 50000 {
+ r.Reply(proto.Fail{"too-long", "", nil}.Cmd())
+ return
+ }
default:
r.ReplyInvalid()
return
diff --git a/server/user/command.go b/server/user/command.go
index b14845c..0c4f6d0 100644
--- a/server/user/command.go
+++ b/server/user/command.go
@@ -23,15 +23,23 @@ func (u *User) SendRequest(r session.Request) {
return
}
name := u.name
+ status := u.status
for k, v := range upd.Fields {
switch k {
case "":
name = v
+ case "status":
+ status = v
default:
r.ReplyInvalid()
return
}
}
+ if len(status) > 512 {
+ r.Reply(proto.Fail{"too-long", "", nil}.Cmd())
+ return
+ }
+ u.status = status
if name != u.name {
err := u.Rename(name)
if err != nil {
diff --git a/server/user/user.go b/server/user/user.go
index 0a9ae4e..fa5f37b 100644
--- a/server/user/user.go
+++ b/server/user/user.go
@@ -17,6 +17,8 @@ type User struct {
store *UserStore
name string
id string
+ status string
+ description string
Stream session.Stream
Channels map[string]bool
Anonymous bool
@@ -98,9 +100,11 @@ func (u *User) Delete() {
}
func (u *User) GetInfo() proto.Object {
- return proto.Object {
- "u", u.id, map[string]string {"": u.name},
+ i := map[string]string {"": u.name}
+ if u.status != "" {
+ i["status"] = u.status
}
+ return proto.Object {"u", u.id, i}
}
func (t Tombstone) GetInfo() proto.Object {
diff --git a/server/validate/validate.go b/server/validate/validate.go
index 4415557..9b3ff0d 100644
--- a/server/validate/validate.go
+++ b/server/validate/validate.go
@@ -6,7 +6,7 @@ import (
)
func Name(name string) bool {
- if len(Fold(name)) == 0 || len(name) >= 256 {
+ if len(Fold(name)) == 0 || len(name) > 256 {
return false
}
for _, r := range name {