fix profile manager

This commit is contained in:
arm64v8a
2023-07-22 15:30:08 +09:00
parent 7f664b1c48
commit 9afa9f3128
11 changed files with 135 additions and 85 deletions

View File

@@ -3,6 +3,7 @@
#include "fmt/includes.h" #include "fmt/includes.h"
#include <QFile> #include <QFile>
#include <QDir>
#include <QColor> #include <QColor>
namespace NekoGui { namespace NekoGui {
@@ -10,34 +11,80 @@ namespace NekoGui {
ProfileManager *profileManager = new ProfileManager(); ProfileManager *profileManager = new ProfileManager();
ProfileManager::ProfileManager() : JsonStore("groups/pm.json") { ProfileManager::ProfileManager() : JsonStore("groups/pm.json") {
callback_after_load = [this]() { LoadManager(); }; _add(new configItem("groups", &groupsTabOrder, itemType::integerList));
callback_before_save = [this]() { SaveManager(); }; }
_add(new configItem("profiles", &_profiles, itemType::integerList));
_add(new configItem("groups", &_groups, itemType::integerList)); QList<int> filterIntJsonFile(const QString &path) {
QList<int> result;
QDir dr(path);
auto entryList = dr.entryList(QDir::Files);
for (auto e: entryList) {
e = e.toLower();
if (!e.endsWith(".json", Qt::CaseInsensitive)) continue;
e = e.remove(".json", Qt::CaseInsensitive);
bool ok;
auto id = e.toInt(&ok);
if (ok) {
result << id;
}
}
std::sort(result.begin(), result.end());
return result;
} }
void ProfileManager::LoadManager() { void ProfileManager::LoadManager() {
JsonStore::Load();
//
profiles = {}; profiles = {};
groups = {}; groups = {};
QList<int> invalidProfileId; profilesIdOrder = filterIntJsonFile("profiles");
for (auto id: _profiles) { groupsIdOrder = filterIntJsonFile("groups");
// Load Proxys
QList<int> delProfile;
for (auto id: profilesIdOrder) {
auto ent = LoadProxyEntity(QString("profiles/%1.json").arg(id)); auto ent = LoadProxyEntity(QString("profiles/%1.json").arg(id));
// Corrupted profile?
if (ent == nullptr || ent->bean == nullptr || ent->bean->version == -114514) { if (ent == nullptr || ent->bean == nullptr || ent->bean->version == -114514) {
// clear invalid profile delProfile << id;
invalidProfileId << id;
continue; continue;
} }
profiles[id] = ent; profiles[id] = ent;
} }
for (auto id: _groups) { // Clear Corrupted profile
groups[id] = LoadGroup(QString("groups/%1.json").arg(id)); for (auto id: delProfile) {
}
for (auto id: invalidProfileId) {
DeleteProfile(id); DeleteProfile(id);
} }
// Load Groups
auto loadedOrder = groupsTabOrder;
groupsTabOrder = {};
for (auto id: groupsIdOrder) {
auto ent = LoadGroup(QString("groups/%1.json").arg(id));
// Corrupted group?
if (ent->id != id) {
continue;
}
// Ensure order contains every group
if (!loadedOrder.contains(id)) {
loadedOrder << id;
}
groups[id] = ent;
}
// Ensure groups contains order
for (auto id: loadedOrder) {
if (groups.count(id)) {
groupsTabOrder << id;
}
}
// First setup
if (groups.empty()) {
auto defaultGroup = NekoGui::ProfileManager::NewGroup();
defaultGroup->name = QObject::tr("Default");
NekoGui::profileManager->AddGroup(defaultGroup);
}
} }
void ProfileManager::SaveManager() { void ProfileManager::SaveManager() {
JsonStore::Save();
} }
std::shared_ptr<ProxyEntity> ProfileManager::LoadProxyEntity(const QString &jsonPath) { std::shared_ptr<ProxyEntity> ProfileManager::LoadProxyEntity(const QString &jsonPath) {
@@ -153,7 +200,7 @@ namespace NekoGui {
if (profiles.empty()) { if (profiles.empty()) {
return 0; return 0;
} else { } else {
return profiles.lastKey() + 1; return profilesIdOrder.last() + 1;
} }
} }
@@ -165,8 +212,7 @@ namespace NekoGui {
ent->gid = gid < 0 ? dataStore->current_group : gid; ent->gid = gid < 0 ? dataStore->current_group : gid;
ent->id = NewProfileID(); ent->id = NewProfileID();
profiles[ent->id] = ent; profiles[ent->id] = ent;
_profiles.push_back(ent->id); profilesIdOrder.push_back(ent->id);
Save();
ent->fn = QString("profiles/%1.json").arg(ent->id); ent->fn = QString("profiles/%1.json").arg(ent->id);
ent->Save(); ent->Save();
@@ -176,9 +222,8 @@ namespace NekoGui {
void ProfileManager::DeleteProfile(int id) { void ProfileManager::DeleteProfile(int id) {
if (id < 0) return; if (id < 0) return;
if (dataStore->started_id == id) return; if (dataStore->started_id == id) return;
profiles.remove(id); profiles.erase(id);
_profiles.removeAll(id); profilesIdOrder.removeAll(id);
Save();
QFile(QString("profiles/%1.json").arg(id)).remove(); QFile(QString("profiles/%1.json").arg(id)).remove();
} }
@@ -199,7 +244,7 @@ namespace NekoGui {
} }
std::shared_ptr<ProxyEntity> ProfileManager::GetProfile(int id) { std::shared_ptr<ProxyEntity> ProfileManager::GetProfile(int id) {
return profiles.value(id, nullptr); return profiles.count(id) ? profiles[id] : nullptr;
} }
// Group // Group
@@ -228,7 +273,7 @@ namespace NekoGui {
if (groups.empty()) { if (groups.empty()) {
return 0; return 0;
} else { } else {
return groups.lastKey() + 1; return groupsIdOrder.last() + 1;
} }
} }
@@ -239,8 +284,8 @@ namespace NekoGui {
ent->id = NewGroupID(); ent->id = NewGroupID();
groups[ent->id] = ent; groups[ent->id] = ent;
_groups.push_back(ent->id); groupsIdOrder.push_back(ent->id);
Save(); groupsTabOrder.push_back(ent->id);
ent->fn = QString("groups/%1.json").arg(ent->id); ent->fn = QString("groups/%1.json").arg(ent->id);
ent->Save(); ent->Save();
@@ -248,22 +293,22 @@ namespace NekoGui {
} }
void ProfileManager::DeleteGroup(int gid) { void ProfileManager::DeleteGroup(int gid) {
if (groups.count() == 1) return; if (groups.size() <= 1) return;
QList<int> toDelete; QList<int> toDelete;
for (const auto &profile: profiles) { for (const auto &[id, profile]: profiles) {
if (profile->gid == gid) toDelete += profile->id; // map访问中不能操作 if (profile->gid == gid) toDelete += id; // map访问中不能操作
} }
for (const auto &id: toDelete) { for (const auto &id: toDelete) {
DeleteProfile(id); DeleteProfile(id);
} }
groups.remove(gid); groups.erase(gid);
_groups.removeAll(gid); groupsIdOrder.removeAll(gid);
Save(); groupsTabOrder.removeAll(gid);
QFile(QString("groups/%1.json").arg(gid)).remove(); QFile(QString("groups/%1.json").arg(gid)).remove();
} }
std::shared_ptr<Group> ProfileManager::GetGroup(int id) { std::shared_ptr<Group> ProfileManager::GetGroup(int id) {
return groups.value(id, nullptr); return groups.count(id) ? groups[id] : nullptr;
} }
std::shared_ptr<Group> ProfileManager::CurrentGroup() { std::shared_ptr<Group> ProfileManager::CurrentGroup() {
@@ -272,8 +317,8 @@ namespace NekoGui {
QList<std::shared_ptr<ProxyEntity>> Group::Profiles() const { QList<std::shared_ptr<ProxyEntity>> Group::Profiles() const {
QList<std::shared_ptr<ProxyEntity>> ret; QList<std::shared_ptr<ProxyEntity>> ret;
for (const auto &ent: profileManager->profiles) { for (const auto &[_, profile]: profileManager->profiles) {
if (id == ent->gid) ret += ent; if (id == profile->gid) ret += profile;
} }
return ret; return ret;
} }

View File

@@ -5,18 +5,25 @@
#include "Group.hpp" #include "Group.hpp"
namespace NekoGui { namespace NekoGui {
class ProfileManager : public JsonStore { class ProfileManager : private JsonStore {
public: public:
// Manager // JsonStore
QMap<int, std::shared_ptr<ProxyEntity>> profiles;
QMap<int, std::shared_ptr<Group>> groups;
// JSON // order -> id
QList<int> _profiles; QList<int> groupsTabOrder;
QList<int> _groups; // with order
// Manager
std::map<int, std::shared_ptr<ProxyEntity>> profiles;
std::map<int, std::shared_ptr<Group>> groups;
ProfileManager(); ProfileManager();
// LoadManager Reset and loads profiles & groups
void LoadManager();
void SaveManager();
[[nodiscard]] static std::shared_ptr<ProxyEntity> NewProxyEntity(const QString &type); [[nodiscard]] static std::shared_ptr<ProxyEntity> NewProxyEntity(const QString &type);
[[nodiscard]] static std::shared_ptr<Group> NewGroup(); [[nodiscard]] static std::shared_ptr<Group> NewGroup();
@@ -38,9 +45,9 @@ namespace NekoGui {
std::shared_ptr<Group> CurrentGroup(); std::shared_ptr<Group> CurrentGroup();
private: private:
void LoadManager(); // sort by id
QList<int> profilesIdOrder;
void SaveManager(); QList<int> groupsIdOrder;
[[nodiscard]] int NewProfileID() const; [[nodiscard]] int NewProfileID() const;

View File

@@ -348,13 +348,8 @@ namespace NekoGui {
} }
QStringList Routing::List() { QStringList Routing::List() {
QStringList l; QDir dr(ROUTES_PREFIX);
QDir d; return dr.entryList(QDir::Files);
if (d.exists(ROUTES_PREFIX)) {
QDir dr(ROUTES_PREFIX);
return dr.entryList(QDir::Files);
}
return l;
} }
void Routing::SetToActive(const QString &name) { void Routing::SetToActive(const QString &name) {

View File

@@ -58,11 +58,6 @@ namespace QtGrpc {
QString serviceName; QString serviceName;
QByteArray nekoray_auth; QByteArray nekoray_auth;
// TODO Fixed?
// https://github.com/semlanik/qtprotobuf/issues/116
// setCachingEnabled: 5 bytesDownloaded
// QNetworkReplyImpl: backend error: caching was enabled after some bytes had been written
// async // async
QNetworkReply *post(const QString &method, const QString &service, const QByteArray &args) { QNetworkReply *post(const QString &method, const QString &service, const QByteArray &args) {
QUrl callUrl = url_base + "/" + service + "/" + method; QUrl callUrl = url_base + "/" + service + "/" + method;

View File

@@ -1301,7 +1301,7 @@ This needs to be run NekoBox with administrator privileges.</source>
</message> </message>
<message> <message>
<source>Default</source> <source>Default</source>
<translation>پیش فرض</translation> <translation type="vanished">پیش فرض</translation>
</message> </message>
<message> <message>
<source>Load routing and apply: %1</source> <source>Load routing and apply: %1</source>
@@ -1650,6 +1650,10 @@ Direct: %2</source>
<source>As Subscription (add to this group)</source> <source>As Subscription (add to this group)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Default</source>
<translation type="unfinished">پیش فرض</translation>
</message>
</context> </context>
<context> <context>
<name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name> <name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name>

View File

@@ -1314,7 +1314,7 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
</message> </message>
<message> <message>
<source>Default</source> <source>Default</source>
<translation>По умолчанию</translation> <translation type="vanished">По умолчанию</translation>
</message> </message>
<message> <message>
<source>Load routing and apply: %1</source> <source>Load routing and apply: %1</source>
@@ -1646,6 +1646,10 @@ Release note:
<source>Used: %1 Remain: %2 Expire: %3</source> <source>Used: %1 Remain: %2 Expire: %3</source>
<translation>Использовано: %1, осталось: %2, истекло: %3</translation> <translation>Использовано: %1, осталось: %2, истекло: %3</translation>
</message> </message>
<message>
<source>Default</source>
<translation type="unfinished">По умолчанию</translation>
</message>
</context> </context>
<context> <context>
<name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name> <name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name>

View File

@@ -1151,7 +1151,7 @@ This needs to be run NekoBox with administrator privileges.</source>
</message> </message>
<message> <message>
<source>Default</source> <source>Default</source>
<translation></translation> <translation type="vanished"></translation>
</message> </message>
<message> <message>
<source>Confirmation</source> <source>Confirmation</source>
@@ -1644,6 +1644,10 @@ Release note:
<source>As Subscription (add to this group)</source> <source>As Subscription (add to this group)</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<source>Default</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name> <name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name>

View File

@@ -24,7 +24,7 @@
DialogManageGroups::DialogManageGroups(QWidget *parent) : QDialog(parent), ui(new Ui::DialogManageGroups) { DialogManageGroups::DialogManageGroups(QWidget *parent) : QDialog(parent), ui(new Ui::DialogManageGroups) {
ui->setupUi(this); ui->setupUi(this);
for (auto id: NekoGui::profileManager->_groups) { for (auto id: NekoGui::profileManager->groupsTabOrder) {
AddGroupToListIfExist(id) AddGroupToListIfExist(id)
} }
@@ -53,10 +53,10 @@ void DialogManageGroups::on_add_clicked() {
void DialogManageGroups::on_update_all_clicked() { void DialogManageGroups::on_update_all_clicked() {
if (QMessageBox::question(this, tr("Confirmation"), tr("Update all subscriptions?")) == QMessageBox::StandardButton::Yes) { if (QMessageBox::question(this, tr("Confirmation"), tr("Update all subscriptions?")) == QMessageBox::StandardButton::Yes) {
for (const auto &gid: NekoGui::profileManager->_groups) { for (const auto &gid: NekoGui::profileManager->groupsTabOrder) {
auto group = NekoGui::profileManager->GetGroup(gid); auto group = NekoGui::profileManager->GetGroup(gid);
if (group == nullptr || group->url.isEmpty()) continue; if (group == nullptr || group->url.isEmpty()) continue;
UI_update_one_group(NekoGui::profileManager->_groups.indexOf(gid)); UI_update_one_group(NekoGui::profileManager->groupsTabOrder.indexOf(gid));
return; return;
} }
} }
@@ -68,15 +68,15 @@ void UI_update_one_group(int _order) {
std::shared_ptr<NekoGui::Group> nextGroup; std::shared_ptr<NekoGui::Group> nextGroup;
forever { forever {
nextOrder += 1; nextOrder += 1;
if (nextOrder >= NekoGui::profileManager->_groups.length()) break; if (nextOrder >= NekoGui::profileManager->groupsTabOrder.size()) break;
auto nextGid = NekoGui::profileManager->_groups[nextOrder]; auto nextGid = NekoGui::profileManager->groupsTabOrder[nextOrder];
nextGroup = NekoGui::profileManager->GetGroup(nextGid); nextGroup = NekoGui::profileManager->GetGroup(nextGid);
if (nextGroup == nullptr || nextGroup->url.isEmpty()) continue; if (nextGroup == nullptr || nextGroup->url.isEmpty()) continue;
break; break;
} }
// calculate this group // calculate this group
auto group = NekoGui::profileManager->GetGroup(NekoGui::profileManager->_groups[_order]); auto group = NekoGui::profileManager->GetGroup(NekoGui::profileManager->groupsTabOrder[_order]);
if (group == nullptr) return; if (group == nullptr) return;
// v2.2: listener is moved to GroupItem, no refresh here. // v2.2: listener is moved to GroupItem, no refresh here.

View File

@@ -44,7 +44,7 @@ DialogEditGroup::DialogEditGroup(const std::shared_ptr<NekoGui::Group> &ent, QWi
connect(ui->copy_links, &QPushButton::clicked, this, [=] { connect(ui->copy_links, &QPushButton::clicked, this, [=] {
QStringList links; QStringList links;
for (const auto &profile: NekoGui::profileManager->profiles) { for (const auto &[_, profile]: NekoGui::profileManager->profiles) {
if (profile->gid != ent->id) continue; if (profile->gid != ent->id) continue;
links += profile->bean->ToShareLink(); links += profile->bean->ToShareLink();
} }
@@ -53,7 +53,7 @@ DialogEditGroup::DialogEditGroup(const std::shared_ptr<NekoGui::Group> &ent, QWi
}); });
connect(ui->copy_links_nkr, &QPushButton::clicked, this, [=] { connect(ui->copy_links_nkr, &QPushButton::clicked, this, [=] {
QStringList links; QStringList links;
for (const auto &profile: NekoGui::profileManager->profiles) { for (const auto &[_, profile]: NekoGui::profileManager->profiles) {
if (profile->gid != ent->id) continue; if (profile->gid != ent->id) continue;
links += profile->bean->ToNekorayShareLink(profile->type); links += profile->bean->ToNekorayShareLink(profile->type);
} }

View File

@@ -57,12 +57,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
}; };
// Load Manager // Load Manager
auto isLoaded = NekoGui::profileManager->Load(); NekoGui::profileManager->LoadManager();
if (!isLoaded) {
auto defaultGroup = NekoGui::ProfileManager::NewGroup();
defaultGroup->name = tr("Default");
NekoGui::profileManager->AddGroup(defaultGroup);
}
// Setup misc UI // Setup misc UI
themeManager->ApplyTheme(NekoGui::dataStore->theme); themeManager->ApplyTheme(NekoGui::dataStore->theme);
@@ -72,11 +67,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(ui->menu_stop, &QAction::triggered, this, [=]() { neko_stop(); }); connect(ui->menu_stop, &QAction::triggered, this, [=]() { neko_stop(); });
connect(ui->tabWidget->tabBar(), &QTabBar::tabMoved, this, [=](int from, int to) { connect(ui->tabWidget->tabBar(), &QTabBar::tabMoved, this, [=](int from, int to) {
// use tabData to track tab & gid // use tabData to track tab & gid
NekoGui::profileManager->_groups.clear(); NekoGui::profileManager->groupsTabOrder.clear();
for (int i = 0; i < ui->tabWidget->tabBar()->count(); i++) { for (int i = 0; i < ui->tabWidget->tabBar()->count(); i++) {
NekoGui::profileManager->_groups += ui->tabWidget->tabBar()->tabData(i).toInt(); NekoGui::profileManager->groupsTabOrder += ui->tabWidget->tabBar()->tabData(i).toInt();
} }
NekoGui::profileManager->Save(); NekoGui::profileManager->SaveManager();
}); });
ui->label_running->installEventFilter(this); ui->label_running->installEventFilter(this);
ui->label_inbound->installEventFilter(this); ui->label_inbound->installEventFilter(this);
@@ -458,13 +453,13 @@ MainWindow::~MainWindow() {
// Group tab manage // Group tab manage
inline int tabIndex2GroupId(int index) { inline int tabIndex2GroupId(int index) {
if (NekoGui::profileManager->_groups.length() <= index) return -1; if (NekoGui::profileManager->groupsTabOrder.length() <= index) return -1;
return NekoGui::profileManager->_groups[index]; return NekoGui::profileManager->groupsTabOrder[index];
} }
inline int groupId2TabIndex(int gid) { inline int groupId2TabIndex(int gid) {
for (int key = 0; key < NekoGui::profileManager->_groups.count(); key++) { for (int key = 0; key < NekoGui::profileManager->groupsTabOrder.count(); key++) {
if (NekoGui::profileManager->_groups[key] == gid) return key; if (NekoGui::profileManager->groupsTabOrder[key] == gid) return key;
} }
return 0; return 0;
} }
@@ -646,6 +641,7 @@ void MainWindow::on_commitDataRequest() {
} }
// //
NekoGui::dataStore->Save(); NekoGui::dataStore->Save();
NekoGui::profileManager->SaveManager();
qDebug() << "End of data save"; qDebug() << "End of data save";
} }
@@ -903,7 +899,7 @@ void MainWindow::refresh_groups() {
} }
int index = 0; int index = 0;
for (const auto &gid: NekoGui::profileManager->_groups) { for (const auto &gid: NekoGui::profileManager->groupsTabOrder) {
auto group = NekoGui::profileManager->GetGroup(gid); auto group = NekoGui::profileManager->GetGroup(gid);
if (index == 0) { if (index == 0) {
ui->tabWidget->setTabText(0, group->name); ui->tabWidget->setTabText(0, group->name);
@@ -923,7 +919,7 @@ void MainWindow::refresh_groups() {
if (NekoGui::profileManager->CurrentGroup() == nullptr) { if (NekoGui::profileManager->CurrentGroup() == nullptr) {
NekoGui::dataStore->current_group = -1; NekoGui::dataStore->current_group = -1;
ui->tabWidget->setCurrentIndex(groupId2TabIndex(0)); ui->tabWidget->setCurrentIndex(groupId2TabIndex(0));
show_group(NekoGui::profileManager->_groups.count() > 0 ? NekoGui::profileManager->_groups.first() : 0); show_group(NekoGui::profileManager->groupsTabOrder.count() > 0 ? NekoGui::profileManager->groupsTabOrder.first() : 0);
} else { } else {
ui->tabWidget->setCurrentIndex(groupId2TabIndex(NekoGui::dataStore->current_group)); ui->tabWidget->setCurrentIndex(groupId2TabIndex(NekoGui::dataStore->current_group));
show_group(NekoGui::dataStore->current_group); show_group(NekoGui::dataStore->current_group);
@@ -944,11 +940,11 @@ void MainWindow::refresh_proxy_list_impl(const int &id, GroupSortAction groupSor
ui->proxyListTable->setRowCount(0); ui->proxyListTable->setRowCount(0);
// 添加行 // 添加行
int row = -1; int row = -1;
for (const auto &profile: NekoGui::profileManager->profiles) { for (const auto &[id, profile]: NekoGui::profileManager->profiles) {
if (NekoGui::dataStore->current_group != profile->gid) continue; if (NekoGui::dataStore->current_group != profile->gid) continue;
row++; row++;
ui->proxyListTable->insertRow(row); ui->proxyListTable->insertRow(row);
ui->proxyListTable->row2Id += profile->id; ui->proxyListTable->row2Id += id;
} }
} }
@@ -1121,7 +1117,7 @@ void MainWindow::on_menu_move_triggered() {
if (ents.isEmpty()) return; if (ents.isEmpty()) return;
auto items = QStringList{}; auto items = QStringList{};
for (auto gid: NekoGui::profileManager->_groups) { for (auto gid: NekoGui::profileManager->groupsTabOrder) {
auto group = NekoGui::profileManager->GetGroup(gid); auto group = NekoGui::profileManager->GetGroup(gid);
if (group == nullptr) continue; if (group == nullptr) continue;
items += Int2String(gid) + " " + group->name; items += Int2String(gid) + " " + group->name;
@@ -1170,7 +1166,7 @@ void MainWindow::on_menu_profile_debug_info_triggered() {
QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(QString("profiles/%1.json").arg(ents.first()->id)).absoluteFilePath())); QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(QString("profiles/%1.json").arg(ents.first()->id)).absoluteFilePath()));
} else if (btn == 2) { } else if (btn == 2) {
NekoGui::dataStore->Load(); NekoGui::dataStore->Load();
NekoGui::profileManager->Load(); NekoGui::profileManager->LoadManager();
refresh_proxy_list(); refresh_proxy_list();
} }
} }
@@ -1398,7 +1394,7 @@ void MainWindow::on_menu_update_subscription_triggered() {
void MainWindow::on_menu_remove_unavailable_triggered() { void MainWindow::on_menu_remove_unavailable_triggered() {
QList<std::shared_ptr<NekoGui::ProxyEntity>> out_del; QList<std::shared_ptr<NekoGui::ProxyEntity>> out_del;
for (const auto &profile: NekoGui::profileManager->profiles) { for (const auto &[_, profile]: NekoGui::profileManager->profiles) {
if (NekoGui::dataStore->current_group != profile->gid) continue; if (NekoGui::dataStore->current_group != profile->gid) continue;
if (profile->latency < 0) out_del += profile; if (profile->latency < 0) out_del += profile;
} }

View File

@@ -116,7 +116,7 @@ void GroupItem::on_edit_clicked() {
} }
void GroupItem::on_remove_clicked() { void GroupItem::on_remove_clicked() {
if (NekoGui::profileManager->groups.count() == 1) return; if (NekoGui::profileManager->groups.size() <= 1) return;
if (QMessageBox::question(this, tr("Confirmation"), tr("Remove %1?").arg(ent->name)) == if (QMessageBox::question(this, tr("Confirmation"), tr("Remove %1?").arg(ent->name)) ==
QMessageBox::StandardButton::Yes) { QMessageBox::StandardButton::Yes) {
NekoGui::profileManager->DeleteGroup(ent->id); NekoGui::profileManager->DeleteGroup(ent->id);