commit 535db0401c5e1bb1076870fe4f6a2f887b48590d
parent 2f85060ea131efbf6b9f4468430d4d99f04fc506
Author: t3sserakt <t3ss@posteo.de>
Date: Wed, 6 May 2026 22:20:39 +0200
WIP: chat text survives until app re run
Diffstat:
1 file changed, 74 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
@@ -685,20 +685,86 @@ class MainActivity : AppCompatActivity() {
chatMessage: ChatMessage
) {
val current = currentSession()
- if (current != null &&
+ val isForeground = current != null &&
current.account.name.equals(session.account.name, ignoreCase = true)
- ) {
+
+ if (isForeground) {
processChatMessage(chatContext, chatMessage)
- } else {
- Log.d(
- TAG,
- "background-session ${session.account.name}: kind=${chatMessage.kind} " +
- "(deferred — will re-render on next switch)"
- )
+ return
+ }
+
+ // Background session: route TEXT/FILE messages into the global chat
+ // viewmodel using the session's own service so they're visible when
+ // the user later switches to this session. Other event kinds will be
+ // re-rendered via loadChats() on switch.
+ 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) {
+ Log.d(
+ TAG,
+ "background-session ${session.account.name}: kind=${chatMessage.kind} " +
+ "(own echo, skip)"
+ )
+ return
+ }
+ val key = stableChatKeyFor(session, chatContext)
+ if (key == null) {
+ Log.w(
+ TAG,
+ "background-session ${session.account.name}: kind=${chatMessage.kind} " +
+ "no stableChatKey — dropping"
+ )
+ return
+ }
+ val vm = chatViewModels.getOrPut(key) { ChatViewModel(chatContext) }
+ chatMessage.type = ChatMessageType.OTHER
+ vm.addMessage(chatMessage)
+ Log.d(
+ TAG,
+ "background-session ${session.account.name}: kind=${chatMessage.kind} " +
+ "added to viewmodel '$key' (msgCount=${vm.messages.value?.size ?: 0})"
+ )
+ }
+ else -> {
+ Log.d(
+ TAG,
+ "background-session ${session.account.name}: kind=${chatMessage.kind} " +
+ "(deferred — will re-render on next switch)"
+ )
+ }
}
}
/**
+ * Same as [stableChatKey] but resolves group/contact info via the given
+ * [session]'s service. Required when the message arrived on a background
+ * session whose native context pointer is in that session's address
+ * space — the foreground service can't dereference it.
+ */
+ private fun stableChatKeyFor(
+ session: AccountSession,
+ chatContext: ChatContext
+ ): String? {
+ val gnunetChat = session.gnunetChat
+ runCatching { gnunetChat.getGroupFromContext(chatContext) }
+ .getOrNull()
+ ?.takeIf { it.name.isNotBlank() }
+ ?.let { return "group:${it.name}" }
+
+ runCatching { gnunetChat.getContextContact(chatContext) }
+ .getOrNull()
+ ?.key
+ ?.takeIf { it.isNotBlank() }
+ ?.let { return "contact:$it" }
+
+ return chatContext.userPointer?.takeIf { it.isNotBlank() }
+ }
+
+ /**
* Switches the foreground UI to [account]. Spawns a new session if one
* doesn't exist. **Never disconnects** existing sessions — both the lobby
* host and the joiner can stay live across the switch, which is what