1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Merge pull request #6388

bodwok (1):
      fix(ui): contact list optimization
This commit is contained in:
Anthony Bilinski 2021-10-24 22:29:14 -07:00
commit 26f021e8bd
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
3 changed files with 74 additions and 29 deletions

View File

@ -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::IFriendListItemPtr> 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)

View File

@ -32,10 +32,12 @@ class FriendListManager : public QObject
public:
using IFriendListItemPtr = std::shared_ptr<IFriendListItem>;
explicit FriendListManager(QObject *parent = nullptr);
explicit FriendListManager(int countContacts, QObject *parent = nullptr);
QVector<IFriendListItemPtr> 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<IFriendListItemPtr> items;
// At startup, while the size of items is less than countContacts, the view will not be processed to improve performance
int countContacts;
};

View File

@ -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<std::shared_ptr<IFriendListItem>> 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;
}