forked from External/ergo
fix #1531
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:
parent
507d53c507
commit
70b20750aa
4 changed files with 59 additions and 36 deletions
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue