feat: create text particles in a stream

This commit is contained in:
talksik
2026-02-06 13:04:16 -08:00
parent f3e5b90191
commit dd655c9679
6 changed files with 111 additions and 4 deletions
+2
View File
@@ -36,6 +36,8 @@ qt_add_executable(llink
src/networkstreammodel.cpp src/networkstreammodel.cpp
src/particlelistmodel.h src/particlelistmodel.h
src/particlelistmodel.cpp src/particlelistmodel.cpp
src/textinputdialog.h
src/textinputdialog.cpp
) )
qt_add_resources(llink qt_add_resources(llink
+44 -1
View File
@@ -6,23 +6,28 @@
#include "authdialog.h" #include "authdialog.h"
#include "authmanager.h" #include "authmanager.h"
#include "settingsdialog.h" #include "settingsdialog.h"
#include "textinputdialog.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include <QApplication> #include <QApplication>
#include <QHeaderView> #include <QHeaderView>
#include <QItemSelectionModel> #include <QItemSelectionModel>
#include <QLabel> #include <QLabel>
#include <QMenu> #include <QMenu>
#include <QKeyEvent>
#include <QMouseEvent> #include <QMouseEvent>
#include <QRandomGenerator> #include <QRandomGenerator>
#include <QToolButton>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QTimer> #include <QTimer>
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), m_trayIcon(nullptr), m_authManager(new AuthManager(this)), m_settingsDialog(nullptr), : QMainWindow(parent), m_trayIcon(nullptr), m_authManager(new AuthManager(this)), m_settingsDialog(nullptr),
m_authDialog(nullptr), m_store(nullptr), m_networkStreamModel(nullptr), m_particleListModel(nullptr), m_authDialog(nullptr), m_store(nullptr), m_networkStreamModel(nullptr), m_particleListModel(nullptr),
m_selectedParticleRow(-1), m_isDragging(false) m_selectedParticleRow(-1), m_isDragging(false), m_textInputDialog(nullptr)
{ {
m_authDialog = new AuthDialog(this); m_authDialog = new AuthDialog(this);
m_textInputDialog = new TextInputDialog(this);
connect(m_textInputDialog, &TextInputDialog::textSubmitted, this, &MainWindow::onTextMessageSubmitted);
ui = new Ui::MainWindow; ui = new Ui::MainWindow;
ui->setupUi(this); ui->setupUi(this);
@@ -102,6 +107,9 @@ MainWindow::MainWindow(QWidget *parent)
ui->topLevelParticlesView->expandAll(); ui->topLevelParticlesView->expandAll();
}); });
// DocumentSend toolbar button opens text input dialog
connect(ui->toolButton_3, &QToolButton::clicked, this, &MainWindow::showTextInputDialog);
m_authManager->tryRestoreSession(); m_authManager->tryRestoreSession();
setupTrayIcon(); setupTrayIcon();
@@ -181,6 +189,9 @@ void MainWindow::setupModels()
connect(ui->particlesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, connect(ui->particlesView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&MainWindow::onParticleSelectionChanged); &MainWindow::onParticleSelectionChanged);
// Install event filter to capture key presses from child views
ui->topLevelParticlesView->installEventFilter(this);
ui->particlesView->installEventFilter(this);
} }
void MainWindow::onTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) void MainWindow::onTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
@@ -376,6 +387,38 @@ void MainWindow::updatePingIndicator()
m_pingLabel->setText("connected " + QString::number(currentPing) + "ms"); m_pingLabel->setText("connected " + QString::number(currentPing) + "ms");
} }
void MainWindow::showTextInputDialog()
{
if (m_selectedStreamId.isEmpty())
return;
m_textInputDialog->show();
m_textInputDialog->raise();
m_textInputDialog->activateWindow();
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
auto *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_T && keyEvent->modifiers() == Qt::NoModifier && !m_selectedStreamId.isEmpty())
{
showTextInputDialog();
return true;
}
}
return QMainWindow::eventFilter(obj, event);
}
void MainWindow::onTextMessageSubmitted(const QString &text)
{
if (m_selectedStreamId.isEmpty())
return;
m_store->createParticle(m_selectedStreamId, "text", {{"content", text}});
}
void MainWindow::mousePressEvent(QMouseEvent *event) void MainWindow::mousePressEvent(QMouseEvent *event)
{ {
if (event->button() == Qt::LeftButton) if (event->button() == Qt::LeftButton)
+5
View File
@@ -19,6 +19,7 @@ QT_END_NAMESPACE
class AuthDialog; class AuthDialog;
class SettingsDialog; class SettingsDialog;
class TextInputDialog;
namespace Ui namespace Ui
{ {
@@ -41,8 +42,10 @@ private slots:
void onTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void onTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void onParticleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void onParticleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void onTextMessageSubmitted(const QString &text);
protected: protected:
bool eventFilter(QObject *obj, QEvent *event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override;
@@ -58,12 +61,14 @@ private:
AuthDialog *m_authDialog; AuthDialog *m_authDialog;
SettingsDialog *m_settingsDialog; SettingsDialog *m_settingsDialog;
TextInputDialog *m_textInputDialog;
// Data and models // Data and models
Store *m_store; Store *m_store;
NetworkStreamModel *m_networkStreamModel; NetworkStreamModel *m_networkStreamModel;
ParticleListModel *m_particleListModel; ParticleListModel *m_particleListModel;
void showTextInputDialog();
void updateStatusBar(); void updateStatusBar();
void updatePingIndicator(); void updatePingIndicator();
QString m_selectedParticleId; QString m_selectedParticleId;
+3 -3
View File
@@ -247,7 +247,7 @@
<number>1</number> <number>1</number>
</property> </property>
<property name="text"> <property name="text">
<string>asdfasdf</string> <string></string>
</property> </property>
<property name="scaledContents"> <property name="scaledContents">
<bool>true</bool> <bool>true</bool>
@@ -282,7 +282,7 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>[email protected]</string> <string></string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set> <set>Qt::AlignmentFlag::AlignCenter</set>
@@ -292,7 +292,7 @@
<item> <item>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>acked by: arthur, ed, sam</string> <string></string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set> <set>Qt::AlignmentFlag::AlignCenter</set>
+28
View File
@@ -0,0 +1,28 @@
#include "textinputdialog.h"
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
TextInputDialog::TextInputDialog(QWidget *parent)
: QDialog(parent), m_lineEdit(new QLineEdit(this)), m_sendButton(new QPushButton("Send", this))
{
setWindowTitle("Send Text Message");
auto *layout = new QVBoxLayout(this);
layout->addWidget(m_lineEdit);
layout->addWidget(m_sendButton);
connect(m_lineEdit, &QLineEdit::returnPressed, this, &TextInputDialog::onSubmit);
connect(m_sendButton, &QPushButton::clicked, this, &TextInputDialog::onSubmit);
}
void TextInputDialog::onSubmit()
{
QString text = m_lineEdit->text().trimmed();
if (text.isEmpty())
return;
emit textSubmitted(text);
m_lineEdit->clear();
hide();
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef TEXTINPUTDIALOG_H
#define TEXTINPUTDIALOG_H
#include <QDialog>
QT_BEGIN_NAMESPACE
class QLineEdit;
class QPushButton;
QT_END_NAMESPACE
class TextInputDialog : public QDialog
{
Q_OBJECT
public:
explicit TextInputDialog(QWidget *parent = nullptr);
signals:
void textSubmitted(const QString &text);
private slots:
void onSubmit();
private:
QLineEdit *m_lineEdit;
QPushButton *m_sendButton;
};
#endif // TEXTINPUTDIALOG_H