Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable-3.9] Fix crash and incorrect implementation of seen chat notofications removal #5897

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/windows-build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

- uses: actions/setup-python@v1
with:
python-version: '3.8'
- name: Install Craft Master with Nextcloud Client Deps
shell: pwsh
run: |
Expand Down
7 changes: 6 additions & 1 deletion src/gui/tray/activitylistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,11 +642,16 @@ void ActivityListModel::removeActivityFromActivityList(const Activity &activity)

void ActivityListModel::checkAndRemoveSeenActivities(const OCC::ActivityList &newActivities)
{
ActivityList activitiesToRemove;
for (const auto &activity : _finalList) {
if (activity._objectType == QStringLiteral("chat") && !newActivities.contains(activity)) {
removeActivityFromActivityList(activity);
activitiesToRemove.push_back(activity);
}
}

for (const auto &toRemove : activitiesToRemove) {
removeActivityFromActivityList(toRemove);
}
}

void ActivityListModel::slotTriggerDefaultAction(const int activityIndex)
Expand Down
10 changes: 7 additions & 3 deletions src/gui/tray/notificationhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ ServerNotificationHandler::ServerNotificationHandler(AccountState *accountState,
{
}

void ServerNotificationHandler::slotFetchNotifications()
bool ServerNotificationHandler::startFetchNotifications()
{
// check connectivity and credentials
if (!(_accountState && _accountState->isConnected() && _accountState->account() && _accountState->account()->credentials() && _accountState->account()->credentials()->ready())) {
deleteLater();
return;
return false;
}
// check if the account has notifications enabled. If the capabilities are
// not yet valid, its assumed that notifications are available.
if (_accountState->account()->capabilities().isValid()) {
if (!_accountState->account()->capabilities().notificationsAvailable()) {
qCInfo(lcServerNotification) << "Account" << _accountState->account()->displayName() << "does not have notifications enabled.";
deleteLater();
return;
return false;
}
}

Expand All @@ -50,6 +50,7 @@ void ServerNotificationHandler::slotFetchNotifications()
_notificationJob->setProperty(propertyAccountStateC, QVariant::fromValue<AccountState *>(_accountState));
_notificationJob->addRawHeader("If-None-Match", _accountState->notificationsEtagResponseHeader());
_notificationJob->start();
return true;
}

void ServerNotificationHandler::slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode)
Expand All @@ -66,12 +67,14 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j
if (statusCode != successStatusCode && statusCode != notModifiedStatusCode) {
qCWarning(lcServerNotification) << "Notifications failed with status code " << statusCode;
deleteLater();
emit jobFinished();
return;
}

if (statusCode == notModifiedStatusCode) {
qCWarning(lcServerNotification) << "Status code " << statusCode << " Not Modified - No new notifications.";
deleteLater();
emit jobFinished();
return;
}

Expand Down Expand Up @@ -170,6 +173,7 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j
}
emit newNotificationList(list);
emit newIncomingCallsList(callList);
emit jobFinished();

deleteLater();
}
Expand Down
5 changes: 3 additions & 2 deletions src/gui/tray/notificationhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ class ServerNotificationHandler : public QObject
signals:
void newNotificationList(OCC::ActivityList);
void newIncomingCallsList(OCC::ActivityList);
void jobFinished();

public slots:
void slotFetchNotifications();
public:
bool startFetchNotifications();

private slots:
void slotNotificationsReceived(const QJsonDocument &json, int statusCode);
Expand Down
35 changes: 25 additions & 10 deletions src/gui/tray/usermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ bool User::canShowNotification(const long notificationId)
!notificationAlreadyShown(notificationId);
}

void User::checkAndRemoveSeenActivities(const ActivityList &list, const int numChatNotificationsReceived)
{
if (numChatNotificationsReceived < _lastChatNotificationsReceivedCount) {
_activityModel->checkAndRemoveSeenActivities(list);
}
_lastChatNotificationsReceivedCount = numChatNotificationsReceived;
}

void User::showDesktopNotification(const QString &title, const QString &message, const long notificationId)
{
if(!canShowNotification(notificationId)) {
Expand Down Expand Up @@ -197,6 +205,11 @@ void User::showDesktopTalkNotification(const Activity &activity)

void User::slotBuildNotificationDisplay(const ActivityList &list)
{
const auto chatNotificationsReceivedCount = std::count_if(std::cbegin(list), std::cend(list), [](const auto &activity) {
return activity._objectType == QStringLiteral("chat");
});
checkAndRemoveSeenActivities(list, chatNotificationsReceivedCount);

ActivityList toNotifyList;

std::copy_if(list.constBegin(), list.constEnd(), std::back_inserter(toNotifyList), [&](const Activity &activity) {
Expand All @@ -221,21 +234,18 @@ void User::slotBuildNotificationDisplay(const ActivityList &list)
return;
}

auto chatNotificationsReceivedCount = 0;

for(const auto &activity : qAsConst(toNotifyList)) {
for (const auto &activity : qAsConst(toNotifyList)) {
if (activity._objectType == QStringLiteral("chat")) {
++chatNotificationsReceivedCount;
showDesktopTalkNotification(activity);
} else {
showDesktopNotification(activity);
}
}
}

if (chatNotificationsReceivedCount < _lastChatNotificationsReceivedCount) {
_activityModel->checkAndRemoveSeenActivities(toNotifyList);
}
_lastChatNotificationsReceivedCount = chatNotificationsReceivedCount;
void User::slotNotificationFetchFinished()
{
_isNotificationFetchRunning = false;
}

void User::slotBuildIncomingCallDialogs(const ActivityList &list)
Expand Down Expand Up @@ -440,13 +450,18 @@ void User::slotRefreshNotifications()
// start a server notification handler if no notification requests
// are running
if (_notificationRequestsRunning == 0) {
if (_isNotificationFetchRunning) {
qCDebug(lcActivity) << "Notification fetch is already running.";
return;
}
auto *snh = new ServerNotificationHandler(_account.data());
connect(snh, &ServerNotificationHandler::newNotificationList,
this, &User::slotBuildNotificationDisplay);
connect(snh, &ServerNotificationHandler::newIncomingCallsList,
this, &User::slotBuildIncomingCallDialogs);

snh->slotFetchNotifications();
connect(snh, &ServerNotificationHandler::jobFinished,
this, &User::slotNotificationFetchFinished);
_isNotificationFetchRunning = snh->startFetchNotifications();
} else {
qCWarning(lcActivity) << "Notification request counter not zero.";
}
Expand Down
5 changes: 5 additions & 0 deletions src/gui/tray/usermodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public slots:
void slotNotifyServerFinished(const QString &reply, int replyCode);
void slotSendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row);
void slotBuildNotificationDisplay(const OCC::ActivityList &list);
void slotNotificationFetchFinished();
void slotBuildIncomingCallDialogs(const OCC::ActivityList &list);
void slotRefreshNotifications();
void slotRefreshActivitiesInitial();
Expand Down Expand Up @@ -163,6 +164,8 @@ private slots:
bool notificationAlreadyShown(const long notificationId);
bool canShowNotification(const long notificationId);

void checkAndRemoveSeenActivities(const ActivityList &list, const int numChatNotificationsReceived);

AccountStatePtr _account;
bool _isCurrentUser;
ActivityListModel *_activityModel;
Expand All @@ -184,6 +187,8 @@ private slots:
int _notificationRequestsRunning = 0;

int _lastChatNotificationsReceivedCount = 0;

bool _isNotificationFetchRunning = false;
};

class UserModel : public QAbstractListModel
Expand Down