summaryrefslogtreecommitdiff
path: root/server/channel
diff options
context:
space:
mode:
authorcitrons <citrons@mondecitronne.com>2025-06-07 22:09:09 -0500
committercitrons <citrons@mondecitronne.com>2025-06-07 22:09:09 -0500
commit8a8f1f98859123e162090538cbdbe7f5c9d34ea4 (patch)
tree548d9ef52bfa1579c17ce1ee600ba3356fa1ffbe /server/channel
parentf38d6eb807e2b921123dd5efd0b2d632a632e579 (diff)
direct messages
Diffstat (limited to 'server/channel')
-rw-r--r--server/channel/channel.go57
1 files changed, 52 insertions, 5 deletions
diff --git a/server/channel/channel.go b/server/channel/channel.go
index 449375b..056b942 100644
--- a/server/channel/channel.go
+++ b/server/channel/channel.go
@@ -6,11 +6,14 @@ import (
"citrons.xyz/talk/server/session"
"citrons.xyz/talk/server/validate"
"citrons.xyz/talk/server/user"
+ "strings"
+ "sort"
)
type ChannelStore struct {
world *object.World
byName map[string]*Channel
+ directChannels map[string]*Channel
deleted map[string]Tombstone
}
@@ -18,6 +21,7 @@ type Channel struct {
store *ChannelStore
id string
name string
+ isDirect bool
members map[string]Membership
messages []proto.Object
byId map[string]int
@@ -31,7 +35,8 @@ type Tombstone struct {
func NewStore(world *object.World) *ChannelStore {
return &ChannelStore {
- world, make(map[string]*Channel), make(map[string]Tombstone),
+ world, make(map[string]*Channel), make(map[string]*Channel),
+ make(map[string]Tombstone),
}
}
@@ -58,12 +63,44 @@ func (cs *ChannelStore) CreateChannel(name string) (*Channel, *proto.Fail) {
return &c, nil
}
+func (cs *ChannelStore) GetDirect(among []string) *Channel {
+ sort.Strings(among)
+ key := strings.Join(among, "\x00")
+ if cs.directChannels[key] == nil {
+ var c Channel
+ c.isDirect = true
+ c.store = cs
+ c.byId = make(map[string]int)
+ c.defaultMembership = DefaultMembership
+ c.members = make(map[string]Membership)
+ for _, member := range among {
+ c.members[member] = c.defaultMembership
+ }
+
+ cs.directChannels[key] = &c
+ c.id = cs.world.NewObject(&c)
+ }
+ return cs.directChannels[key]
+}
+
func (cs *ChannelStore) ByName(name string) *Channel {
return cs.byName[validate.Fold(name)]
}
func (c *Channel) Name() string {
- return c.name
+ if !c.isDirect {
+ return c.name
+ } else {
+ var members []string
+ for member := range c.members {
+ u := c.store.world.GetObject(member)
+ if u != nil {
+ members = append(members, u.GetInfo().Fields[""])
+ }
+ }
+ sort.Strings(members)
+ return strings.Join(members, ", ")
+ }
}
func (c *Channel) Id() string {
@@ -108,6 +145,9 @@ func (c *Channel) Put(m proto.Object) proto.Object {
}
func (c *Channel) prune() {
+ if c.isDirect {
+ return
+ }
for m, _ := range c.members {
switch c.store.world.GetObject(m).(type) {
case *user.User:
@@ -167,12 +207,19 @@ func (c *Channel) Delete() {
c.store.world.PutObject(c.id, deleted)
}
-func (c *Channel) GetInfo() proto.Object {
- return proto.Object {
- "channel", c.id, map[string]string {"": c.name},
+func (c *Channel) Kind() string {
+ switch {
+ case c.isDirect:
+ return "direct-channel"
+ default:
+ return "channel"
}
}
+func (c *Channel) GetInfo() proto.Object {
+ return proto.Object {c.Kind(), c.id, map[string]string {"": c.Name()}}
+}
+
func (t Tombstone) GetInfo() proto.Object {
return proto.Object {
"gone", "", map[string]string {"": t.name, "kind": "channel"},