summaryrefslogtreecommitdiff
path: root/server/channel/channel.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/channel/channel.go')
-rw-r--r--server/channel/channel.go68
1 files changed, 67 insertions, 1 deletions
diff --git a/server/channel/channel.go b/server/channel/channel.go
index e2a18c5..d907bc0 100644
--- a/server/channel/channel.go
+++ b/server/channel/channel.go
@@ -179,6 +179,14 @@ func (c *Channel) Rename(name string) *proto.Fail {
}
func (c *Channel) Put(m proto.Object, From *session.Session) proto.Object {
+ for uid := range c.Members() {
+ switch u := c.kind.world.GetCachedObject(uid).(type) {
+ case (*user.User):
+ if len(u.PrivateStream.Subscribers()) != 0 && !c.Unread(uid) {
+ u.PrivateStream.Event(proto.NewCmd("unread", c.id))
+ }
+ }
+ }
m.Id = proto.GenId()
m.Fields["t"] = proto.Timestamp()
err := c.kind.db.Update(func(tx *bolt.Tx) error {
@@ -283,6 +291,56 @@ func (c *Channel) History(min, max int) []proto.Object {
return result
}
+func (c *Channel) Unread(uid string) bool {
+ lastIndex := c.HistorySize() - 1
+ if (lastIndex < 0) {
+ return false
+ }
+ latest := c.History(lastIndex, lastIndex + 1)[0].Id
+
+ unread := true
+ err := c.kind.db.View(func(tx *bolt.Tx) error {
+ udata := tx.Bucket([]byte("user data"))
+ if udata == nil {
+ return nil
+ }
+ user := udata.Bucket([]byte(uid))
+ if user == nil {
+ return nil
+ }
+ readStatus := user.Bucket([]byte("read status"))
+ if readStatus == nil {
+ return nil
+ }
+ unread = string(readStatus.Get([]byte(c.id))) != latest
+ return nil
+ })
+ if err != nil {
+ log.Fatal("error reading database: ", err)
+ }
+
+ return unread
+}
+
+func (c *Channel) SetRead(uid string) {
+ lastIndex := c.HistorySize() - 1
+ if (lastIndex < 0) {
+ return
+ }
+ latest := c.History(lastIndex, lastIndex + 1)[0].Id
+
+ err := c.kind.db.Update(func(tx *bolt.Tx) error {
+ udata, _ := tx.CreateBucketIfNotExists([]byte("user data"))
+ user, _ := udata.CreateBucketIfNotExists([]byte(uid))
+ readStatus, _ := user.CreateBucketIfNotExists([]byte("read status"))
+ readStatus.Put([]byte(c.id), []byte(latest))
+ return nil
+ })
+ if err != nil {
+ log.Fatal("error updating database: ", err)
+ }
+}
+
func (c *Channel) Join(u *user.User) *proto.Fail {
if c.isDirect {
return &proto.Fail {"invalid", "", nil}
@@ -427,7 +485,15 @@ func (c *Channel) Kind() string {
}
func (c *Channel) InfoFor(uid string) proto.Object {
- return proto.Object {
+ i := proto.Object {
c.Kind(), c.id, map[string]string {"": c.NameFor(uid)},
}
+ if uid != "" {
+ if c.Unread(uid) {
+ i.Fields["unread"] = "yes"
+ } else {
+ i.Fields["unread"] = "no"
+ }
+ }
+ return i
}