stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll - stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close - utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP), add deferred drain in both Phase J and L - stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39, exchange ed25519_pubkey in both handshake directions - etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb - chat_sync.c: fix lk->conn NULL dereference for TCP links - test_stcp.c: update stcp_server_create/stcp_client_connect callsites - tools/chat_tcp_test: change transport udp→tcp
This commit is contained in:
1 parent
a3783b5f55
commit
38c9f229bc
1272 files changed
+968388
-1
No files matched your search
@@ -0,0 +1,181 @@
|
||||
#include "soundsettingspage.h"
|
||||
#include "sound_manager.h"
|
||||
#include "../db/db_manager.h"
|
||||
#include "../transport/gui_bridge.h"
|
||||
#include "../../lib/mem.h"
|
||||
extern "C" {
|
||||
#include "chat/chat_core.h"
|
||||
}
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QSlider>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QDebug>
|
||||
|
||||
SoundSettingsPage::SoundSettingsPage(DbManager* db, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_db(db)
|
||||
{
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 12, 0, 0);
|
||||
layout->setSpacing(14);
|
||||
|
||||
m_enabledCheck = new QCheckBox("Enable sounds", this);
|
||||
m_enabledCheck->setStyleSheet("font-size: 13px;");
|
||||
layout->addWidget(m_enabledCheck);
|
||||
|
||||
auto* volLayout = new QHBoxLayout();
|
||||
auto* volLabel = new QLabel("Volume:", this);
|
||||
volLabel->setStyleSheet("font-size: 13px;");
|
||||
volLayout->addWidget(volLabel);
|
||||
|
||||
m_volumeSlider = new QSlider(Qt::Horizontal, this);
|
||||
m_volumeSlider->setRange(0, 100);
|
||||
m_volumeSlider->setFixedWidth(200);
|
||||
m_volumeSlider->setStyleSheet(
|
||||
"QSlider::groove:horizontal { height: 6px; border-radius: 3px; background: palette(mid); }"
|
||||
"QSlider::handle:horizontal { width: 14px; height: 14px; margin: -4px 0; border-radius: 7px; background: #3390EC; }");
|
||||
volLayout->addWidget(m_volumeSlider);
|
||||
|
||||
m_volumeLabel = new QLabel("80%", this);
|
||||
m_volumeLabel->setFixedWidth(36);
|
||||
m_volumeLabel->setStyleSheet("font-size: 13px;");
|
||||
volLayout->addWidget(m_volumeLabel);
|
||||
volLayout->addStretch();
|
||||
layout->addLayout(volLayout);
|
||||
|
||||
auto* sep = new QFrame(this);
|
||||
sep->setFrameShape(QFrame::HLine);
|
||||
sep->setStyleSheet("QFrame { color: palette(mid); }");
|
||||
layout->addWidget(sep);
|
||||
|
||||
auto* header = new QLabel("Events", this);
|
||||
header->setStyleSheet("font-size: 13px; font-weight: bold;");
|
||||
layout->addWidget(header);
|
||||
|
||||
m_events[0] = {"msg_incoming", "Incoming message", nullptr, nullptr, nullptr};
|
||||
m_events[1] = {"msg_outgoing", "Outgoing message", nullptr, nullptr, nullptr};
|
||||
m_events[2] = {"connect", "Peer connected", nullptr, nullptr, nullptr};
|
||||
m_events[3] = {"disconnect", "Peer disconnected", nullptr, nullptr, nullptr};
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto& e = m_events[i];
|
||||
auto* row = new QHBoxLayout();
|
||||
row->setSpacing(8);
|
||||
|
||||
auto* lbl = new QLabel(e.label, this);
|
||||
lbl->setFixedWidth(140);
|
||||
lbl->setStyleSheet("font-size: 13px;");
|
||||
row->addWidget(lbl);
|
||||
|
||||
e.check = new QCheckBox(this);
|
||||
row->addWidget(e.check);
|
||||
|
||||
e.slider = new QSlider(Qt::Horizontal, this);
|
||||
e.slider->setRange(0, 100);
|
||||
e.slider->setFixedWidth(100);
|
||||
e.slider->setStyleSheet(
|
||||
"QSlider::groove:horizontal { height: 4px; border-radius: 2px; background: palette(mid); }"
|
||||
"QSlider::handle:horizontal { width: 10px; height: 10px; margin: -3px 0; border-radius: 5px; background: #3390EC; }");
|
||||
row->addWidget(e.slider);
|
||||
|
||||
e.volLabel = new QLabel("80%", this);
|
||||
e.volLabel->setFixedWidth(30);
|
||||
e.volLabel->setStyleSheet("font-size: 12px;");
|
||||
row->addWidget(e.volLabel);
|
||||
|
||||
row->addStretch();
|
||||
layout->addLayout(row);
|
||||
|
||||
connect(e.slider, &QSlider::valueChanged, this, [this, i](int val) {
|
||||
m_events[i].volLabel->setText(QString::number(val) + "%");
|
||||
});
|
||||
}
|
||||
|
||||
layout->addStretch();
|
||||
|
||||
connect(m_enabledCheck, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
bool on = (state == Qt::Checked);
|
||||
m_volumeSlider->setEnabled(on);
|
||||
m_volumeLabel->setEnabled(on);
|
||||
});
|
||||
connect(m_volumeSlider, &QSlider::valueChanged, this, [this](int val) {
|
||||
m_volumeLabel->setText(QString::number(val) + "%");
|
||||
});
|
||||
}
|
||||
|
||||
void SoundSettingsPage::loadFromDb() {
|
||||
if (!m_db) return;
|
||||
|
||||
bool enabled = m_db->getUiStateInt("sound_enabled", 1);
|
||||
m_enabledCheck->setChecked(enabled);
|
||||
|
||||
int vol = m_db->getUiStateInt("sound_volume", 80);
|
||||
m_volumeSlider->setValue(vol);
|
||||
m_volumeSlider->setEnabled(enabled);
|
||||
m_volumeLabel->setEnabled(enabled);
|
||||
m_volumeLabel->setText(QString::number(vol) + "%");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto& e = m_events[i];
|
||||
QString onKey = QStringLiteral("sound_%1_on").arg(e.key);
|
||||
QString volKey = QStringLiteral("sound_%1_vol").arg(e.key);
|
||||
bool on = m_db->getUiStateInt(onKey, i == 0 ? 1 : 0); // only msg_incoming on by default
|
||||
int ev = m_db->getUiStateInt(volKey, 80);
|
||||
e.check->setChecked(on);
|
||||
e.slider->setValue(ev);
|
||||
e.volLabel->setText(QString::number(ev) + "%");
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSettingsPage::applyAndSave() {
|
||||
SoundManager* sm = SoundManager::instance();
|
||||
|
||||
bool enabled = m_enabledCheck->isChecked();
|
||||
float masterVol = m_volumeSlider->value() / 100.0f;
|
||||
sm->setEnabled(enabled);
|
||||
sm->setVolume(masterVol);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto& e = m_events[i];
|
||||
bool on = e.check->isChecked();
|
||||
float ev = e.slider->value() / 100.0f;
|
||||
sm->setEvent(e.key, on, ev);
|
||||
|
||||
/* async DB persist — key\0value\0 */
|
||||
QString onKey = QStringLiteral("sound_%1_on").arg(e.key);
|
||||
QString volKey = QStringLiteral("sound_%1_vol").arg(e.key);
|
||||
QByteArray onVal = on ? QByteArray("1") : QByteArray("0");
|
||||
QByteArray volVal = QByteArray::number(e.slider->value());
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
const char* k = j == 0 ? onKey.toUtf8().constData() : volKey.toUtf8().constData();
|
||||
const char* v = j == 0 ? onVal.constData() : volVal.constData();
|
||||
size_t klen = strlen(k), vlen = strlen(v);
|
||||
size_t total = klen + 1 + vlen + 1;
|
||||
if (total > 256) continue;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, k, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, v, vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/* save global settings */
|
||||
{
|
||||
const char* keys[] = {"sound_enabled", "sound_volume"};
|
||||
QByteArray vals[] = {enabled ? QByteArray("1") : QByteArray("0"),
|
||||
QByteArray::number(m_volumeSlider->value())};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
size_t klen = strlen(keys[j]), vlen = vals[j].size();
|
||||
size_t total = klen + 1 + vlen + 1;
|
||||
if (total > 256) continue;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, keys[j], klen + 1);
|
||||
memcpy((char*)arg + klen + 1, vals[j].constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user