~singpolyma/cheogram-android

bcef5f0f1e4e3bf3862728e10620b202e8a777e8 — Stephen Paul Weber 10 months ago 15dfa7f
Re-use existing forked thread when exists

When replying to or mentioning a null-thread message, re-use the thread
id of any existing forked thread from a previous reply to that message
if there is one, so that not everyone replying to a null thread message
ends up generating a new thread when most of the time they mean to all
end up in the same new thread.

Of course user may tap thread icon at any time if they actually want a
second fork.

Mentions still do not generate a new thread since their association is
not tracked, but will follow the forked thread if it exists.
M src/main/java/eu/siacs/conversations/entities/Conversation.java => src/main/java/eu/siacs/conversations/entities/Conversation.java +17 -0
@@ 599,6 599,23 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
        return reactionEmoji;
    }

    public Set<Message> findReplies(String id) {
        Set<Message> replies = new HashSet<>();

        synchronized (this.messages) {
            for (int i = this.messages.size() - 1; i >= 0; --i) {
                final Message message = messages.get(i);
                if (id.equals(message.getServerMsgId())) break;
                if (id.equals(message.getUuid())) break;
                final Element r = message.getReply();
                if (r != null && r.getAttribute("id") != null && id.equals(r.getAttribute("id"))) {
                    replies.add(message);
                }
            }
        }
        return replies;
    }

    public long loadMoreTimestamp() {
        if (messages.size() < 1) return 0;
        if (getLockThread() && messages.size() > 5000) return 0;

M src/main/java/eu/siacs/conversations/ui/ConversationFragment.java => src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +19 -2
@@ 1500,10 1500,23 @@ public class ConversationFragment extends XmppFragment
        if (message.isPrivateMessage()) privateMessageWith(message.getCounterpart());
        setThread(message.getThread());
        conversation.setUserSelectedThread(true);
        if (message.getThread() == null && conversation.getMode() == Conversation.MODE_MULTI) newThread();
        if (!forkNullThread(message)) newThread();
        setupReply(message);
    }

    private boolean forkNullThread(Message message) {
        if (message.getThread() != null || conversation.getMode() != Conversation.MODE_MULTI) return true;
        for (final Message m : conversation.findReplies(message.getServerMsgId())) {
            final Element thread = m.getThread();
            if (thread != null) {
                setThread(thread);
                return true;
            }
        }

        return false;
    }

    private void setupReply(Message message) {
        conversation.setReplyTo(message);
        if (message == null) {


@@ 4188,8 4201,12 @@ public class ConversationFragment extends XmppFragment

    @Override
    public void onContactPictureClicked(Message message) {
        if (message.isPrivateMessage()) privateMessageWith(message.getCounterpart());
        setThread(message.getThread());
        if (message.isPrivateMessage()) {
            privateMessageWith(message.getCounterpart());
            return;
        }
        forkNullThread(message);
        conversation.setUserSelectedThread(true);

        final boolean received = message.getStatus() <= Message.STATUS_RECEIVED;