1
0
Fork 0
forked from External/ergo
AWAY status should be tracked per-session:

1. With auto-away enabled, away status is aggregated across sessions
   (if any session is not away, the client is not away, else use
   the away status that was set most recently)
2. With auto-away disabled, we get the legacy behavior where AWAY
   applies directly to the client
This commit is contained in:
Shivaram Lingamneni 2021-03-18 02:53:18 -04:00
parent 507d53c507
commit 70b20750aa
4 changed files with 59 additions and 36 deletions

View file

@ -107,6 +107,7 @@ func (client *Client) AllSessionData(currentSession *Session, hasPrivs bool) (da
}
func (client *Client) AddSession(session *Session) (success bool, numSessions int, lastSeen time.Time, back bool) {
config := client.server.Config()
client.stateMutex.Lock()
defer client.stateMutex.Unlock()
@ -126,11 +127,12 @@ func (client *Client) AddSession(session *Session) (success bool, numSessions in
client.setLastSeen(time.Now().UTC(), session.deviceID)
}
client.sessions = newSessions
if client.autoAway {
back = true
client.autoAway = false
client.away = false
// TODO(#1551) there should be a cap to opt out of this behavior on a session
if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
client.awayMessage = ""
if len(client.sessions) == 1 {
back = true
}
}
return true, len(client.sessions), lastSeen, back
}
@ -196,20 +198,54 @@ func (client *Client) Hostname() string {
func (client *Client) Away() (result bool, message string) {
client.stateMutex.Lock()
result, message = client.away, client.awayMessage
message = client.awayMessage
client.stateMutex.Unlock()
result = client.awayMessage != ""
return
}
func (client *Client) SetAway(away bool, awayMessage string) (changed bool) {
func (session *Session) SetAway(awayMessage string) {
client := session.client
config := client.server.Config()
client.stateMutex.Lock()
changed = away != client.away
client.away = away
client.awayMessage = awayMessage
client.stateMutex.Unlock()
defer client.stateMutex.Unlock()
session.awayMessage = awayMessage
session.awayAt = time.Now().UTC()
autoAway := client.registered && client.alwaysOn && persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway)
if autoAway {
client.setAutoAwayNoMutex(config)
} else {
client.awayMessage = awayMessage
}
return
}
func (client *Client) setAutoAwayNoMutex(config *Config) {
// aggregate the away statuses of the individual sessions:
var globalAwayState string
var awaySetAt time.Time
for _, cSession := range client.sessions {
if cSession.awayMessage == "" {
// a session is active, we are not auto-away
client.awayMessage = ""
return
} else if cSession.awayAt.After(awaySetAt) {
// choose the latest available away message from any session
globalAwayState = cSession.awayMessage
awaySetAt = cSession.awayAt
}
}
if awaySetAt.IsZero() {
// no sessions, enable auto-away
client.awayMessage = config.languageManager.Translate(client.languages, `User is currently disconnected`)
} else {
client.awayMessage = globalAwayState
}
}
func (client *Client) AlwaysOn() (alwaysOn bool) {
client.stateMutex.RLock()
alwaysOn = client.registered && client.alwaysOn
@ -269,12 +305,6 @@ func (client *Client) AwayMessage() (result string) {
return
}
func (client *Client) SetAwayMessage(message string) {
client.stateMutex.Lock()
client.awayMessage = message
client.stateMutex.Unlock()
}
func (client *Client) Account() string {
client.stateMutex.RLock()
defer client.stateMutex.RUnlock()