aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbodqhrohro <bodqhrohro@gmail.com>2020-01-05 16:03:10 +0300
committerbodqhrohro <bodqhrohro@gmail.com>2020-01-05 16:03:10 +0300
commitb8fcac6ae24dd5e07f366741f0f282f33b18b503 (patch)
tree61f86331504dcd079f1a964d103ec299aa70f351
parenta435a0a556cb88fe1fcc7e3bf860b45530d895e7 (diff)
Resend chat statuses on probe presence
-rw-r--r--telegram/cache/cache.go63
-rw-r--r--telegram/handlers.go6
-rw-r--r--telegram/utils.go12
-rw-r--r--xmpp/handlers.go9
4 files changed, 79 insertions, 11 deletions
diff --git a/telegram/cache/cache.go b/telegram/cache/cache.go
index d1d16f9..b799709 100644
--- a/telegram/cache/cache.go
+++ b/telegram/cache/cache.go
@@ -6,20 +6,30 @@ import (
"github.com/zelenin/go-tdlib/client"
)
+// Status stores formatted data for XMPP presence
+type Status struct {
+ ID int64
+ XMPP string
+ Description string
+}
+
// Cache allows operating the chats and users cache in
// a thread-safe manner
type Cache struct {
- chats map[int64]*client.Chat
- users map[int32]*client.User
- chatsLock sync.Mutex
- usersLock sync.Mutex
+ chats map[int64]*client.Chat
+ users map[int32]*client.User
+ statuses map[int64]*Status
+ chatsLock sync.Mutex
+ usersLock sync.Mutex
+ statusesLock sync.Mutex
}
// NewCache initializes a cache
func NewCache() *Cache {
return &Cache{
- chats: map[int64]*client.Chat{},
- users: map[int32]*client.User{},
+ chats: map[int64]*client.Chat{},
+ users: map[int32]*client.User{},
+ statuses: map[int64]*Status{},
}
}
@@ -49,6 +59,26 @@ func (cache *Cache) UsersKeys() []int32 {
return keys
}
+// StatusesRange loops through the map in a thread-safe manner
+func (cache *Cache) StatusesRange() chan *Status {
+ cache.statusesLock.Lock()
+
+ statusChan := make(chan *Status, 1)
+
+ go func() {
+ defer func() {
+ cache.statusesLock.Unlock()
+ close(statusChan)
+ }()
+
+ for _, status := range cache.statuses {
+ statusChan <- status
+ }
+ }()
+
+ return statusChan
+}
+
// GetChat retrieves chat by id if it's present in the cache
func (cache *Cache) GetChat(id int64) (*client.Chat, bool) {
cache.chatsLock.Lock()
@@ -67,6 +97,15 @@ func (cache *Cache) GetUser(id int32) (*client.User, bool) {
return user, ok
}
+// GetStatus retrieves status by id if it's present in the cache
+func (cache *Cache) GetStatus(id int64) (*Status, bool) {
+ cache.statusesLock.Lock()
+ defer cache.statusesLock.Unlock()
+
+ status, ok := cache.statuses[id]
+ return status, ok
+}
+
// SetChat stores a chat in the cache
func (cache *Cache) SetChat(id int64, chat *client.Chat) {
cache.chatsLock.Lock()
@@ -82,3 +121,15 @@ func (cache *Cache) SetUser(id int32, user *client.User) {
cache.users[id] = user
}
+
+// SetStatus stores a status in the cache
+func (cache *Cache) SetStatus(id int64, show string, status string) {
+ cache.statusesLock.Lock()
+ defer cache.statusesLock.Unlock()
+
+ cache.statuses[id] = &Status{
+ ID: id,
+ XMPP: show,
+ Description: status,
+ }
+}
diff --git a/telegram/handlers.go b/telegram/handlers.go
index aaa1e3d..aef8286 100644
--- a/telegram/handlers.go
+++ b/telegram/handlers.go
@@ -120,13 +120,13 @@ func (c *Client) updateHandler() {
func (c *Client) updateUser(update *client.UpdateUser) {
c.cache.SetUser(update.User.Id, update.User)
show, status := c.userStatusToText(update.User.Status)
- go c.processStatusUpdate(int64(update.User.Id), status, show)
+ go c.ProcessStatusUpdate(int64(update.User.Id), status, show)
}
// user status changed
func (c *Client) updateUserStatus(update *client.UpdateUserStatus) {
show, status := c.userStatusToText(update.Status)
- go c.processStatusUpdate(int64(update.UserId), status, show, gateway.SPImmed(false))
+ go c.ProcessStatusUpdate(int64(update.UserId), status, show, gateway.SPImmed(false))
}
// new chat discovered
@@ -166,7 +166,7 @@ func (c *Client) updateNewChat(update *client.UpdateNewChat) {
}
if update.Chat.Id < 0 {
- c.processStatusUpdate(update.Chat.Id, update.Chat.Title, "chat")
+ c.ProcessStatusUpdate(update.Chat.Id, update.Chat.Title, "chat")
}
}()
}
diff --git a/telegram/utils.go b/telegram/utils.go
index b3e815f..8de1f5f 100644
--- a/telegram/utils.go
+++ b/telegram/utils.go
@@ -14,6 +14,7 @@ import (
"strings"
"time"
+ "dev.narayana.im/narayana/telegabber/telegram/cache"
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
log "github.com/sirupsen/logrus"
@@ -129,8 +130,8 @@ func (c *Client) userStatusToText(status client.UserStatus) (string, string) {
return show, textStatus
}
-// set contact status
-func (c *Client) processStatusUpdate(chatID int64, status string, show string, args ...args.V) error {
+// ProcessStatusUpdate sets contact status
+func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, args ...args.V) error {
if !c.Online() {
return nil
}
@@ -171,6 +172,8 @@ func (c *Client) processStatusUpdate(chatID int64, status string, show string, a
}
}
+ c.cache.SetStatus(chatID, show, status)
+
gateway.SendPresence(
c.xmpp,
c.jid,
@@ -512,3 +515,8 @@ func (c *Client) ProcessOutgoingMessage(chatID int64, text string, messageID int
}
}
}
+
+// StatusesRange proxies the following function from unexported cache
+func (c *Client) StatusesRange() chan *cache.Status {
+ return c.cache.StatusesRange()
+}
diff --git a/xmpp/handlers.go b/xmpp/handlers.go
index 2addd7b..8778423 100644
--- a/xmpp/handlers.go
+++ b/xmpp/handlers.go
@@ -176,6 +176,15 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
err = session.Connect()
if err != nil {
log.Error(errors.Wrap(err, "TDlib connection failure"))
+ } else {
+ for status := range session.StatusesRange() {
+ go session.ProcessStatusUpdate(
+ status.ID,
+ status.XMPP,
+ status.Description,
+ gateway.SPImmed(false),
+ )
+ }
}
}()
}