commit 7dfcf601a5803aaeeec6dff82a2e1f6e0687ca29
parent ccc537d422172539be6b8f29f904f5809c52574d
Author: t3sserakt <t3ss@posteo.de>
Date: Wed, 20 May 2026 17:46:18 +0200
WIP: open bug fixing: group chat showing only on right side for all users
Diffstat:
2 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/MainActivity.kt b/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/MainActivity.kt
@@ -325,7 +325,14 @@ class MainActivity : AppCompatActivity() {
MessageKind.FILE -> {
val senderKey = chatMessage.sender?.key ?: ""
val profileKey = gnunetChat.getProfileKey(handle)
- if (senderKey.isNotEmpty() && senderKey == profileKey) {
+ val ownEchoSkip = senderKey.isNotEmpty() && senderKey == profileKey
+ Log.d(
+ TAG,
+ "TEXT/FILE foreground: senderKey='${senderKey.take(16)}...' " +
+ "(len=${senderKey.length}) profileKey='${profileKey.take(16)}...' " +
+ "(len=${profileKey.length}) match=$ownEchoSkip text='${chatMessage.text}'"
+ )
+ if (ownEchoSkip) {
// Already added this message to the view when we sent it,
// so skip the echo to avoid a duplicate.
return
@@ -707,17 +714,40 @@ class MainActivity : AppCompatActivity() {
when (chatMessage.kind) {
MessageKind.TEXT, MessageKind.FILE -> {
val senderKey = chatMessage.sender?.key ?: ""
- val ownKey = runCatching {
- session.gnunetChat.getProfileKey(session.handle)
- }.getOrDefault("")
- if (senderKey.isNotEmpty() && senderKey == ownKey) {
+
+ // Skip if the sender matches ANY of our local sessions'
+ // profile keys (not just this background session's). In
+ // multi-handle group chat, when account A (foreground)
+ // sends a message, the daemon broadcasts it to every
+ // handle subscribed to the group, including B's. B's
+ // background handler then sees a TEXT whose sender is A.
+ // A's foreground has already optimistically added that
+ // message to the shared "group:<name>" viewmodel via
+ // ChatFragment's sendButton; if we also add it here, the
+ // user sees the same text twice. Treat "sender is any of
+ // our active accounts" as an own-echo and skip.
+ //
+ // Edge case left open intentionally: an external peer
+ // sending to a group where multiple of our local
+ // accounts are both members would still duplicate
+ // (foreground handler adds + background handler adds).
+ // Rare enough that we accept it for now; can be tackled
+ // with viewmodel-level dedup if it ever matters.
+ val isOurOwnEcho = senderKey.isNotEmpty() && sessions.values.any { other ->
+ val k = runCatching {
+ other.gnunetChat.getProfileKey(other.handle)
+ }.getOrDefault("")
+ k.isNotEmpty() && k == senderKey
+ }
+ if (isOurOwnEcho) {
Log.d(
TAG,
"background-session ${session.account.name}: kind=${chatMessage.kind} " +
- "(own echo, skip)"
+ "(own echo from one of our sessions, skip)"
)
return
}
+
val key = stableChatKeyFor(session, chatContext)
if (key == null) {
Log.w(
diff --git a/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/chat/ChatFragment.kt b/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/chat/ChatFragment.kt
@@ -213,9 +213,19 @@ class ChatFragment : Fragment(R.layout.fragment_chat) {
try {
val profileKey = gnunetChat.getProfileKey(mainActivity.getChatHandle())
val history = gnunetChat.iterateContextMessages(chatContext)
+ Log.d(
+ "ChatFragment",
+ "iterate: profileKey='${profileKey.take(16)}...' " +
+ "(len=${profileKey.length}) historySize=${history.size}"
+ )
for (msg in history) {
- val isOwn = msg.sender?.key?.isNotBlank() == true &&
- msg.sender.key == profileKey
+ val sKey = msg.sender?.key ?: ""
+ val isOwn = sKey.isNotBlank() && sKey == profileKey
+ Log.d(
+ "ChatFragment",
+ "iterate.msg: senderKey='${sKey.take(16)}...' " +
+ "(len=${sKey.length}) isOwn=$isOwn text='${msg.text}'"
+ )
val typed = msg.copy(type = if (isOwn) ChatMessageType.OWN else ChatMessageType.OTHER)
chatViewModel.addMessage(typed)
}