Skip to content

Commit

Permalink
Merge pull request #4472 from nextcloud/bugfix/tray-colours
Browse files Browse the repository at this point in the history
Fix activity list item issues with colours/layout/etc.
  • Loading branch information
claucambra authored May 16, 2022
2 parents 9d1c378 + 4634961 commit 96e4fce
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 73 deletions.
29 changes: 23 additions & 6 deletions src/gui/tray/ActivityItem.qml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ MouseArea {
hoverEnabled: true

// We center the children vertically in the middle of this MouseArea to create the padding.
height: childrenRect.height + (Style.standardSpacing * 2)
height: contentLayout.implicitHeight + (Style.standardSpacing * 2)

Accessible.role: Accessible.ListItem
Accessible.name: (model.path !== "" && model.displayPath !== "") ? qsTr("Open %1 locally").arg(model.displayPath) : model.message
Accessible.onPressAction: root.clicked()

function showReplyOptions() {
function toggleReplyOptions() {
isTalkReplyOptionVisible = !isTalkReplyOptionVisible
}

Expand All @@ -55,13 +55,14 @@ MouseArea {
}

ColumnLayout {
id: contentLayout
anchors.left: root.left
anchors.right: root.right
anchors.rightMargin: Style.standardSpacing
anchors.leftMargin: Style.standardSpacing
anchors.verticalCenter: parent.verticalCenter

spacing: 0
spacing: 10

ActivityItemContent {
id: activityContent
Expand All @@ -77,15 +78,30 @@ MouseArea {
onDismissButtonClicked: activityModel.slotTriggerDismiss(model.index)
}

Loader {
id: talkReplyTextFieldLoader
active: root.isChatActivity && root.isTalkReplyPossible && root.activityData.messageSent === ""
visible: root.isTalkReplyOptionVisible

Layout.leftMargin: Style.trayListItemIconSize + activityContent.spacing
Layout.preferredHeight: root.isTalkReplyOptionVisible ? implicitHeight : 0

sourceComponent: TalkReplyTextField {
onSendReply: {
UserModel.currentUser.sendReplyMessage(model.index, model.conversationToken, reply, model.messageId);
talkReplyTextFieldLoader.visible = false;
}
}
}

ActivityItemActions {
id: activityActions

visible: !root.isFileActivityList && model.linksForActionButtons.length > 0 && !isTalkReplyOptionVisible

Layout.fillWidth: true
Layout.leftMargin: 60
Layout.bottomMargin: model.links.length > 1 ? 5 : 0
Layout.preferredHeight: Style.minActivityHeight
Layout.leftMargin: Style.trayListItemIconSize + activityContent.spacing
Layout.minimumHeight: Style.minActivityHeight

displayActions: model.displayActions
objectType: model.objectType
Expand All @@ -98,6 +114,7 @@ MouseArea {
flickable: root.flickable

onTriggerAction: activityModel.slotTriggerAction(model.index, actionIndex)
onShowReplyField: root.toggleReplyOptions()
}
}
}
9 changes: 5 additions & 4 deletions src/gui/tray/ActivityItemActions.qml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ RowLayout {
property Flickable flickable

signal triggerAction(int actionIndex)
signal showReplyField()

Repeater {
id: actionsRepeater
Expand All @@ -42,15 +43,15 @@ RowLayout {
text: model.modelData.label
toolTipText: model.modelData.label

imageSource: model.modelData.imageSource
imageSourceHover: model.modelData.imageSourceHovered
imageSource: model.modelData.imageSource ? model.modelData.imageSource + UserModel.currentUser.headerColor : ""
imageSourceHover: model.modelData.imageSourceHovered ? model.modelData.imageSourceHovered + UserModel.currentUser.headerTextColor : ""

textColor: imageSource !== "" ? UserModel.currentUser.headerColor : Style.ncTextColor
textColorHovered: imageSource !== "" ? Style.lightHover : Style.ncTextColor
textColorHovered: imageSource !== "" ? UserModel.currentUser.headerTextColor : Style.ncTextColor

bold: primary

onClicked: !isTalkReplyButton? root.triggerAction(model.index) : showReplyOptions(model.index)
onClicked: !isTalkReplyButton ? root.triggerAction(model.index) : root.showReplyField()
}
}

Expand Down
18 changes: 2 additions & 16 deletions src/gui/tray/ActivityItemContent.qml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ RowLayout {
id: thumbnailItem
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.preferredWidth: Style.trayListItemIconSize
Layout.preferredHeight: model.thumbnail.isMimeTypeIcon ? Style.trayListItemIconSize * 0.9 : Style.trayListItemIconSize
Layout.preferredHeight: model.thumbnail && model.thumbnail.isMimeTypeIcon ? Style.trayListItemIconSize * 0.9 : Style.trayListItemIconSize
readonly property int imageWidth: width * (1 - Style.thumbnailImageSizeReduction)
readonly property int imageHeight: height * (1 - Style.thumbnailImageSizeReduction)
readonly property int thumbnailRadius: model.thumbnail.isUserAvatar ? width / 2 : 3
readonly property int thumbnailRadius: model.thumbnail && model.thumbnail.isUserAvatar ? width / 2 : 3

Loader {
id: thumbnailImageLoader
Expand Down Expand Up @@ -166,20 +166,6 @@ RowLayout {
color: Style.ncSecondaryTextColor
visible: text !== ""
}

Loader {
id: talkReplyTextFieldLoader
active: isChatActivity && isTalkReplyPossible
visible: isTalkReplyOptionVisible

anchors.top: activityTextDateTime.bottom
anchors.topMargin: 10

sourceComponent: TalkReplyTextField {
id: talkReplyMessage
anchors.fill: parent
}
}
}

Button {
Expand Down
21 changes: 12 additions & 9 deletions src/gui/tray/TalkReplyTextField.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,32 @@ import com.nextcloud.desktopclient 1.0
Item {
id: root

signal sendReply(string reply)

function sendReplyMessage() {
if (replyMessageTextField.text === "") {
return;
}

UserModel.currentUser.sendReplyMessage(model.index, model.conversationToken, replyMessageTextField.text, model.messageId);
replyMessageTextField.visible = false
root.sendReply(replyMessageTextField.text);
}

height: 38
width: 250

TextField {
id: replyMessageTextField
visible: model.messageSent === ""

// TODO use Layout to manage width/height. The Layout.minimunWidth does not apply to the width set.
height: 38
width: 250

onAccepted: root.sendReplyMessage()

anchors.fill: parent
topPadding: 4
rightPadding: sendReplyMessageButton.width
visible: model.messageSent === ""

color: Style.ncSecondaryTextColor
placeholderText: qsTr("Reply to …")

onAccepted: root.sendReplyMessage()

background: Rectangle {
id: replyMessageTextFieldBorder
radius: 24
Expand Down
33 changes: 7 additions & 26 deletions src/gui/tray/activitydata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,9 @@ OCC::Activity Activity::fromActivityJson(const QJsonObject &json, const AccountP
activity._file = json.value(QStringLiteral("object_name")).toString();
activity._link = QUrl(json.value(QStringLiteral("link")).toString());
activity._dateTime = QDateTime::fromString(json.value(QStringLiteral("datetime")).toString(), Qt::ISODate);
activity._darkIcon = json.value(QStringLiteral("icon")).toString(); // We have both dark and light for theming purposes
activity._lightIcon = json.value(QStringLiteral("icon")).toString(); // Some icons get changed in the ActivityListModel
activity._icon = json.value(QStringLiteral("icon")).toString();
activity._isCurrentUserFileActivity = activity._objectType == QStringLiteral("files") && activityUser == account->davUser();

const auto darkIconPath = QStringLiteral("qrc://:/client/theme/white/");
const auto lightIconPath = QStringLiteral("qrc://:/client/theme/black/");
if(activity._darkIcon.contains("change.svg")) {
activity._darkIcon = darkIconPath + QStringLiteral("change.svg");
activity._lightIcon = lightIconPath + QStringLiteral("change.svg");
} else if(activity._darkIcon.contains("calendar.svg")) {
activity._darkIcon = darkIconPath + QStringLiteral("calendar.svg");
activity._lightIcon = lightIconPath + QStringLiteral("calendar.svg");
} else if(activity._darkIcon.contains("personal.svg")) {
activity._darkIcon = darkIconPath + QStringLiteral("user.svg");
activity._lightIcon = lightIconPath + QStringLiteral("user.svg");
} else if(activity._darkIcon.contains("core/img/actions")) {
activity._darkIcon.insert(activity._darkIcon.indexOf(".svg"), "-white");
}

auto richSubjectData = json.value(QStringLiteral("subject_rich")).toArray();

if(richSubjectData.size() > 1) {
Expand Down Expand Up @@ -144,15 +128,12 @@ OCC::Activity Activity::fromActivityJson(const QJsonObject &json, const AccountP
}

if(!previewsData.isEmpty()) {
if(activity._darkIcon.contains(QStringLiteral("add-color.svg"))) {
activity._darkIcon = "qrc:///client/theme/colored/add-bordered.svg";
activity._lightIcon = "qrc:///client/theme/colored/add-bordered.svg";
} else if(activity._darkIcon.contains(QStringLiteral("delete-color.svg"))) {
activity._darkIcon = "qrc:///client/theme/colored/delete-bordered.svg";
activity._lightIcon = "qrc:///client/theme/colored/add-bordered.svg";
} else if(activity._darkIcon.contains(QStringLiteral("change.svg"))) {
activity._darkIcon = "qrc:///client/theme/colored/change-bordered.svg";
activity._lightIcon = "qrc:///client/theme/colored/add-bordered.svg";
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";
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/gui/tray/activitydata.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ class Activity
QDateTime _dateTime;
qint64 _expireAtMsecs = -1;
QString _accName;
QString _darkIcon;
QString _lightIcon;
QString _icon;
bool _isCurrentUserFileActivity = false;
QVector<PreviewData> _previews;

Expand Down
15 changes: 7 additions & 8 deletions src/gui/tray/activitylistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,13 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
}
} else {
// We have an activity
if (a._darkIcon.isEmpty()) {
if (a._icon.isEmpty()) {
colorIconPath.append("activity.svg");
return colorIconPath;
}
return role == DarkIconRole ? a._darkIcon : a._lightIcon;

const QString basePath = QStringLiteral("image://tray-image-provider/") % a._icon % QStringLiteral("/");
return role == DarkIconRole ? QString(basePath + QStringLiteral("white")) : QString(basePath + QStringLiteral("black"));
}
};

Expand Down Expand Up @@ -485,8 +487,7 @@ void ActivityListModel::insertOrRemoveDummyFetchingActivity()
a._objectType = dummyFetchingActivityObjectType;
a._subject = tr("Fetching activities…");
a._dateTime = QDateTime::currentDateTime();
a._darkIcon = QLatin1String("qrc:///client/theme/colored/change-bordered.svg");
a._lightIcon = QLatin1String("qrc:///client/theme/colored/change-bordered.svg");
a._icon = QLatin1String("qrc:///client/theme/colored/change-bordered.svg");

beginInsertRows({}, 0, 0);
_finalList.prepend(a);
Expand Down Expand Up @@ -792,10 +793,8 @@ QVariant ActivityListModel::convertLinkToActionButton(const OCC::ActivityLink &a
const QString replyButtonPath = QStringLiteral("image://svgimage-custom-color/reply.svg");

if (isReplyIconApplicable) {
activityLinkCopy._imageSource =
QString(replyButtonPath + "/" + OCC::Theme::instance()->wizardHeaderBackgroundColor().name());
activityLinkCopy._imageSourceHovered =
QString(replyButtonPath + "/" + OCC::Theme::instance()->wizardHeaderTitleColor().name());
activityLinkCopy._imageSource = QString(replyButtonPath + "/");
activityLinkCopy._imageSourceHovered = QString(replyButtonPath + "/");
}

return QVariant::fromValue(activityLinkCopy);
Expand Down
24 changes: 22 additions & 2 deletions src/gui/tray/asyncimageresponse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@ AsyncImageResponse::AsyncImageResponse(const QString &id, const QSize &requested
return;
}

_imagePaths = id.split(QLatin1Char(';'), Qt::SkipEmptyParts);
auto actualId = id;
const auto idSplit = id.split(QStringLiteral("/"), Qt::SkipEmptyParts);
const auto color = QColor(idSplit.last());

if(color.isValid()) {
_svgRecolor = color;
actualId.remove("/" % idSplit.last());
}

_imagePaths = actualId.split(QLatin1Char(';'), Qt::SkipEmptyParts);
_requestedImageSize = requestedSize;

if (_imagePaths.isEmpty()) {
Expand Down Expand Up @@ -96,7 +105,18 @@ void AsyncImageResponse::slotProcessNetworkReply()
scaledSvg.fill("transparent");
QPainter painterForSvg(&scaledSvg);
svgRenderer.render(&painterForSvg);
setImageAndEmitFinished(scaledSvg);

if(!_svgRecolor.isValid()) {
setImageAndEmitFinished(scaledSvg);
return;
}

QImage image(_requestedImageSize, QImage::Format_ARGB32);
image.fill(_svgRecolor);
QPainter imagePainter(&image);
imagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
imagePainter.drawImage(0, 0, scaledSvg);
setImageAndEmitFinished(image);
return;
} else {
processNextImage();
Expand Down
1 change: 1 addition & 0 deletions src/gui/tray/asyncimageresponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ private slots:
QImage _image;
QStringList _imagePaths;
QSize _requestedImageSize;
QColor _svgRecolor;
int _index = 0;
};

0 comments on commit 96e4fce

Please sign in to comment.