feat: media_async + media_index modules, media_files table, tests

- media_async: thread-per-task async engine with primitives (sha256, sign, copy, uuid, file_size)
- media_index: media_files DB table with register_async for indexing chunks
- chat_msg: async media submission via register_async, simplified chat_msg_submit fields
- voice_recorder/attachment_sender: write single file (no chunk splitting on caller side)
- inputbar/messagelist: updated to new simplified submit interface
- test_media_async: 4-thread stress test (200K ops / 2 sec, 0 errors)
- test_media_index: 9 cases covering commit edge cases + async flow
- build: Makefile.am, CMakeLists.txt, utun_sources.cmake updated
This commit is contained in:
evgeny committed 2026-07-29 14:15:10 +03:00
1 parent ce5a84da24
commit 65dbfa6813
43 files changed
+1983 -391

No files matched your search

+90
View File
@@ -0,0 +1,90 @@
#include "storagesettingspage.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 <QFormLayout>
#include <QCheckBox>
#include <QSpinBox>
#include <QLabel>
#include <QFrame>
static void saveUiStateInt(const char* key, int val) {
QByteArray v = QByteArray::number(val);
size_t klen = strlen(key), vlen = (size_t)v.size(), total = klen + 1 + vlen + 1;
if (total > 256) return;
void* arg = u_malloc(total);
memcpy(arg, key, klen + 1);
memcpy((char*)arg + klen + 1, v.constData(), vlen + 1);
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
}
StorageSettingsPage::StorageSettingsPage(DbManager* db, QWidget* parent)
: QWidget(parent)
, m_db(db)
{
auto* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 12, 0, 0);
layout->setSpacing(14);
auto* title = new QLabel("Media Storage", this);
title->setStyleSheet("font-weight: bold; font-size: 13px;");
layout->addWidget(title);
auto* form = new QFormLayout();
form->setSpacing(10);
form->setContentsMargins(0, 8, 0, 0);
m_autoloadCheck = new QCheckBox("Autoload media", this);
m_autoloadCheck->setStyleSheet("font-size: 13px;");
form->addRow(m_autoloadCheck);
m_autoloadMaxSize = new QSpinBox(this);
m_autoloadMaxSize->setRange(1, 500);
m_autoloadMaxSize->setSuffix(" MB");
m_autoloadMaxSize->setFixedWidth(110);
m_autoloadMaxSize->setStyleSheet(
"QSpinBox { border: 1px solid palette(mid); border-radius: 4px;"
" padding: 5px 8px; font-size: 13px; background: palette(base); }");
form->addRow("Autoload max size:", m_autoloadMaxSize);
m_maxStorageSize = new QSpinBox(this);
m_maxStorageSize->setRange(1, 100);
m_maxStorageSize->setSuffix(" GB");
m_maxStorageSize->setFixedWidth(110);
m_maxStorageSize->setStyleSheet(
"QSpinBox { border: 1px solid palette(mid); border-radius: 4px;"
" padding: 5px 8px; font-size: 13px; background: palette(base); }");
form->addRow("Max storage size:", m_maxStorageSize);
layout->addLayout(form);
auto* sep = new QFrame(this);
sep->setFrameShape(QFrame::HLine);
sep->setStyleSheet("QFrame { color: palette(mid); }");
layout->addWidget(sep);
layout->addStretch();
}
void StorageSettingsPage::loadFromDb() {
if (!m_db) return;
bool autoload = m_db->getUiStateInt("storage_autoload", 1);
m_autoloadCheck->setChecked(autoload);
int maxSizeMb = m_db->getUiStateInt("storage_autoload_maxsize_mb", 10);
m_autoloadMaxSize->setValue(maxSizeMb);
int maxGb = m_db->getUiStateInt("storage_maxsize_gb", 1);
m_maxStorageSize->setValue(maxGb);
}
void StorageSettingsPage::applyAndSave() {
saveUiStateInt("storage_autoload", m_autoloadCheck->isChecked() ? 1 : 0);
saveUiStateInt("storage_autoload_maxsize_mb", m_autoloadMaxSize->value());
saveUiStateInt("storage_maxsize_gb", m_maxStorageSize->value());
}