From 24316e8cf89f3d24548d7d4233a2a40f1b9913fd Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 4 Aug 2026 22:42:22 +0300 Subject: [PATCH] split InviteDialog into ShareInviteDialog + InviteByLinkDialog, add INV button to channel list --- tools/chatgui/CMakeLists.txt | 1 + tools/chatgui/src/channellist.cpp | 14 ++ tools/chatgui/src/channellist.h | 1 + tools/chatgui/src/inviteby.cpp | 189 ++++++++++++++++++++++++ tools/chatgui/src/inviteby.h | 30 ++++ tools/chatgui/src/invitedialog.cpp | 225 +---------------------------- tools/chatgui/src/invitedialog.h | 27 +--- tools/chatgui/src/mainwindow.cpp | 17 ++- tools/chatgui/src/mainwindow.h | 3 +- 9 files changed, 259 insertions(+), 248 deletions(-) create mode 100644 tools/chatgui/src/inviteby.cpp create mode 100644 tools/chatgui/src/inviteby.h diff --git a/tools/chatgui/CMakeLists.txt b/tools/chatgui/CMakeLists.txt index 7a85743e..94c92b10 100644 --- a/tools/chatgui/CMakeLists.txt +++ b/tools/chatgui/CMakeLists.txt @@ -106,6 +106,7 @@ add_executable(chatgui src/qrcode_utils.cpp src/invite_link.cpp src/invitedialog.cpp + src/inviteby.cpp src/joindialog.cpp src/settingsdialog.cpp src/networksettingspage.cpp diff --git a/tools/chatgui/src/channellist.cpp b/tools/chatgui/src/channellist.cpp index 0cf579e2..878e653b 100644 --- a/tools/chatgui/src/channellist.cpp +++ b/tools/chatgui/src/channellist.cpp @@ -134,6 +134,20 @@ ChannelList::ChannelList(DbManager* db, QWidget *parent) connect(createBtn, &QPushButton::clicked, this, [this] { emit createGroupRequested(); }); fl->addWidget(createBtn); + auto *inviteBtn = new QPushButton("INV", footer); + inviteBtn->setFixedSize(36, 28); + inviteBtn->setToolTip(QString::fromUtf8("Пригласить в канал по ссылке")); + inviteBtn->setStyleSheet( + "QPushButton { border: 1.5px solid #E67E22; border-radius: 6px;" + " font-size: 11px; font-weight: bold; color: #E67E22; background: transparent; }" + "QPushButton:hover { background: #E67E22; color: white; }"); + connect(inviteBtn, &QPushButton::clicked, this, [this] { + QModelIndex cur = m_listView->currentIndex(); + if (cur.isValid()) + emit inviteByLinkRequested(cur.data(ChannelChannelIdRole).toString()); + }); + fl->addWidget(inviteBtn); + auto *plusBtn = new QPushButton("+", footer); plusBtn->setFixedSize(28, 28); plusBtn->setToolTip(QString::fromUtf8("Присоединиться")); diff --git a/tools/chatgui/src/channellist.h b/tools/chatgui/src/channellist.h index b779d312..5a4d38a5 100644 --- a/tools/chatgui/src/channellist.h +++ b/tools/chatgui/src/channellist.h @@ -22,6 +22,7 @@ public: signals: void channelSelected(const QString& channelId); void inviteRequested(const QString& channelId); + void inviteByLinkRequested(const QString& channelId); void joinRequested(); void createGroupRequested(); void settingsRequested(); diff --git a/tools/chatgui/src/inviteby.cpp b/tools/chatgui/src/inviteby.cpp new file mode 100644 index 00000000..50d01320 --- /dev/null +++ b/tools/chatgui/src/inviteby.cpp @@ -0,0 +1,189 @@ +#include "inviteby.h" +#include "invite_link.h" +#include "debug_ui.h" +#include "../transport/utun_node.h" +#include "../transport/gui_bridge.h" +#include "../db/db_manager.h" +extern "C" { +#include "chat/chat_core.h" +#include "chat/chat_sync.h" +#include "transport_layer/secure_channel.h" +} +#include +#include +#include +#include +#include +#include +#include +#include + +InviteByLinkDialog::InviteByLinkDialog(const QString& channelId, UtunNode* node, QWidget* parent) + : QDialog(parent), m_channelId(channelId), m_node(node) +{ + setWindowTitle(QString::fromUtf8("Пригласить в канал %1").arg(channelId)); + setMinimumWidth(420); + setModal(true); + + auto *layout = new QVBoxLayout(this); + layout->setSpacing(12); + + auto *title = new QLabel(QString::fromUtf8("Вставьте utun:// ссылку приглашаемого узла:"), this); + title->setStyleSheet("font-weight: bold; font-size: 12px;"); + layout->addWidget(title); + + m_inviteLinkEdit = new QLineEdit(this); + m_inviteLinkEdit->setPlaceholderText("utun://..."); + m_inviteLinkEdit->setStyleSheet( + "QLineEdit { border: 1px solid palette(mid); border-radius: 4px;" + " padding: 6px 8px; font-size: 12px; background: palette(base); }"); + layout->addWidget(m_inviteLinkEdit); + + m_inviteStatusLabel = new QLabel(this); + m_inviteStatusLabel->setWordWrap(true); + m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); + layout->addWidget(m_inviteStatusLabel); + + auto *btnLayout = new QHBoxLayout(); + btnLayout->addStretch(); + m_inviteSendBtn = new QPushButton(QString::fromUtf8("Пригласить"), this); + m_inviteSendBtn->setStyleSheet( + "QPushButton { border: none; border-radius: 4px;" + " padding: 5px 14px; font-size: 12px; font-weight: bold;" + " background: #3390EC; color: white; }" + "QPushButton:hover { background: #2B7ED4; }" + "QPushButton:disabled { background: palette(mid); color: palette(midlight); }"); + connect(m_inviteSendBtn, &QPushButton::clicked, this, &InviteByLinkDialog::onSendInvite); + btnLayout->addWidget(m_inviteSendBtn); + + auto *closeBtn = new QPushButton("OK", this); + connect(closeBtn, &QPushButton::clicked, this, &QDialog::accept); + btnLayout->addWidget(closeBtn); + layout->addLayout(btnLayout); + + connect(m_inviteLinkEdit, &QLineEdit::returnPressed, this, &InviteByLinkDialog::onSendInvite); + connect(m_inviteLinkEdit, &QLineEdit::textChanged, this, &InviteByLinkDialog::onInviteLinkTextChanged); +} + +void InviteByLinkDialog::onInviteLinkTextChanged() { + QString link = m_inviteLinkEdit->text().trimmed(); + if (link.isEmpty()) { + m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); + m_inviteStatusLabel->clear(); + return; + } + if (!link.startsWith(QLatin1String("utun://"))) { + m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); + m_inviteStatusLabel->setText(QString::fromUtf8("Ожидается utun:// ссылка...")); + return; + } + + InviteData d = decodeInviteLink(link); + if (!d.error.isEmpty()) { + m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); + m_inviteStatusLabel->setText(QString::fromUtf8("Неверная ссылка: ") + d.error); + return; + } + + uint64_t targetNodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData()); + uint64_t myNodeId = m_node ? m_node->nodeIdHex().toULongLong(nullptr, 16) : 0; + QString pkHex = QString::fromLatin1(d.pubkey.toHex()); + QString pkShort = pkHex.left(8) + ".." + pkHex.right(4); + QString addrInfo; + for (int i = 0; i < d.addrs.size() && i < 3; i++) { + if (i > 0) addrInfo += ", "; + if (d.addrs[i].family == 4) { + const uint8_t* ab = (const uint8_t*)d.addrs[i].address.constData(); + if (d.addrs[i].address.size() >= 4) + addrInfo += QString("%1.%2.%3.%4:%5").arg(ab[0]).arg(ab[1]).arg(ab[2]).arg(ab[3]).arg(d.addrs[i].port); + else + addrInfo += QString("v4:?:%1").arg(d.addrs[i].port); + } else { + addrInfo += QString("v6:[%1..]:%2").arg( + QString::fromLatin1(d.addrs[i].address.left(4).toHex())).arg(d.addrs[i].port); + } + } + if (d.addrs.size() > 3) addrInfo += QString(" +%1 more").arg(d.addrs.size() - 3); + + QString diag = QString::fromUtf8("Ссылка: узел 0x%1 ключ %2, %3 адр. (%4)\nПриглашение в канал: %5") + .arg(targetNodeId, 16, 16, QChar('0')) + .arg(pkShort) + .arg(d.addrs.size()) + .arg(addrInfo) + .arg(m_channelId); + + if (myNodeId != 0 && myNodeId == targetNodeId) { + m_inviteStatusLabel->setStyleSheet("color: #E67E22; font-size: 11px; padding: 2px 0;"); + m_inviteStatusLabel->setText(diag + QString::fromUtf8(" ⚠ Это ваша собственная ссылка")); + } else { + m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); + m_inviteStatusLabel->setText(diag); + } +} + +void InviteByLinkDialog::setInviteStatus(const QString& text, bool isError) { + if (isError) + m_inviteStatusLabel->setStyleSheet("color: #D0021B; font-size: 11px; padding: 2px 0;"); + else + m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); + m_inviteStatusLabel->setText(text); +} + +void InviteByLinkDialog::onSendInvite() { + if (m_inviteSending) return; + QString link = m_inviteLinkEdit->text().trimmed(); + if (link.isEmpty()) { + setInviteStatus(QString::fromUtf8("Вставьте utun:// ссылку узла."), true); + return; + } + + InviteData d = decodeInviteLink(link); + if (!d.error.isEmpty()) { + setInviteStatus(QString::fromUtf8("Неверная ссылка: ") + d.error, true); + return; + } + if (d.pubkey.size() != 32) { + setInviteStatus(QString::fromUtf8("Pubkey не 32 байта."), true); + return; + } + if (d.addrs.isEmpty()) { + setInviteStatus(QString::fromUtf8("Нет адресов."), true); + return; + } + + uint64_t targetNodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData()); + + { + uint64_t myNodeId = m_node ? m_node->nodeIdHex().toULongLong(nullptr, 16) : 0; + if (myNodeId != 0 && myNodeId == targetNodeId) { + GUI_WARN("invite_by_link: self-invite rejected — link contains own pubkey, node=0x%016llx", (unsigned long long)myNodeId); + setInviteStatus(QString::fromUtf8("Ошибка: это ваша собственная ссылка (нельзя пригласить себя)"), true); + return; + } + } + + m_inviteSending = true; + m_inviteSendBtn->setEnabled(false); + + GUI_INFO("invite_by_link: channel=%s target=0x%016llx addrs=%d", + m_channelId.toUtf8().constData(), targetNodeId, d.addrs.size()); + + /* Save addresses to DB */ + QByteArray addrsBuf; + for (const auto& a : d.addrs) { + addrsBuf.append(static_cast(a.family)); + addrsBuf.append(static_cast(a.socketId)); + addrsBuf.append(static_cast(a.proto)); + addrsBuf.append(a.address); + addrsBuf.append(static_cast((a.port >> 8) & 0xFF)); + addrsBuf.append(static_cast(a.port & 0xFF)); + } + + chat_sync_invite_to_channel(chat_core_get_inst(), m_channelId.toUtf8().constData(), targetNodeId); + + setInviteStatus(QString::fromUtf8("Приглашение отправлено. OK")); + QTimer::singleShot(2000, this, [this]() { + m_inviteSending = false; + m_inviteSendBtn->setEnabled(true); + }); +} diff --git a/tools/chatgui/src/inviteby.h b/tools/chatgui/src/inviteby.h new file mode 100644 index 00000000..1fee8597 --- /dev/null +++ b/tools/chatgui/src/inviteby.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include +#include + +class UtunNode; + +class InviteByLinkDialog : public QDialog { + Q_OBJECT +public: + explicit InviteByLinkDialog(const QString& channelId, UtunNode* node, QWidget* parent = nullptr); + +private slots: + void onInviteLinkTextChanged(); + void onSendInvite(); + +private: + void setInviteStatus(const QString& text, bool isError = false); + + QString m_channelId; + UtunNode* m_node; + QLineEdit* m_inviteLinkEdit = nullptr; + QLabel* m_inviteStatusLabel = nullptr; + QPushButton* m_inviteSendBtn = nullptr; + bool m_inviteSending = false; + uint64_t m_inviteTargetNodeId = 0; +}; diff --git a/tools/chatgui/src/invitedialog.cpp b/tools/chatgui/src/invitedialog.cpp index 86caacb4..c7bcc685 100644 --- a/tools/chatgui/src/invitedialog.cpp +++ b/tools/chatgui/src/invitedialog.cpp @@ -1,15 +1,5 @@ #include "invitedialog.h" -#include "invite_link.h" #include "qrcode_utils.h" -#include "debug_ui.h" -#include "../transport/utun_node.h" -#include "../transport/gui_bridge.h" -#include "../db/db_manager.h" -extern "C" { -#include "chat/chat_core.h" -#include "chat/chat_sync.h" -#include "transport_layer/secure_channel.h" -} #include #include #include @@ -17,14 +7,11 @@ extern "C" { #include #include #include -#include -#include -InviteDialog::InviteDialog(const QString& link, const QString& channelId, - UtunNode* node, QWidget* parent) - : QDialog(parent), m_link(link), m_channelId(channelId), m_node(node) +ShareInviteDialog::ShareInviteDialog(const QString& link, QWidget* parent) + : QDialog(parent), m_link(link) { - setWindowTitle("Пригласительная ссылка"); + setWindowTitle(QString::fromUtf8("Пригласительная ссылка")); setMinimumWidth(420); setModal(true); @@ -37,15 +24,12 @@ InviteDialog::InviteDialog(const QString& link, const QString& channelId, layout->addWidget(linkEdit); auto *btnLayout = new QHBoxLayout(); - auto *copyBtn = new QPushButton("Копировать", this); + auto *copyBtn = new QPushButton(QString::fromUtf8("Копировать"), this); connect(copyBtn, &QPushButton::clicked, this, [this, linkEdit]() { QClipboard* cb = QApplication::clipboard(); - cb->clear(QClipboard::Clipboard); cb->setText(m_link, QClipboard::Clipboard); - if (cb->supportsSelection()) { - cb->clear(QClipboard::Selection); + if (cb->supportsSelection()) cb->setText(m_link, QClipboard::Selection); - } linkEdit->setFocus(); }); btnLayout->addWidget(copyBtn); @@ -60,206 +44,7 @@ InviteDialog::InviteDialog(const QString& link, const QString& channelId, qrLabel->setAlignment(Qt::AlignCenter); layout->addWidget(qrLabel, 0, Qt::AlignCenter); - /* ── Разделитель ── */ - auto *sep = new QFrame(this); - sep->setFrameShape(QFrame::HLine); - sep->setStyleSheet("QFrame { color: palette(mid); }"); - layout->addWidget(sep); - - /* ── Пригласить по чужой ссылке ── */ - auto *inviteTitle = new QLabel("Пригласить в эту группу:", this); - inviteTitle->setStyleSheet("font-weight: bold; font-size: 12px;"); - layout->addWidget(inviteTitle); - - m_inviteLinkEdit = new QLineEdit(this); - m_inviteLinkEdit->setPlaceholderText("utun://..."); - m_inviteLinkEdit->setStyleSheet( - "QLineEdit { border: 1px solid palette(mid); border-radius: 4px;" - " padding: 6px 8px; font-size: 12px; background: palette(base); }"); - layout->addWidget(m_inviteLinkEdit); - - m_inviteStatusLabel = new QLabel(this); - m_inviteStatusLabel->setWordWrap(true); - m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); - layout->addWidget(m_inviteStatusLabel); - - auto *invBtnLayout = new QHBoxLayout(); - invBtnLayout->addStretch(); - m_inviteSendBtn = new QPushButton("Пригласить", this); - m_inviteSendBtn->setStyleSheet( - "QPushButton { border: none; border-radius: 4px;" - " padding: 5px 14px; font-size: 12px; font-weight: bold;" - " background: #3390EC; color: white; }" - "QPushButton:hover { background: #2B7ED4; }" - "QPushButton:disabled { background: palette(mid); color: palette(midlight); }"); - connect(m_inviteSendBtn, &QPushButton::clicked, this, &InviteDialog::onSendInvite); - invBtnLayout->addWidget(m_inviteSendBtn); - layout->addLayout(invBtnLayout); - - connect(m_inviteLinkEdit, &QLineEdit::returnPressed, this, &InviteDialog::onSendInvite); - connect(m_inviteLinkEdit, &QLineEdit::textChanged, this, &InviteDialog::onInviteLinkTextChanged); - auto *closeBtn = new QPushButton("OK", this); connect(closeBtn, &QPushButton::clicked, this, &QDialog::accept); layout->addWidget(closeBtn, 0, Qt::AlignRight); - - QTimer::singleShot(0, this, [this]() { - QClipboard* cb = QApplication::clipboard(); - cb->clear(QClipboard::Clipboard); - cb->setText(m_link, QClipboard::Clipboard); - if (cb->supportsSelection()) { - cb->clear(QClipboard::Selection); - cb->setText(m_link, QClipboard::Selection); - } - }); -} - -void InviteDialog::onInviteByLink() { - /* Toggle visibility of invite-by-link section (handled in constructor now) */ -} - -void InviteDialog::onInviteLinkTextChanged() { - QString link = m_inviteLinkEdit->text().trimmed(); - if (link.isEmpty()) { - m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); - m_inviteStatusLabel->clear(); - return; - } - if (!link.startsWith(QLatin1String("utun://"))) { - m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); - m_inviteStatusLabel->setText("Ожидается utun:// ссылка..."); - return; - } - - InviteData d = decodeInviteLink(link); - if (!d.error.isEmpty()) { - m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); - m_inviteStatusLabel->setText("Неверная ссылка: " + d.error); - return; - } - - uint64_t targetNodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData()); - uint64_t myNodeId = m_node ? m_node->nodeIdHex().toULongLong(nullptr, 16) : 0; - QString pkHex = QString::fromLatin1(d.pubkey.toHex()); - QString pkShort = pkHex.left(8) + ".." + pkHex.right(4); - QString addrInfo; - for (int i = 0; i < d.addrs.size() && i < 3; i++) { - if (i > 0) addrInfo += ", "; - if (d.addrs[i].family == 4 && d.addrs[i].address.size() >= 4) { - const uint8_t* ab = (const uint8_t*)d.addrs[i].address.constData(); - addrInfo += QString("%1.%2.%3.%4:%5").arg(ab[0]).arg(ab[1]).arg(ab[2]).arg(ab[3]).arg(d.addrs[i].port); - } else { - addrInfo += QString("v6:[%1..]:%2").arg( - QString::fromLatin1(d.addrs[i].address.left(4).toHex())).arg(d.addrs[i].port); - } - } - if (d.addrs.size() > 3) addrInfo += QString(" +%1 more").arg(d.addrs.size() - 3); - - QString diag = QString("Ссылка: узел 0x%1 ключ %2, %3 адр. (%4)\nПриглашение в канал: %5") - .arg(targetNodeId, 16, 16, QChar('0')) - .arg(pkShort) - .arg(d.addrs.size()) - .arg(addrInfo) - .arg(m_channelId); - - if (myNodeId != 0 && myNodeId == targetNodeId) { - m_inviteStatusLabel->setStyleSheet("color: #E67E22; font-size: 11px; padding: 2px 0;"); - m_inviteStatusLabel->setText(diag + " ⚠ Это ваша собственная ссылка"); - } else { - m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); - m_inviteStatusLabel->setText(diag); - } -} - -void InviteDialog::setInviteStatus(const QString& text, bool isError) { - if (isError) - m_inviteStatusLabel->setStyleSheet("color: #D0021B; font-size: 11px; padding: 2px 0;"); - else - m_inviteStatusLabel->setStyleSheet("color: gray; font-size: 11px; padding: 2px 0;"); - m_inviteStatusLabel->setText(text); -} - -void InviteDialog::onSendInvite() { - if (m_inviteSending) return; - QString link = m_inviteLinkEdit->text().trimmed(); - if (link.isEmpty()) { - setInviteStatus("Вставьте utun:// ссылку узла.", true); - return; - } - - InviteData d = decodeInviteLink(link); - if (!d.error.isEmpty()) { - setInviteStatus("Неверная ссылка: " + d.error, true); - return; - } - if (d.pubkey.size() != 32) { - setInviteStatus("Pubkey не 32 байта.", true); - return; - } - if (d.addrs.isEmpty()) { - setInviteStatus("Нет адресов.", true); - return; - } - - uint64_t targetNodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData()); - - /* diagnostic: show decoded link info */ - { - uint64_t myNodeId = m_node ? m_node->nodeIdHex().toULongLong(nullptr, 16) : 0; - QString pkHex = QString::fromLatin1(d.pubkey.toHex()); - QString pkShort = pkHex.left(8) + ".." + pkHex.right(4); - QString addrInfo; - for (int i = 0; i < d.addrs.size() && i < 3; i++) { - if (i > 0) addrInfo += ", "; - if (d.addrs[i].family == 4 && d.addrs[i].address.size() >= 4) { - const uint8_t* ab = (const uint8_t*)d.addrs[i].address.constData(); - addrInfo += QString("%1.%2.%3.%4:%5").arg(ab[0]).arg(ab[1]).arg(ab[2]).arg(ab[3]).arg(d.addrs[i].port); - } else { - addrInfo += QString("v6:[%1..]:%2").arg( - QString::fromLatin1(d.addrs[i].address.left(4).toHex())).arg(d.addrs[i].port); - } - } - if (d.addrs.size() > 3) addrInfo += QString(" +%1 more").arg(d.addrs.size() - 3); - QString diag = QString("Ссылка: узел 0x%1 ключ %2, %3 адр. (%4)\nПриглашение в канал: %5") - .arg(targetNodeId, 16, 16, QChar('0')) - .arg(pkShort) - .arg(d.addrs.size()) - .arg(addrInfo) - .arg(m_channelId); - GUI_INFO("invite_by_link: %s", diag.toUtf8().constData()); - if (myNodeId != 0 && myNodeId == targetNodeId) { - GUI_WARN("invite_by_link: self-invite rejected — link contains own pubkey, node=0x%016llx", (unsigned long long)myNodeId); - setInviteStatus("Ошибка: это ваша собственная ссылка (нельзя пригласить себя)", true); - return; - } - setInviteStatus(diag); - } - m_inviteSending = true; - m_inviteTargetNodeId = targetNodeId; - m_inviteSendBtn->setEnabled(false); - setInviteStatus("Приглашаем узел 0x" + QString::number(targetNodeId, 16) + "..."); - - /* Save addresses to DB */ - QByteArray addrsBuf; - for (const auto& a : d.addrs) { - addrsBuf.append(static_cast(a.family)); - addrsBuf.append(static_cast(a.socketId)); - addrsBuf.append(static_cast(a.proto)); - addrsBuf.append(a.address); - addrsBuf.append(static_cast((a.port >> 8) & 0xFF)); - addrsBuf.append(static_cast(a.port & 0xFF)); - } - - GUI_INFO("invite_by_link: channel=%s target=0x%016llx addrs=%d", - m_channelId.toUtf8().constData(), targetNodeId, d.addrs.size()); - - /* Post to uasync thread */ - chat_sync_invite_to_channel( - chat_core_get_inst(), m_channelId.toUtf8().constData(), targetNodeId); - - setInviteStatus("Приглашение отправлено. OK"); - QTimer::singleShot(2000, this, [this]() { - m_inviteSending = false; - m_inviteSendBtn->setEnabled(true); - }); } diff --git a/tools/chatgui/src/invitedialog.h b/tools/chatgui/src/invitedialog.h index 33135f80..49fafe57 100644 --- a/tools/chatgui/src/invitedialog.h +++ b/tools/chatgui/src/invitedialog.h @@ -2,33 +2,12 @@ #include #include -#include -#include -#include -#include -class UtunNode; - -class InviteDialog : public QDialog { +class ShareInviteDialog : public QDialog { Q_OBJECT public: - explicit InviteDialog(const QString& link, const QString& channelId, - UtunNode* node, QWidget* parent = nullptr); - -private slots: - void onInviteByLink(); - void onInviteLinkTextChanged(); - void onSendInvite(); + explicit ShareInviteDialog(const QString& link, QWidget* parent = nullptr); private: - void setInviteStatus(const QString& text, bool isError = false); - - QString m_link; - QString m_channelId; - UtunNode* m_node; - QLineEdit* m_inviteLinkEdit = nullptr; - QLabel* m_inviteStatusLabel = nullptr; - QPushButton* m_inviteSendBtn = nullptr; - bool m_inviteSending = false; - uint64_t m_inviteTargetNodeId = 0; + QString m_link; }; diff --git a/tools/chatgui/src/mainwindow.cpp b/tools/chatgui/src/mainwindow.cpp index ad8c2930..f8ce54cc 100644 --- a/tools/chatgui/src/mainwindow.cpp +++ b/tools/chatgui/src/mainwindow.cpp @@ -3,6 +3,7 @@ #include "messagelist.h" #include "accountlist.h" #include "invitedialog.h" +#include "inviteby.h" #include "joindialog.h" #include "settingsdialog.h" #include "creategroupdialog.h" @@ -281,7 +282,8 @@ void MainWindow::setupConnects() { char* cid = u_strdup(cidBA.constData()); if (cid) gui_bridge_post_uasync_fn(chat_core_connect_channel_trampoline, cid); }); - connect(m_channelList, &ChannelList::inviteRequested, this, &MainWindow::showInviteDialog); + connect(m_channelList, &ChannelList::inviteRequested, this, &MainWindow::showShareInviteDialog); + connect(m_channelList, &ChannelList::inviteByLinkRequested, this, &MainWindow::showInviteByLinkDialog); connect(m_channelList, &ChannelList::joinRequested, this, &MainWindow::showJoinDialog); connect(m_channelList, &ChannelList::createGroupRequested, this, &MainWindow::onCreateGroupRequested); connect(m_channelList, &ChannelList::settingsRequested, this, &MainWindow::showSettings); @@ -344,7 +346,7 @@ void MainWindow::onTrayActivated(QSystemTrayIcon::ActivationReason reason) { } } -void MainWindow::showInviteDialog(const QString& channelId) { +void MainWindow::showShareInviteDialog(const QString& channelId) { if (!m_db || !m_db->isOpen()) return; QByteArray pubkey; @@ -364,7 +366,16 @@ void MainWindow::showInviteDialog(const QString& channelId) { return; } - InviteDialog dlg(link, channelId, m_node, this); + ShareInviteDialog dlg(link, this); + dlg.exec(); +} + +void MainWindow::showInviteByLinkDialog(const QString& channelId) { + if (!m_node || !m_node->isRunning()) { + QMessageBox::warning(this, "Error", "Node is not running."); + return; + } + InviteByLinkDialog dlg(channelId, m_node, this); dlg.exec(); } diff --git a/tools/chatgui/src/mainwindow.h b/tools/chatgui/src/mainwindow.h index 16220fcb..2640b77e 100644 --- a/tools/chatgui/src/mainwindow.h +++ b/tools/chatgui/src/mainwindow.h @@ -26,7 +26,8 @@ protected: private slots: void onTrayActivated(QSystemTrayIcon::ActivationReason reason); - void showInviteDialog(const QString& channelId); + void showShareInviteDialog(const QString& channelId); + void showInviteByLinkDialog(const QString& channelId); void showJoinDialog(); void onCreateGroupRequested(); void showSettings();