Bridge desktop DM deletion requests and results

This commit is contained in:
evgeny committed 2026-10-26 22:11:39 +01:00
1 parent f0b7b22f92
commit 8e3c536cbb
2 files changed
+44 -11

No files matched your search

+8 -4
View File
@@ -44,7 +44,7 @@ struct UTUN_INSTANCE;
#define GUI_EVT_INVITE_LINK_READY 29 /* data: [ch_id_len:1][ch_id:var][request_id:8][link_len:2][link:var] — пустой link = ошибка */
#define GUI_EVT_INVITE_CANDIDATES 30 /* data: [ch_id_len:1][ch_id:var][auto_node_id:8][count:2][node_id:8]* — достижимые узлы для invite */
#define GUI_EVT_DM_MSG_RECEIVED 32 /* data: [conv_id_len:1][conv_id:var][author_node_id:8] */
#define GUI_EVT_DM_CONV_UPDATED 33 /* data: [conv_id_len:1][conv_id:var] — беседа создана/изменена */
#define GUI_EVT_DM_CONV_UPDATED 33 /* data: [conv_id_len:1][conv_id:var][generation:8] — беседа создана/изменена */
#define GUI_EVT_CALL_INCOMING 34 /* data: [ch_id_len:1][ch_id:var][caller_node_id:8][call_id:8] */
#define GUI_EVT_CALL_RINGING 35 /* data: [call_id:8] */
#define GUI_EVT_CALL_ACCEPTED 36 /* data: [call_id:8] */
@@ -52,7 +52,7 @@ struct UTUN_INSTANCE;
#define GUI_EVT_CALL_DECLINED 38 /* data: [call_id:8][reason:1] */
#define GUI_EVT_CALL_STATS 39 /* data: [call_id:8][rtt:2][buffer:2][tempo:2][dropped:2][underruns:2][min:2][max:2][reserve:2] */
#define GUI_EVT_CALL_ERROR 40 /* data: [call_id:8][err:1][text:var] */
#define GUI_EVT_DM_MESSAGES 41 /* data: [conv_id_len:1][conv_id:var][count:2]([dir:1][seq:8][ts:8][author:8][ct_len:1][ct:var][data_len:2][data:var])* */
#define GUI_EVT_DM_MESSAGES 41 /* data: [conv_id_len:1][conv_id:var][generation:8][JSON:utf8] */
#define GUI_EVT_CALL_PATH 42 /* data: [call_id:8][text:var] — BGP-маршрут до пира звонка */
#define GUI_EVT_RADIO_TALK 43 /* data: [group_id:8][src_node_id:8][stream_id:2][on:1] — кто-то начал/закончил говорить */
#define GUI_EVT_CALL_CONNECTION 44 /* data: [call_id:8][CONN_TYPE:1][next_hop_node_id:8] */
@@ -228,15 +228,19 @@ typedef void (*gui_network_changed_fn)(int event_type);
void gui_bridge_set_network_changed_cb(gui_network_changed_fn cb);
void gui_bridge_set_dm_call_route_cb(void (*cb)(const uint8_t* data, int len));
typedef void (*gui_dm_conv_updated_fn)(const char* conv_id, int conv_id_len);
typedef void (*gui_dm_conv_updated_fn)(const char* conv_id, int conv_id_len, uint64_t generation);
void gui_bridge_set_dm_conv_updated_cb(gui_dm_conv_updated_fn cb);
/* Callback: расшифрованные сообщения DM-беседы (вызывается из GUI-потока)
* data: [conv_id_len:1][conv_id:var][count:2]([dir:1][seq:8][ts:8][author:8][ct_len:1][ct:var][data_len:2][data:var])* */
* data: [conv_id_len:1][conv_id:var][generation:8][JSON:utf8]. */
typedef void (*gui_dm_messages_fn)(const uint8_t* data, int len);
void gui_bridge_set_dm_messages_cb(gui_dm_messages_fn cb);
/* CHAT_EVT_DM_INVITE_RESULT: коррелированный результат отправки приглашения. */
void gui_bridge_set_dm_invite_result_cb(gui_dm_messages_fn cb);
/* Запрос локального удаления из GUI: 0=поставлен в uasync, -1=отказ до постановки.
* conv_id — десятичный ID, generation/request_id ненулевые; callback получает CHAT_EVT_DM_DELETE_RESULT в GUI. */
int gui_bridge_delete_dm(const char* conv_id, uint64_t generation, uint64_t request_id);
void gui_bridge_set_dm_delete_result_cb(gui_dm_messages_fn cb);
/* Файловый браузер: wire-ответы и прогресс общих передач, в GUI-потоке. */
void gui_bridge_set_member_files_response_cb(gui_dm_messages_fn cb);
void gui_bridge_set_member_files_transfer_cb(gui_dm_messages_fn cb);
+36 -7
View File
@@ -18,6 +18,7 @@ extern "C" {
#include "../../../src/chat/chat_member.h"
#include "../../../src/chat/chat_core.h"
#include "../../../src/chat/chat_join_port.h"
#include "../../../src/dm/dm_core.h"
}
/* ── Внутренний объект-приёмник в GUI-потоке ── */
@@ -78,6 +79,7 @@ static gui_dm_messages_fn g_dm_messages_cb = nullptr;
static gui_dm_messages_fn g_attachment_preparation_cb = nullptr;
static gui_dm_messages_fn g_dm_call_route_cb = nullptr;
static gui_dm_messages_fn g_dm_invite_result_cb = nullptr;
static gui_dm_messages_fn g_dm_delete_result_cb = nullptr;
static gui_dm_messages_fn g_member_files_response_cb = nullptr;
static gui_dm_messages_fn g_member_files_transfer_cb = nullptr;
static gui_dm_messages_fn g_avatar_result_cb = nullptr;
@@ -155,6 +157,12 @@ void GuiBridgeReceiver::processPost(int eventType, QByteArray data) {
case CHAT_EVT_DM_INVITE_RESULT:
if (g_dm_invite_result_cb) g_dm_invite_result_cb(d, dlen);
break;
case CHAT_EVT_DM_DELETE_RESULT:
if (dlen != 25 || d[24] > 1) {
DEBUG_ERROR(DEBUG_CATEGORY_DM, "gui_bridge: invalid DM delete result bytes=%d", dlen); break;
}
if (g_dm_delete_result_cb) g_dm_delete_result_cb(d, dlen);
break;
case CHAT_EVT_DM_CALL_ROUTE:
if (g_dm_call_route_cb) g_dm_call_route_cb(d, dlen);
break;
@@ -352,13 +360,13 @@ void GuiBridgeReceiver::processPost(int eventType, QByteArray data) {
}
break;
case GUI_EVT_DM_CONV_UPDATED:
if (dlen >= 2) {
uint8_t cl = d[0];
if (dlen >= 1 + cl) {
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "gui_bridge: DM_CONV_UPDATED conv=%.*s",
cl, (const char*)d + 1);
if (g_dm_conv_updated_cb) g_dm_conv_updated_cb((const char*)d + 1, cl);
}
if (dlen >= 10 && d[0] && dlen == 9 + d[0]) {
uint64_t generation; memcpy(&generation, d + 1 + d[0], 8);
DEBUG_INFO(DEBUG_CATEGORY_DM, "gui_bridge: DM_CONV_UPDATED conv=%.*s generation=%llu",
d[0], (const char*)d + 1, (unsigned long long)generation);
if (g_dm_conv_updated_cb) g_dm_conv_updated_cb((const char*)d + 1, d[0], generation);
} else {
DEBUG_ERROR(DEBUG_CATEGORY_DM, "gui_bridge: invalid DM conversation update bytes=%d", dlen);
}
break;
case GUI_EVT_DM_MESSAGES:
@@ -672,6 +680,7 @@ void gui_bridge_set_network_changed_cb(gui_network_changed_fn cb) { g_network_ch
void gui_bridge_set_stream_sources_cb(gui_dm_messages_fn cb) { g_stream_sources_cb = cb; }
void gui_bridge_set_dm_call_route_cb(gui_dm_messages_fn cb) { g_dm_call_route_cb = cb; }
void gui_bridge_set_dm_invite_result_cb(gui_dm_messages_fn cb) { g_dm_invite_result_cb = cb; }
void gui_bridge_set_dm_delete_result_cb(gui_dm_messages_fn cb) { g_dm_delete_result_cb = cb; }
void gui_bridge_set_member_files_response_cb(gui_dm_messages_fn cb) { g_member_files_response_cb = cb; }
void gui_bridge_set_member_files_transfer_cb(gui_dm_messages_fn cb) { g_member_files_transfer_cb = cb; }
void gui_bridge_set_avatar_result_cb(gui_dm_messages_fn cb) { g_avatar_result_cb = cb; }
@@ -683,6 +692,26 @@ void gui_bridge_set_msg_submitted_cb(gui_dm_messages_fn cb) { g_msg_submitted_cb
void gui_bridge_set_radio_mute_result_cb(gui_dm_messages_fn cb) { g_radio_mute_result_cb = cb; }
void gui_bridge_set_radio_call_cb(gui_dm_messages_fn cb) { g_radio_call_cb = cb; }
/* Резервируем post вместе с запросом: UI получает отказ, если поставить удаление в очередь невозможно. */
int gui_bridge_delete_dm(const char* conv_id, uint64_t generation, uint64_t request_id) {
if (!g_inst || !g_ua || !uasync_is_running(g_ua) || !conv_id || !conv_id[0] || strlen(conv_id) >= 64 ||
strspn(conv_id, "0123456789") != strlen(conv_id) || !generation || !request_id) {
DEBUG_ERROR(DEBUG_CATEGORY_DM, "DM delete: invalid request or stopped core generation=%llu request=%llu",
(unsigned long long)generation, (unsigned long long)request_id); return -1;
}
auto* req = static_cast<dm_delete_req*>(u_calloc(1, sizeof(dm_delete_req)));
auto* post = static_cast<posted_task*>(u_calloc(1, sizeof(posted_task)));
if (!req || !post) {
DEBUG_ERROR(DEBUG_CATEGORY_DM, "DM delete: request allocation failed"); u_free(req); u_free(post); return -1;
}
req->inst = g_inst; req->generation = generation; req->request_id = request_id; strcpy(req->conv_id, conv_id);
post->callback = dm_delete_trampoline; post->arg = req;
uasync_post_reserved(g_ua, post);
DEBUG_INFO(DEBUG_CATEGORY_DM, "DM delete queued: conv=%s generation=%llu request=%llu", conv_id,
(unsigned long long)generation, (unsigned long long)request_id);
return 0;
}
int gui_bridge_toggle_member_radio_mute(const char* channel_id, uint64_t node_id) {
const int running = g_inst && g_ua ? uasync_is_running(g_ua) : 0;
const bool valid_channel = channel_id && channel_id[0] && strlen(channel_id) < 64;