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.10] Bugfix/activity list fixes #6087

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<file>src/gui/tray/EditFileLocallyLoadingDialog.qml</file>
<file>src/gui/tray/NCBusyIndicator.qml</file>
<file>src/gui/tray/NCToolTip.qml</file>
<file>src/gui/tray/NCProgressBar.qml</file>
<file>src/gui/tray/EnforcedPlainTextLabel.qml</file>
<file>theme/Style/Style.qml</file>
<file>theme/Style/qmldir</file>
Expand Down
2 changes: 1 addition & 1 deletion src/gui/folderman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,7 @@ QStringList FolderMan::findFileInLocalFolders(const QString &relPath, const Acco
if (acc && folder->accountState()->account() != acc) {
continue;
}
if (!serverPath.startsWith(folder->remotePath()))
if (!serverPath.startsWith(folder->remotePathTrailingSlash()))
continue;

QString path = folder->cleanPath() + '/';
Expand Down
26 changes: 26 additions & 0 deletions src/gui/tray/ActivityList.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ import com.nextcloud.desktopclient 1.0 as NC
ScrollView {
id: controlRoot
property alias model: sortedActivityList.sourceModel
property alias count: activityList.count
property alias atYBeginning : activityList.atYBeginning
property bool isFileActivityList: false
property int iconSize: Style.trayListItemIconSize
property int delegateHorizontalPadding: 0

property bool scrollingToTop: false

function scrollToTop() {
// Triggers activation of repeating upward flick timer
scrollingToTop = true
}

signal openFile(string filePath)
signal activityItemClicked(int index)

Expand All @@ -22,6 +31,9 @@ ScrollView {

data: NC.WheelHandler {
target: controlRoot.contentItem
onWheel: {
scrollingToTop = false
}
}

ListView {
Expand All @@ -36,6 +48,20 @@ ScrollView {
currentIndex: -1
interactive: true

Timer {
id: repeatUpFlickTimer
interval: Style.activityListScrollToTopTimerInterval
running: controlRoot.scrollingToTop
repeat: true
onTriggered: {
if (!activityList.atYBeginning) {
activityList.flick(0, Style.activityListScrollToTopVelocity)
} else {
controlRoot.scrollingToTop = false
}
}
}

highlight: Rectangle {
id: activityHover
anchors.fill: activityList.currentItem
Expand Down
44 changes: 44 additions & 0 deletions src/gui/tray/NCProgressBar.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 by Oleksandr Zolotov <[email protected]>
*
* 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.
*/

import QtQuick 2.15
import QtQuick.Controls 2.15
import Style 1.0

ProgressBar {
id: control

background: Rectangle {
implicitWidth: Style.progressBarWidth
implicitHeight: Style.progressBarBackgroundHeight
radius: Style.progressBarRadius
color: Style.progressBarBackgroundColor
border.color: Style.progressBarBackgroundBorderColor
border.width: Style.progressBarBackgroundBorderWidth
}

contentItem: Item {
implicitWidth: Style.progressBarWidth
implicitHeight: Style.progressBarContentHeight

Rectangle {
width: control.visualPosition * parent.width
height: parent.height
radius: Style.progressBarRadius
color: Style.progressBarContentColor
border.color: Style.progressBarContentBorderColor
border.width: Style.progressBarContentBorderWidth
}
}
}
31 changes: 4 additions & 27 deletions src/gui/tray/SyncStatus.qml
Original file line number Diff line number Diff line change
Expand Up @@ -61,36 +61,13 @@ RowLayout {

Loader {
Layout.fillWidth: true
Layout.preferredHeight: Style.progressBarPreferredHeight

active: syncStatus.syncing
visible: syncStatus.syncing
active: syncStatus.syncing && syncStatus.totalFiles > 0
visible: active

sourceComponent: ProgressBar {
sourceComponent: NCProgressBar {
id: syncProgressBar

// TODO: Rather than setting all these palette colours manually,
// create a custom style and do it for all components globally.
//
// Additionally, we need to override the entire palette when we
// set one palette property, as otherwise we default back to the
// theme palette -- not the parent palette
palette {
text: Style.ncTextColor
windowText: Style.ncTextColor
buttonText: Style.ncTextColor
brightText: Style.ncTextBrightColor
highlight: Style.lightHover
highlightedText: Style.ncTextColor
light: Style.lightHover
midlight: Style.ncSecondaryTextColor
mid: Style.darkerHover
dark: Style.menuBorder
button: Style.buttonBackgroundColor
window: palette.dark // NOTE: Fusion theme uses darker window colour for the border of the progress bar
base: Style.backgroundColor
toolTipBase: Style.backgroundColor
toolTipText: Style.ncTextColor
}
value: syncStatus.syncProgress
}
}
Expand Down
70 changes: 70 additions & 0 deletions src/gui/tray/Window.qml
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,69 @@ ApplicationWindow {
anchors.right: trayWindowMainItem.right
}

Loader {
id: newActivitiesButtonLoader

anchors.top: activityList.top
anchors.topMargin: 5
anchors.horizontalCenter: activityList.horizontalCenter

width: Style.newActivitiesButtonWidth
height: Style.newActivitiesButtonHeight

z: 1

active: false

sourceComponent: CustomButton {
id: newActivitiesButton
hoverEnabled: true
padding: Style.smallSpacing

textColor: Style.currentUserHeaderTextColor
textColorHovered: Style.currentUserHeaderTextColor
contentsFont.bold: true
bgNormalColor: Qt.lighter(bgHoverColor, 1.25)
bgHoverColor: Style.currentUserHeaderColor
bgNormalOpacity: Style.newActivitiesBgNormalOpacity
bgHoverOpacity: Style.newActivitiesBgHoverOpacity

anchors.fill: parent

text: qsTr("New activities")

icon.source: "image://svgimage-custom-color/expand-less-black.svg" + "/" + Style.currentUserHeaderTextColor
icon.width: Style.activityLabelBaseWidth
icon.height: Style.activityLabelBaseWidth

onClicked: {
activityList.scrollToTop();
newActivitiesButtonLoader.active = false
}

Timer {
id: newActivitiesButtonDisappearTimer
interval: Style.newActivityButtonDisappearTimeout
running: newActivitiesButtonLoader.active && !newActivitiesButton.hovered
repeat: false
onTriggered: fadeoutActivitiesButtonDisappear.running = true
}

OpacityAnimator {
id: fadeoutActivitiesButtonDisappear
target: newActivitiesButton;
from: 1;
to: 0;
duration: Style.newActivityButtonDisappearFadeTimeout
loops: 1
running: false
onFinished: newActivitiesButtonLoader.active = false
}
}
}

ActivityList {
id: activityList
visible: !trayWindowMainItem.isUnifiedSearchActive
anchors.top: syncStatus.bottom
anchors.left: trayWindowMainItem.left
Expand All @@ -864,6 +926,14 @@ ApplicationWindow {
onActivityItemClicked: {
model.slotTriggerDefaultAction(index)
}
Connections {
target: activityModel
onInteractiveActivityReceived: {
if (!activityList.atYBeginning) {
newActivitiesButtonLoader.active = true;
}
}
}
}
} // Item trayWindowMainItem
}
11 changes: 9 additions & 2 deletions src/gui/tray/activitylistmodel.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*

Check notice on line 1 in src/gui/tray/activitylistmodel.cpp

View workflow job for this annotation

GitHub Actions / build

Run clang-format on src/gui/tray/activitylistmodel.cpp

File src/gui/tray/activitylistmodel.cpp (lines 640, 641): Code does not conform to Custom style guidelines.
* Copyright (C) by Klaas Freitag <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -156,7 +156,7 @@
if (!fileName.isEmpty()) {
const auto folder = FolderMan::instance()->folder(a._folder);

const QString relPath = folder ? folder->remotePath() + fileName : fileName;
const QString relPath = folder ? folder->remotePathTrailingSlash() + fileName : fileName;

const auto localFiles = FolderMan::instance()->findFileInLocalFolders(relPath, ast->account());

Expand Down Expand Up @@ -184,7 +184,7 @@
if (!a._file.isEmpty()) {
const auto folder = FolderMan::instance()->folder(a._folder);

QString relPath = folder ? folder->remotePath() + a._file : a._file;
QString relPath = folder ? folder->remotePathTrailingSlash() + a._file : a._file;

const auto localFiles = FolderMan::instance()->findFileInLocalFolders(relPath, ast->account());

Expand Down Expand Up @@ -636,6 +636,13 @@
qCDebug(lcActivity) << "Notification successfully added to the notification list: " << activity._subject;
addEntriesToActivityList({activity});
_notificationLists.prepend(activity);
for (const auto &link : activity._links) {
if (link._verb == QByteArrayLiteral("POST")
|| link._verb == QByteArrayLiteral("REPLY")
|| link._verb == QByteArrayLiteral("WEB")) {
emit interactiveActivityReceived();
}
}
}

void ActivityListModel::addSyncFileItemToActivityList(const Activity &activity)
Expand Down
2 changes: 2 additions & 0 deletions src/gui/tray/activitylistmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ public slots:
void activityJobStatusCode(int statusCode);
void sendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row);

void interactiveActivityReceived();

protected:
[[nodiscard]] bool currentlyFetching() const;

Expand Down
53 changes: 53 additions & 0 deletions src/gui/tray/sortedactivitylistmodel.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*

Check notice on line 1 in src/gui/tray/sortedactivitylistmodel.cpp

View workflow job for this annotation

GitHub Actions / build

Run clang-format on src/gui/tray/sortedactivitylistmodel.cpp

File src/gui/tray/sortedactivitylistmodel.cpp (lines 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43): Code does not conform to Custom style guidelines.
* Copyright (C) by Claudio Cambra <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
Expand All @@ -13,9 +13,37 @@
*/

#include "activitylistmodel.h"
#include <QVector>

#include "sortedactivitylistmodel.h"

namespace
{
struct ActivityLinksSearchResult {
bool hasPOST = false;
bool hasREPLY = false;
bool hasWEB = false;
bool hasDELETE = false;
};

ActivityLinksSearchResult searchForVerbsInLinks(const QVector<OCC::ActivityLink> &links)
{
ActivityLinksSearchResult result;
for (const auto &link : links) {
if (link._verb == QByteArrayLiteral("POST")) {
result.hasPOST = true;
} else if (link._verb == QByteArrayLiteral("REPLY")) {
result.hasREPLY = true;
} else if (link._verb == QByteArrayLiteral("WEB")) {
result.hasWEB = true;
} else if (link._verb == QByteArrayLiteral("DELETE")) {
result.hasDELETE = true;
}
}
return result;
}
}

namespace OCC {

SortedActivityListModel::SortedActivityListModel(QObject *parent)
Expand Down Expand Up @@ -44,6 +72,31 @@
return false;
}

const auto leftActivityVerbsSearchResult = searchForVerbsInLinks(leftActivity._links);
const auto rightActivityVerbsSearchResult = searchForVerbsInLinks(rightActivity._links);

if (leftActivityVerbsSearchResult.hasPOST != rightActivityVerbsSearchResult.hasPOST) {
return leftActivityVerbsSearchResult.hasPOST;
}

if (leftActivityVerbsSearchResult.hasREPLY != rightActivityVerbsSearchResult.hasREPLY) {
return leftActivityVerbsSearchResult.hasREPLY;
}

if (leftActivityVerbsSearchResult.hasWEB != rightActivityVerbsSearchResult.hasWEB) {
return leftActivityVerbsSearchResult.hasWEB;
}

if (leftActivityVerbsSearchResult.hasDELETE != rightActivityVerbsSearchResult.hasDELETE) {
return leftActivityVerbsSearchResult.hasDELETE;
}

const auto leftActivityIsSecurityAction = leftActivity._fileAction == QStringLiteral("security");
const auto rightActivityIsSecurityAction = rightActivity._fileAction == QStringLiteral("security");
if (leftActivityIsSecurityAction != rightActivityIsSecurityAction) {
return leftActivityIsSecurityAction;
}

// Let's now check for errors as we want those near the top too
// Sync result errors go first
const auto leftSyncResultStatus = leftActivity._syncResultStatus;
Expand Down
Loading
Loading