From 69ae8b57cbe46ee23019dd2e7a2a0a9c24def462 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 29 Oct 2026 12:29:39 +0100 Subject: [PATCH] Bind private conversation start requests to the worker conversation ID --- .../main/java/com/utun/chat/data/ChatRepository.kt | 3 ++- .../src/main/java/com/utun/chat/data/NativeLib.kt | 6 ++++-- .../jni_bridge/android_jni_bridge.c | 14 ++++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt index 1b605a49..45d795b7 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt @@ -543,7 +543,8 @@ class ChatRepository(private val reportFailure: (String) -> Unit = { LogManager. /* ── DM (личные сообщения) ── */ - fun dmStart(nodeId: Long, sourceChId: String, peerName: String) = + /** ID принятого запроса, привязанный к instance; null означает отказ очереди, событие ещё не подтверждает commit. */ + fun dmStart(nodeId: Long, sourceChId: String, peerName: String): String? = NativeLib.dmStart(nodeId, sourceChId, peerName) fun dmSend(convId: String, text: String, generation: Long, requestId: Long): Boolean = diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt index ec358197..f203a028 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/NativeLib.kt @@ -379,7 +379,9 @@ object NativeLib { fun radioTalkEnd(groupId: Long) { nativeRadioTalkEnd(groupId) } /* ── DM (личные сообщения) ── */ - fun dmStart(nodeId: Long, sourceChId: String, peerName: String): Boolean = nativeDmStart(nodeId, sourceChId, peerName) + /** Зафиксированный worker ID принятой беседы; null — отказ без события. Commit подтверждает DM_CONV_UPDATED с тем же ID. */ + fun dmStart(nodeId: Long, sourceChId: String, peerName: String): String? = + nativeDmStart(nodeId, sourceChId, peerName).takeIf { it != 0L }?.toULong()?.toString() /** UTF-8 без Modified UTF-8: true подтверждает очередь, CHAT_EVT_MSG_SUBMITTED — запись истории/outbox. */ fun dmSend(convId: String, text: String, generation: Long, requestId: Long): Boolean = nativeDmSend(convId, text.toByteArray(Charsets.UTF_8), generation, requestId) @@ -522,7 +524,7 @@ object NativeLib { /* ── DM JNI ── */ private external fun nativeDmDelete(convId: String, generation: Long, request: Long): Boolean - private external fun nativeDmStart(nodeId: Long, sourceChId: String, peerName: String): Boolean + private external fun nativeDmStart(nodeId: Long, sourceChId: String, peerName: String): Long private external fun nativeDmSend(convId: String, text: ByteArray, generation: Long, requestId: Long): Boolean private external fun nativeDmInvite(requestId: Long, peer: Long, source: String, channelId: Long, name: String, cancel: Boolean): Boolean private external fun nativeIsChannelMember(channelId: String, nodeId: Long): Boolean diff --git a/tools/chatgui-android/jni_bridge/android_jni_bridge.c b/tools/chatgui-android/jni_bridge/android_jni_bridge.c index e1e665cd..b4c859e6 100644 --- a/tools/chatgui-android/jni_bridge/android_jni_bridge.c +++ b/tools/chatgui-android/jni_bridge/android_jni_bridge.c @@ -22,6 +22,7 @@ #include "../../../src/radio/radio_call.h" #include "../../../src/radio/radio_audio.h" #include "../../../src/dm/dm_core.h" +#include "../../../src/dm/dm_crypto.h" #include "../../../src/dm/dm_media.h" #include "../../../lib/debug_config.h" #include "../../../lib/u_async.h" @@ -1590,7 +1591,7 @@ static jobject g_event_callback = NULL; static jmethodID g_event_mid = NULL; static pthread_mutex_t g_event_callback_lock = PTHREAD_MUTEX_INITIALIZER; -enum bridge_query_kind { QUERY_CHANNELS, QUERY_MESSAGES, QUERY_MEMBERS, QUERY_DETAIL, QUERY_LINKS, QUERY_NODE, QUERY_SET_NICK, +enum bridge_query_kind { QUERY_CHANNELS, QUERY_MESSAGES, QUERY_MEMBERS, QUERY_DETAIL, QUERY_LINKS, QUERY_NODE, QUERY_SET_NICK, QUERY_DM_START, QUERY_OWNER, QUERY_MEMBERSHIP, QUERY_SETTING, QUERY_SOUND, QUERY_RADIO_SUBSCRIBERS, QUERY_RADIO_START }; /* Строки/ID заимствованы до возврата instance_lite_call; JSON становится собственностью JNI caller. */ struct bridge_query { @@ -1613,6 +1614,10 @@ static void bridge_query_run(void* arg) { case QUERY_LINKS: q->json = utun_bridge_get_member_links_json(q->node); break; case QUERY_NODE: q->number = (int64_t)utun_bridge_get_my_node_id(); break; case QUERY_SET_NICK: utun_bridge_set_member_nick(q->channel, q->node, q->value); break; + case QUERY_DM_START: + if (!utun_bridge_dm_start(q->node, q->channel, q->value)) + q->number = (int64_t)dm_derive_conv_id(instance_lite_get_instance()->node_id, q->node); + break; case QUERY_OWNER: q->number = utun_bridge_is_channel_owner(q->channel); break; case QUERY_MEMBERSHIP: q->number = topo_node_sqlite_member_in_channel(instance_lite_get_instance()->topo_sqlite_db, q->channel, q->node); break; @@ -2266,15 +2271,16 @@ JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeFeedbackComma ((char*)(req + 1))[len] = 0; int posted = bridge_post_request(chat_feedback_command_trampoline, req, &req->inst); return posted == 0 ? JNI_TRUE : JNI_FALSE; } -JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeDmStart( +JNIEXPORT jlong JNICALL Java_com_utun_chat_data_NativeLib_nativeDmStart( JNIEnv* env, jobject thiz, jlong nodeId, jstring sourceChId, jstring peerName) { (void)thiz; const char* ch = sourceChId ? jni_utf8(env, sourceChId) : NULL; const char* nm = peerName ? jni_utf8(env, peerName) : NULL; - int result = utun_bridge_dm_start((uint64_t)nodeId, ch, nm); + struct bridge_query query = {.kind = QUERY_DM_START, .channel = ch, .value = nm, .node = (uint64_t)nodeId}; + if ((!sourceChId || ch) && (!peerName || nm)) bridge_query_call(&query); if (nm) u_free((void*)nm); if (ch) u_free((void*)ch); - return result == 0 ? JNI_TRUE : JNI_FALSE; + return (jlong)query.number; } JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeDmSend(