replace "Sync now" button by "Solve all conflicts" for many conflicts
authorMatthieu Gallien <matthieu.gallien@nextcloud.com>
Wed, 3 May 2023 16:09:12 +0000 (18:09 +0200)
committerMatthieu Gallien <matthieu_gallien@yahoo.fr>
Wed, 17 May 2023 06:43:54 +0000 (08:43 +0200)
offer an easy way to open a dialog to solve all conflicts at once
replacing the "Sync now" button

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
src/gui/ResolveConflictsDialog.qml
src/gui/systray.cpp
src/gui/systray.h
src/gui/tray/SyncStatus.qml
src/gui/tray/activitylistmodel.cpp
src/gui/tray/activitylistmodel.h

index 5234b8a8a79b04d3c24b3d3e5aabe781e709f3ea..38adcea7138bd40e1fa23169f4dfd001364929c3 100644 (file)
@@ -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
index f2e1d12d0774903766056e8569de6556eb9ab398..25276b84f10743ff72b4af0ebaae7062cb5f11e9 100644 (file)
@@ -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();
index 69c34a65f4adf3ac03adf9a3b4df92234c3893cc..21607233e6ed33ece0f0036444c3d70dd2485b95 100644 (file)
@@ -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();
 
index a1dc370c8555ab366f503ce2ad237533e35c125e..8fa91b454323f4105afdd53b385e2e77814bac2d 100644 (file)
@@ -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();
+        }
+    }
 }
index f3cb3838f3ee826588e0209867d8e44eba4a3155..6d7ceec74aa731201490651e641ba03f3f3861a0 100644 (file)
@@ -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;
+}
+
 }
index eae46ea78b587da3711dfa2c3a072c1523d9c5ef..17e22eaeadbd9d5a28362e0b3e8c9f4cc580c09c 100644 (file)
@@ -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;
 };
 }