From 4b2969925bfee6c54afa1b8097177e8b931b8106 Mon Sep 17 00:00:00 2001
From: Bohdan Horbeshko <bodqhrohro@gmail.com>
Date: Sat, 5 Feb 2022 05:21:56 -0500
Subject: Fix status caching and send status on subscription

---
 telegram/utils.go |  5 +++-
 xmpp/handlers.go  | 82 +++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 60 insertions(+), 27 deletions(-)

diff --git a/telegram/utils.go b/telegram/utils.go
index 87176fc..6d668b3 100644
--- a/telegram/utils.go
+++ b/telegram/utils.go
@@ -194,8 +194,11 @@ func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, a
 		}
 	}
 
+	cachedStatus, ok := c.cache.GetStatus(chatID)
 	if status == "" {
-		if user != nil {
+		if ok {
+			show, status = cachedStatus.XMPP, cachedStatus.Description
+		} else if user != nil && user.Status != nil {
 			show, status = c.userStatusToText(user.Status, chatID)
 		} else {
 			show, status = "chat", chat.Title
diff --git a/xmpp/handlers.go b/xmpp/handlers.go
index 5db8df6..0f4b949 100644
--- a/xmpp/handlers.go
+++ b/xmpp/handlers.go
@@ -60,32 +60,24 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) {
 		}).Warn("Message")
 		log.Debugf("%#v", msg)
 
-		fromJid, err := stanza.NewJid(msg.From)
-		if err != nil {
-			log.Error("Invalid from JID!")
+		bare, resource, ok := splitFrom(msg.From)
+		if !ok {
 			return
 		}
 
-		session, ok := sessions[fromJid.Bare()]
+		session, ok := sessions[bare]
 		if !ok {
 			log.Error("Message from stranger")
 			return
 		}
 
-		toParts := strings.Split(msg.To, "@")
-		toID := toParts[0]
-		if len(toParts) > 1 {
-			toIDInt, err := strconv.ParseInt(toID, 10, 64)
-			if err == nil {
-				session.ProcessOutgoingMessage(toIDInt, msg.Body, msg.From)
-				return
-			}
-			log.WithFields(log.Fields{
-				"toID": toID,
-			}).Error(errors.Wrap(err, "Invalid to JID!"))
-		} else if toID == gateway.Jid.Bare() {
+		toID, ok := toToID(msg.To)
+		if ok {
+			session.ProcessOutgoingMessage(toID, msg.Body, msg.From)
+			return
+		} else if msg.To == gateway.Jid.Bare() {
 			if strings.HasPrefix(msg.Body, "/") {
-				response := session.ProcessTransportCommand(msg.Body, fromJid.Resource)
+				response := session.ProcessTransportCommand(msg.Body, resource)
 				if response != "" {
 					gateway.SendMessage(msg.From, "", response, component)
 				}
@@ -133,6 +125,20 @@ func handleSubscription(s xmpp.Sender, p stanza.Presence) {
 	}
 
 	_ = gateway.ResumableSend(component, reply)
+
+	toID, ok := toToID(p.To)
+	if !ok {
+		return
+	}
+	bare, _, ok := splitFrom(p.From)
+	if !ok {
+		return
+	}
+	session, ok := getTelegramInstance(bare, &persistence.Session{}, component)
+	if !ok {
+		return
+	}
+	go session.ProcessStatusUpdate(toID, "", "", gateway.SPImmed(false))
 }
 
 func handlePresence(s xmpp.Sender, p stanza.Presence) {
@@ -155,13 +161,11 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
 	log.Debugf("%#v", p)
 
 	// create session
-	fromJid, err := stanza.NewJid(p.From)
-	if err != nil {
-		log.Error("Invalid from JID!")
+	bare, resource, ok := splitFrom(p.From)
+	if !ok {
 		return
 	}
-	bareFromJid := fromJid.Bare()
-	session, ok := getTelegramInstance(bareFromJid, &persistence.Session{}, component)
+	session, ok := getTelegramInstance(bare, &persistence.Session{}, component)
 	if !ok {
 		return
 	}
@@ -169,20 +173,20 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
 	switch p.Type {
 	// destroy session
 	case "unsubscribed", "unsubscribe":
-		if session.Disconnect(fromJid.Resource, false) {
+		if session.Disconnect(resource, false) {
 			sessionLock.Lock()
-			delete(sessions, bareFromJid)
+			delete(sessions, bare)
 			sessionLock.Unlock()
 		}
 	// go offline
 	case "unavailable", "error":
-		session.Disconnect(fromJid.Resource, false)
+		session.Disconnect(resource, false)
 	// go online
 	case "probe", "", "online":
 		// due to the weird implementation of go-tdlib wrapper, it won't
 		// return the client instance until successful authorization
 		go func() {
-			err = session.Connect(fromJid.Resource)
+			err := session.Connect(resource)
 			if err != nil {
 				log.Error(errors.Wrap(err, "TDlib connection failure"))
 			} else {
@@ -290,3 +294,29 @@ func handleGetVcardTempIq(s xmpp.Sender, iq *stanza.IQ) {
 
 	_ = gateway.ResumableSend(component, &answer)
 }
+
+func splitFrom(from string) (string, string, bool) {
+	fromJid, err := stanza.NewJid(from)
+	if err != nil {
+		log.WithFields(log.Fields{
+			"from": from,
+		}).Error(errors.Wrap(err, "Invalid from JID!"))
+		return "", "", false
+	}
+	return fromJid.Bare(), fromJid.Resource, true
+}
+
+func toToID(to string) (int64, bool) {
+	toParts := strings.Split(to, "@")
+	if len(toParts) < 2 {
+		return 0, false
+	}
+	toID, err := strconv.ParseInt(toParts[0], 10, 64)
+	if err != nil {
+		log.WithFields(log.Fields{
+			"to": to,
+		}).Error(errors.Wrap(err, "Invalid to JID!"))
+		return 0, false
+	}
+	return toID, true
+}
-- 
cgit v1.2.3