refactor: decouple network detail widget from business logic
This commit is contained in:
+41
-13
@@ -108,7 +108,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
m_splitter->setStretchFactor(0, 1);
|
m_splitter->setStretchFactor(0, 1);
|
||||||
m_splitter->setStretchFactor(1, 4);
|
m_splitter->setStretchFactor(1, 4);
|
||||||
m_splitter->setStretchFactor(2, 1);
|
m_splitter->setStretchFactor(2, 1);
|
||||||
m_splitter->setStretchFactor(3, 5);
|
|
||||||
|
|
||||||
setupModels();
|
setupModels();
|
||||||
|
|
||||||
@@ -124,7 +123,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
connect(m_authManager, &AuthManager::signedOut, m_authDialog, &AuthDialog::show);
|
connect(m_authManager, &AuthManager::signedOut, m_authDialog, &AuthDialog::show);
|
||||||
connect(m_authManager, &AuthManager::signedIn, this, [this]() {
|
connect(m_authManager, &AuthManager::signedIn, this, [this]() {
|
||||||
m_store->setCurrentUserEmail(m_authManager->sessionData()->email);
|
m_store->setCurrentUserEmail(m_authManager->sessionData()->email);
|
||||||
m_networkDetailWidget->setCurrentUserEmail(m_authManager->sessionData()->email);
|
|
||||||
m_store->loadStartupData();
|
m_store->loadStartupData();
|
||||||
});
|
});
|
||||||
connect(m_store, &Store::startupDataLoaded, this, [this]() {
|
connect(m_store, &Store::startupDataLoaded, this, [this]() {
|
||||||
@@ -158,9 +156,9 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
// "New stream" button
|
// "New stream" button
|
||||||
m_createStreamDialog = new CreateStreamDialog(this);
|
m_createStreamDialog = new CreateStreamDialog(this);
|
||||||
connect(m_newStreamButton, &QPushButton::clicked, this, [this]() {
|
connect(m_newStreamButton, &QPushButton::clicked, this, [this]() {
|
||||||
if (m_selectedNetworkName.isEmpty())
|
if (m_selectedNetworkId.isEmpty())
|
||||||
return;
|
return;
|
||||||
const Network *network = m_store->networkById(m_selectedNetworkName);
|
const Network *network = m_store->networkById(m_selectedNetworkId);
|
||||||
if (network)
|
if (network)
|
||||||
m_createStreamDialog->setNetworkMembers(network->members);
|
m_createStreamDialog->setNetworkMembers(network->members);
|
||||||
m_createStreamDialog->show();
|
m_createStreamDialog->show();
|
||||||
@@ -169,14 +167,14 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
});
|
});
|
||||||
connect(m_createStreamDialog, &CreateStreamDialog::streamRequested, this,
|
connect(m_createStreamDialog, &CreateStreamDialog::streamRequested, this,
|
||||||
[this](const QString &name, const QString &visibility, const QStringList &members) {
|
[this](const QString &name, const QString &visibility, const QStringList &members) {
|
||||||
m_store->createStream(m_selectedNetworkName, name, "", visibility, members);
|
m_store->createStream(m_selectedNetworkId, name, "", visibility, members);
|
||||||
});
|
});
|
||||||
|
|
||||||
// "Add members" toolbar button (ListAdd icon in right sidebar)
|
// "Add members" toolbar button (ListAdd icon in right sidebar)
|
||||||
connect(m_addMembersButton, &QToolButton::clicked, this, [this]() {
|
connect(m_addMembersButton, &QToolButton::clicked, this, [this]() {
|
||||||
if (m_selectedStreamId.isEmpty() || m_selectedNetworkName.isEmpty())
|
if (m_selectedStreamId.isEmpty() || m_selectedNetworkId.isEmpty())
|
||||||
return;
|
return;
|
||||||
const Network *network = m_store->networkById(m_selectedNetworkName);
|
const Network *network = m_store->networkById(m_selectedNetworkId);
|
||||||
const Stream *stream = m_store->streamById(m_selectedStreamId);
|
const Stream *stream = m_store->streamById(m_selectedStreamId);
|
||||||
if (!network || !stream)
|
if (!network || !stream)
|
||||||
return;
|
return;
|
||||||
@@ -446,10 +444,32 @@ void MainWindow::setupModels()
|
|||||||
// Create store (data loaded after sign-in via loadStartupData)
|
// Create store (data loaded after sign-in via loadStartupData)
|
||||||
m_store = new Store(this);
|
m_store = new Store(this);
|
||||||
|
|
||||||
m_networkDetailWidget = new NetworkDetailWidget(m_store);
|
m_networkDetailWidget = new NetworkDetailWidget(this);
|
||||||
m_splitter->addWidget(m_networkDetailWidget);
|
m_splitter->addWidget(m_networkDetailWidget);
|
||||||
|
m_splitter->setStretchFactor(3, 4);
|
||||||
m_networkDetailWidget->hide();
|
m_networkDetailWidget->hide();
|
||||||
|
|
||||||
|
// Push fresh data when networks change
|
||||||
|
connect(m_store, &Store::networksChanged, this, [this]() {
|
||||||
|
if (!m_selectedNetworkId.isEmpty() && m_networkDetailWidget->isVisible())
|
||||||
|
{
|
||||||
|
const Network *network = m_store->networkById(m_selectedNetworkId);
|
||||||
|
if (network)
|
||||||
|
m_networkDetailWidget->setNetwork(*network, m_authManager->sessionData() ? m_authManager->sessionData()->email : QString());
|
||||||
|
else
|
||||||
|
m_networkDetailWidget->clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle add-member requests from the widget
|
||||||
|
connect(m_networkDetailWidget, &NetworkDetailWidget::addMemberRequested, this,
|
||||||
|
[this](const QString &networkId, const QString &email) {
|
||||||
|
auto *op = m_store->addNetworkMembers(networkId, {email});
|
||||||
|
connect(op, &Operation::success, this, [this, networkId](const QJsonDocument &) {
|
||||||
|
m_store->fetchNetwork(networkId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Create and set tree model
|
// Create and set tree model
|
||||||
m_networkStreamModel = new NetworkStreamModel(m_store, this);
|
m_networkStreamModel = new NetworkStreamModel(m_store, this);
|
||||||
m_treeView->setModel(m_networkStreamModel);
|
m_treeView->setModel(m_networkStreamModel);
|
||||||
@@ -514,7 +534,7 @@ void MainWindow::onTreeSelectionChanged(const QItemSelection &selected, const QI
|
|||||||
// Also track the parent network
|
// Also track the parent network
|
||||||
QModelIndex parentIndex = m_networkStreamModel->parent(index);
|
QModelIndex parentIndex = m_networkStreamModel->parent(index);
|
||||||
QString networkId = m_networkStreamModel->networkIdFromIndex(parentIndex);
|
QString networkId = m_networkStreamModel->networkIdFromIndex(parentIndex);
|
||||||
m_selectedNetworkName = networkId;
|
m_selectedNetworkId = networkId;
|
||||||
|
|
||||||
// Show stream members
|
// Show stream members
|
||||||
m_membersList->clear();
|
m_membersList->clear();
|
||||||
@@ -548,10 +568,18 @@ void MainWindow::onTreeSelectionChanged(const QItemSelection &selected, const QI
|
|||||||
m_membersList->clear();
|
m_membersList->clear();
|
||||||
|
|
||||||
QString networkId = m_networkStreamModel->networkIdFromIndex(index);
|
QString networkId = m_networkStreamModel->networkIdFromIndex(index);
|
||||||
m_selectedNetworkName = networkId;
|
m_selectedNetworkId = networkId;
|
||||||
|
|
||||||
// Show network detail widget
|
// Show network detail widget
|
||||||
m_networkDetailWidget->setNetwork(networkId);
|
const Network *network = m_store->networkById(networkId);
|
||||||
|
if (network)
|
||||||
|
{
|
||||||
|
m_networkDetailWidget->setNetwork(*network, m_authManager->sessionData() ? m_authManager->sessionData()->email : QString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_networkDetailWidget->clear();
|
||||||
|
}
|
||||||
m_contentView->hide();
|
m_contentView->hide();
|
||||||
m_rightSidebar->hide();
|
m_rightSidebar->hide();
|
||||||
m_networkDetailWidget->show();
|
m_networkDetailWidget->show();
|
||||||
@@ -622,9 +650,9 @@ void MainWindow::updateStatusBar()
|
|||||||
QStringList pathComponents;
|
QStringList pathComponents;
|
||||||
|
|
||||||
// Add network if selected
|
// Add network if selected
|
||||||
if (!m_selectedNetworkName.isEmpty())
|
if (!m_selectedNetworkId.isEmpty())
|
||||||
{
|
{
|
||||||
const Network *network = m_store->networkById(m_selectedNetworkName);
|
const Network *network = m_store->networkById(m_selectedNetworkId);
|
||||||
if (network)
|
if (network)
|
||||||
{
|
{
|
||||||
pathComponents << network->name;
|
pathComponents << network->name;
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@ private:
|
|||||||
void showTextInputDialog();
|
void showTextInputDialog();
|
||||||
void updateStatusBar();
|
void updateStatusBar();
|
||||||
QString m_selectedParticleId;
|
QString m_selectedParticleId;
|
||||||
QString m_selectedNetworkName;
|
QString m_selectedNetworkId;
|
||||||
QString m_selectedStreamId;
|
QString m_selectedStreamId;
|
||||||
int m_selectedParticleRow;
|
int m_selectedParticleRow;
|
||||||
QLabel *m_currentPathLabel;
|
QLabel *m_currentPathLabel;
|
||||||
|
|||||||
+25
-49
@@ -1,5 +1,4 @@
|
|||||||
#include "networkdetailwidget.h"
|
#include "networkdetailwidget.h"
|
||||||
#include "store.h"
|
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
@@ -8,8 +7,8 @@
|
|||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
NetworkDetailWidget::NetworkDetailWidget(Store *store, QWidget *parent)
|
NetworkDetailWidget::NetworkDetailWidget(QWidget *parent)
|
||||||
: QWidget(parent), m_store(store)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
auto *layout = new QVBoxLayout(this);
|
auto *layout = new QVBoxLayout(this);
|
||||||
layout->setContentsMargins(16, 16, 16, 16);
|
layout->setContentsMargins(16, 16, 16, 16);
|
||||||
@@ -54,7 +53,6 @@ NetworkDetailWidget::NetworkDetailWidget(Store *store, QWidget *parent)
|
|||||||
buttonRow->addStretch();
|
buttonRow->addStretch();
|
||||||
layout->addLayout(buttonRow);
|
layout->addLayout(buttonRow);
|
||||||
|
|
||||||
// Admin actions
|
|
||||||
connect(m_addMemberBtn, &QPushButton::clicked, this, [this]() {
|
connect(m_addMemberBtn, &QPushButton::clicked, this, [this]() {
|
||||||
bool ok;
|
bool ok;
|
||||||
QString email = QInputDialog::getText(this, "Add Member",
|
QString email = QInputDialog::getText(this, "Add Member",
|
||||||
@@ -62,64 +60,42 @@ NetworkDetailWidget::NetworkDetailWidget(Store *store, QWidget *parent)
|
|||||||
QString(), &ok);
|
QString(), &ok);
|
||||||
if (ok && !email.isEmpty())
|
if (ok && !email.isEmpty())
|
||||||
{
|
{
|
||||||
auto *op = m_store->addNetworkMembers(m_networkId, {email});
|
emit addMemberRequested(m_networkId, email);
|
||||||
connect(op, &Operation::success, this, [this](const QJsonDocument &) {
|
|
||||||
m_store->fetchNetwork(m_networkId);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh when networks change
|
|
||||||
connect(m_store, &Store::networksChanged, this, [this]() {
|
|
||||||
if (!m_networkId.isEmpty())
|
|
||||||
refresh();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkDetailWidget::setNetwork(const QString &networkId)
|
void NetworkDetailWidget::setNetwork(const Network &network, const QString ¤tUserEmail)
|
||||||
{
|
{
|
||||||
m_networkId = networkId;
|
m_networkId = network.id;
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkDetailWidget::setCurrentUserEmail(const QString &email)
|
m_nameLabel->setText(network.name);
|
||||||
{
|
m_adminLabel->setText("Admin: " + network.admin.emailPrefix);
|
||||||
m_currentUserEmail = email;
|
|
||||||
if (!m_networkId.isEmpty())
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkDetailWidget::refresh()
|
m_streamBar->setMaximum(network.openStreamCapacity > 0 ? network.openStreamCapacity : 1);
|
||||||
{
|
m_streamBar->setValue(network.openStreamCount);
|
||||||
const Network *network = m_store->networkById(m_networkId);
|
|
||||||
if (!network)
|
|
||||||
{
|
|
||||||
m_nameLabel->setText("");
|
|
||||||
m_adminLabel->setText("");
|
|
||||||
m_streamBar->setValue(0);
|
|
||||||
m_streamBarLabel->setText("");
|
|
||||||
m_membersList->clear();
|
|
||||||
m_addMemberBtn->hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nameLabel->setText(network->name);
|
|
||||||
m_adminLabel->setText("Admin: " + network->admin.emailPrefix);
|
|
||||||
|
|
||||||
m_streamBar->setMaximum(network->openStreamCapacity > 0 ? network->openStreamCapacity : 1);
|
|
||||||
m_streamBar->setValue(network->openStreamCount);
|
|
||||||
m_streamBarLabel->setText(QString("%1 / %2 open streams")
|
m_streamBarLabel->setText(QString("%1 / %2 open streams")
|
||||||
.arg(network->openStreamCount)
|
.arg(network.openStreamCount)
|
||||||
.arg(network->openStreamCapacity));
|
.arg(network.openStreamCapacity));
|
||||||
|
|
||||||
m_membersList->clear();
|
m_membersList->clear();
|
||||||
for (const auto &member : network->members)
|
for (const auto &member : network.members)
|
||||||
{
|
{
|
||||||
m_membersList->addItem(member.email);
|
m_membersList->addItem(member.email);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show admin controls only if current user is admin
|
bool isAdmin = (!currentUserEmail.isEmpty() &&
|
||||||
bool isAdmin = (!m_currentUserEmail.isEmpty() &&
|
currentUserEmail == network.admin.email);
|
||||||
m_currentUserEmail == network->admin.email);
|
|
||||||
m_addMemberBtn->setVisible(isAdmin);
|
m_addMemberBtn->setVisible(isAdmin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkDetailWidget::clear()
|
||||||
|
{
|
||||||
|
m_networkId.clear();
|
||||||
|
m_nameLabel->setText("");
|
||||||
|
m_adminLabel->setText("");
|
||||||
|
m_streamBar->setValue(0);
|
||||||
|
m_streamBarLabel->setText("");
|
||||||
|
m_membersList->clear();
|
||||||
|
m_addMemberBtn->hide();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,30 +1,31 @@
|
|||||||
#ifndef NETWORKDETAILWIDGET_H
|
#ifndef NETWORKDETAILWIDGET_H
|
||||||
#define NETWORKDETAILWIDGET_H
|
#define NETWORKDETAILWIDGET_H
|
||||||
|
|
||||||
|
#include "models.h"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class Store;
|
QT_BEGIN_NAMESPACE
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QProgressBar;
|
class QProgressBar;
|
||||||
class QListWidget;
|
class QListWidget;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
class NetworkDetailWidget : public QWidget
|
class NetworkDetailWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NetworkDetailWidget(Store *store, QWidget *parent = nullptr);
|
explicit NetworkDetailWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
void setNetwork(const QString &networkId);
|
void setNetwork(const Network &network, const QString ¤tUserEmail);
|
||||||
void setCurrentUserEmail(const QString &email);
|
void clear();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void addMemberRequested(const QString &networkId, const QString &email);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refresh();
|
|
||||||
|
|
||||||
Store *m_store;
|
|
||||||
QString m_networkId;
|
QString m_networkId;
|
||||||
QString m_currentUserEmail;
|
|
||||||
|
|
||||||
QLabel *m_nameLabel;
|
QLabel *m_nameLabel;
|
||||||
QLabel *m_adminLabel;
|
QLabel *m_adminLabel;
|
||||||
|
|||||||
Reference in New Issue
Block a user