Own message list requests and acknowledge PM text persistence
This commit is contained in:
1 parent
4c1512cb78
commit
9d48821af2
3 files changed
+48
-57
No files matched your search
@@ -1126,7 +1126,9 @@ void dm_send_trampoline(void* arg) {
|
||||
struct UTUN_INSTANCE* inst = req->inst;
|
||||
char conv[64]; strncpy(conv, req->conv_id, sizeof(conv) - 1); conv[sizeof(conv) - 1] = '\0';
|
||||
uint64_t generation = req->generation ? req->generation : dm_history_generation(inst, conv);
|
||||
uint64_t request_id = req->request_id;
|
||||
int rc = dm_history_current(inst, conv, generation) ? dm_send(inst, conv, "text", req->data, req->data_len) : -1;
|
||||
chat_event_submitted(inst, request_id, rc == 0);
|
||||
u_free(arg);
|
||||
if (rc != 0)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "%s: dm_send_trampoline — dm_send failed conv=%s",
|
||||
|
||||
@@ -157,6 +157,7 @@ struct dm_send_req {
|
||||
struct UTUN_INSTANCE* inst; /* Заимствованное ядро. */
|
||||
char conv_id[64]; /* Десятичный ID беседы с NUL. */
|
||||
uint64_t generation; /* 0: захватить при входе в uasync, до любой фоновой работы. */
|
||||
uint64_t request_id; /* Ненулевой ID composer: результат локальной записи через CHAT_EVT_MSG_SUBMITTED. */
|
||||
uint32_t data_len; /* Число байт текста, до DM_DATA_MAX. */
|
||||
uint8_t* data; /* Указывает на data_len байт в том же блоке после структуры. */
|
||||
};
|
||||
|
||||
@@ -59,7 +59,6 @@ extern "C" {
|
||||
#include "../../lib/mem.h"
|
||||
#include "../../lib/audio_compressor.h"
|
||||
#include "../../lib/debug_config.h"
|
||||
void chat_core_save_ui_state_trampoline(void* arg);
|
||||
}
|
||||
|
||||
#include "radio_audio_engine.h"
|
||||
@@ -596,9 +595,9 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
}
|
||||
auto* arg = (chat_sound_arg*)u_calloc(1, sizeof(chat_sound_arg));
|
||||
if (!arg) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "group menu: sound allocation failed"); return; }
|
||||
arg->inst = gui_bridge_get_inst(); arg->on = sound->isChecked();
|
||||
arg->on = sound->isChecked();
|
||||
snprintf(arg->ch_id, sizeof(arg->ch_id), "%s", channel.toUtf8().constData());
|
||||
gui_bridge_post_uasync_fn(chat_core_set_sound_on_message_trampoline, arg);
|
||||
if (gui_bridge_post_bound_fn(chat_core_set_sound_on_message_trampoline, arg, &arg->inst) < 0) u_free(arg);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -639,10 +638,10 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
if (target.isEmpty() || target.startsWith("dm:") || id <= 0) return false;
|
||||
auto* req = (struct attachment_dl_req*)u_calloc(1, sizeof(struct attachment_dl_req));
|
||||
if (!req) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment: download request allocation failed"); return false; }
|
||||
req->inst = gui_bridge_get_inst(); req->msg_id = id;
|
||||
req->msg_id = id;
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s", target.toUtf8().constData());
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
return true;
|
||||
if (gui_bridge_post_bound_fn(chat_core_attachment_download_trampoline, req, &req->inst) == 0) return true;
|
||||
u_free(req); return false;
|
||||
});
|
||||
m_view->setItemDelegate(msgDelegate);
|
||||
m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
@@ -692,7 +691,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
}
|
||||
auto* req = (struct chat_msg_submit*)u_calloc(1, sizeof(struct chat_msg_submit) + bytes.size());
|
||||
if (!req) { GUI_ERROR("edit: allocation failed"); m_inputBar->submissionResult(request, false); return; }
|
||||
req->inst = gui_bridge_get_inst(); req->request_id = request; req->expected_ver = version;
|
||||
req->request_id = request; req->expected_ver = version;
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s", channel.toUtf8().constData());
|
||||
memcpy(req->message_id, id.constData(), 32); req->data = (uint8_t*)(req + 1); req->data_len = bytes.size();
|
||||
memcpy(req->data, bytes.constData(), bytes.size());
|
||||
@@ -710,20 +709,23 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
|
||||
if (isDmChannel(m_currentChannelId)) {
|
||||
if (!m_currentDmGeneration || m_dmDeleting.value(dmConvId(m_currentChannelId)) == m_currentDmGeneration) {
|
||||
GUI_WARN("PM text rejected: unavailable/deleting target=%s", qPrintable(m_currentChannelId)); return;
|
||||
GUI_WARN("PM text rejected: unavailable/deleting target=%s", qPrintable(m_currentChannelId));
|
||||
m_inputBar->submissionResult(request, false); return;
|
||||
}
|
||||
QByteArray textData = text.toUtf8();
|
||||
QString conv = dmConvId(m_currentChannelId);
|
||||
struct dm_send_req* req = (struct dm_send_req*)u_malloc(sizeof(struct dm_send_req) + textData.size());
|
||||
if (!req) return;
|
||||
if (!req) { GUI_ERROR("PM text request allocation failed"); m_inputBar->submissionResult(request, false); return; }
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
req->generation = m_currentDmGeneration;
|
||||
req->request_id = request;
|
||||
strncpy(req->conv_id, conv.toUtf8().constData(), sizeof(req->conv_id) - 1);
|
||||
req->data = (uint8_t*)(req + 1);
|
||||
req->data_len = (uint32_t)textData.size();
|
||||
memcpy(req->data, textData.constData(), textData.size());
|
||||
gui_bridge_post_uasync_fn(dm_send_trampoline, req);
|
||||
if (gui_bridge_post_bound_fn(dm_send_trampoline, req, &req->inst) < 0) {
|
||||
u_free(req); m_inputBar->submissionResult(request, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -748,17 +750,17 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
|
||||
connect(m_inputBar, &InputBar::submitAttachment, this, [this](const QString& target, struct attachment_send_req* req) {
|
||||
const bool dm = isDmChannel(target);
|
||||
if (!gui_bridge_get_inst() || !gui_bridge_is_uasync_ready() ||
|
||||
(dm && (!req->dm_generation || m_dmDeleting.value(dmConvId(target)) == req->dm_generation))) {
|
||||
if (dm && (!req->dm_generation || m_dmDeleting.value(dmConvId(target)) == req->dm_generation)) {
|
||||
GUI_ERROR("send: attachment target/core unavailable target=%s generation=%llu", qPrintable(target),
|
||||
(unsigned long long)req->dm_generation); m_inputBar->submissionResult(req->request_id, false);
|
||||
if (req->pcm_release) req->pcm_release(req->pcm_owner); else u_free((void*)req->pcm);
|
||||
audio_compressor_destroy(req->compressor); u_free(req); return;
|
||||
attachment_send_discard(req); return;
|
||||
}
|
||||
req->inst = gui_bridge_get_inst(); req->is_dm = isDmChannel(target);
|
||||
req->is_dm = dm;
|
||||
QByteArray id = (req->is_dm ? dmConvId(target) : target).toUtf8();
|
||||
snprintf(req->target, sizeof(req->target), "%s", id.constData());
|
||||
gui_bridge_post_uasync_fn(attachment_send_trampoline, req);
|
||||
if (gui_bridge_submit_attachment(req) < 0) {
|
||||
m_inputBar->submissionResult(req->request_id, false); attachment_send_discard(req);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_inputBar, &InputBar::sendFileAttachment, this, [this](const QString& target, const QString& mediaSrc, const QString& mediaDest,
|
||||
@@ -769,21 +771,24 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
if (isDmChannel(target)) {
|
||||
if (target != m_currentChannelId || !m_currentDmGeneration ||
|
||||
m_dmDeleting.value(dmConvId(target)) == m_currentDmGeneration) {
|
||||
GUI_WARN("PM file rejected: unavailable/deleting target=%s", qPrintable(target)); return;
|
||||
GUI_WARN("PM file rejected: unavailable/deleting target=%s", qPrintable(target));
|
||||
m_inputBar->submissionResult(request, false); return;
|
||||
}
|
||||
auto* req = (struct dm_file_req*)u_calloc(1, sizeof(struct dm_file_req));
|
||||
if (!req) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "PM file request allocation failed"); return; }
|
||||
req->inst = gui_bridge_get_inst();
|
||||
if (!req) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "PM file request allocation failed"); m_inputBar->submissionResult(request, false); return; }
|
||||
req->generation = m_currentDmGeneration;
|
||||
QByteArray conv = dmConvId(target).toUtf8(), path = mediaSrc.toUtf8(), name = displayName.toUtf8();
|
||||
if (path.size() >= (int)sizeof(req->path) || name.size() >= (int)sizeof(req->info.name)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "PM attachment path or name is too long"); u_free(req); return;
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "PM attachment path or name is too long");
|
||||
u_free(req); m_inputBar->submissionResult(request, false); return;
|
||||
}
|
||||
snprintf(req->conv, sizeof(req->conv), "%s", conv.constData());
|
||||
snprintf(req->path, sizeof(req->path), "%s", path.constData());
|
||||
req->info.kind = ATTACHMENT_FILE;
|
||||
snprintf(req->info.name, sizeof(req->info.name), "%s", name.constData());
|
||||
gui_bridge_post_uasync_fn(dm_send_file_trampoline, req);
|
||||
if (gui_bridge_post_bound_fn(dm_send_file_trampoline, req, &req->inst) < 0) {
|
||||
u_free(req); m_inputBar->submissionResult(request, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1104,15 +1109,7 @@ void MessageList::saveChannelState() {
|
||||
auto postSaveKey = [&cid](const char* suffix, qint64 val) {
|
||||
QByteArray key = "ch_" + cid + suffix;
|
||||
QByteArray valStr = QByteArray::number(val);
|
||||
size_t keyLen = (size_t)key.size(), valLen = (size_t)valStr.size();
|
||||
size_t total = keyLen + 1 + valLen + 1;
|
||||
if (total > 256) return;
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key.constData(), keyLen + 1);
|
||||
memcpy(arg->data + keyLen + 1, valStr.constData(), valLen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
return gui_bridge_post_setting(GUI_SETTING_UI_STATE, key.constData(), valStr.constData()) == 0;
|
||||
};
|
||||
|
||||
if (lastReadMsgId > 0)
|
||||
@@ -1200,21 +1197,14 @@ void MessageList::updateReadPosition() {
|
||||
auto postSaveKey = [&cid](const char* suffix, qint64 val) {
|
||||
QByteArray key = "ch_" + cid + suffix;
|
||||
QByteArray valStr = QByteArray::number(val);
|
||||
size_t keyLen = (size_t)key.size(), valLen = (size_t)valStr.size();
|
||||
size_t total = keyLen + 1 + valLen + 1;
|
||||
if (total > 256) return;
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key.constData(), keyLen + 1);
|
||||
memcpy(arg->data + keyLen + 1, valStr.constData(), valLen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
return gui_bridge_post_setting(GUI_SETTING_UI_STATE, key.constData(), valStr.constData()) == 0;
|
||||
};
|
||||
|
||||
if (newReadMsgId > m_lastReadMsgId) {
|
||||
m_lastReadMsgId = newReadMsgId;
|
||||
postSaveKey("_last_read", m_lastReadMsgId);
|
||||
emit readPositionChanged(m_currentChannelId, m_lastReadMsgId);
|
||||
if (postSaveKey("_last_read", newReadMsgId)) {
|
||||
m_lastReadMsgId = newReadMsgId;
|
||||
emit readPositionChanged(m_currentChannelId, m_lastReadMsgId);
|
||||
}
|
||||
}
|
||||
|
||||
postSaveKey("_last_pos", lastPosMsgId);
|
||||
@@ -1460,12 +1450,11 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
|
||||
if (chId.isEmpty() || msgId <= 0) return;
|
||||
struct attachment_dl_req* req = (struct attachment_dl_req*)
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return;
|
||||
if (!req) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "download request allocation failed"); return; }
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, chId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = msgId;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
if (gui_bridge_post_bound_fn(chat_core_attachment_download_trampoline, req, &req->inst) < 0) u_free(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1481,14 +1470,11 @@ void MessageList::clearDmCallRoute() {
|
||||
|
||||
void MessageList::refreshDmCallRoute() {
|
||||
if (!isDmChannel(m_currentChannelId)) return;
|
||||
auto* inst = gui_bridge_get_inst();
|
||||
if (!inst) { clearDmCallRoute(); return; }
|
||||
auto* req = (struct dm_messages_req*)u_calloc(1, sizeof(struct dm_messages_req));
|
||||
if (!req) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "PM route request: allocation failed"); clearDmCallRoute(); return; }
|
||||
req->inst = inst;
|
||||
QByteArray conv = dmConvId(m_currentChannelId).toUtf8();
|
||||
snprintf(req->conv_id, sizeof(req->conv_id), "%s", conv.constData());
|
||||
gui_bridge_post_uasync_fn(dm_call_route_trampoline, req);
|
||||
if (gui_bridge_post_bound_fn(dm_call_route_trampoline, req, &req->inst) < 0) { u_free(req); clearDmCallRoute(); }
|
||||
}
|
||||
|
||||
void MessageList::onDmCallRoute(const uint8_t* data, int len) {
|
||||
@@ -1543,12 +1529,11 @@ void MessageList::requestDmMessages(const QString& channelId) {
|
||||
}
|
||||
QString conv = dmConvId(channelId);
|
||||
struct dm_messages_req* req = (struct dm_messages_req*)u_malloc(sizeof(*req));
|
||||
if (!req) return;
|
||||
if (!req) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "PM history request allocation failed"); return; }
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
req->generation = m_currentDmGeneration;
|
||||
strncpy(req->conv_id, conv.toUtf8().constData(), sizeof(req->conv_id) - 1);
|
||||
gui_bridge_post_uasync_fn(dm_messages_trampoline, req);
|
||||
if (gui_bridge_post_bound_fn(dm_messages_trampoline, req, &req->inst) < 0) u_free(req);
|
||||
}
|
||||
|
||||
void MessageList::onAttachmentPreparation(const uint8_t* data, int len) {
|
||||
@@ -1742,18 +1727,21 @@ void MessageList::onRadioToggled(bool on) {
|
||||
m_radioBtn->setChecked(m_radioOn);
|
||||
return;
|
||||
}
|
||||
a->inst = gui_bridge_get_inst();
|
||||
a->group_id = groupId;
|
||||
a->on = on ? 1 : 0;
|
||||
gui_bridge_post_uasync_fn(radio_set_active_trampoline, a);
|
||||
if (gui_bridge_post_bound_fn(radio_set_active_trampoline, a, &a->inst) < 0) {
|
||||
u_free(a);
|
||||
if (!on) RadioAudioEngine::instance()->stop();
|
||||
QSignalBlocker blocker(m_radioBtn); m_radioBtn->setChecked(m_radioOn); return;
|
||||
}
|
||||
|
||||
if (on) {
|
||||
if (RadioAudioEngine::instance()->start(groupId) != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: radio start failed group=%016llx", (unsigned long long)groupId);
|
||||
auto* undo = static_cast<radio_set_active_arg*>(u_calloc(1, sizeof(radio_set_active_arg)));
|
||||
if (undo) {
|
||||
undo->inst = gui_bridge_get_inst(); undo->group_id = groupId;
|
||||
gui_bridge_post_uasync_fn(radio_set_active_trampoline, undo);
|
||||
undo->group_id = groupId;
|
||||
if (gui_bridge_post_bound_fn(radio_set_active_trampoline, undo, &undo->inst) < 0) u_free(undo);
|
||||
} else DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: cannot cancel failed radio subscription");
|
||||
QSignalBlocker blocker(m_radioBtn);
|
||||
m_radioBtn->setChecked(false);
|
||||
|
||||
Reference in new issue
Block a user