bool canOsXSendUserNotification();
void sendOsXUserNotification(const QString &title, const QString &message);
void sendOsXUpdateNotification(const QString &title, const QString &message, const QUrl &webUrl);
+void sendOsXTalkNotification(const QString &title, const QString &message, const QString &token, const QString &replyTo, const AccountStatePtr accountState);
void setTrayWindowLevelAndVisibleOnAllSpaces(QWindow *window);
double menuBarThickness();
#endif
void showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon icon = Information);
void showUpdateMessage(const QString &title, const QString &message, const QUrl &webUrl);
+ void showTalkMessage(const QString &title, const QString &message, const QString &replyTo, const QString &token, const AccountStatePtr &accountState);
void setToolTip(const QString &tip);
void createCallDialog(const OCC::Activity &callNotification, const OCC::AccountStatePtr accountState);
connect(this, &User::sendReplyMessage, this, &User::slotSendReplyMessage);
}
+void User::checkNotifiedNotifications()
+{
+ // after one hour, clear the gui log notification store
+ constexpr qint64 clearGuiLogInterval = 60 * 60 * 1000;
+ if (_guiLogTimer.elapsed() > clearGuiLogInterval) {
+ _notifiedNotifications.clear();
+ }
+}
+
+bool User::notificationAlreadyShown(const long notificationId)
+{
+ checkNotifiedNotifications();
+ return _notifiedNotifications.contains(notificationId);
+}
+
+bool User::canShowNotification(const long notificationId)
+{
+ ConfigFile cfg;
+ return cfg.optionalServerNotifications() &&
+ isDesktopNotificationsAllowed() &&
+ !notificationAlreadyShown(notificationId);
+}
+
void User::showDesktopNotification(const QString &title, const QString &message, const long notificationId)
{
+ if(!canShowNotification(notificationId)) {
+ return;
+ }
+
+ _notifiedNotifications.insert(notificationId);
+ Logger::instance()->postGuiLog(title, message);
+ // restart the gui log timer now that we show a new notification
+ _guiLogTimer.start();
+}
+
+void User::showDesktopNotification(const Activity &activity)
+{
+ const auto notificationId = activity._id;
+ const auto message = AccountManager::instance()->accounts().count() == 1 ? "" : activity._accName;
+ showDesktopNotification(activity._subject, message, notificationId);
+}
+
+void User::showDesktopNotification(const ActivityList &activityList)
+{
+ const auto subject = QStringLiteral("%1 notifications").arg(activityList.count());
+ const auto notificationId = -static_cast<int>(qHash(subject));
+
+ if (!canShowNotification(notificationId)) {
+ return;
+ }
+
+ const auto multipleAccounts = AccountManager::instance()->accounts().count() > 1;
+ const auto message = multipleAccounts ? activityList.constFirst()._accName : QString();
+
// Notification ids are uints, which are 4 bytes. Error activities don't have ids, however, so we generate one.
// To avoid possible collisions between the activity ids which are actually the notification ids received from
// the server (which are always positive) and our "fake" error activity ids, we assign a negative id to the
//
// To ensure that we can still treat an unsigned int as normal, we use a long, which is 8 bytes.
- ConfigFile cfg;
- if (!cfg.optionalServerNotifications() || !isDesktopNotificationsAllowed()) {
- return;
+ Logger::instance()->postGuiLog(subject, message);
+
+ for(const auto &activity : activityList) {
+ _notifiedNotifications.insert(activity._id);
+ _activityModel->addNotificationToActivityList(activity);
}
+}
- // after one hour, clear the gui log notification store
- constexpr qint64 clearGuiLogInterval = 60 * 60 * 1000;
- if (_guiLogTimer.elapsed() > clearGuiLogInterval) {
- _notifiedNotifications.clear();
+void User::showDesktopTalkNotification(const Activity &activity)
+{
+ const auto notificationId = activity._id;
+
+ if (!canShowNotification(notificationId)) {
+ return;
}
- if (_notifiedNotifications.contains(notificationId)) {
+ if (activity._talkNotificationData.messageId.isEmpty()) {
+ showDesktopNotification(activity._subject, activity._message, notificationId);
return;
}
_notifiedNotifications.insert(notificationId);
- Logger::instance()->postGuiLog(title, message);
- // restart the gui log timer now that we show a new notification
+ _activityModel->addNotificationToActivityList(activity);
+
+ Systray::instance()->showTalkMessage(activity._subject,
+ activity._message,
+ activity._talkNotificationData.conversationToken,
+ activity._talkNotificationData.messageId,
+ _account);
_guiLogTimer.start();
}
void User::slotBuildNotificationDisplay(const ActivityList &list)
{
- const auto multipleAccounts = AccountManager::instance()->accounts().count() > 1;
ActivityList toNotifyList;
std::copy_if(list.constBegin(), list.constEnd(), std::back_inserter(toNotifyList), [&](const Activity &activity) {
});
if(toNotifyList.count() > 2) {
- const auto subject = QStringLiteral("%1 notifications").arg(toNotifyList.count());
- const auto message = multipleAccounts ? toNotifyList.constFirst()._accName : QString();
- showDesktopNotification(subject, message, -static_cast<int>(qHash(subject)));
-
- // Set these activities as notified here, rather than in showDesktopNotification
- for(const auto &activity : qAsConst(toNotifyList)) {
- _notifiedNotifications.insert(activity._id);
- _activityModel->addNotificationToActivityList(activity);
- }
-
+ showDesktopNotification(toNotifyList);
return;
}
for(const auto &activity : qAsConst(toNotifyList)) {
- const auto message = activity._objectType == QStringLiteral("chat")
- ? activity._message : AccountManager::instance()->accounts().count() == 1 ? "" : activity._accName;
-
- showDesktopNotification(activity._subject, message, activity._id); // We assigned the notif. id to the activity id
- _activityModel->addNotificationToActivityList(activity);
+ if (activity._objectType == QStringLiteral("chat")) {
+ showDesktopTalkNotification(activity);
+ } else {
+ showDesktopNotification(activity);
+ }
}
}
// add 'other errors' to activity list
_activityModel->addErrorToActivityList(activity);
- showDesktopNotification(activity._subject, activity._message, activity._id);
+ showDesktopNotification(activity);
if (!_expiredActivitiesCheckTimer.isActive()) {
_expiredActivitiesCheckTimer.start(expiredActivitiesCheckIntervalMsecs);
void slotSendReplyMessage(const int activityIndex, const QString &conversationToken, const QString &message, const QString &replyTo);
void forceSyncNow() const;
-private:
+private slots:
void slotPushNotificationsReady();
void slotDisconnectPushNotifications();
void slotReceivedPushNotification(Account *account);
void slotReceivedPushActivity(Account *account);
void slotCheckExpiredActivities();
+ void checkNotifiedNotifications();
+ void showDesktopNotification(const QString &title, const QString &message, const long notificationId);
+ void showDesktopNotification(const Activity &activity);
+ void showDesktopNotification(const ActivityList &activityList);
+ void showDesktopTalkNotification(const Activity &activity);
+
+private:
void connectPushNotifications() const;
[[nodiscard]] bool checkPushNotificationsAreReady() const;
bool isActivityOfCurrentAccount(const Folder *folder) const;
[[nodiscard]] bool isUnsolvableConflict(const SyncFileItemPtr &item) const;
- void showDesktopNotification(const QString &title, const QString &message, const long notificationId);
+ bool notificationAlreadyShown(const long notificationId);
+ bool canShowNotification(const long notificationId);
-private:
AccountStatePtr _account;
bool _isCurrentUser;
ActivityListModel *_activityModel;