click on action bar title should open chat details screen

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java |  8 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java      | 10 
src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java     | 58 
src/main/java/eu/siacs/conversations/ui/util/ActionBarUtil.java        | 88 
4 files changed, 139 insertions(+), 25 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java 🔗

@@ -1,5 +1,6 @@
 package eu.siacs.conversations.ui;
 
+import android.app.Activity;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -87,6 +88,13 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
         }
     };
 
+    public static void open(final Activity activity, final Conversation conversation) {
+        Intent intent = new Intent(activity, ConferenceDetailsActivity.class);
+        intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
+        intent.putExtra("uuid", conversation.getUuid());
+        activity.startActivity(intent);
+    }
+
     private final OnClickListener mNotifyStatusClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -186,10 +186,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 
         @Override
         public void onClick(View v) {
-            Intent intent = new Intent(getActivity(), ConferenceDetailsActivity.class);
-            intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
-            intent.putExtra("uuid", conversation.getUuid());
-            startActivity(intent);
+            ConferenceDetailsActivity.open(getActivity(), conversation);
         }
     };
     private final OnClickListener leaveMuc = new OnClickListener() {
@@ -1272,10 +1269,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
                 activity.switchToContactDetails(conversation.getContact());
                 break;
             case R.id.action_muc_details:
-                Intent intent = new Intent(getActivity(), ConferenceDetailsActivity.class);
-                intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
-                intent.putExtra("uuid", conversation.getUuid());
-                startActivity(intent);
+                ConferenceDetailsActivity.open(getActivity(), conversation);
                 break;
             case R.id.action_invite:
                 startActivityForResult(ChooseContactActivity.create(activity, conversation), REQUEST_INVITE_TO_CONVERSATION);

src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java 🔗

@@ -30,6 +30,8 @@
 package eu.siacs.conversations.ui;
 
 
+import static eu.siacs.conversations.ui.ConversationFragment.REQUEST_DECRYPT_PGP;
+
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.Fragment;
@@ -65,13 +67,16 @@ import eu.siacs.conversations.R;
 import eu.siacs.conversations.crypto.OmemoSetting;
 import eu.siacs.conversations.databinding.ActivityConversationsBinding;
 import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Conversational;
 import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.ui.interfaces.OnBackendConnected;
 import eu.siacs.conversations.ui.interfaces.OnConversationArchived;
 import eu.siacs.conversations.ui.interfaces.OnConversationRead;
 import eu.siacs.conversations.ui.interfaces.OnConversationSelected;
 import eu.siacs.conversations.ui.interfaces.OnConversationsListItemUpdated;
+import eu.siacs.conversations.ui.util.ActionBarUtil;
 import eu.siacs.conversations.ui.util.ActivityResult;
 import eu.siacs.conversations.ui.util.ConversationMenuConfigurator;
 import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
@@ -83,8 +88,6 @@ import eu.siacs.conversations.utils.XmppUri;
 import eu.siacs.conversations.xmpp.Jid;
 import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
 
-import static eu.siacs.conversations.ui.ConversationFragment.REQUEST_DECRYPT_PGP;
-
 public class ConversationsActivity extends XmppActivity implements OnConversationSelected, OnConversationArchived, OnConversationsListItemUpdated, OnConversationRead, XmppConnectionService.OnAccountUpdate, XmppConnectionService.OnConversationUpdate, XmppConnectionService.OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast, XmppConnectionService.OnAffiliationChanged {
 
     public static final String ACTION_VIEW_CONVERSATION = "eu.siacs.conversations.action.VIEW";
@@ -604,18 +607,38 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
 
     private void invalidateActionBarTitle() {
         final ActionBar actionBar = getSupportActionBar();
-        if (actionBar != null) {
-            Fragment mainFragment = getFragmentManager().findFragmentById(R.id.main_fragment);
-            if (mainFragment instanceof ConversationFragment) {
-                final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
-                if (conversation != null) {
-                    actionBar.setTitle(EmojiWrapper.transform(conversation.getName()));
-                    actionBar.setDisplayHomeAsUpEnabled(true);
-                    return;
-                }
+        if (actionBar == null) {
+            return;
+        }
+        final FragmentManager fragmentManager = getFragmentManager();
+        final Fragment mainFragment = fragmentManager.findFragmentById(R.id.main_fragment);
+        if (mainFragment instanceof ConversationFragment) {
+            final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
+            if (conversation != null) {
+                actionBar.setTitle(EmojiWrapper.transform(conversation.getName()));
+                actionBar.setDisplayHomeAsUpEnabled(true);
+                ActionBarUtil.setActionBarOnClickListener(
+                        binding.toolbar,
+                        (v) -> openConversationDetails(conversation)
+                );
+                return;
+            }
+        }
+        actionBar.setTitle(R.string.app_name);
+        actionBar.setDisplayHomeAsUpEnabled(false);
+        ActionBarUtil.resetActionBarOnClickListeners(binding.toolbar);
+    }
+
+    private void openConversationDetails(final Conversation conversation) {
+        if (conversation.getMode() == Conversational.MODE_MULTI) {
+            ConferenceDetailsActivity.open(this, conversation);
+        } else {
+            final Contact contact = conversation.getContact();
+            if (contact.isSelf()) {
+                switchToAccount(conversation.getAccount());
+            } else {
+                switchToContactDetails(contact);
             }
-            actionBar.setTitle(R.string.app_name);
-            actionBar.setDisplayHomeAsUpEnabled(false);
         }
     }
 
@@ -624,17 +647,18 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
         if (performRedirectIfNecessary(conversation, false)) {
             return;
         }
-        Fragment mainFragment = getFragmentManager().findFragmentById(R.id.main_fragment);
+        final FragmentManager fragmentManager = getFragmentManager();
+        final Fragment mainFragment = fragmentManager.findFragmentById(R.id.main_fragment);
         if (mainFragment instanceof ConversationFragment) {
             try {
-                getFragmentManager().popBackStack();
-            } catch (IllegalStateException e) {
+                fragmentManager.popBackStack();
+            } catch (final IllegalStateException e) {
                 Log.w(Config.LOGTAG, "state loss while popping back state after archiving conversation", e);
                 //this usually means activity is no longer active; meaning on the next open we will run through this again
             }
             return;
         }
-        Fragment secondaryFragment = getFragmentManager().findFragmentById(R.id.secondary_fragment);
+        final Fragment secondaryFragment = fragmentManager.findFragmentById(R.id.secondary_fragment);
         if (secondaryFragment instanceof ConversationFragment) {
             if (((ConversationFragment) secondaryFragment).getConversation() == conversation) {
                 Conversation suggestion = ConversationsOverviewFragment.getSuggestion(this, conversation);

src/main/java/eu/siacs/conversations/ui/util/ActionBarUtil.java 🔗

@@ -0,0 +1,88 @@
+package eu.siacs.conversations.ui.util;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.lang.reflect.Field;
+
+public class ActionBarUtil {
+
+    public static void resetActionBarOnClickListeners(@NonNull View view) {
+        final View title = findActionBarTitle(view);
+        final View subtitle = findActionBarSubTitle(view);
+        if (title != null) {
+            title.setOnClickListener(null);
+        }
+        if (subtitle != null) {
+            subtitle.setOnClickListener(null);
+        }
+    }
+
+    public static void setActionBarOnClickListener(@NonNull View view,
+                                                   @NonNull final View.OnClickListener onClickListener) {
+        final View title = findActionBarTitle(view);
+        final View subtitle = findActionBarSubTitle(view);
+        if (title != null) {
+            title.setOnClickListener(onClickListener);
+        }
+        if (subtitle != null) {
+            subtitle.setOnClickListener(onClickListener);
+        }
+    }
+
+    private static @Nullable View findActionBarTitle(@NonNull View root) {
+        return findActionBarItem(root, "action_bar_title", "mTitleTextView");
+    }
+
+    private static @Nullable
+    View findActionBarSubTitle(@NonNull View root) {
+        return findActionBarItem(root, "action_bar_subtitle", "mSubtitleTextView");
+    }
+
+    private static @Nullable View findActionBarItem(@NonNull View root,
+                                                    @NonNull String resourceName,
+                                                    @NonNull String toolbarFieldName) {
+        View result = findViewSupportOrAndroid(root, resourceName);
+
+        if (result == null) {
+            View actionBar = findViewSupportOrAndroid(root, "action_bar");
+            if (actionBar != null) {
+                result = reflectiveRead(actionBar, toolbarFieldName);
+            }
+        }
+        if (result == null && root.getClass().getName().endsWith("widget.Toolbar")) {
+            result = reflectiveRead(root, toolbarFieldName);
+        }
+        return result;
+    }
+
+    @SuppressWarnings("ConstantConditions")
+    private static @Nullable View findViewSupportOrAndroid(@NonNull View root,
+                                                           @NonNull String resourceName) {
+        Context context = root.getContext();
+        View result = null;
+        if (result == null) {
+            int supportID = context.getResources().getIdentifier(resourceName, "id", context.getPackageName());
+            result = root.findViewById(supportID);
+        }
+        if (result == null) {
+            int androidID = context.getResources().getIdentifier(resourceName, "id", "android");
+            result = root.findViewById(androidID);
+        }
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> T reflectiveRead(@NonNull Object object, @NonNull String fieldName) {
+        try {
+            Field field = object.getClass().getDeclaredField(fieldName);
+            field.setAccessible(true);
+            return (T) field.get(object);
+        } catch (final Exception ex) {
+            return null;
+        }
+    }
+}