From 45b69519c4f511bf5eedb85b1f6a8cd31f1f6307 Mon Sep 17 00:00:00 2001 From: bodwok Date: Tue, 5 Oct 2021 01:04:06 +0300 Subject: [PATCH] fix(ui): contact list optimization --- src/model/friendlist/friendlistmanager.cpp | 57 ++++++++++++++++------ src/model/friendlist/friendlistmanager.h | 11 ++++- src/widget/friendlistwidget.cpp | 35 ++++++++----- 3 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/model/friendlist/friendlistmanager.cpp b/src/model/friendlist/friendlistmanager.cpp index 7b3b9652c..c89275ff7 100644 --- a/src/model/friendlist/friendlistmanager.cpp +++ b/src/model/friendlist/friendlistmanager.cpp @@ -20,9 +20,9 @@ #include "friendlistmanager.h" #include "src/widget/genericchatroomwidget.h" -FriendListManager::FriendListManager(QObject *parent) : QObject(parent) +FriendListManager::FriendListManager(int countContacts, QObject *parent) : QObject(parent) { - + this->countContacts = countContacts; } QVector FriendListManager::getItems() const @@ -35,6 +35,11 @@ bool FriendListManager::needHideCircles() const return hideCircles; } +bool FriendListManager::getPositionsChanged() const +{ + return positionsChanged; +} + void FriendListManager::addFriendListItem(IFriendListItem *item) { if (item->isGroup()) { @@ -44,15 +49,16 @@ void FriendListManager::addFriendListItem(IFriendListItem *item) items.push_back(IFriendListItemPtr(item)); } - updatePositions(); - emit itemsChanged(); + if (countContacts <= items.size()) { + countContacts = 0; + setSortRequired(); + } } void FriendListManager::removeFriendListItem(IFriendListItem *item) { removeAll(item); - updatePositions(); - emit itemsChanged(); + setSortRequired(); } void FriendListManager::sortByName() @@ -87,7 +93,7 @@ void FriendListManager::setFilter(const QString &searchString, bool hideOnline, filterParams.hideOffline = hideOffline; filterParams.hideGroups = hideGroups; - emit itemsChanged(); + setSortRequired(); } void FriendListManager::applyFilter() @@ -126,19 +132,40 @@ void FriendListManager::applyFilter() void FriendListManager::updatePositions() { + positionsChanged = true; + if (byName) { - std::sort(items.begin(), items.end(), - [&](const IFriendListItemPtr &a, const IFriendListItemPtr &b) { - return cmpByName(a, b, groupsOnTop); + auto sortName = [&](const IFriendListItemPtr &a, const IFriendListItemPtr &b) { + return cmpByName(a, b, groupsOnTop); + }; + if (!needSort) { + if (std::is_sorted(items.begin(), items.end(), sortName)) { + positionsChanged = false; + return; } - ); + } + std::sort(items.begin(), items.end(),sortName); + } else { - std::sort(items.begin(), items.end(), - [&](const IFriendListItemPtr &a, const IFriendListItemPtr &b) { - return cmpByActivity(a, b); + auto sortActivity = [&](const IFriendListItemPtr &a, const IFriendListItemPtr &b) { + return cmpByActivity(a, b); + }; + if (!needSort) { + if (std::is_sorted(items.begin(), items.end(), sortActivity)) { + positionsChanged = false; + return; } - ); + } + std::sort(items.begin(), items.end(), sortActivity); } + + needSort = false; +} + +void FriendListManager::setSortRequired() +{ + needSort = true; + emit itemsChanged(); } void FriendListManager::setGroupsOnTop(bool v) diff --git a/src/model/friendlist/friendlistmanager.h b/src/model/friendlist/friendlistmanager.h index a3c3dd2b9..e4cd05913 100644 --- a/src/model/friendlist/friendlistmanager.h +++ b/src/model/friendlist/friendlistmanager.h @@ -32,10 +32,12 @@ class FriendListManager : public QObject public: using IFriendListItemPtr = std::shared_ptr; - explicit FriendListManager(QObject *parent = nullptr); + explicit FriendListManager(int countContacts, QObject *parent = nullptr); QVector getItems() const; bool needHideCircles() const; + // If the contact positions have changed, need to redraw view + bool getPositionsChanged() const; void addFriendListItem(IFriendListItem* item); void removeFriendListItem(IFriendListItem* item); @@ -45,7 +47,8 @@ public: void setFilter(const QString& searchString, bool hideOnline, bool hideOffline, bool hideGroups); void applyFilter(); - void updatePositions(); + void updatePositions(); + void setSortRequired(); void setGroupsOnTop(bool v); @@ -67,6 +70,10 @@ private: bool byName = true; bool hideCircles = false; bool groupsOnTop; + bool positionsChanged; + bool needSort; QVector items; + // At startup, while the size of items is less than countContacts, the view will not be processed to improve performance + int countContacts; }; diff --git a/src/widget/friendlistwidget.cpp b/src/widget/friendlistwidget.cpp index e358e8676..3250cf022 100644 --- a/src/widget/friendlistwidget.cpp +++ b/src/widget/friendlistwidget.cpp @@ -101,7 +101,8 @@ FriendListWidget::FriendListWidget(const Core &_core, Widget* parent, bool group : QWidget(parent) , core{_core} { - manager = new FriendListManager(this); + int countContacts = core.getFriendList().size(); + manager = new FriendListManager(countContacts, this); manager->setGroupsOnTop(groupsOnTop); connect(manager, &FriendListManager::itemsChanged, this, &FriendListWidget::itemsChanged); @@ -137,15 +138,18 @@ void FriendListWidget::setMode(SortingMode mode) this->mode = mode; Settings::getInstance().setFriendSortingMode(mode); - sortByMode(mode); + manager->setSortRequired(); } void FriendListWidget::sortByMode(SortingMode mode) { - cleanMainLayout(); - if (mode == SortingMode::Name) { manager->sortByName(); + if (!manager->getPositionsChanged()) { + return; + } + + cleanMainLayout(); for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) { addCircleWidget(i); @@ -202,6 +206,13 @@ void FriendListWidget::sortByMode(SortingMode mode) } } } else if (mode == SortingMode::Activity) { + + manager->sortByActivity(); + if (!manager->getPositionsChanged()) { + return; + } + cleanMainLayout(); + QLocale ql(Settings::getInstance().getTranslation()); QDate today = QDate::currentDate(); #define COMMENT "Category for sorting friends by activity" @@ -222,7 +233,6 @@ void FriendListWidget::sortByMode(SortingMode mode) // clang-format on #undef COMMENT - manager->sortByActivity(); QVector> itemsTmp = manager->getItems(); for (int i = 0; i < itemsTmp.size(); ++i) { @@ -386,9 +396,9 @@ void FriendListWidget::addCircleWidget(FriendWidget* friendWidget) if (window()->isActiveWindow()) circleWidget->editName(); - } - itemsChanged(); + manager->setSortRequired(); + } } void FriendListWidget::removeCircleWidget(CircleWidget* widget) @@ -412,7 +422,7 @@ void FriendListWidget::renameCircleWidget(CircleWidget* circleWidget, const QStr circleWidget->setName(newName); if (mode == SortingMode::Name) { - itemsChanged(); + manager->setSortRequired(); } } @@ -423,7 +433,6 @@ void FriendListWidget::onGroupchatPositionChanged(bool top) if (mode != SortingMode::Name) return; - manager->updatePositions(); itemsChanged(); } @@ -559,10 +568,12 @@ void FriendListWidget::moveWidget(FriendWidget* widget, Status::Status s, bool a CircleWidget* circleWidget = CircleWidget::getFromID(circleId); if (circleWidget == nullptr || add) { - if (circleId != -1) + if (circleId != -1) { Settings::getInstance().setFriendCircleID(f->getPublicKey(), -1); - - itemsChanged(); + manager->setSortRequired(); + } else { + itemsChanged(); + } return; }