forked from External/ergo
implement draft/pre-away (#2044)
* implement draft/pre-away * clean up some subtleties in auto-away aggregation. * consistently apply auto-away only to always-on * `AWAY *` should not produce user-visible changes wherever possible
This commit is contained in:
parent
12f7796933
commit
1da11ae8ae
8 changed files with 63 additions and 38 deletions
|
|
@ -92,7 +92,7 @@ func (client *Client) AllSessionData(currentSession *Session, hasPrivs bool) (da
|
|||
return
|
||||
}
|
||||
|
||||
func (client *Client) AddSession(session *Session) (success bool, numSessions int, lastSeen time.Time, back bool) {
|
||||
func (client *Client) AddSession(session *Session) (success bool, numSessions int, lastSeen time.Time, wasAway, nowAway string) {
|
||||
config := client.server.Config()
|
||||
client.stateMutex.Lock()
|
||||
defer client.stateMutex.Unlock()
|
||||
|
|
@ -113,14 +113,22 @@ func (client *Client) AddSession(session *Session) (success bool, numSessions in
|
|||
client.setLastSeen(time.Now().UTC(), session.deviceID)
|
||||
}
|
||||
client.sessions = newSessions
|
||||
// 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
|
||||
wasAway = client.awayMessage
|
||||
if client.autoAwayEnabledNoMutex(config) {
|
||||
client.setAutoAwayNoMutex(config)
|
||||
} else {
|
||||
if session.awayMessage != "" && session.awayMessage != "*" {
|
||||
// set the away message
|
||||
client.awayMessage = session.awayMessage
|
||||
} else if session.awayMessage == "" && !session.awayAt.IsZero() {
|
||||
// weird edge case: explicit `AWAY` or `AWAY :` during pre-registration makes the client back
|
||||
client.awayMessage = ""
|
||||
}
|
||||
// else: the client sent no AWAY command at all, no-op
|
||||
// or: the client sent `AWAY *`, which should not modify the publicly visible away state
|
||||
}
|
||||
return true, len(client.sessions), lastSeen, back
|
||||
nowAway = client.awayMessage
|
||||
return true, len(client.sessions), lastSeen, wasAway, nowAway
|
||||
}
|
||||
|
||||
func (client *Client) removeSession(session *Session) (success bool, length int) {
|
||||
|
|
@ -195,7 +203,7 @@ func (client *Client) Away() (result bool, message string) {
|
|||
return
|
||||
}
|
||||
|
||||
func (session *Session) SetAway(awayMessage string) {
|
||||
func (session *Session) SetAway(awayMessage string) (wasAway, nowAway string) {
|
||||
client := session.client
|
||||
config := client.server.Config()
|
||||
|
||||
|
|
@ -205,15 +213,21 @@ func (session *Session) SetAway(awayMessage string) {
|
|||
session.awayMessage = awayMessage
|
||||
session.awayAt = time.Now().UTC()
|
||||
|
||||
autoAway := client.registered && client.alwaysOn && persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway)
|
||||
if autoAway {
|
||||
wasAway = client.awayMessage
|
||||
if client.autoAwayEnabledNoMutex(config) {
|
||||
client.setAutoAwayNoMutex(config)
|
||||
} else {
|
||||
} else if awayMessage != "*" {
|
||||
client.awayMessage = awayMessage
|
||||
}
|
||||
} // else: `AWAY *`, should not modify publicly visible away state
|
||||
nowAway = client.awayMessage
|
||||
return
|
||||
}
|
||||
|
||||
func (client *Client) autoAwayEnabledNoMutex(config *Config) bool {
|
||||
return client.registered && client.alwaysOn &&
|
||||
persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway)
|
||||
}
|
||||
|
||||
func (client *Client) setAutoAwayNoMutex(config *Config) {
|
||||
// aggregate the away statuses of the individual sessions:
|
||||
var globalAwayState string
|
||||
|
|
@ -223,8 +237,8 @@ func (client *Client) setAutoAwayNoMutex(config *Config) {
|
|||
// 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
|
||||
} else if cSession.awayAt.After(awaySetAt) && cSession.awayMessage != "*" {
|
||||
// choose the latest valid away message from any session
|
||||
globalAwayState = cSession.awayMessage
|
||||
awaySetAt = cSession.awayAt
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue