Mark expired online statuses as away
This commit is contained in:
parent
8c20aaa30d
commit
3cdb625c5e
|
@ -34,6 +34,12 @@ func stringToLogConstant(c string) int32 {
|
|||
return level
|
||||
}
|
||||
|
||||
// DelayedStatus describes an online status expiring on timeout
|
||||
type DelayedStatus struct {
|
||||
TimestampOnline int64
|
||||
TimestampExpired int64
|
||||
}
|
||||
|
||||
// Client stores the metadata for lazily invoked TDlib instance
|
||||
type Client struct {
|
||||
client *client.Client
|
||||
|
@ -50,6 +56,9 @@ type Client struct {
|
|||
cache *cache.Cache
|
||||
online bool
|
||||
|
||||
DelayedStatuses map[int64]*DelayedStatus
|
||||
DelayedStatusesLock sync.Mutex
|
||||
|
||||
locks clientLocks
|
||||
}
|
||||
|
||||
|
@ -115,6 +124,7 @@ func NewClient(conf config.TelegramConfig, jid string, component *xmpp.Component
|
|||
content: &conf.Content,
|
||||
cache: cache.NewCache(),
|
||||
options: options,
|
||||
DelayedStatuses: make(map[int64]*DelayedStatus),
|
||||
locks: clientLocks{
|
||||
chatMessageLocks: make(map[int64]*sync.Mutex),
|
||||
},
|
||||
|
|
|
@ -119,13 +119,13 @@ func (c *Client) updateHandler() {
|
|||
// new user discovered
|
||||
func (c *Client) updateUser(update *client.UpdateUser) {
|
||||
c.cache.SetUser(update.User.Id, update.User)
|
||||
show, status := c.userStatusToText(update.User.Status)
|
||||
show, status := c.userStatusToText(update.User.Status, update.User.Id)
|
||||
go c.ProcessStatusUpdate(update.User.Id, status, show)
|
||||
}
|
||||
|
||||
// user status changed
|
||||
func (c *Client) updateUserStatus(update *client.UpdateUserStatus) {
|
||||
show, status := c.userStatusToText(update.Status)
|
||||
show, status := c.userStatusToText(update.Status, update.UserId)
|
||||
go c.ProcessStatusUpdate(update.UserId, status, show, gateway.SPImmed(false))
|
||||
}
|
||||
|
||||
|
|
|
@ -94,14 +94,27 @@ func (c *Client) GetContactByID(id int64, chat *client.Chat) (*client.Chat, *cli
|
|||
return chat, user, nil
|
||||
}
|
||||
|
||||
func (c *Client) userStatusToText(status client.UserStatus) (string, string) {
|
||||
func (c *Client) userStatusToText(status client.UserStatus, chatID int64) (string, string) {
|
||||
var show, textStatus string
|
||||
|
||||
switch status.UserStatusType() {
|
||||
case client.TypeUserStatusOnline:
|
||||
onlineStatus, _ := status.(*client.UserStatusOnline)
|
||||
|
||||
c.DelayedStatusesLock.Lock()
|
||||
c.DelayedStatuses[chatID] = &DelayedStatus{
|
||||
TimestampOnline: time.Now().Unix(),
|
||||
TimestampExpired: int64(onlineStatus.Expires),
|
||||
}
|
||||
c.DelayedStatusesLock.Unlock()
|
||||
|
||||
textStatus = "Online"
|
||||
case client.TypeUserStatusRecently:
|
||||
show, textStatus = "dnd", "Last seen recently"
|
||||
|
||||
c.DelayedStatusesLock.Lock()
|
||||
delete(c.DelayedStatuses, chatID)
|
||||
c.DelayedStatusesLock.Unlock()
|
||||
case client.TypeUserStatusLastWeek:
|
||||
show, textStatus = "unavailable", "Last seen last week"
|
||||
case client.TypeUserStatusLastMonth:
|
||||
|
@ -111,20 +124,30 @@ func (c *Client) userStatusToText(status client.UserStatus) (string, string) {
|
|||
case client.TypeUserStatusOffline:
|
||||
offlineStatus, _ := status.(*client.UserStatusOffline)
|
||||
// this will stop working in 2038 O\
|
||||
elapsed := time.Now().Unix() - int64(offlineStatus.WasOnline)
|
||||
wasOnline := int64(offlineStatus.WasOnline)
|
||||
elapsed := time.Now().Unix() - wasOnline
|
||||
if elapsed < 3600 {
|
||||
show = "away"
|
||||
} else {
|
||||
show = "xa"
|
||||
}
|
||||
textStatus = time.Unix(int64(offlineStatus.WasOnline), 0).
|
||||
In(c.Session.TimezoneToLocation()).
|
||||
Format("Last seen at 15:04 02/01/2006")
|
||||
textStatus = c.LastSeenStatus(wasOnline)
|
||||
|
||||
c.DelayedStatusesLock.Lock()
|
||||
delete(c.DelayedStatuses, chatID)
|
||||
c.DelayedStatusesLock.Unlock()
|
||||
}
|
||||
|
||||
return show, textStatus
|
||||
}
|
||||
|
||||
// LastSeenStatus formats a timestamp to a "Last seen at" string
|
||||
func (c *Client) LastSeenStatus(timestamp int64) string {
|
||||
return time.Unix(int64(timestamp), 0).
|
||||
In(c.Session.TimezoneToLocation()).
|
||||
Format("Last seen at 15:04 02/01/2006")
|
||||
}
|
||||
|
||||
// ProcessStatusUpdate sets contact status
|
||||
func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, args ...args.V) error {
|
||||
if !c.Online() {
|
||||
|
@ -161,7 +184,7 @@ func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, a
|
|||
|
||||
if status == "" {
|
||||
if user != nil {
|
||||
show, status = c.userStatusToText(user.Status)
|
||||
show, status = c.userStatusToText(user.Status, chatID)
|
||||
} else {
|
||||
show, status = "chat", chat.Title
|
||||
}
|
||||
|
|
|
@ -85,6 +85,25 @@ func heartbeat(component *xmpp.Component) {
|
|||
// status updater thread
|
||||
for {
|
||||
time.Sleep(60e9)
|
||||
now := time.Now().Unix()
|
||||
|
||||
sessionLock.Lock()
|
||||
for _, session := range sessions {
|
||||
session.DelayedStatusesLock.Lock()
|
||||
for chatID, delayedStatus := range session.DelayedStatuses {
|
||||
if delayedStatus.TimestampExpired <= now {
|
||||
go session.ProcessStatusUpdate(
|
||||
chatID,
|
||||
session.LastSeenStatus(delayedStatus.TimestampOnline),
|
||||
"away",
|
||||
)
|
||||
delete(session.DelayedStatuses, chatID)
|
||||
}
|
||||
}
|
||||
session.DelayedStatusesLock.Unlock()
|
||||
}
|
||||
sessionLock.Unlock()
|
||||
|
||||
for key, presence := range gateway.Queue {
|
||||
err = gateway.ResumableSend(component, presence)
|
||||
if err != nil {
|
||||
|
|
|
@ -189,8 +189,8 @@ func handlePresence(s xmpp.Sender, p stanza.Presence) {
|
|||
for status := range session.StatusesRange() {
|
||||
go session.ProcessStatusUpdate(
|
||||
status.ID,
|
||||
status.XMPP,
|
||||
status.Description,
|
||||
status.XMPP,
|
||||
gateway.SPImmed(false),
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue