From 2142fed8fefc770a3417347ad7ffb6eb280c0aad Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Tue, 26 Jul 2022 12:31:17 -0500 Subject: [PATCH] Menu item to refresh features for a contact Shouldn't be needed in general, so hidden under a sub-menu, but for advanced use cases and especially services without caps, can enable features that normally would not be detected. --- .../conversations/entities/Conversation.java | 17 ++++-- .../services/XmppConnectionService.java | 27 ++++++--- .../ui/ConversationFragment.java | 60 +++++++++++++------ src/main/res/menu/fragment_conversation.xml | 8 ++- 4 files changed, 81 insertions(+), 31 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index a2de23a7c8f5074ede72e1b9530fe723866e0791..78735014be5dc3e6d672e903416d1ee261d751d7 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -1180,6 +1180,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl pagerAdapter.setupViewPager(pager, tabs); } + public void showViewPager() { + pagerAdapter.show(); + } + public void hideViewPager() { pagerAdapter.hide(); } @@ -1214,10 +1218,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl public void setupViewPager(ViewPager pager, TabLayout tabs) { mPager = pager; mTabs = tabs; - if (sessions == null) { - sessions = new ArrayList<>(); - notifyDataSetChanged(); - } + show(); pager.setAdapter(this); tabs.setupWithViewPager(mPager); pager.setCurrentItem(getCurrentTab()); @@ -1232,6 +1233,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl }); } + public void show() { + if (sessions == null) { + sessions = new ArrayList<>(); + notifyDataSetChanged(); + } + mTabs.setVisibility(View.VISIBLE); + } + public void hide() { mPager.setCurrentItem(0); mTabs.setVisibility(View.GONE); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index afecec477c8b091753231e05e8d229e855f6f725..b2aa59129d238cbfdf84492d49b47e14eee20374 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -4673,6 +4673,7 @@ public class XmppConnectionService extends Service { if (result != null) { return result; } else { + if (key.first == null || key.second == null) return null; result = databaseBackend.findDiscoveryResult(key.first, key.second); if (result != null) { discoCache.put(key, result); @@ -4700,6 +4701,10 @@ public class XmppConnectionService extends Service { } public void fetchCaps(Account account, final Jid jid, final Presence presence) { + fetchCaps(account, jid, presence, null); + } + + public void fetchCaps(Account account, final Jid jid, final Presence presence, Runnable cb) { final Pair key = new Pair<>(presence.getHash(), presence.getVer()); final ServiceDiscoveryResult disco = getCachedServiceDiscoveryResult(key); @@ -4726,14 +4731,15 @@ public class XmppConnectionService extends Service { sendIqPacket(account, request, (a, response) -> { if (response.getType() == IqPacket.TYPE.RESULT) { final ServiceDiscoveryResult discoveryResult = new ServiceDiscoveryResult(response); - if (presence.getVer().equals(discoveryResult.getVer())) { + if (presence.getVer() == null || presence.getVer().equals(discoveryResult.getVer())) { databaseBackend.insertDiscoveryResult(discoveryResult); - injectServiceDiscoveryResult(a.getRoster(), presence.getHash(), presence.getVer(), discoveryResult); + injectServiceDiscoveryResult(a.getRoster(), presence.getHash(), presence.getVer(), jid.getResource(), discoveryResult); if (discoveryResult.hasIdentity("gateway", "pstn")) { final Contact contact = account.getRoster().getContact(jid); contact.registerAsPhoneAccount(this); mQuickConversationsService.considerSyncBackground(false); } + if (cb != null) cb.run(); } else { Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": mismatch in caps for contact " + jid + " " + presence.getVer() + " vs " + discoveryResult.getVer()); } @@ -4749,14 +4755,21 @@ public class XmppConnectionService extends Service { sendIqPacket(account, request, callback); } - private void injectServiceDiscoveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) { + private void injectServiceDiscoveryResult(Roster roster, String hash, String ver, String resource, ServiceDiscoveryResult disco) { boolean rosterNeedsSync = false; for (final Contact contact : roster.getContacts()) { boolean serviceDiscoverySet = false; - for (final Presence presence : contact.getPresences().getPresences()) { - if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) { - presence.setServiceDiscoveryResult(disco); - serviceDiscoverySet = true; + Presence onePresence = contact.getPresences().get(resource == null ? "" : resource); + if (onePresence != null) { + onePresence.setServiceDiscoveryResult(disco); + serviceDiscoverySet = true; + } + if (hash != null && ver != null) { + for (final Presence presence : contact.getPresences().getPresences()) { + if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) { + presence.setServiceDiscoveryResult(disco); + serviceDiscoverySet = true; + } } } if (serviceDiscoverySet) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 779615d579deb1104944f8e77fa59492ecdc0093..0a359004bf272b94bba8e89708baae8b28a57fbb 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1527,6 +1527,9 @@ public class ConversationFragment extends XmppFragment case R.id.action_toggle_pinned: togglePinned(); break; + case R.id.action_refresh_feature_discovery: + refreshFeatureDiscovery(); + break; default: break; } @@ -1566,6 +1569,17 @@ public class ConversationFragment extends XmppFragment } } + private void refreshFeatureDiscovery() { + for (Map.Entry entry : conversation.getContact().getPresences().getPresencesMap().entrySet()) { + Jid jid = conversation.getContact().getJid(); + if (!entry.getKey().equals("")) jid = jid.withResource(entry.getKey()); + activity.xmppConnectionService.fetchCaps(conversation.getAccount(), jid, entry.getValue(), () -> { + if (activity == null) return; + activity.runOnUiThread(() -> { refresh(); }); + }); + } + } + private void togglePinned() { final boolean pinned = conversation.getBooleanAttribute(Conversation.ATTRIBUTE_PINNED_ON_TOP, false); @@ -2510,29 +2524,36 @@ public class ConversationFragment extends XmppFragment binding.commandsView.setOnItemClickListener((parent, view, position, id) -> { conversation.startCommand(commandAdapter.getItem(position), activity.xmppConnectionService); }); - Jid commandJid = conversation.getContact().resourceWhichSupport(Namespace.COMMANDS); - if (commandJid == null) { - conversation.hideViewPager(); - } else { - binding.tabLayout.setVisibility(View.VISIBLE); - activity.xmppConnectionService.fetchCommands(conversation.getAccount(), commandJid, (a, iq) -> { - if (activity == null) return; - - activity.runOnUiThread(() -> { - if (iq.getType() == IqPacket.TYPE.RESULT) { - for (Element child : iq.query().getChildren()) { - if (!"item".equals(child.getName()) || !Namespace.DISCO_ITEMS.equals(child.getNamespace())) continue; - commandAdapter.add(child); - } + refreshCommands(); + } + + return true; + } + + protected void refreshCommands() { + if (commandAdapter == null) return; + + Jid commandJid = conversation.getContact().resourceWhichSupport(Namespace.COMMANDS); + if (commandJid == null) { + conversation.hideViewPager(); + } else { + conversation.showViewPager(); + activity.xmppConnectionService.fetchCommands(conversation.getAccount(), commandJid, (a, iq) -> { + if (activity == null) return; + + activity.runOnUiThread(() -> { + if (iq.getType() == IqPacket.TYPE.RESULT) { + commandAdapter.clear(); + for (Element child : iq.query().getChildren()) { + if (!"item".equals(child.getName()) || !Namespace.DISCO_ITEMS.equals(child.getNamespace())) continue; + commandAdapter.add(child); } + } - if (commandAdapter.getCount() < 1) conversation.hideViewPager(); - }); + if (commandAdapter.getCount() < 1) conversation.hideViewPager(); }); - } + }); } - - return true; } private void resetUnreadMessagesCount() { @@ -2833,6 +2854,7 @@ public class ConversationFragment extends XmppFragment } updateSendButton(); updateEditablity(); + refreshCommands(); } } } diff --git a/src/main/res/menu/fragment_conversation.xml b/src/main/res/menu/fragment_conversation.xml index 1e12f91c134b47bab0e3d7718ea2a9100b92744d..8ff992a53176c1bb6d619d9f3011c7382bbcd247 100644 --- a/src/main/res/menu/fragment_conversation.xml +++ b/src/main/res/menu/fragment_conversation.xml @@ -135,8 +135,14 @@ android:orderInCategory="73" android:title="@string/add_to_favorites" app:showAsAction="never" /> + + - \ No newline at end of file +