nextcloud-desktop/src/gui/tray/activitydata.cpp
Matthieu Gallien 10f9ef5cd5
to store subjectRichParameters use a QVariantMap that is qml friendly
will make it much easier to access fom qml in order to use the data
inside to improve activity list items

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
2023-05-17 18:16:08 +02:00

233 lines
12 KiB
C++

/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <QtCore>
#include "activitydata.h"
#include "folderman.h"
namespace {
QUrl stringToUrl(const QUrl &accountUrl, const QString &link) {
auto url = QUrl::fromUserInput(link);
if (!url.isValid()) {
return {};
}
if (url.host().isEmpty()) {
url.setScheme(accountUrl.scheme());
url.setHost(accountUrl.host());
}
if (url.port() == -1) {
url.setPort(accountUrl.port());
}
return url;
};
}
namespace OCC {
bool operator<(const Activity &rhs, const Activity &lhs)
{
return rhs._dateTime > lhs._dateTime;
}
bool operator>(const Activity &rhs, const Activity &lhs)
{
return rhs._dateTime < lhs._dateTime;
}
bool operator==(const Activity &rhs, const Activity &lhs)
{
return (rhs._type == lhs._type && rhs._id == lhs._id && rhs._accName == lhs._accName);
}
bool operator!=(const Activity &rhs, const Activity &lhs)
{
return !(rhs == lhs);
}
Activity::Identifier Activity::ident() const
{
return Identifier(_id, _accName);
}
ActivityLink ActivityLink::createFomJsonObject(const QJsonObject &obj)
{
ActivityLink activityLink;
activityLink._label = QUrl::fromPercentEncoding(obj.value(QStringLiteral("label")).toString().toUtf8());
activityLink._link = obj.value(QStringLiteral("link")).toString();
activityLink._verb = obj.value(QStringLiteral("type")).toString().toUtf8();
activityLink._primary = obj.value(QStringLiteral("primary")).toBool();
return activityLink;
}
OCC::Activity Activity::fromActivityJson(const QJsonObject &json, const AccountPtr account)
{
const auto activityUser = json.value(QStringLiteral("user")).toString();
Activity activity;
activity._type = Activity::ActivityType;
activity._objectType = json.value(QStringLiteral("object_type")).toString();
activity._objectId = json.value(QStringLiteral("object_id")).toInt();
activity._objectName = json.value(QStringLiteral("object_name")).toString();
activity._id = json.value(QStringLiteral("activity_id")).toInt();
activity._fileAction = json.value(QStringLiteral("type")).toString();
activity._accName = account->displayName();
activity._subject = json.value(QStringLiteral("subject")).toString();
activity._message = json.value(QStringLiteral("message")).toString();
activity._file = json.value(QStringLiteral("object_name")).toString();
activity._link = stringToUrl(account->url(), json.value(QStringLiteral("link")).toString());
activity._dateTime = QDateTime::fromString(json.value(QStringLiteral("datetime")).toString(), Qt::ISODate);
activity._icon = json.value(QStringLiteral("icon")).toString();
activity._isCurrentUserFileActivity = activity._objectType == QStringLiteral("files") && activityUser == account->davUser();
activity._isMultiObjectActivity = json.value("objects").toObject().count() > 1;
auto richSubjectData = json.value(QStringLiteral("subject_rich")).toArray();
if(richSubjectData.size() > 1) {
activity._subjectRich = richSubjectData[0].toString();
auto parameters = richSubjectData[1].toObject();
const QRegularExpression subjectRichParameterRe(QStringLiteral("({[a-zA-Z0-9]*})"));
const QRegularExpression subjectRichParameterBracesRe(QStringLiteral("[{}]"));
for (auto i = parameters.begin(); i != parameters.end(); ++i) {
const auto parameterJsonObject = i.value().toObject();
const auto richParamLink = stringToUrl(account->url(), parameterJsonObject.value(QStringLiteral("link")).toString());
activity._subjectRichParameters[i.key()] = QVariant::fromValue(Activity::RichSubjectParameter{
parameterJsonObject.value(QStringLiteral("type")).toString(),
parameterJsonObject.value(QStringLiteral("id")).toString(),
parameterJsonObject.value(QStringLiteral("name")).toString(),
parameterJsonObject.contains(QStringLiteral("path")) ? parameterJsonObject.value(QStringLiteral("path")).toString() : QString(),
richParamLink,
});
if (activity._objectType == QStringLiteral("calendar") && activity._link.isEmpty()) {
activity._link = richParamLink;
}
}
auto displayString = activity._subjectRich;
auto subjectRichParameterMatch = subjectRichParameterRe.globalMatch(displayString);
while (subjectRichParameterMatch.hasNext()) {
const auto match = subjectRichParameterMatch.next();
auto word = match.captured(1);
word.remove(subjectRichParameterBracesRe);
Q_ASSERT(activity._subjectRichParameters.contains(word));
displayString = displayString.replace(match.captured(1), activity._subjectRichParameters[word].value<Activity::RichSubjectParameter>().name);
}
activity._subjectDisplay = displayString;
}
const auto previewsData = json.value(QStringLiteral("previews")).toArray();
const QMimeDatabase mimeDb;
for(const auto &preview : previewsData) {
const auto jsonPreviewData = preview.toObject();
PreviewData data;
data._link = jsonPreviewData.value(QStringLiteral("link")).toString();
data._mimeType = jsonPreviewData.value(QStringLiteral("mimeType")).toString();
data._fileId = jsonPreviewData.value(QStringLiteral("fileId")).toInt();
data._view = jsonPreviewData.value(QStringLiteral("view")).toString();
data._filename = jsonPreviewData.value(QStringLiteral("filename")).toString();
const auto mimeType = mimeDb.mimeTypeForName(data._mimeType);
if(data._mimeType.contains(QStringLiteral("text/")) || data._mimeType.contains(QStringLiteral("/pdf"))) {
data._source = account->url().toString() + relativeServerFileTypeIconPath(mimeType);
data._isMimeTypeIcon = true;
} else {
data._source = jsonPreviewData.value(QStringLiteral("source")).toString();
data._isMimeTypeIcon = jsonPreviewData.value(QStringLiteral("isMimeTypeIcon")).toBool();
}
activity._previews.append(data);
}
if(!previewsData.isEmpty()) {
if(activity._icon.contains(QStringLiteral("add-color.svg"))) {
activity._icon = "qrc:///client/theme/colored/add-bordered.svg";
} else if(activity._icon.contains(QStringLiteral("delete-color.svg"))) {
activity._icon = "qrc:///client/theme/colored/delete-bordered.svg";
} else if(activity._icon.contains(QStringLiteral("change.svg"))) {
activity._icon = "qrc:///client/theme/colored/change-bordered.svg";
}
}
auto actions = json.value("actions").toArray();
foreach (auto action, actions) {
activity._links.append(ActivityLink::createFomJsonObject(action.toObject()));
}
return activity;
}
QString Activity::relativeServerFileTypeIconPath(const QMimeType &mimeType)
{
if(mimeType.isValid() && mimeType.inherits("text/plain")) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/text.svg");
} else if (mimeType.isValid() && mimeType.name().startsWith("image")) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/image.svg");
} else if (mimeType.isValid() && mimeType.name().startsWith("audio")) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/audio.svg");
} else if (mimeType.isValid() && mimeType.name().startsWith("video")) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/video.svg");
} else if (mimeType.isValid() && (mimeType.inherits("application/vnd.oasis.opendocument.text") ||
mimeType.inherits("application/msword") ||
mimeType.inherits("application/vnd.openxmlformats-officedocument.wordprocessingml.document") ||
mimeType.inherits("application/vnd.openxmlformats-officedocument.wordprocessingml.template")||
mimeType.inherits("application/vnd.ms-word.document.macroEnabled.12") ||
mimeType.inherits("application/vnd.ms-word.template.macroEnabled.12") ||
mimeType.inherits("application/vnd.apple.pages"))) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/x-office-document.svg");
} else if (mimeType.isValid() && mimeType.inherits("application/vnd.oasis.opendocument.graphics")) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/x-office-drawing.svg");
} else if (mimeType.isValid() && (mimeType.inherits("application/vnd.oasis.opendocument.presentation") ||
mimeType.inherits("application/vnd.ms-powerpoint") ||
mimeType.inherits("application/vnd.openxmlformats-officedocument.presentationml.presentation") ||
mimeType.inherits("application/vnd.openxmlformats-officedocument.presentationml.template") ||
mimeType.inherits("application/vnd.openxmlformats-officedocument.presentationml.slideshow") ||
mimeType.inherits("application/vnd.ms-powerpoint.addin.macroEnabled.12") ||
mimeType.inherits("application/vnd.ms-powerpoint.presentation.macroEnabled.12") ||
mimeType.inherits("application/vnd.ms-powerpoint.template.macroEnabled.12") ||
mimeType.inherits("application/vnd.ms-powerpoint.slideshow.macroEnabled.12") ||
mimeType.inherits("application/vnd.apple.keynote"))) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/x-office-presentation.svg");
} else if (mimeType.isValid() && (mimeType.inherits("application/vnd.oasis.opendocument.spreadsheet") ||
mimeType.inherits("application/vnd.ms-excel") ||
mimeType.inherits("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") ||
mimeType.inherits("application/vnd.openxmlformats-officedocument.spreadsheetml.template") ||
mimeType.inherits("application/vnd.ms-excel.sheet.macroEnabled.12") ||
mimeType.inherits("application/vnd.ms-excel.template.macroEnabled.12") ||
mimeType.inherits("application/vnd.ms-excel.addin.macroEnabled.12") ||
mimeType.inherits("application/vnd.ms-excel.sheet.binary.macroEnabled.12") ||
mimeType.inherits("application/vnd.apple.numbers"))) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/x-office-document.svg");
} else if (mimeType.isValid() && mimeType.inherits("application/pdf")) {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/application-pdf.svg");
} else {
return QStringLiteral("/index.php/apps/theming/img/core/filetypes/file.svg");
}
}
}