Request Android member snapshots on the core thread
This commit is contained in:
1 parent
6c5c1ef0a0
commit
658c248867
3 files changed
+34
-3
No files matched your search
@@ -72,6 +72,7 @@ data class Message(val id: Long, val author: String, val text: String, val ts: L
|
||||
data class ChatMember(val nodeId: Long, val name: String, val online: Boolean = false,
|
||||
val isAdmin: Boolean = false, val isSuper: Boolean = false,
|
||||
val isModer: Boolean = false, val isStorage: Boolean = false,
|
||||
val radioActive: Boolean = false,
|
||||
val isVerified: Boolean = false, val isDeleted: Boolean = false,
|
||||
val nodeType: Int = 0,
|
||||
val rtt: Int = 0, val isSelf: Boolean = false,
|
||||
@@ -167,7 +168,7 @@ data class MemberWire(
|
||||
)
|
||||
|
||||
fun parseMemberWire(data: ByteArray, offset: Int = 0): MemberWire? {
|
||||
if (offset + 79 > data.size) return null
|
||||
if (offset < 0 || offset > data.size - 79) return null
|
||||
val buf = ByteBuffer.wrap(data, offset, 79).order(ByteOrder.LITTLE_ENDIAN)
|
||||
val nodeId = buf.getLong()
|
||||
val online = buf.get().toInt() and 0xFF
|
||||
@@ -181,10 +182,12 @@ fun parseMemberWire(data: ByteArray, offset: Int = 0): MemberWire? {
|
||||
return MemberWire(nodeId, online, isSelf, flags, rtt, natType, storage, name)
|
||||
}
|
||||
|
||||
fun MemberWire.toChatMember(): ChatMember = ChatMember(
|
||||
nodeId = nodeId, name = name, online = online != 0,
|
||||
/* Wire не содержит verified/nodeType и состояния транспортов: сохраняем их из текущей строки. */
|
||||
fun MemberWire.toChatMember(previous: ChatMember = ChatMember(nodeId, name)): ChatMember = previous.copy(
|
||||
name = name, online = online != 0,
|
||||
isAdmin = (flags and 2) != 0, isSuper = (flags and 1) != 0,
|
||||
isModer = (flags and 4) != 0, isStorage = storage,
|
||||
isDeleted = (flags and 8) != 0, radioActive = (flags and 0x10) != 0,
|
||||
rtt = if (rtt == 0xFFFF) 0 else rtt, isSelf = isSelf
|
||||
)
|
||||
|
||||
|
||||
@@ -115,6 +115,8 @@ object NativeLib {
|
||||
|
||||
/* ── Channel members ── */
|
||||
fun getChannelMembers(channelId: String): String = nativeGetChannelMembers(channelId) ?: "[]"
|
||||
/** Асинхронный live-снимок; ответ — событие MEMBER_LIST. */
|
||||
fun requestMemberList(channelId: String): Boolean = nativeRequestMemberList(channelId)
|
||||
fun getMemberDetail(channelId: String, nodeId: Long): String = nativeGetMemberDetail(channelId, nodeId) ?: "{}"
|
||||
fun setMemberNick(channelId: String, nodeId: Long, nick: String) { nativeSetMemberNick(channelId, nodeId, nick) }
|
||||
fun isChannelOwner(channelId: String): Boolean = nativeIsChannelOwner(channelId)
|
||||
@@ -240,6 +242,7 @@ object NativeLib {
|
||||
|
||||
/* ── Channel members JNI ── */
|
||||
private external fun nativeGetChannelMembers(channelId: String): String?
|
||||
private external fun nativeRequestMemberList(channelId: String): Boolean
|
||||
private external fun nativeGetMemberDetail(channelId: String, nodeId: Long): String?
|
||||
private external fun nativeSetMemberNick(channelId: String, nodeId: Long, nick: String)
|
||||
private external fun nativeIsChannelOwner(channelId: String): Boolean
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "../../../lib/mem.h"
|
||||
#include "../../../lib/sqlite3.h"
|
||||
#include "../../../src/chat/chat_core.h"
|
||||
#include "../../../src/chat/chat_member.h"
|
||||
#include "../../../src/chat/invite_build.h"
|
||||
#include "../../../src/chat/chat_setting.h"
|
||||
#include "../../../src/routing_layer/topo_node_sqlite.h"
|
||||
@@ -2294,6 +2295,30 @@ JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeVoiceDecodeClose(
|
||||
|
||||
/* ── Channel members JNI ── */
|
||||
|
||||
/* Живой снимок группы читается в uasync; результат приходит как MEMBER_LIST. */
|
||||
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeRequestMemberList(
|
||||
JNIEnv* env, jobject thiz, jstring channelId) {
|
||||
(void)thiz;
|
||||
struct UTUN_INSTANCE* inst = instance_lite_get_instance();
|
||||
struct UASYNC* ua = instance_lite_get_uasync();
|
||||
if (!inst || !ua || !channelId) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "request_member_list: missing instance/uasync/channel"); return JNI_FALSE;
|
||||
}
|
||||
const char* ch = (*env)->GetStringUTFChars(env, channelId, NULL);
|
||||
if (!ch) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "request_member_list: cannot read channel"); return JNI_FALSE; }
|
||||
struct chat_member_list_req* req = u_calloc(1, sizeof(*req));
|
||||
if (!req || !ch[0] || strlen(ch) >= sizeof(req->ch_id)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "request_member_list: allocation/invalid channel ch=%s", ch);
|
||||
u_free(req); (*env)->ReleaseStringUTFChars(env, channelId, ch); return JNI_FALSE;
|
||||
}
|
||||
req->inst = inst;
|
||||
memcpy(req->ch_id, ch, strlen(ch) + 1);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CHAT_SYNC, "request_member_list: queued ch=%s", ch);
|
||||
(*env)->ReleaseStringUTFChars(env, channelId, ch);
|
||||
uasync_post(ua, chat_core_request_member_list_trampoline, req);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_com_utun_chat_data_NativeLib_nativeGetChannelMembers(
|
||||
JNIEnv* env, jobject thiz, jstring channelId) {
|
||||
(void)thiz;
|
||||
|
||||
Reference in new issue
Block a user