messenger-android

Android graphical user interfaces for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit 9cad087f70c97c1488075ac9eff99bc11119d4b5
parent fdd181c242585b014bd1b082e49b5001b2ddc64b
Author: t3sserakt <t3ss@posteo.de>
Date:   Wed, 15 Apr 2026 15:14:42 +0200

group fixing

Diffstat:
MGNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/chat/MemberListFragment.kt | 44++++++++++++++++++++++++++++++++++++++++++--
MGNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/group/SelectGroupMembersFragment.kt | 10++++++++++
MGNUnetMessenger/app/src/main/res/layout/fragment_member_list.xml | 8++++++++
MGNUnetMessenger/gradle/libs.versions.toml | 2+-
4 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/chat/MemberListFragment.kt b/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/chat/MemberListFragment.kt @@ -25,17 +25,22 @@ package org.gnunet.gnunetmessenger.ui.chat import android.os.Bundle +import android.util.Log import android.view.View import android.widget.Button +import android.widget.TextView import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import kotlinx.coroutines.launch import org.gnunet.gnunetmessenger.MainActivity import org.gnunet.gnunetmessenger.R +import org.gnunet.gnunetmessenger.model.ChatContact import org.gnunet.gnunetmessenger.ui.adapters.ContactListAdapter import org.gnunet.gnunetmessenger.viewmodel.ContactListViewModel @@ -45,21 +50,56 @@ class MemberListFragment : Fragment(R.layout.fragment_member_list) { private lateinit var adapter: ContactListAdapter private val viewModel: ContactListViewModel by activityViewModels() + private var existingMemberKeys: Set<String> = emptySet() + private var latestContacts: List<ChatContact> = emptyList() + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val chatGroup = args.chatGroup - val gnunetChat = (requireActivity() as MainActivity).getGnunetChatInstance() + val mainActivity = requireActivity() as MainActivity + val gnunetChat = mainActivity.getGnunetChatInstance() val recyclerView = view.findViewById<RecyclerView>(R.id.memberRecyclerView) val inviteButton = view.findViewById<Button>(R.id.confirmButton) + val hint = view.findViewById<TextView>(R.id.memberListHint) recyclerView.layoutManager = LinearLayoutManager(requireContext()) adapter = ContactListAdapter() recyclerView.adapter = adapter + fun renderList() { + val invitable = latestContacts.filter { + it.key.isBlank() || it.key !in existingMemberKeys + } + adapter.submitList(invitable) + hint.text = if (invitable.isEmpty()) { + "No contacts available to invite. Share your identity via a lobby to add contacts first." + } else { + "Select contacts to invite" + } + } + viewModel.contacts.observe(viewLifecycleOwner, Observer { contactList -> - adapter.submitList(contactList) + latestContacts = contactList ?: emptyList() + renderList() }) + // Refresh the contact list each time this screen opens so stale/empty + // view-model state doesn't leave the list blank. + mainActivity.loadChats() + + // Load existing members asynchronously so we can filter them out. + viewLifecycleOwner.lifecycleScope.launch { + existingMemberKeys = try { + gnunetChat.listGroupContacts(chatGroup) + .mapNotNull { it.key.takeIf { k -> k.isNotBlank() } } + .toSet() + } catch (t: Throwable) { + Log.w("MemberListFragment", "listGroupContacts failed", t) + emptySet() + } + renderList() + } + inviteButton.setOnClickListener { val selectedContacts = adapter.getSelectedContacts() for (contact in selectedContacts) { diff --git a/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/group/SelectGroupMembersFragment.kt b/GNUnetMessenger/app/src/main/java/org/gnunet/gnunetmessenger/ui/group/SelectGroupMembersFragment.kt @@ -27,6 +27,7 @@ package org.gnunet.gnunetmessenger.ui.group import android.os.Bundle import android.view.View import android.widget.Button +import android.widget.TextView import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer @@ -63,10 +64,19 @@ class SelectGroupMembersFragment : Fragment(R.layout.fragment_select_group_membe adapter = ContactListAdapter() recyclerView.adapter = adapter + val hint = view.findViewById<TextView>(R.id.selectionHint) viewModel.contacts.observe(viewLifecycleOwner, Observer { contactList -> adapter.submitList(contactList) + hint.text = if (contactList.isNullOrEmpty()) { + "You have no contacts yet — share your identity via a lobby first. You can also create the group now and invite members later." + } else { + "Invite members (optional — you can also invite later from the member list)" + } }) + // Refresh contacts so the list is fresh whenever this screen opens. + mainActivity.loadChats() + view.findViewById<Button>(R.id.btn_confirm_selection).setOnClickListener { val selected = adapter.getSelectedContacts() val groupName = arguments?.getString("groupName") ?: "New Group" diff --git a/GNUnetMessenger/app/src/main/res/layout/fragment_member_list.xml b/GNUnetMessenger/app/src/main/res/layout/fragment_member_list.xml @@ -27,6 +27,14 @@ android:orientation="vertical" android:padding="16dp"> + <TextView + android:id="@+id/memberListHint" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Select contacts to invite" + android:textAppearance="?android:attr/textAppearanceMedium" + android:paddingBottom="8dp" /> + <androidx.recyclerview.widget.RecyclerView android:id="@+id/memberRecyclerView" android:layout_width="match_parent" diff --git a/GNUnetMessenger/gradle/libs.versions.toml b/GNUnetMessenger/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.9.1" +agp = "8.13.2" cardview = "1.0.0" kotlin = "2.2.0" coreKtx = "1.10.1"