diff --git a/tools/chatgui/src/joindialog.cpp b/tools/chatgui/src/joindialog.cpp index 6a5f10b9..8012f267 100644 --- a/tools/chatgui/src/joindialog.cpp +++ b/tools/chatgui/src/joindialog.cpp @@ -76,6 +76,46 @@ JoinDialog::JoinDialog(UtunNode* node, DbManager* db, QWidget* parent) layout->addLayout(btnLayout); connect(m_linkEdit, &QLineEdit::returnPressed, this, &JoinDialog::onConnectClicked); + connect(m_linkEdit, &QLineEdit::textChanged, this, &JoinDialog::onLinkTextChanged); + + m_decodeTimer = new QTimer(this); + m_decodeTimer->setSingleShot(true); + m_decodeTimer->setInterval(400); + connect(m_decodeTimer, &QTimer::timeout, this, [this]() { + QString link = m_linkEdit->text().trimmed(); + if (link.isEmpty()) { + setStatus(""); + return; + } + InviteData d = decodeInviteLink(link); + if (!d.error.isEmpty() || d.pubkey.size() != 32) { + setStatus(""); + return; + } + uint8_t hash[32]; + SC_SHA256_CTX ctx; + sc_sha256_init(&ctx); + sc_sha256_update(&ctx, (const uint8_t*)d.pubkey.constData(), 32); + sc_sha256_final(&ctx, hash); + uint64_t nodeId; + memcpy(&nodeId, hash, sizeof(nodeId)); + nodeId &= 0x7FFFFFFFFFFFFFFFULL; + + QStringList addrList; + for (const auto& a : d.addrs) { + QString addrStr; + if (a.family == 4 && a.address.size() == 4) { + const uint8_t* b = (const uint8_t*)a.address.constData(); + addrStr = QString("%1.%2.%3.%4").arg(b[0]).arg(b[1]).arg(b[2]).arg(b[3]); + } else { + addrStr = QString("ipv6:%1").arg(a.address.toHex().constData()); + } + addrList.append(QString("%1:%2").arg(addrStr).arg(a.port)); + } + setStatus(QString("Node: 0x%1 | %2") + .arg(nodeId, 16, 16, QLatin1Char('0')) + .arg(addrList.join(", "))); + }); gui_bridge_set_connect_result_cb([](uint64_t nodeId, uint64_t channelId, int result) { JoinDialog* dlg = qobject_cast(QApplication::activeModalWidget()); @@ -95,6 +135,10 @@ void JoinDialog::setStatus(const QString& text, bool isError) { m_statusLabel->setText(text); } +void JoinDialog::onLinkTextChanged() { + m_decodeTimer->start(); +} + void JoinDialog::onConnectClicked() { if (m_connecting) return; QString link = m_linkEdit->text().trimmed(); diff --git a/tools/chatgui/src/joindialog.h b/tools/chatgui/src/joindialog.h index 717876b0..de8d53f1 100644 --- a/tools/chatgui/src/joindialog.h +++ b/tools/chatgui/src/joindialog.h @@ -4,6 +4,7 @@ #include #include #include +#include #include class UtunNode; @@ -20,6 +21,7 @@ signals: private slots: void onConnectClicked(); + void onLinkTextChanged(); private: void setStatus(const QString& text, bool isError = false); @@ -31,6 +33,7 @@ private: QLabel* m_statusLabel; QPushButton* m_connectBtn; QPushButton* m_cancelBtn; + QTimer* m_decodeTimer; bool m_connecting = false; uint64_t m_pendingNodeId = 0; uint64_t m_pendingChannelId = 0;