core: Limit "User is away" to 1hr or when changed
authorShane Synan <digitalcircuit36939@gmail.com>
Thu, 23 Aug 2018 02:36:47 +0000 (21:36 -0500)
committerManuel Nickschas <sputnick@quassel-irc.org>
Tue, 28 Aug 2018 20:43:11 +0000 (22:43 +0200)
Increase the "* User is away" silencing to one hour, and add tracking
for changes in away state.  Only print the "* User is away" if away
state has changed since last away message (including removing and
applying the same away message), or if 1 hour has elapsed.

This reduces the spamming of "* User is away" when one often knows
that, yes, the user is away.  Any change in away state or message
will still be shown.

src/common/ircuser.cpp
src/common/ircuser.h
src/core/eventstringifier.cpp

index 5018911..6133e43 100644 (file)
@@ -165,6 +165,7 @@ void IrcUser::setAway(const bool &away)
 {
     if (away != _away) {
         _away = away;
 {
     if (away != _away) {
         _away = away;
+        markAwayChanged();
         SYNC(ARG(away))
         emit awaySet(away);
     }
         SYNC(ARG(away))
         emit awaySet(away);
     }
@@ -175,6 +176,7 @@ void IrcUser::setAwayMessage(const QString &awayMessage)
 {
     if (!awayMessage.isEmpty() && _awayMessage != awayMessage) {
         _awayMessage = awayMessage;
 {
     if (!awayMessage.isEmpty() && _awayMessage != awayMessage) {
         _awayMessage = awayMessage;
+        markAwayChanged();
         SYNC(ARG(awayMessage))
     }
 }
         SYNC(ARG(awayMessage))
     }
 }
index 9d203e5..b217688 100644 (file)
@@ -106,6 +106,31 @@ public :
     inline QDateTime lastSpokenTo(BufferId id) const { return _lastSpokenTo.value(id); }
     void setLastSpokenTo(BufferId id, const QDateTime &time);
 
     inline QDateTime lastSpokenTo(BufferId id) const { return _lastSpokenTo.value(id); }
     void setLastSpokenTo(BufferId id, const QDateTime &time);
 
+    /**
+     * Gets whether or not the away state has changed since it was last acknowledged
+     *
+     * Away state is marked as changed by any modification to away status (away/here, message)
+     *
+     * NOTE: On servers lacking support for IRCv3 away-notify, this won't update until an autoWHO-
+     * run for away/here changes, or until sending a message to the user for away message changes.
+     *
+     * @see IrcUser::acknowledgeAwayChanged()
+     *
+     * @return True if current away state is unchanged from last acknowledgement, otherwise false
+     */
+    inline bool hasAwayChanged() const { return _awayChanged; }
+
+    /**
+     * Sets the last away state change as acknowledged
+     *
+     * @see IrcUser::hasAwayChanged()
+     */
+    inline void acknowledgeAwayChanged()
+    {
+        // Don't sync this as individual clients may suppress different kinds of behaviors
+        _awayChanged = false;
+    }
+
 public slots:
     void setUser(const QString &user);
     void setHost(const QString &host);
 public slots:
     void setUser(const QString &user);
     void setHost(const QString &host);
@@ -191,6 +216,15 @@ private:
         return (_nick.toLower() == nickname.toLower());
     }
 
         return (_nick.toLower() == nickname.toLower());
     }
 
+    /**
+     * Sets the last away state change as unacknowledged
+     *
+     * @see IrcUser::hasAwayChanged()
+     */
+    inline void markAwayChanged()
+    {
+        _awayChanged = true;
+    }
 
     bool _initialized;
 
 
     bool _initialized;
 
@@ -222,6 +256,10 @@ private:
 
     QHash<BufferId, QDateTime> _lastActivity;
     QHash<BufferId, QDateTime> _lastSpokenTo;
 
     QHash<BufferId, QDateTime> _lastActivity;
     QHash<BufferId, QDateTime> _lastSpokenTo;
+
+    // Given it's never been acknowledged, assume changes exist on IrcUser creation
+    /// Tracks if changes in away state (away/here, message) have yet to be acknowledged
+    bool _awayChanged = true;
 };
 
 
 };
 
 
index f43e547..b8c67b9 100644 (file)
@@ -453,10 +453,18 @@ void EventStringifier::processIrcEvent301(IrcEvent *e)
             QDateTime now = QDateTime::currentDateTime();
             now.setTimeSpec(Qt::UTC);
             // Don't print "user is away" messages more often than this
             QDateTime now = QDateTime::currentDateTime();
             now.setTimeSpec(Qt::UTC);
             // Don't print "user is away" messages more often than this
-            const int silenceTime = 60;
-            if (ircuser->lastAwayMessageTime().addSecs(silenceTime) >= now)
+            // 1 hour = 60 min * 60 sec
+            const int silenceTime = 60 * 60;
+            // Check if away state has NOT changed and silence time hasn't yet elapsed
+            if (!ircuser->hasAwayChanged()
+                    && ircuser->lastAwayMessageTime().addSecs(silenceTime) >= now) {
+                // Away message hasn't changed and we're still within the period of silence; don't
+                // repeat the message
                 send = false;
                 send = false;
+            }
             ircuser->setLastAwayMessageTime(now);
             ircuser->setLastAwayMessageTime(now);
+            // Mark any changes in away as acknowledged
+            ircuser->acknowledgeAwayChanged();
         }
     }
     if (send)
         }
     }
     if (send)