mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-11 06:29:29 +01:00
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
@ -621,10 +621,6 @@ In this section, we give an overview of the modes Oragono supports.
|
||||
|
||||
These are the modes which can be set on you when you're connected.
|
||||
|
||||
### +a - Away
|
||||
|
||||
If this mode is set, you're marked as being away. This mode is set with the /AWAY command.
|
||||
|
||||
### +i - Invisible
|
||||
|
||||
If this mode is set, you're marked as 'invisible'. This means that your channels won't be shown when users `/WHOIS` you (except for IRC operators, they can see all the channels you're in).
|
||||
|
@ -78,8 +78,6 @@ type Client struct {
|
||||
accountName string // display name of the account: uncasefolded, '*' if not logged in
|
||||
accountRegDate time.Time
|
||||
accountSettings AccountSettings
|
||||
away bool
|
||||
autoAway bool
|
||||
awayMessage string
|
||||
brbTimer BrbTimer
|
||||
channels ChannelSet
|
||||
@ -177,6 +175,9 @@ type Session struct {
|
||||
|
||||
quitMessage string
|
||||
|
||||
awayMessage string
|
||||
awayAt time.Time
|
||||
|
||||
capabilities caps.Set
|
||||
capState caps.State
|
||||
capVersion caps.Version
|
||||
@ -486,8 +487,6 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, channelToStatus m
|
||||
}
|
||||
|
||||
if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
||||
client.autoAway = true
|
||||
client.away = true
|
||||
client.awayMessage = client.t("User is currently disconnected")
|
||||
}
|
||||
}
|
||||
@ -675,7 +674,7 @@ func (client *Client) run(session *Session) {
|
||||
session.playResume()
|
||||
session.resumeDetails = nil
|
||||
client.brbTimer.Disable()
|
||||
client.SetAway(false, "") // clear BRB message if any
|
||||
session.SetAway("") // clear BRB message if any
|
||||
} else {
|
||||
client.playReattachMessages(session)
|
||||
}
|
||||
@ -1458,15 +1457,13 @@ func (client *Client) destroy(session *Session) {
|
||||
client.dirtyBits |= IncludeLastSeen
|
||||
}
|
||||
|
||||
autoAway := false
|
||||
becameAutoAway := false
|
||||
var awayMessage string
|
||||
if alwaysOn && !client.away && remainingSessions == 0 &&
|
||||
persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
||||
autoAway = true
|
||||
client.autoAway = true
|
||||
client.away = true
|
||||
awayMessage = config.languageManager.Translate(client.languages, `User is currently disconnected`)
|
||||
client.awayMessage = awayMessage
|
||||
if alwaysOn && persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
||||
wasAway := client.awayMessage != ""
|
||||
client.setAutoAwayNoMutex(config)
|
||||
awayMessage = client.awayMessage
|
||||
becameAutoAway = !wasAway && awayMessage != ""
|
||||
}
|
||||
|
||||
if client.registrationTimer != nil {
|
||||
@ -1523,7 +1520,7 @@ func (client *Client) destroy(session *Session) {
|
||||
client.server.stats.Remove(registered, invisible, operator)
|
||||
}
|
||||
|
||||
if autoAway {
|
||||
if becameAutoAway {
|
||||
dispatchAwayNotify(client, true, awayMessage)
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -352,7 +352,7 @@ func awayHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
|
||||
}
|
||||
}
|
||||
|
||||
client.SetAway(isAway, awayMessage)
|
||||
rb.session.SetAway(awayMessage)
|
||||
|
||||
if isAway {
|
||||
rb.Add(nil, server.name, RPL_NOWAWAY, client.nick, client.t("You have been marked as being away"))
|
||||
@ -439,7 +439,7 @@ func brbHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
|
||||
|
||||
if len(client.Sessions()) == 1 {
|
||||
// true BRB
|
||||
client.SetAway(true, message)
|
||||
rb.session.SetAway(message)
|
||||
}
|
||||
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user