~singpolyma/cheogram-android

2142fed8fefc770a3417347ad7ffb6eb280c0aad — Stephen Paul Weber 2 years ago d751f11
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.
M src/main/java/eu/siacs/conversations/entities/Conversation.java => src/main/java/eu/siacs/conversations/entities/Conversation.java +13 -4
@@ 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);

M src/main/java/eu/siacs/conversations/services/XmppConnectionService.java => src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +20 -7
@@ 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<String, String> 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) {

M src/main/java/eu/siacs/conversations/ui/ConversationFragment.java => src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +41 -19
@@ 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<String, Presence> 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();
            }
        }
    }

M src/main/res/menu/fragment_conversation.xml => src/main/res/menu/fragment_conversation.xml +7 -1
@@ 135,8 135,14 @@
                android:orderInCategory="73"
                android:title="@string/add_to_favorites"
                app:showAsAction="never" />

            <item
                android:id="@+id/action_refresh_feature_discovery"
                android:orderInCategory="74"
                android:title="Refresh Feature Discovery"
                app:showAsAction="never" />
        </menu>
    </item>


</menu>
\ No newline at end of file
</menu>