diff --git a/src/gui/ResolveConflictsDialog.qml b/src/gui/ResolveConflictsDialog.qml index 5234b8a8a..38adcea71 100644 --- a/src/gui/ResolveConflictsDialog.qml +++ b/src/gui/ResolveConflictsDialog.qml @@ -25,6 +25,8 @@ import "./tray" Window { id: root + required property var allConflicts + flags: Qt.Dialog visible: true @@ -112,6 +114,8 @@ Window { SyncConflictsModel { id: realModel + + conflictActivities: root.allConflicts } ScrollView { @@ -125,46 +129,7 @@ Window { id: conflictListView model: DelegateModel { - model: ListModel { - ListElement { - existingFileName: 'Text File.txt' - conflictFileName: 'Text File.txt' - existingSize: '2 B' - conflictSize: '15 B' - existingDate: '28 avril 2023 09:53' - conflictDate: '28 avril 2023 09:53' - existingSelected: false - conflictSelected: false - existingPreviewUrl: 'https://nextcloud.local/index.php/apps/theming/img/core/filetypes/text.svg?v=b9feb2d6' - conflictPreviewUrl: 'https://nextcloud.local/index.php/apps/theming/img/core/filetypes/text.svg?v=b9feb2d6' - } - - ListElement { - existingFileName: 'Text File.txt' - conflictFileName: 'Text File.txt' - existingSize: '2 B' - conflictSize: '15 B' - existingDate: '28 avril 2023 09:53' - conflictDate: '28 avril 2023 09:53' - existingSelected: false - conflictSelected: false - existingPreviewUrl: 'https://nextcloud.local/index.php/apps/theming/img/core/filetypes/text.svg?v=b9feb2d6' - conflictPreviewUrl: 'https://nextcloud.local/index.php/apps/theming/img/core/filetypes/text.svg?v=b9feb2d6' - } - - ListElement { - existingFileName: 'Text File.txt' - conflictFileName: 'Text File.txt' - existingSize: '2 B' - conflictSize: '15 B' - existingDate: '28 avril 2023 09:53' - conflictDate: '28 avril 2023 09:53' - existingSelected: false - conflictSelected: false - existingPreviewUrl: 'https://nextcloud.local/index.php/apps/theming/img/core/filetypes/text.svg?v=b9feb2d6' - conflictPreviewUrl: 'https://nextcloud.local/index.php/apps/theming/img/core/filetypes/text.svg?v=b9feb2d6' - } - } + model: realModel delegate: ConflictDelegate { width: conflictListView.contentItem.width diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp index f2e1d12d0..25276b84f 100644 --- a/src/gui/systray.cpp +++ b/src/gui/systray.cpp @@ -285,10 +285,12 @@ void Systray::destroyEditFileLocallyLoadingDialog() _editFileLocallyLoadingDialog = nullptr; } -void Systray::createResolveConflictsDialog() +void Systray::createResolveConflictsDialog(const OCC::ActivityList &allConflicts) { const auto callDialog = new QQmlComponent(_trayEngine, QStringLiteral("qrc:/qml/src/gui/ResolveConflictsDialog.qml")); - const QVariantMap initialProperties{}; + const QVariantMap initialProperties{ + {"allConflicts", QVariant::fromValue(allConflicts)}, + }; if(callDialog->isError()) { qCWarning(lcSystray) << callDialog->errorString(); diff --git a/src/gui/systray.h b/src/gui/systray.h index 69c34a65f..21607233e 100644 --- a/src/gui/systray.h +++ b/src/gui/systray.h @@ -121,7 +121,7 @@ public slots: void createCallDialog(const OCC::Activity &callNotification, const OCC::AccountStatePtr accountState); void createEditFileLocallyLoadingDialog(const QString &fileName); void destroyEditFileLocallyLoadingDialog(); - void createResolveConflictsDialog(); + void createResolveConflictsDialog(const OCC::ActivityList &allConflicts); void slotCurrentUserChanged(); diff --git a/src/gui/tray/SyncStatus.qml b/src/gui/tray/SyncStatus.qml index a1dc370c8..8fa91b454 100644 --- a/src/gui/tray/SyncStatus.qml +++ b/src/gui/tray/SyncStatus.qml @@ -121,7 +121,8 @@ RowLayout { contentsFont.bold: true bgColor: Style.currentUserHeaderColor - visible: !syncStatus.syncing && + visible: !activityModel.hasManySyncConflicts && + !syncStatus.syncing && NC.UserModel.currentUser.hasLocalFolder && NC.UserModel.currentUser.isConnected enabled: visible @@ -131,4 +132,27 @@ RowLayout { } } } + + CustomButton { + Layout.preferredWidth: syncNowFm.boundingRect(text).width + + leftPadding + + rightPadding + + Style.standardSpacing * 2 + Layout.rightMargin: Style.trayHorizontalMargin + + text: qsTr("Solve all conflicts") + textColor: Style.adjustedCurrentUserHeaderColor + textColorHovered: Style.currentUserHeaderTextColor + contentsFont.bold: true + bgColor: Style.currentUserHeaderColor + + visible: activityModel.hasManySyncConflicts && + !syncStatus.syncing && + NC.UserModel.currentUser.hasLocalFolder && + NC.UserModel.currentUser.isConnected + enabled: visible + onClicked: { + Systray.createResolveConflictsDialog(); + } + } } diff --git a/src/gui/tray/activitylistmodel.cpp b/src/gui/tray/activitylistmodel.cpp index f3cb3838f..6d7ceec74 100644 --- a/src/gui/tray/activitylistmodel.cpp +++ b/src/gui/tray/activitylistmodel.cpp @@ -548,6 +548,21 @@ void ActivityListModel::addEntriesToActivityList(const ActivityList &activityLis _finalList.append(activity); } endInsertRows(); + + auto conflictsCount = 0; + for(const auto &activity : _finalList) { + if (activity._syncFileItemStatus == SyncFileItem::Conflict) { + ++conflictsCount; + } + } + + if (!_hasManySyncConflicts && conflictsCount > 2) { + _hasManySyncConflicts = true; + emit hasManySyncConflictsChanged(); + } else if (_hasManySyncConflicts && conflictsCount <= 2) { + _hasManySyncConflicts = false; + emit hasManySyncConflictsChanged(); + } } void ActivityListModel::addErrorToActivityList(const Activity &activity) @@ -893,4 +908,10 @@ QString ActivityListModel::replyMessageSent(const Activity &activity) const { return activity._talkNotificationData.messageSent; } + +bool ActivityListModel::hasManySyncConflicts() const +{ + return _hasManySyncConflicts; +} + } diff --git a/src/gui/tray/activitylistmodel.h b/src/gui/tray/activitylistmodel.h index eae46ea78..17e22eaea 100644 --- a/src/gui/tray/activitylistmodel.h +++ b/src/gui/tray/activitylistmodel.h @@ -42,6 +42,7 @@ class ActivityListModel : public QAbstractListModel Q_OBJECT Q_PROPERTY(quint32 maxActionButtons READ maxActionButtons CONSTANT) Q_PROPERTY(AccountState *accountState READ accountState WRITE setAccountState NOTIFY accountStateChanged) + Q_PROPERTY(bool hasManySyncConflicts READ hasManySyncConflicts NOTIFY hasManySyncConflictsChanged) public: enum DataRole { @@ -105,6 +106,8 @@ public: [[nodiscard]] QString replyMessageSent(const Activity &activity) const; + [[nodiscard]] bool hasManySyncConflicts() const; + public slots: void slotRefreshActivity(); void slotRefreshActivityInitial(); @@ -126,6 +129,7 @@ public slots: signals: void accountStateChanged(); + void hasManySyncConflictsChanged(); void activityJobStatusCode(int statusCode); void sendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row); @@ -192,6 +196,8 @@ private: bool _doneFetching = false; bool _hideOldActivities = true; + bool _hasManySyncConflicts = false; + static constexpr quint32 MaxActionButtons = 3; }; }