|  |  |  | @ -244,6 +244,7 @@ import java.util.concurrent.atomic.AtomicBoolean; | 
		
	
		
			
				|  |  |  |  | import java.util.concurrent.atomic.AtomicInteger; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import network.loki.messenger.R; | 
		
	
		
			
				|  |  |  |  | import nl.komponents.kovenant.combine.Tuple2; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import static org.thoughtcrime.securesms.TransportOption.Type; | 
		
	
		
			
				|  |  |  |  | import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; | 
		
	
	
		
			
				
					|  |  |  | @ -313,6 +314,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  |   private   Stub<UnverifiedBannerView>  unverifiedBannerView; | 
		
	
		
			
				|  |  |  |  |   private   Stub<GroupShareProfileView> groupShareProfileView; | 
		
	
		
			
				|  |  |  |  |   private   TypingStatusTextWatcher     typingTextWatcher; | 
		
	
		
			
				|  |  |  |  |   private   MentionTextWatcher          mentionTextWatcher; | 
		
	
		
			
				|  |  |  |  |   private   ConversationSearchBottomBar searchNav; | 
		
	
		
			
				|  |  |  |  |   private   MenuItem                    searchViewItem; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -342,6 +344,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  |   private final DynamicNoActionBarTheme dynamicTheme    = new DynamicNoActionBarTheme(); | 
		
	
		
			
				|  |  |  |  |   private final DynamicLanguage         dynamicLanguage = new DynamicLanguage(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private UserSelectionView userSelectionView; | 
		
	
		
			
				|  |  |  |  |   private int               mentionStartIndex = -1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   @Override | 
		
	
		
			
				|  |  |  |  |   protected void onPreCreate() { | 
		
	
	
		
			
				
					|  |  |  | @ -393,16 +397,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  |               composeText.addTextChangedListener(typingTextWatcher); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             composeText.setSelection(composeText.length(), composeText.length()); | 
		
	
		
			
				|  |  |  |  |             composeText.addTextChangedListener(mentionTextWatcher); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         }); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     }); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     LokiAPIUtilities.INSTANCE.populateUserIDCacheIfNeeded(threadId, this); | 
		
	
		
			
				|  |  |  |  |     UserSelectionView userSelectionView = findViewById(R.id.userSelectionView); | 
		
	
		
			
				|  |  |  |  |     LokiUserDatabase userDatabase = DatabaseFactory.getLokiUserDatabase(this); | 
		
	
		
			
				|  |  |  |  |     userSelectionView.setHasGroupContext(true); | 
		
	
		
			
				|  |  |  |  |     userSelectionView.setUsers(LokiAPI.Companion.getUserIDs("", threadId, userDatabase)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (this.recipient.isGroupRecipient()) { | 
		
	
		
			
				|  |  |  |  |       if (this.recipient.getName().equals("Loki Public Chat")) { | 
		
	
	
		
			
				
					|  |  |  | @ -1562,6 +1563,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  |     inlineAttachmentToggle = ViewUtil.findById(this, R.id.inline_attachment_container); | 
		
	
		
			
				|  |  |  |  |     inputPanel             = ViewUtil.findById(this, R.id.bottom_panel); | 
		
	
		
			
				|  |  |  |  |     searchNav              = ViewUtil.findById(this, R.id.conversation_search_nav); | 
		
	
		
			
				|  |  |  |  |     userSelectionView      = ViewUtil.findById(this, R.id.userSelectionView); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     ImageButton quickCameraToggle      = ViewUtil.findById(this, R.id.quick_camera_toggle); | 
		
	
		
			
				|  |  |  |  |     ImageButton inlineAttachmentButton = ViewUtil.findById(this, R.id.inline_attachment_button); | 
		
	
	
		
			
				
					|  |  |  | @ -1574,6 +1576,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  |     attachmentManager      = new AttachmentManager(this, this); | 
		
	
		
			
				|  |  |  |  |     audioRecorder          = new AudioRecorder(this); | 
		
	
		
			
				|  |  |  |  |     typingTextWatcher      = new TypingStatusTextWatcher(); | 
		
	
		
			
				|  |  |  |  |     mentionTextWatcher     = new MentionTextWatcher(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     SendButtonListener        sendButtonListener        = new SendButtonListener(); | 
		
	
		
			
				|  |  |  |  |     ComposeKeyPressedListener composeKeyPressedListener = new ComposeKeyPressedListener(); | 
		
	
	
		
			
				
					|  |  |  | @ -2601,7 +2604,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private void silentlySetComposeText(String text) { | 
		
	
		
			
				|  |  |  |  |     typingTextWatcher.setEnabled(false); | 
		
	
		
			
				|  |  |  |  |     mentionTextWatcher.setEnabled(false); | 
		
	
		
			
				|  |  |  |  |     composeText.setText(text); | 
		
	
		
			
				|  |  |  |  |     mentionTextWatcher.setEnabled(true); | 
		
	
		
			
				|  |  |  |  |     typingTextWatcher.setEnabled(true); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -2716,7 +2721,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private class TypingStatusTextWatcher extends SimpleTextWatcher { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     private boolean enabled = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     @Override | 
		
	
	
		
			
				
					|  |  |  | @ -2731,6 +2735,36 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private class MentionTextWatcher extends SimpleTextWatcher { | 
		
	
		
			
				|  |  |  |  |     private boolean enabled = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     @Override | 
		
	
		
			
				|  |  |  |  |     public void onTextChanged(String text) { | 
		
	
		
			
				|  |  |  |  |       if (!enabled) { return; } | 
		
	
		
			
				|  |  |  |  |       int currentEndIndex = (text.length() != 0) ? text.length() - 1 : 0; | 
		
	
		
			
				|  |  |  |  |       char lastCharacter = text.charAt(currentEndIndex); | 
		
	
		
			
				|  |  |  |  |       LokiUserDatabase userDatabase = DatabaseFactory.getLokiUserDatabase(ConversationActivity.this); | 
		
	
		
			
				|  |  |  |  |       if (lastCharacter == '@') { | 
		
	
		
			
				|  |  |  |  |         List<Tuple2<String, String>> users = LokiAPI.Companion.getUsers("", threadId, userDatabase); | 
		
	
		
			
				|  |  |  |  |         mentionStartIndex = currentEndIndex + 1; | 
		
	
		
			
				|  |  |  |  |         userSelectionView.show(users, threadId); | 
		
	
		
			
				|  |  |  |  |       } else if (!Character.isAlphabetic(lastCharacter) || !Character.isUpperCase(lastCharacter) || !Character.isLowerCase(lastCharacter)) { | 
		
	
		
			
				|  |  |  |  |         mentionStartIndex = -1; | 
		
	
		
			
				|  |  |  |  |         userSelectionView.hide(); | 
		
	
		
			
				|  |  |  |  |       } else { | 
		
	
		
			
				|  |  |  |  |         if (mentionStartIndex != -1) { | 
		
	
		
			
				|  |  |  |  |           String query = text.substring(mentionStartIndex); | 
		
	
		
			
				|  |  |  |  |           List<Tuple2<String, String>> users = LokiAPI.Companion.getUsers(query, threadId, userDatabase); | 
		
	
		
			
				|  |  |  |  |           userSelectionView.show(users, threadId); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     public void setEnabled(boolean enabled) { | 
		
	
		
			
				|  |  |  |  |       this.enabled = enabled; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   @Override | 
		
	
		
			
				|  |  |  |  |   public void setThreadId(long threadId) { | 
		
	
		
			
				|  |  |  |  |     this.threadId = threadId; | 
		
	
	
		
			
				
					|  |  |  | 
 |