diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 574035e2c..d35d4808c 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/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) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 7bbd4c8e5..93a5ad2bf 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/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); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java index 86f49064a..171eea6ad 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +++ b/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); diff --git a/src/main/java/eu/siacs/conversations/ui/util/ActionBarUtil.java b/src/main/java/eu/siacs/conversations/ui/util/ActionBarUtil.java new file mode 100644 index 000000000..80f0ae93e --- /dev/null +++ b/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 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; + } + } +}