mirror of
https://github.com/ergochat/ergo.git
synced 2025-02-16 13:40:48 +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.
|
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
|
### +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).
|
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
|
accountName string // display name of the account: uncasefolded, '*' if not logged in
|
||||||
accountRegDate time.Time
|
accountRegDate time.Time
|
||||||
accountSettings AccountSettings
|
accountSettings AccountSettings
|
||||||
away bool
|
|
||||||
autoAway bool
|
|
||||||
awayMessage string
|
awayMessage string
|
||||||
brbTimer BrbTimer
|
brbTimer BrbTimer
|
||||||
channels ChannelSet
|
channels ChannelSet
|
||||||
@ -177,6 +175,9 @@ type Session struct {
|
|||||||
|
|
||||||
quitMessage string
|
quitMessage string
|
||||||
|
|
||||||
|
awayMessage string
|
||||||
|
awayAt time.Time
|
||||||
|
|
||||||
capabilities caps.Set
|
capabilities caps.Set
|
||||||
capState caps.State
|
capState caps.State
|
||||||
capVersion caps.Version
|
capVersion caps.Version
|
||||||
@ -486,8 +487,6 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, channelToStatus m
|
|||||||
}
|
}
|
||||||
|
|
||||||
if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
||||||
client.autoAway = true
|
|
||||||
client.away = true
|
|
||||||
client.awayMessage = client.t("User is currently disconnected")
|
client.awayMessage = client.t("User is currently disconnected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,7 +674,7 @@ func (client *Client) run(session *Session) {
|
|||||||
session.playResume()
|
session.playResume()
|
||||||
session.resumeDetails = nil
|
session.resumeDetails = nil
|
||||||
client.brbTimer.Disable()
|
client.brbTimer.Disable()
|
||||||
client.SetAway(false, "") // clear BRB message if any
|
session.SetAway("") // clear BRB message if any
|
||||||
} else {
|
} else {
|
||||||
client.playReattachMessages(session)
|
client.playReattachMessages(session)
|
||||||
}
|
}
|
||||||
@ -1458,15 +1457,13 @@ func (client *Client) destroy(session *Session) {
|
|||||||
client.dirtyBits |= IncludeLastSeen
|
client.dirtyBits |= IncludeLastSeen
|
||||||
}
|
}
|
||||||
|
|
||||||
autoAway := false
|
becameAutoAway := false
|
||||||
var awayMessage string
|
var awayMessage string
|
||||||
if alwaysOn && !client.away && remainingSessions == 0 &&
|
if alwaysOn && persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
||||||
persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
wasAway := client.awayMessage != ""
|
||||||
autoAway = true
|
client.setAutoAwayNoMutex(config)
|
||||||
client.autoAway = true
|
awayMessage = client.awayMessage
|
||||||
client.away = true
|
becameAutoAway = !wasAway && awayMessage != ""
|
||||||
awayMessage = config.languageManager.Translate(client.languages, `User is currently disconnected`)
|
|
||||||
client.awayMessage = awayMessage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if client.registrationTimer != nil {
|
if client.registrationTimer != nil {
|
||||||
@ -1523,7 +1520,7 @@ func (client *Client) destroy(session *Session) {
|
|||||||
client.server.stats.Remove(registered, invisible, operator)
|
client.server.stats.Remove(registered, invisible, operator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if autoAway {
|
if becameAutoAway {
|
||||||
dispatchAwayNotify(client, true, awayMessage)
|
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) {
|
func (client *Client) AddSession(session *Session) (success bool, numSessions int, lastSeen time.Time, back bool) {
|
||||||
|
config := client.server.Config()
|
||||||
client.stateMutex.Lock()
|
client.stateMutex.Lock()
|
||||||
defer client.stateMutex.Unlock()
|
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.setLastSeen(time.Now().UTC(), session.deviceID)
|
||||||
}
|
}
|
||||||
client.sessions = newSessions
|
client.sessions = newSessions
|
||||||
if client.autoAway {
|
// TODO(#1551) there should be a cap to opt out of this behavior on a session
|
||||||
back = true
|
if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
||||||
client.autoAway = false
|
|
||||||
client.away = false
|
|
||||||
client.awayMessage = ""
|
client.awayMessage = ""
|
||||||
|
if len(client.sessions) == 1 {
|
||||||
|
back = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true, len(client.sessions), lastSeen, back
|
return true, len(client.sessions), lastSeen, back
|
||||||
}
|
}
|
||||||
@ -196,20 +198,54 @@ func (client *Client) Hostname() string {
|
|||||||
|
|
||||||
func (client *Client) Away() (result bool, message string) {
|
func (client *Client) Away() (result bool, message string) {
|
||||||
client.stateMutex.Lock()
|
client.stateMutex.Lock()
|
||||||
result, message = client.away, client.awayMessage
|
message = client.awayMessage
|
||||||
client.stateMutex.Unlock()
|
client.stateMutex.Unlock()
|
||||||
|
result = client.awayMessage != ""
|
||||||
return
|
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()
|
client.stateMutex.Lock()
|
||||||
changed = away != client.away
|
defer client.stateMutex.Unlock()
|
||||||
client.away = away
|
|
||||||
client.awayMessage = awayMessage
|
session.awayMessage = awayMessage
|
||||||
client.stateMutex.Unlock()
|
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
|
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) {
|
func (client *Client) AlwaysOn() (alwaysOn bool) {
|
||||||
client.stateMutex.RLock()
|
client.stateMutex.RLock()
|
||||||
alwaysOn = client.registered && client.alwaysOn
|
alwaysOn = client.registered && client.alwaysOn
|
||||||
@ -269,12 +305,6 @@ func (client *Client) AwayMessage() (result string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) SetAwayMessage(message string) {
|
|
||||||
client.stateMutex.Lock()
|
|
||||||
client.awayMessage = message
|
|
||||||
client.stateMutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (client *Client) Account() string {
|
func (client *Client) Account() string {
|
||||||
client.stateMutex.RLock()
|
client.stateMutex.RLock()
|
||||||
defer client.stateMutex.RUnlock()
|
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 {
|
if isAway {
|
||||||
rb.Add(nil, server.name, RPL_NOWAWAY, client.nick, client.t("You have been marked as being away"))
|
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 {
|
if len(client.Sessions()) == 1 {
|
||||||
// true BRB
|
// true BRB
|
||||||
client.SetAway(true, message)
|
rb.session.SetAway(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user