Mention by display name rather than hex encoded public key

This commit is contained in:
Niels Andriesse 2019-10-11 11:13:34 +11:00
parent 3d78dac65c
commit 7ea349ff00
3 changed files with 61 additions and 30 deletions

View File

@ -159,6 +159,7 @@ import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate;
import org.thoughtcrime.securesms.loki.LokiAPIUtilities; import org.thoughtcrime.securesms.loki.LokiAPIUtilities;
import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate; import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate;
import org.thoughtcrime.securesms.loki.LokiUserDatabase; import org.thoughtcrime.securesms.loki.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.Mention;
import org.thoughtcrime.securesms.loki.UserSelectionView; import org.thoughtcrime.securesms.loki.UserSelectionView;
import org.thoughtcrime.securesms.mediasend.Media; import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mediasend.MediaSendActivity; import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
@ -234,6 +235,7 @@ import org.whispersystems.signalservice.loki.utilities.Analytics;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
@ -345,8 +347,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private final DynamicNoActionBarTheme dynamicTheme = new DynamicNoActionBarTheme(); private final DynamicNoActionBarTheme dynamicTheme = new DynamicNoActionBarTheme();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage(); private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
// Mentions
private UserSelectionView userSelectionView; private UserSelectionView userSelectionView;
private int mentionStartIndex = -1; private int currentMentionStartIndex = -1;
private ArrayList<Mention> mentions = new ArrayList<>();
private String oldText = "";
@Override @Override
protected void onPreCreate() { protected void onPreCreate() {
@ -400,10 +406,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
composeText.setSelection(composeText.length(), composeText.length()); composeText.setSelection(composeText.length(), composeText.length());
composeText.addTextChangedListener(mentionTextWatcher); composeText.addTextChangedListener(mentionTextWatcher);
userSelectionView.setOnUserSelected(tuple -> { userSelectionView.setOnUserSelected(tuple -> {
Mention mention = new Mention(currentMentionStartIndex, tuple.getFirst(), tuple.getSecond());
mentions.add(mention);
String oldText = composeText.getText().toString(); String oldText = composeText.getText().toString();
String newText = oldText.substring(0, mentionStartIndex) + tuple.getFirst(); String newText = oldText.substring(0, currentMentionStartIndex) + "@" + tuple.getSecond();
composeText.setText(newText); composeText.setText(newText);
composeText.setSelection(newText.length()); composeText.setSelection(newText.length());
userSelectionView.hide();
return Unit.INSTANCE; return Unit.INSTANCE;
}); });
} }
@ -2081,12 +2090,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} }
private String getMessage() throws InvalidMessageException { private String getMessage() throws InvalidMessageException {
String rawText = composeText.getTextTrimmed(); String result = composeText.getTextTrimmed();
if (result.length() < 1 && !attachmentManager.isAttachmentPresent()) throw new InvalidMessageException();
if (rawText.length() < 1 && !attachmentManager.isAttachmentPresent()) int shift = 0;
throw new InvalidMessageException(getString(R.string.ConversationActivity_message_is_empty_exclamation)); for (Mention mention : mentions) {
int startIndex = mention.getLocationInString() + shift;
return rawText; int endIndex = startIndex + mention.getDisplayName().length() + 1; // + 1 to include the @
shift = shift + mention.getHexEncodedPublicKey().length() - mention.getDisplayName().length();
result = result.substring(0, startIndex) + "@" + mention.getHexEncodedPublicKey() + result.substring(endIndex);
}
return result;
} }
private Pair<String, Optional<Slide>> getSplitMessage(String rawText, int maxPrimaryMessageSize) { private Pair<String, Optional<Slide>> getSplitMessage(String rawText, int maxPrimaryMessageSize) {
@ -2612,9 +2625,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void silentlySetComposeText(String text) { private void silentlySetComposeText(String text) {
typingTextWatcher.setEnabled(false); typingTextWatcher.setEnabled(false);
mentionTextWatcher.setEnabled(false);
composeText.setText(text); composeText.setText(text);
mentionTextWatcher.setEnabled(true); clearMentions();
typingTextWatcher.setEnabled(true); typingTextWatcher.setEnabled(true);
} }
@ -2744,33 +2756,49 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} }
private class MentionTextWatcher extends SimpleTextWatcher { private class MentionTextWatcher extends SimpleTextWatcher {
private boolean enabled = true;
@Override @Override
public void onTextChanged(String text) { public void onTextChanged(String text) {
if (!enabled | text.length() == 0) { return; } boolean isBackspace = text.length() < oldText.length();
int currentEndIndex = text.length() - 1; if (isBackspace) {
char lastCharacter = text.charAt(currentEndIndex); currentMentionStartIndex = -1;
LokiUserDatabase userDatabase = DatabaseFactory.getLokiUserDatabase(ConversationActivity.this); for (Mention mention : mentions) {
if (lastCharacter == '@') { boolean isValid;
List<Tuple2<String, String>> users = LokiAPI.Companion.getUsers("", threadId, userDatabase); if (mention.getLocationInString() > (text.length() - 1)) {
mentionStartIndex = currentEndIndex + 1; isValid = false;
userSelectionView.show(users, threadId); } else {
} else if (Character.isWhitespace(lastCharacter)) { isValid = text.substring(mention.getLocationInString()).startsWith("@" + mention.getDisplayName());
mentionStartIndex = -1; }
userSelectionView.hide(); if (!isValid) {
} else { mentions.remove(mention);
if (mentionStartIndex != -1) { }
String query = text.substring(mentionStartIndex); }
List<Tuple2<String, String>> users = LokiAPI.Companion.getUsers(query, threadId, userDatabase); } else if (text.length() > 0) {
int currentEndIndex = text.length() - 1;
char lastCharacter = text.charAt(currentEndIndex);
LokiUserDatabase userDatabase = DatabaseFactory.getLokiUserDatabase(ConversationActivity.this);
if (lastCharacter == '@') {
List<Tuple2<String, String>> users = LokiAPI.Companion.getUsers("", threadId, userDatabase);
currentMentionStartIndex = currentEndIndex;
userSelectionView.show(users, threadId); userSelectionView.show(users, threadId);
} else if (Character.isWhitespace(lastCharacter)) {
currentMentionStartIndex = -1;
userSelectionView.hide();
} else {
if (currentMentionStartIndex != -1) {
String query = text.substring(currentMentionStartIndex + 1); // + 1 to get rid of the @
List<Tuple2<String, String>> users = LokiAPI.Companion.getUsers(query, threadId, userDatabase);
userSelectionView.show(users, threadId);
}
} }
} }
} }
}
public void setEnabled(boolean enabled) { private void clearMentions() {
this.enabled = enabled; oldText = "";
} currentMentionStartIndex = -1;
mentions.clear();
} }
@Override @Override

View File

@ -0,0 +1,3 @@
package org.thoughtcrime.securesms.loki
data class Mention(val locationInString: Int, val hexEncodedPublicKey: String, val displayName: String)

View File

@ -8,7 +8,7 @@ import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_new_conversation.* import kotlinx.android.synthetic.main.fragment_new_conversation.*
import network.loki.messenger.R import network.loki.messenger.R
class NewConversationFragment() : Fragment() { class NewConversationFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_new_conversation, container, false) return inflater.inflate(R.layout.fragment_new_conversation, container, false)