From 00effb0e2fe63f328daf87352db41a52bde102f7 Mon Sep 17 00:00:00 2001 From: Camila San Date: Tue, 10 Jul 2018 14:37:49 +0200 Subject: [PATCH] Adds 'accept' button for remote share notifications. - Stores object_type form the api response to check if notification is remote_share, so the primary button text is 'accept' instead of 'more information'. Signed-off-by: Camila San --- src/gui/activitydata.h | 1 + src/gui/activityitemdelegate.cpp | 18 ++++++--- src/gui/activityitemdelegate.h | 2 + src/gui/activitylistmodel.cpp | 6 ++- src/gui/activitywidget.cpp | 55 ++++++++++++++------------- src/gui/servernotificationhandler.cpp | 11 ++++-- 6 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/gui/activitydata.h b/src/gui/activitydata.h index 3518cb1cdf..e1c527e651 100644 --- a/src/gui/activitydata.h +++ b/src/gui/activitydata.h @@ -55,6 +55,7 @@ public: Type _type; qlonglong _id; + QString _object_type; QString _subject; QString _message; QString _file; diff --git a/src/gui/activityitemdelegate.cpp b/src/gui/activityitemdelegate.cpp index d7d2dfc34e..12a5b661bf 100644 --- a/src/gui/activityitemdelegate.cpp +++ b/src/gui/activityitemdelegate.cpp @@ -35,6 +35,7 @@ int ActivityItemDelegate::_secondaryButtonWidth = 0; int ActivityItemDelegate::_spaceBetweenButtons = 0; int ActivityItemDelegate::_timeWidth = 0; int ActivityItemDelegate::_buttonHeight = 0; +QString ActivityItemDelegate::_remote_share("remote_share"); int ActivityItemDelegate::iconHeight() { @@ -85,6 +86,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & // get the data Activity::Type activityType = qvariant_cast(index.data(ActionRole)); QIcon actionIcon = qvariant_cast(index.data(ActionIconRole)); + QString objectType = qvariant_cast(index.data(ObjectTypeRole)); QString actionText = qvariant_cast(index.data(ActionTextRole)); QString messageText = qvariant_cast(index.data(MessageRole)); QList customList = index.data(ActionsLinksRole).toList(); @@ -159,8 +161,10 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & secondaryButton.icon = QIcon(QLatin1String(":/client/resources/more.svg")); secondaryButton.iconSize = QSize(iconSize, iconSize); - // Primary button will be 'More Information' + // Primary button will be 'More Information' or 'Accept' primaryButton.text = tr("More information"); + if(objectType == _remote_share) primaryButton.text = tr("Accept"); + primaryButton.rect.setLeft(left - margin * 2 - fm.width(primaryButton.text)); // save info to be able to filter mouse clicks @@ -270,14 +274,16 @@ bool ActivityItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, if (mouseEventX > x && mouseEventX < x + buttonsWidth){ if(mouseEventY > y && mouseEventY < y + _buttonHeight){ - // ...primary button ('more information' on notifications or 'open browser' on errors) - if (mouseEventX > x && mouseEventX < x + _primaryButtonWidth) + // ...primary button ('more information' or 'accept' on notifications or 'open browser' on errors) + if (mouseEventX > x && mouseEventX < x + _primaryButtonWidth){ emit primaryButtonClickedOnItemView(index); // ...secondary button ('dismiss' on notifications or 'open file manager' on errors) - x += _primaryButtonWidth + _spaceBetweenButtons; - if (mouseEventX > x && mouseEventX < x + _secondaryButtonWidth) - emit secondaryButtonClickedOnItemView(index); + } else { + x += _primaryButtonWidth + _spaceBetweenButtons; + if (mouseEventX > x && mouseEventX < x + _secondaryButtonWidth) + emit secondaryButtonClickedOnItemView(index); + } } } } diff --git a/src/gui/activityitemdelegate.h b/src/gui/activityitemdelegate.h index 9979f12236..e85de2a809 100644 --- a/src/gui/activityitemdelegate.h +++ b/src/gui/activityitemdelegate.h @@ -29,6 +29,7 @@ public: enum datarole { ActionIconRole = Qt::UserRole + 1, UserIconRole, AccountRole, + ObjectTypeRole, ActionsLinksRole, ActionTextRole, ActionRole, @@ -58,6 +59,7 @@ private: static int _spaceBetweenButtons; static int _timeWidth; static int _buttonHeight; + static QString _remote_share; }; } // namespace OCC diff --git a/src/gui/activitylistmodel.cpp b/src/gui/activitylistmodel.cpp index de24232949..4e3511a21a 100644 --- a/src/gui/activitylistmodel.cpp +++ b/src/gui/activitylistmodel.cpp @@ -106,6 +106,9 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const } else return QIcon(QLatin1String(":/client/resources/activity.png")); return QVariant(); break; + case ActivityItemDelegate::ObjectTypeRole: + return a._object_type; + break; case ActivityItemDelegate::ActionRole:{ QVariant type; type.setValue(a._type); @@ -164,7 +167,7 @@ void ActivityListModel::startFetchJob() if (!_accountState->isConnected()) { return; } - JsonApiJob *job = new JsonApiJob(_accountState->account(), QLatin1String("ocs/v1.php/cloud/activity"), this); + JsonApiJob *job = new JsonApiJob(_accountState->account(), QLatin1String("ocs/v2.php/cloud/activity"), this); QObject::connect(job, &JsonApiJob::jsonReceived, this, &ActivityListModel::slotActivitiesReceived); job->setProperty("AccountStatePtr", QVariant::fromValue>(_accountState)); @@ -197,6 +200,7 @@ void ActivityListModel::slotActivitiesReceived(const QJsonDocument &json, int st a._type = Activity::ActivityType; a._accName = ast->account()->displayName(); a._id = json.value("id").toInt(); + a._object_type = ""; a._subject = json.value("subject").toString(); a._message = json.value("message").toString(); a._file = json.value("file").toString(); diff --git a/src/gui/activitywidget.cpp b/src/gui/activitywidget.cpp index 8d11a3ca01..4b1cd27be5 100644 --- a/src/gui/activitywidget.cpp +++ b/src/gui/activitywidget.cpp @@ -124,29 +124,22 @@ void ActivityWidget::slotItemCompleted(const QString &folder, const SyncFileItem // check if we are adding it to the right account and if it is useful information (protocol errors) if(folderInstance->accountState() == _accountState){ - QString pathToFile = QString("%1/%2").arg(folderInstance->cleanPath(), item->_file); - qCWarning(lcActivity) << "Item " << pathToFile << " retrieved resulted in " << item->_errorString; + qCWarning(lcActivity) << "Item " << item->_file << " retrieved resulted in " << item->_errorString; Activity activity; activity._type = Activity::ErrorType; activity._dateTime = QDateTime::fromString(QDateTime::currentDateTime().toString(), Qt::ISODate); activity._subject = item->_errorString; activity._message = item->_originalFile; - - // TODO: maybe use the full path to access the file in the browser - // folderInstance->accountState()->account()->deprecatedPrivateLinkUrl(item->_fileId).toString(); - activity._link = folderInstance->accountState()->account()->url(); activity._status = item->_status; activity._accName = folderInstance->accountState()->account()->displayName(); - activity._file = item->_file; - ActivityLink al; - al._label = tr("Open Folder"); - al._link = QString("%1/%2").arg(folderInstance->cleanPath(), item->_file); - al._verb = ""; - al._isPrimary = true; - activity._links.append(al); + // TODO: the added '/' is needed so FolderMan::instance()->findFileInLocalFolders can find it + // why the local path in this case does not start with a '/'? + // _file in other cases (when they exist in remote) starts with '/' + // findFileInLocalFolders removes the remotePath before checking if the file exists (?) + activity._file = folderInstance->remotePath() + item->_file; // add 'protocol error' to activity list _model->addErrorToActivityList(activity); @@ -189,19 +182,35 @@ void ActivityWidget::addError(const QString &folderAlias, const QString &message void ActivityWidget::slotPrimaryButtonClickedOnListView(const QModelIndex &index){ QUrl link = qvariant_cast(index.data(ActivityItemDelegate::LinkRole)); + QString objectType = index.data(ActivityItemDelegate::ObjectTypeRole).toString(); if(!link.isEmpty()){ qCWarning(lcActivity) << "Opening" << link.toString() << "in browser for Notification/Activity" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); Utility::openBrowser(link, this); - } + } else if(objectType == "remote_share"){ + QVariant customItem = index.data(ActivityItemDelegate::ActionsLinksRole).toList().first(); + ActivityLink actionLink = qvariant_cast(customItem); + if(actionLink._label == "Accept"){ + qCWarning(lcActivity) << objectType << "action" << actionLink._label << "for" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); + const QString accountName = index.data(ActivityItemDelegate::AccountRole).toString(); + slotSendNotificationRequest(accountName, actionLink._link, actionLink._verb, index.row()); + } else { + qCWarning(lcActivity) << "Failed: " << objectType << "action" << actionLink._label << "for" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); + } + } } void ActivityWidget::slotSecondaryButtonClickedOnListView(const QModelIndex &index){ QList customList = index.data(ActivityItemDelegate::ActionsLinksRole).toList(); + QString objectType = index.data(ActivityItemDelegate::ObjectTypeRole).toString(); + QList actionLinks; foreach(QVariant customItem, customList){ actionLinks << qvariant_cast(customItem); } + if(objectType == "remote_share" && actionLinks.first()._label == "Accept") + actionLinks.removeFirst(); + if(qvariant_cast(index.data(ActivityItemDelegate::ActionRole)) == Activity::Type::NotificationType){ const QString accountName = index.data(ActivityItemDelegate::AccountRole).toString(); if(actionLinks.size() == 1){ @@ -223,15 +232,8 @@ void ActivityWidget::slotSecondaryButtonClickedOnListView(const QModelIndex &ind } } - if(qvariant_cast(index.data(ActivityItemDelegate::ActionRole)) == Activity::Type::ErrorType){ - // check if this is actually a folder that we can open - if (FolderMan::instance()->folderForPath(actionLinks.first()._link)) { - if (QFile(actionLinks.first()._link).exists()) { - qCWarning(lcActivity) << "Opening path" << actionLinks.first()._link << "in the file manager for Notification/Activity" << qvariant_cast(index.data(ActivityItemDelegate::ActionTextRole)); - showInFileManager(actionLinks.first()._link); - } - } - } + if(qvariant_cast(index.data(ActivityItemDelegate::ActionRole)) == Activity::Type::ErrorType) + slotOpenFile(index); } void ActivityWidget::slotNotificationRequestFinished(int statusCode) @@ -370,9 +372,10 @@ void ActivityWidget::slotOpenFile(QModelIndex indx) qCDebug(lcActivity) << indx.isValid() << indx.data(ActivityItemDelegate::PathRole).toString() << QFile::exists(indx.data(ActivityItemDelegate::PathRole).toString()); if (indx.isValid()) { QString fullPath = indx.data(ActivityItemDelegate::PathRole).toString(); - // TODO: use full path to file - if (QFile::exists(fullPath)) { - showInFileManager(fullPath); + if(!fullPath.isEmpty()){ + if (QFile::exists(fullPath)) { + showInFileManager(fullPath); + } } } } diff --git a/src/gui/servernotificationhandler.cpp b/src/gui/servernotificationhandler.cpp index 60dafe63f1..c03ea5df06 100644 --- a/src/gui/servernotificationhandler.cpp +++ b/src/gui/servernotificationhandler.cpp @@ -108,6 +108,10 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j a._type = Activity::NotificationType; a._accName = ai->account()->displayName(); a._id = json.value("notification_id").toInt(); + + //need to know, specially for remote_share + a._object_type = json.value("object_type").toString(); + a._subject = json.value("subject").toString(); a._message = json.value("message").toString(); @@ -117,15 +121,14 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j connect(iconJob, &IconJob::jobFinished, this, &ServerNotificationHandler::slotIconDownloaded); } - QString s = json.value("link").toString(); - if (!s.isEmpty()) { - QUrl link(s); + QUrl link(json.value("link").toString()); + if (!link.isEmpty()) { if(link.host().isEmpty()){ link.setScheme(ai->account()->url().scheme()); link.setHost(ai->account()->url().host()); } - a._link = link; } + a._link = link; a._dateTime = QDateTime::fromString(json.value("datetime").toString(), Qt::ISODate); auto actions = json.value("actions").toArray();