From 52ab3fa80508e86aef8f6e6e7c2b45c526ad78e7 Mon Sep 17 00:00:00 2001 From: Rustum Zia Date: Tue, 25 Mar 2025 21:58:23 -0400 Subject: [PATCH] Message compose: support parsing list of recipients --- .../com/fsck/k9/view/RecipientSelectView.java | 34 ++++++++++++++----- .../TokenCompleteTextView.java | 15 +++----- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/legacy/ui/legacy/src/main/java/com/fsck/k9/view/RecipientSelectView.java b/legacy/ui/legacy/src/main/java/com/fsck/k9/view/RecipientSelectView.java index bf57600bdf7..b7bdfc46dd2 100644 --- a/legacy/ui/legacy/src/main/java/com/fsck/k9/view/RecipientSelectView.java +++ b/legacy/ui/legacy/src/main/java/com/fsck/k9/view/RecipientSelectView.java @@ -5,6 +5,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; import android.annotation.SuppressLint; @@ -167,21 +168,33 @@ private void bindObjectView(Recipient recipient, View view) { holder.showCryptoState(isAvailable, showCryptoEnabled); } - @Override - protected Recipient defaultObject(String completionText) { + private List parseRecipients(String text) { try { - List
parsedAddresses = emailAddressParser.parse(completionText); + List
parsedAddresses = emailAddressParser.parse(text); if (parsedAddresses.isEmpty()) { setError(getContext().getString(R.string.recipient_error_parse_failed)); - return null; + return List.of(); } - return new Recipient(parsedAddresses.get(0)); + List recipients = new ArrayList<>(); + for (Address a : parsedAddresses) { + recipients.add(new Recipient(a)); + } + return recipients; } catch (NonAsciiEmailAddressException e) { setError(getContext().getString(R.string.recipient_error_non_ascii)); - return null; + return List.of(); + } + } + + @Override + protected Recipient defaultObject(String completionText) { + List recipients = parseRecipients(completionText); + if (!recipients.isEmpty()) { + return recipients.get(0); } + return null; } public void setLoaderManager(@Nullable LoaderManager loaderManager) { @@ -245,9 +258,12 @@ public void showDropDown() { @Override public void performCompletion() { if (getListSelection() == ListView.INVALID_POSITION && enoughToFilter()) { - Object recipientText = defaultObject(currentCompletionText()); - if (recipientText != null) { - replaceText(convertSelectionToString(recipientText)); + List recipients = parseRecipients(currentCompletionText()); + if (!recipients.isEmpty()) { + clearCompletionText(); + for (Recipient r : recipients) { + addObjectSync(r); + } } } else { super.performCompletion(); diff --git a/library/TokenAutoComplete/src/main/java/com/tokenautocomplete/TokenCompleteTextView.java b/library/TokenAutoComplete/src/main/java/com/tokenautocomplete/TokenCompleteTextView.java index 5585e31116e..975609875d6 100644 --- a/library/TokenAutoComplete/src/main/java/com/tokenautocomplete/TokenCompleteTextView.java +++ b/library/TokenAutoComplete/src/main/java/com/tokenautocomplete/TokenCompleteTextView.java @@ -145,7 +145,8 @@ public CharSequence filter(CharSequence source, int start, int end, } //Detect split characters, remove them and complete the current token instead - if (tokenizer.containsTokenTerminator(source)) { + // We only want to handle the case where the user inputs a single split character here + if (source.length() == 1 && tokenizer.containsTokenTerminator(source)) { performCompletion(); return ""; } @@ -392,16 +393,10 @@ private Range getCurrentCandidateTokenRange() { candidateStringEnd = spanStart; } } - - List tokenRanges = tokenizer.findTokenRanges(editable, candidateStringStart, candidateStringEnd); - - for (Range range: tokenRanges) { - if (range.start <= cursorEndPosition && cursorEndPosition <= range.end) { - return range; - } + if (candidateStringEnd < candidateStringStart) { + return new Range(cursorEndPosition, cursorEndPosition); } - - return new Range(cursorEndPosition, cursorEndPosition); + return new Range(candidateStringStart, candidateStringEnd); } /**