mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 05:22:23 +00:00
Merge branch 'dev' into session-restore
This commit is contained in:
@@ -31,19 +31,20 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.hardware.Camera;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Browser;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.Telephony;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.content.pm.ShortcutInfoCompat;
|
||||
import android.support.v4.content.pm.ShortcutManagerCompat;
|
||||
import android.support.v4.graphics.drawable.IconCompat;
|
||||
@@ -56,6 +57,7 @@ import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Pair;
|
||||
import android.util.TypedValue;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@@ -69,6 +71,8 @@ import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -80,8 +84,6 @@ import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.ConversationListActivity;
|
||||
import org.thoughtcrime.securesms.ConversationListArchiveActivity;
|
||||
import org.thoughtcrime.securesms.ExpirationDialog;
|
||||
import org.thoughtcrime.securesms.GroupCreateActivity;
|
||||
import org.thoughtcrime.securesms.GroupMembersDialog;
|
||||
@@ -155,15 +157,16 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.loki.LokiAPIUtilities;
|
||||
import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
|
||||
import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.LokiThreadDatabaseDelegate;
|
||||
import org.thoughtcrime.securesms.loki.LokiUserDatabase;
|
||||
import org.thoughtcrime.securesms.loki.MentionCandidateSelectionView;
|
||||
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
|
||||
import org.thoughtcrime.securesms.loki.SessionRestoreBannerView;
|
||||
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.MentionCandidateSelectionView;
|
||||
import org.thoughtcrime.securesms.mediasend.Media;
|
||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||
@@ -209,6 +212,7 @@ import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent;
|
||||
import org.thoughtcrime.securesms.stickers.StickerSearchRepository;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.Dialogs;
|
||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
@@ -229,17 +233,20 @@ import org.thoughtcrime.securesms.util.views.Stub;
|
||||
import org.whispersystems.libsignal.InvalidMessageException;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.loki.api.LokiAPI;
|
||||
import org.whispersystems.signalservice.loki.api.LokiPublicChat;
|
||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
||||
import org.whispersystems.signalservice.loki.api.PairingAuthorisation;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
||||
import org.whispersystems.signalservice.loki.messaging.Mention;
|
||||
import org.whispersystems.signalservice.loki.utilities.Analytics;
|
||||
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -307,7 +314,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private AnimatingToggle buttonToggle;
|
||||
private SendButton sendButton;
|
||||
private ImageButton attachButton;
|
||||
protected ConversationTitleView titleView;
|
||||
private TextView titleTextView;
|
||||
private TextView charactersLeft;
|
||||
private ConversationFragment fragment;
|
||||
private Button unblockButton;
|
||||
@@ -322,6 +329,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private MentionTextWatcher mentionTextWatcher;
|
||||
private ConversationSearchBottomBar searchNav;
|
||||
private MenuItem searchViewItem;
|
||||
private ProgressBar messageStatusProgressBar;
|
||||
private ImageView muteIndicatorImageView;
|
||||
private TextView actionBarSubtitleTextView;
|
||||
|
||||
private AttachmentTypeSelector attachmentTypeSelector;
|
||||
private AttachmentManager attachmentManager;
|
||||
@@ -341,15 +351,22 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private int distributionType;
|
||||
private boolean archived;
|
||||
private boolean isSecureText;
|
||||
private boolean isDefaultSms = true;
|
||||
private boolean isMmsEnabled = true;
|
||||
private boolean isSecurityInitialized = false;
|
||||
private boolean isDefaultSms = true;
|
||||
private boolean isMmsEnabled = true;
|
||||
private boolean isSecurityInitialized = false;
|
||||
private int expandedKeyboardHeight = 0;
|
||||
private int collapsedKeyboardHeight = Integer.MAX_VALUE;
|
||||
private int keyboardHeight = 0;
|
||||
|
||||
private final IdentityRecordList identityRecords = new IdentityRecordList();
|
||||
private final DynamicNoActionBarTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
private ArrayList<BroadcastReceiver> broadcastReceivers = new ArrayList<>();
|
||||
private String messageStatus = null;
|
||||
|
||||
// Mentions
|
||||
private View mentionCandidateSelectionViewContainer;
|
||||
private MentionCandidateSelectionView mentionCandidateSelectionView;
|
||||
private int currentMentionStartIndex = -1;
|
||||
private ArrayList<Mention> mentions = new ArrayList<>();
|
||||
@@ -382,6 +399,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
fragment = initFragment(R.id.fragment_content, new ConversationFragment(), dynamicLanguage.getCurrentLocale());
|
||||
fragment.friendRequestViewDelegate = this;
|
||||
|
||||
registerMessageStatusObserver("calculatingPoW");
|
||||
registerMessageStatusObserver("contactingNetwork");
|
||||
registerMessageStatusObserver("sendingMessage");
|
||||
registerMessageStatusObserver("messageSent");
|
||||
registerMessageStatusObserver("messageFailed");
|
||||
|
||||
initializeReceivers();
|
||||
initializeActionBar();
|
||||
initializeViews();
|
||||
@@ -412,6 +435,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
composeText.setSelection(composeText.length(), composeText.length());
|
||||
composeText.addTextChangedListener(mentionTextWatcher);
|
||||
mentionCandidateSelectionView.setGlide(glideRequests);
|
||||
mentionCandidateSelectionView.setOnMentionCandidateSelected( mentionCandidate -> {
|
||||
mentions.add(mentionCandidate);
|
||||
String oldText = composeText.getText().toString();
|
||||
@@ -441,15 +465,39 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
LokiAPIUtilities.INSTANCE.populateUserHexEncodedPublicKeyCacheIfNeeded(threadId, this);
|
||||
|
||||
if (this.recipient.isGroupRecipient()) {
|
||||
if (this.recipient.getName().equals("Loki Public Chat")) {
|
||||
Analytics.Companion.getShared().track("Loki Public Chat Opened");
|
||||
} else {
|
||||
Analytics.Companion.getShared().track("RSS Feed Opened");
|
||||
}
|
||||
} else {
|
||||
Analytics.Companion.getShared().track("Conversation Opened");
|
||||
LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId);
|
||||
if (publicChat != null) {
|
||||
ApplicationContext.getInstance(this).getLokiPublicChatAPI().getUserCount(publicChat.getChannel(), publicChat.getServer()).success(integer -> {
|
||||
updateSubtitleTextView();
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
View rootView = findViewById(R.id.rootView);
|
||||
rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
|
||||
int height = rootView.getRootView().getHeight() - rootView.getHeight();
|
||||
int thresholdInDP = 120;
|
||||
float scale = getResources().getDisplayMetrics().density;
|
||||
int thresholdInPX = (int)(thresholdInDP * scale);
|
||||
if (expandedKeyboardHeight == 0 || height > thresholdInPX) {
|
||||
expandedKeyboardHeight = height;
|
||||
}
|
||||
collapsedKeyboardHeight = Math.min(collapsedKeyboardHeight, height);
|
||||
keyboardHeight = expandedKeyboardHeight - collapsedKeyboardHeight;
|
||||
});
|
||||
}
|
||||
|
||||
private void registerMessageStatusObserver(String status) {
|
||||
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
long timestamp = intent.getLongExtra("long", 0);
|
||||
handleMessageStatusChanged(status, timestamp);
|
||||
}
|
||||
};
|
||||
broadcastReceivers.add(broadcastReceiver);
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter(status));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -495,7 +543,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
initializeIdentityRecords();
|
||||
composeText.setTransport(sendButton.getSelectedTransport());
|
||||
|
||||
titleView.setTitle(glideRequests, recipient);
|
||||
updateTitleTextView(glideRequests, recipient);
|
||||
updateSubtitleTextView();
|
||||
setActionBarColor(recipient.getColor());
|
||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||
setGroupShareProfileReminder(recipient);
|
||||
@@ -549,6 +598,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
saveDraft();
|
||||
if (recipient != null) recipient.removeListener(this);
|
||||
if (securityUpdateReceiver != null) unregisterReceiver(securityUpdateReceiver);
|
||||
for (BroadcastReceiver broadcastReceiver : broadcastReceivers) {
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@@ -584,7 +636,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
case GROUP_EDIT:
|
||||
recipient = Recipient.from(this, data.getParcelableExtra(GroupCreateActivity.GROUP_ADDRESS_EXTRA), true);
|
||||
recipient.addListener(this);
|
||||
titleView.setTitle(glideRequests, recipient);
|
||||
updateTitleTextView(glideRequests, recipient);
|
||||
updateSubtitleTextView();
|
||||
NotificationChannels.updateContactChannelName(this, recipient);
|
||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||
supportInvalidateOptionsMenu();
|
||||
@@ -755,7 +808,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
searchViewItem = menu.findItem(R.id.menu_search);
|
||||
|
||||
SearchView searchView = (SearchView) searchViewItem.getActionView();
|
||||
SearchView searchView = (SearchView)searchViewItem.getActionView();
|
||||
SearchView.OnQueryTextListener queryListener = new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
@@ -860,7 +913,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
//////// Event Handlers
|
||||
|
||||
private void handleReturnToConversationList() {
|
||||
Intent intent = new Intent(this, (archived ? ConversationListArchiveActivity.class : ConversationListActivity.class));
|
||||
Intent intent = new Intent(this, HomeActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
@@ -1188,11 +1241,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private boolean handleDisplayQuickContact() {
|
||||
if (recipient.getAddress().isGroup()) return false;
|
||||
|
||||
if (recipient.getContactUri() != null) {
|
||||
ContactsContract.QuickContact.showQuickContact(ConversationActivity.this, titleView, recipient.getContactUri(), ContactsContract.QuickContact.MODE_LARGE, null);
|
||||
} else {
|
||||
handleAddToContacts();
|
||||
}
|
||||
// if (recipient.getContactUri() != null) {
|
||||
// ContactsContract.QuickContact.showQuickContact(ConversationActivity.this, titleView, recipient.getContactUri(), ContactsContract.QuickContact.MODE_LARGE, null);
|
||||
// } else {
|
||||
// handleAddToContacts();
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1200,8 +1253,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private void handleAddAttachment() {
|
||||
if (this.isMmsEnabled || isSecureText) {
|
||||
if (attachmentTypeSelector == null) {
|
||||
attachmentTypeSelector = new AttachmentTypeSelector(this, getSupportLoaderManager(), new AttachmentTypeListener());
|
||||
attachmentTypeSelector = new AttachmentTypeSelector(this, getSupportLoaderManager(), new AttachmentTypeListener(), keyboardHeight);
|
||||
}
|
||||
attachmentTypeSelector.keyboardHeight = keyboardHeight;
|
||||
attachmentTypeSelector.show(this, attachButton);
|
||||
} else {
|
||||
handleManualMmsRequired();
|
||||
@@ -1582,7 +1636,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
unverifiedBannerView.get().hide();
|
||||
}
|
||||
|
||||
titleView.setVerified(isSecureText && identityRecords.isVerified());
|
||||
// titleView.setVerified(isSecureText && identityRecords.isVerified());
|
||||
|
||||
future.set(true);
|
||||
}
|
||||
@@ -1593,7 +1647,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
titleView = findViewById(R.id.conversation_title_view);
|
||||
titleTextView = findViewById(R.id.titleTextView);
|
||||
buttonToggle = ViewUtil.findById(this, R.id.button_toggle);
|
||||
sendButton = ViewUtil.findById(this, R.id.send_button);
|
||||
attachButton = ViewUtil.findById(this, R.id.attach_button);
|
||||
@@ -1612,8 +1666,12 @@ 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);
|
||||
mentionCandidateSelectionViewContainer = ViewUtil.findById(this, R.id.mentionCandidateSelectionViewContainer);
|
||||
mentionCandidateSelectionView = ViewUtil.findById(this, R.id.userSelectionView);
|
||||
sessionRestoreBannerView = ViewUtil.findById(this, R.id.sessionRestoreBannerView);
|
||||
messageStatusProgressBar = ViewUtil.findById(this, R.id.messageStatusProgressBar);
|
||||
muteIndicatorImageView = ViewUtil.findById(this, R.id.muteIndicatorImageView);
|
||||
actionBarSubtitleTextView = ViewUtil.findById(this, R.id.subtitleTextView);
|
||||
|
||||
ImageButton quickCameraToggle = ViewUtil.findById(this, R.id.quick_camera_toggle);
|
||||
ImageButton inlineAttachmentButton = ViewUtil.findById(this, R.id.inline_attachment_button);
|
||||
@@ -1641,8 +1699,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
calculateCharactersRemaining();
|
||||
updateLinkPreviewState();
|
||||
composeText.setTransport(newTransport);
|
||||
buttonToggle.getBackground().setColorFilter(newTransport.getBackgroundColor(), Mode.MULTIPLY);
|
||||
buttonToggle.getBackground().invalidateSelf();
|
||||
if (manuallySelected) recordTransportPreference(newTransport);
|
||||
});
|
||||
|
||||
@@ -1674,12 +1730,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
protected void initializeActionBar() {
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.getOverflowIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar supportActionBar = getSupportActionBar();
|
||||
if (supportActionBar == null) throw new AssertionError();
|
||||
|
||||
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
// supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
supportActionBar.setDisplayShowTitleEnabled(false);
|
||||
}
|
||||
|
||||
@@ -1805,8 +1862,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
Log.i(TAG, "onModified(" + recipient.getAddress().serialize() + ")");
|
||||
Util.runOnMain(() -> {
|
||||
Log.i(TAG, "onModifiedRun(): " + recipient.getRegistered());
|
||||
titleView.setTitle(glideRequests, recipient);
|
||||
titleView.setVerified(identityRecords.isVerified());
|
||||
updateTitleTextView(glideRequests, recipient);
|
||||
updateSubtitleTextView();
|
||||
// titleView.setVerified(identityRecords.isVerified());
|
||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||
setActionBarColor(recipient.getColor());
|
||||
setGroupShareProfileReminder(recipient);
|
||||
@@ -2002,8 +2060,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private void setActionBarColor(MaterialColor color) {
|
||||
ActionBar supportActionBar = getSupportActionBar();
|
||||
if (supportActionBar == null) throw new AssertionError();
|
||||
supportActionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.core_grey_90)));
|
||||
setStatusBarColor(getResources().getColor(R.color.black));
|
||||
supportActionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.action_bar_background)));
|
||||
setStatusBarColor(getResources().getColor(R.color.action_bar_background));
|
||||
}
|
||||
|
||||
private void setBlockedUserState(Recipient recipient, boolean isSecureText, boolean isDefaultSms) {
|
||||
@@ -2172,9 +2230,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
Context context = ConversationActivity.this;
|
||||
List<MarkedMessageInfo> messageIds = DatabaseFactory.getThreadDatabase(context).setRead(params[0], false);
|
||||
|
||||
// Only send notifications for private chats
|
||||
if (!getRecipient().isGroupRecipient()) { MessageNotifier.updateNotification(context); }
|
||||
|
||||
MarkReadReceiver.process(context, messageIds);
|
||||
|
||||
return null;
|
||||
@@ -2281,8 +2336,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private void setInputPanelEnabled(boolean enabled) {
|
||||
Util.runOnMain(() -> {
|
||||
updateToggleButtonState();
|
||||
int hintID = enabled ? R.string.activity_conversation_default_hint : R.string.activity_conversation_pending_friend_request_hint;
|
||||
inputPanel.setHint(getResources().getString(hintID));
|
||||
String hint = enabled ? "Message" : "Pending message request";
|
||||
inputPanel.setHint(hint);
|
||||
inputPanel.setEnabled(enabled);
|
||||
if (enabled) {
|
||||
inputPanel.composeText.requestFocus();
|
||||
@@ -2867,6 +2922,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
if (isBackspace) {
|
||||
currentMentionStartIndex = -1;
|
||||
mentionCandidateSelectionView.hide();
|
||||
mentionCandidateSelectionViewContainer.setVisibility(View.GONE);
|
||||
ArrayList<Mention> mentionsToRemove = new ArrayList<>();
|
||||
for (Mention mention : mentions) {
|
||||
if (!text.contains(mention.getDisplayName())) {
|
||||
@@ -2891,14 +2947,17 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
if (lastCharacter == '@' && Character.isWhitespace(secondToLastCharacter)) {
|
||||
List<Mention> mentionCandidates = LokiAPI.Companion.getMentionCandidates("", threadId, userHexEncodedPublicKey, threadDatabase, userDatabase);
|
||||
currentMentionStartIndex = lastCharacterIndex;
|
||||
mentionCandidateSelectionViewContainer.setVisibility(View.VISIBLE);
|
||||
mentionCandidateSelectionView.show(mentionCandidates, threadId);
|
||||
} else if (Character.isWhitespace(lastCharacter)) {
|
||||
currentMentionStartIndex = -1;
|
||||
mentionCandidateSelectionView.hide();
|
||||
mentionCandidateSelectionViewContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (currentMentionStartIndex != -1) {
|
||||
String query = text.substring(currentMentionStartIndex + 1); // + 1 to get rid of the @
|
||||
List<Mention> mentionCandidates = LokiAPI.Companion.getMentionCandidates(query, threadId, userHexEncodedPublicKey, threadDatabase, userDatabase);
|
||||
mentionCandidateSelectionViewContainer.setVisibility(View.VISIBLE);
|
||||
mentionCandidateSelectionView.show(mentionCandidates, threadId);
|
||||
}
|
||||
}
|
||||
@@ -2943,7 +3002,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
author,
|
||||
body,
|
||||
slideDeck,
|
||||
recipient);
|
||||
recipient,
|
||||
threadId);
|
||||
|
||||
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
|
||||
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
|
||||
@@ -2958,20 +3018,22 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
author,
|
||||
messageRecord.getBody(),
|
||||
slideDeck,
|
||||
recipient);
|
||||
recipient,
|
||||
threadId);
|
||||
} else {
|
||||
inputPanel.setQuote(GlideApp.with(this),
|
||||
messageRecord.getDateSent(),
|
||||
author,
|
||||
messageRecord.getBody(),
|
||||
messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck(),
|
||||
recipient);
|
||||
recipient,
|
||||
threadId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageActionToolbarOpened() {
|
||||
searchViewItem.collapseActionView();
|
||||
searchViewItem.collapseActionView();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3081,6 +3143,128 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
// region Loki
|
||||
private void updateTitleTextView(GlideRequests glide, Recipient recipient) {
|
||||
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this);
|
||||
List<PairingAuthorisation> deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getPairingAuthorisations(userHexEncodedPublicKey);
|
||||
HashSet<String> userLinkedDeviceHexEncodedPublicKeys = new HashSet<>();
|
||||
for (PairingAuthorisation deviceLink : deviceLinks) {
|
||||
userLinkedDeviceHexEncodedPublicKeys.add(deviceLink.getPrimaryDevicePublicKey().toLowerCase());
|
||||
userLinkedDeviceHexEncodedPublicKeys.add(deviceLink.getSecondaryDevicePublicKey().toLowerCase());
|
||||
}
|
||||
userLinkedDeviceHexEncodedPublicKeys.add(userHexEncodedPublicKey.toLowerCase());
|
||||
if (recipient == null) {
|
||||
titleTextView.setText("Compose");
|
||||
} else if (userLinkedDeviceHexEncodedPublicKeys.contains(recipient.getAddress().toString().toLowerCase())) {
|
||||
titleTextView.setText("Note to Self");
|
||||
} else {
|
||||
titleTextView.setText((recipient.getName() == null || recipient.getName().isEmpty()) ? recipient.getAddress().toString() : recipient.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSubtitleTextView() {
|
||||
muteIndicatorImageView.setVisibility(View.GONE);
|
||||
actionBarSubtitleTextView.setVisibility(View.VISIBLE);
|
||||
if (messageStatus != null) {
|
||||
switch (messageStatus) {
|
||||
case "calculatingPoW": actionBarSubtitleTextView.setText("Encrypting message"); break;
|
||||
case "contactingNetwork": actionBarSubtitleTextView.setText("Tracing a path"); break;
|
||||
case "sendingMessage": actionBarSubtitleTextView.setText("Sending message"); break;
|
||||
case "messageSent": actionBarSubtitleTextView.setText("Message sent securely"); break;
|
||||
case "messageFailed": actionBarSubtitleTextView.setText("Message failed to send"); break;
|
||||
}
|
||||
} else if (recipient.isMuted()) {
|
||||
muteIndicatorImageView.setVisibility(View.VISIBLE);
|
||||
actionBarSubtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()));
|
||||
} else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Loki Messenger Updates") && !recipient.getName().equals("Loki News")) {
|
||||
LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId);
|
||||
if (publicChat != null) {
|
||||
Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(publicChat.getChannel(), publicChat.getServer());
|
||||
if (userCount == null) { userCount = 0; }
|
||||
if (userCount >= 200) {
|
||||
actionBarSubtitleTextView.setText("200+ members");
|
||||
} else {
|
||||
actionBarSubtitleTextView.setText(userCount + " members");
|
||||
}
|
||||
} else if (PublicKeyValidation.isValid(recipient.getAddress().toString())) {
|
||||
actionBarSubtitleTextView.setText(recipient.getAddress().toString());
|
||||
} else {
|
||||
actionBarSubtitleTextView.setVisibility(View.GONE);
|
||||
}
|
||||
} else if (PublicKeyValidation.isValid(recipient.getAddress().toString())) {
|
||||
actionBarSubtitleTextView.setText(recipient.getAddress().toString());
|
||||
} else {
|
||||
actionBarSubtitleTextView.setVisibility(View.GONE);
|
||||
}
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension((actionBarSubtitleTextView.getVisibility() == View.GONE) ? R.dimen.very_large_font_size : R.dimen.large_font_size));
|
||||
}
|
||||
|
||||
private void setMessageStatusProgressAnimatedIfPossible(int progress) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
messageStatusProgressBar.setProgress(progress, true);
|
||||
} else {
|
||||
messageStatusProgressBar.setProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMessageStatusProgressBar() {
|
||||
if (messageStatus != null) {
|
||||
messageStatusProgressBar.setAlpha(1.0f);
|
||||
switch (messageStatus) {
|
||||
case "calculatingPoW": setMessageStatusProgressAnimatedIfPossible(25); break;
|
||||
case "contactingNetwork": setMessageStatusProgressAnimatedIfPossible(50); break;
|
||||
case "sendingMessage": setMessageStatusProgressAnimatedIfPossible(75); break;
|
||||
case "messageSent":
|
||||
setMessageStatusProgressAnimatedIfPossible(100);
|
||||
new Handler().postDelayed(() -> messageStatusProgressBar.animate().alpha(0).setDuration(250).start(), 250);
|
||||
new Handler().postDelayed(() -> messageStatusProgressBar.setProgress(0), 500);
|
||||
break;
|
||||
case "messageFailed":
|
||||
messageStatusProgressBar.animate().alpha(0).setDuration(250).start();
|
||||
new Handler().postDelayed(() -> messageStatusProgressBar.setProgress(0), 250);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMessageStatusChanged(String newMessageStatus, long timestamp) {
|
||||
if (timestamp == 0) { return; }
|
||||
updateForNewMessageStatusIfNeeded(newMessageStatus, timestamp);
|
||||
if (newMessageStatus.equals("messageFailed") || newMessageStatus.equals("messageSent")) {
|
||||
new Handler().postDelayed(() -> clearMessageStatusIfNeeded(timestamp), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private int precedence(String messageStatus) {
|
||||
if (messageStatus != null) {
|
||||
switch (messageStatus) {
|
||||
case "calculatingPoW": return 0;
|
||||
case "contactingNetwork": return 1;
|
||||
case "sendingMessage": return 2;
|
||||
case "messageSent": return 3;
|
||||
case "messageFailed": return 4;
|
||||
default: return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateForNewMessageStatusIfNeeded(String newMessageStatus, long timestamp) {
|
||||
if (!DatabaseFactory.getSmsDatabase(this).isOutgoingMessage(timestamp) && !DatabaseFactory.getMmsDatabase(this).isOutgoingMessage(timestamp)) { return; }
|
||||
if (precedence(newMessageStatus) > precedence(messageStatus)) {
|
||||
messageStatus = newMessageStatus;
|
||||
updateSubtitleTextView();
|
||||
updateMessageStatusProgressBar();
|
||||
}
|
||||
}
|
||||
|
||||
private void clearMessageStatusIfNeeded(long timestamp) {
|
||||
if (!DatabaseFactory.getSmsDatabase(this).isOutgoingMessage(timestamp) && !DatabaseFactory.getMmsDatabase(this).isOutgoingMessage(timestamp)) { return; }
|
||||
messageStatus = null;
|
||||
updateSubtitleTextView();
|
||||
updateMessageStatusProgressBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptFriendRequest(@NotNull MessageRecord friendRequest) {
|
||||
// Send the accept to the original friend request thread id
|
||||
|
||||
@@ -31,7 +31,6 @@ import android.widget.TextView;
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.BindableConversationItem;
|
||||
import network.loki.messenger.R;
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.conversation.ConversationAdapter.HeaderViewHolder;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
@@ -41,7 +40,7 @@ import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
@@ -65,6 +64,8 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
/**
|
||||
* A cursor adapter for a conversation thread. Ultimately
|
||||
* used by ComposeMessageActivity to display a conversation
|
||||
|
||||
@@ -47,6 +47,7 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.Window;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
@@ -79,7 +80,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.longmessage.LongMessageActivity;
|
||||
import org.thoughtcrime.securesms.mediasend.Media;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
@@ -509,7 +510,6 @@ public class ConversationFragment extends Fragment
|
||||
builder.setMessage(getActivity().getResources().getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messagesCount, messagesCount));
|
||||
builder.setCancelable(true);
|
||||
|
||||
// Loki - The delete option is only visible to the user in a public chat
|
||||
LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId);
|
||||
|
||||
builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
|
||||
@@ -521,42 +521,52 @@ public class ConversationFragment extends Fragment
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(MessageRecord... messageRecords) {
|
||||
ArrayList<Long> serverIDs = new ArrayList<>();
|
||||
ArrayList<Long> ignoredMessages = new ArrayList<>();
|
||||
ArrayList<Long> failedMessages = new ArrayList<>();
|
||||
boolean isSentByUser = true;
|
||||
LokiPublicChatAPI publicChatAPI = ApplicationContext.getInstance(getContext()).getLokiPublicChatAPI();
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
isSentByUser = isSentByUser && messageRecord.isOutgoing();
|
||||
Long serverID = DatabaseFactory.getLokiMessageDatabase(getContext()).getServerID(messageRecord.id);
|
||||
if (serverID != null) {
|
||||
serverIDs.add(serverID);
|
||||
} else {
|
||||
ignoredMessages.add(messageRecord.getId());
|
||||
}
|
||||
}
|
||||
if (publicChat != null && publicChatAPI != null) {
|
||||
publicChatAPI
|
||||
.deleteMessages(serverIDs, publicChat.getChannel(), publicChat.getServer(), isSentByUser)
|
||||
.success(l -> {
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
Long serverID = DatabaseFactory.getLokiMessageDatabase(getContext()).getServerID(messageRecord.id);
|
||||
if (l.contains(serverID)) {
|
||||
if (messageRecord.isMms()) {
|
||||
DatabaseFactory.getMmsDatabase(getActivity()).delete(messageRecord.getId());
|
||||
} else {
|
||||
DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageRecord.getId());
|
||||
}
|
||||
} else if (!ignoredMessages.contains(serverID)) {
|
||||
failedMessages.add(messageRecord.getId());
|
||||
Log.d("Loki", "Failed to delete message: " + messageRecord.getId() + ".");
|
||||
}
|
||||
if (publicChat != null) {
|
||||
ArrayList<Long> serverIDs = new ArrayList<>();
|
||||
ArrayList<Long> ignoredMessages = new ArrayList<>();
|
||||
ArrayList<Long> failedMessages = new ArrayList<>();
|
||||
boolean isSentByUser = true;
|
||||
LokiPublicChatAPI publicChatAPI = ApplicationContext.getInstance(getContext()).getLokiPublicChatAPI();
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
isSentByUser = isSentByUser && messageRecord.isOutgoing();
|
||||
Long serverID = DatabaseFactory.getLokiMessageDatabase(getContext()).getServerID(messageRecord.id);
|
||||
if (serverID != null) {
|
||||
serverIDs.add(serverID);
|
||||
} else {
|
||||
ignoredMessages.add(messageRecord.getId());
|
||||
}
|
||||
return null;
|
||||
}). fail(e -> {
|
||||
Log.d("Loki", "Couldn't delete message due to error: " + e.toString() + ".");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if (publicChat != null && publicChatAPI != null) {
|
||||
publicChatAPI
|
||||
.deleteMessages(serverIDs, publicChat.getChannel(), publicChat.getServer(), isSentByUser)
|
||||
.success(l -> {
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
Long serverID = DatabaseFactory.getLokiMessageDatabase(getContext()).getServerID(messageRecord.id);
|
||||
if (l.contains(serverID)) {
|
||||
if (messageRecord.isMms()) {
|
||||
DatabaseFactory.getMmsDatabase(getActivity()).delete(messageRecord.getId());
|
||||
} else {
|
||||
DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageRecord.getId());
|
||||
}
|
||||
} else if (!ignoredMessages.contains(serverID)) {
|
||||
failedMessages.add(messageRecord.getId());
|
||||
Log.d("Loki", "Failed to delete message: " + messageRecord.getId() + ".");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}). fail(e -> {
|
||||
Log.d("Loki", "Couldn't delete message due to error: " + e.toString() + ".");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
if (messageRecord.isMms()) {
|
||||
DatabaseFactory.getMmsDatabase(getActivity()).delete(messageRecord.getId());
|
||||
} else {
|
||||
DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageRecord.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -966,6 +976,15 @@ public class ConversationFragment extends Fragment
|
||||
list.getAdapter().notifyDataSetChanged();
|
||||
|
||||
actionMode = ((AppCompatActivity)getActivity()).startSupportActionMode(actionModeCallback);
|
||||
|
||||
View titleTextView = (getActivity().findViewById(R.id.action_bar_title));
|
||||
if (titleTextView != null) {
|
||||
titleTextView.setBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
ViewParent titleTextViewContainerView = titleTextView.getParent();
|
||||
if (titleTextViewContainerView != null) {
|
||||
((View)titleTextViewContainerView).setBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1082,7 +1101,6 @@ public class ConversationFragment extends Fragment
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = getActivity().getWindow();
|
||||
statusBarColor = window.getStatusBarColor();
|
||||
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
|
||||
}
|
||||
|
||||
setCorrectMenuVisibility(menu);
|
||||
|
||||
@@ -60,7 +60,6 @@ import org.thoughtcrime.securesms.MessageDetailsActivity;
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.components.AlertView;
|
||||
import org.thoughtcrime.securesms.components.AudioView;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.ConversationItemFooter;
|
||||
import org.thoughtcrime.securesms.components.ConversationItemThumbnail;
|
||||
import org.thoughtcrime.securesms.components.DocumentView;
|
||||
@@ -87,10 +86,11 @@ import org.thoughtcrime.securesms.jobs.SmsSendJob;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.FriendRequestView;
|
||||
import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
|
||||
import org.thoughtcrime.securesms.loki.MentionUtilities;
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.MentionUtilities;
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestView;
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.FriendRequestViewDelegate;
|
||||
import org.thoughtcrime.securesms.loki.redesign.views.ProfilePictureView;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.ImageSlide;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
@@ -102,7 +102,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.stickers.StickerUrl;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.LongClickCopySpan;
|
||||
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
|
||||
@@ -154,7 +153,7 @@ public class ConversationItem extends LinearLayout
|
||||
private TextView groupSender;
|
||||
private TextView groupSenderProfileName;
|
||||
private View groupSenderHolder;
|
||||
private AvatarImageView contactPhoto;
|
||||
private ProfilePictureView profilePictureView;
|
||||
private ImageView moderatorIconImageView;
|
||||
private ViewGroup contactPhotoHolder;
|
||||
private AlertView alertView;
|
||||
@@ -211,7 +210,7 @@ public class ConversationItem extends LinearLayout
|
||||
this.groupSender = findViewById(R.id.group_message_sender);
|
||||
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
|
||||
this.alertView = findViewById(R.id.indicators_parent);
|
||||
this.contactPhoto = findViewById(R.id.contact_photo);
|
||||
this.profilePictureView = findViewById(R.id.profilePictureView);
|
||||
this.moderatorIconImageView = findViewById(R.id.moderator_icon_image_view);
|
||||
this.contactPhotoHolder = findViewById(R.id.contact_photo_container);
|
||||
this.bodyBubble = findViewById(R.id.body_bubble);
|
||||
@@ -271,6 +270,7 @@ public class ConversationItem extends LinearLayout
|
||||
setMessageSpacing(context, messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
|
||||
setFooter(messageRecord, nextMessageRecord, locale, groupThread);
|
||||
setFriendRequestView(messageRecord);
|
||||
adjustMarginsIfNeeded(messageRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -356,9 +356,9 @@ public class ConversationItem extends LinearLayout
|
||||
|
||||
private void setBubbleState(MessageRecord messageRecord) {
|
||||
if (messageRecord.isOutgoing()) {
|
||||
bodyBubble.getBackground().setColorFilter(defaultBubbleColor, PorterDuff.Mode.MULTIPLY);
|
||||
bodyBubble.getBackground().setColorFilter(getResources().getColor(R.color.sent_message_background), PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
bodyBubble.getBackground().setColorFilter(messageRecord.getRecipient().getColor().toConversationColor(context), PorterDuff.Mode.MULTIPLY);
|
||||
bodyBubble.getBackground().setColorFilter(getResources().getColor(R.color.received_message_background), PorterDuff.Mode.MULTIPLY);
|
||||
}
|
||||
|
||||
if (audioViewStub.resolved()) {
|
||||
@@ -367,15 +367,7 @@ public class ConversationItem extends LinearLayout
|
||||
}
|
||||
|
||||
private void setAudioViewTint(MessageRecord messageRecord, Recipient recipient) {
|
||||
if (messageRecord.isOutgoing()) {
|
||||
if (DynamicTheme.LIGHT.equals(TextSecurePreferences.getTheme(context))) {
|
||||
audioViewStub.get().setTint(getContext().getResources().getColor(R.color.core_grey_60), defaultBubbleColor);
|
||||
} else {
|
||||
audioViewStub.get().setTint(Color.WHITE, defaultBubbleColor);
|
||||
}
|
||||
} else {
|
||||
audioViewStub.get().setTint(Color.WHITE, recipient.getColor().toConversationColor(context));
|
||||
}
|
||||
audioViewStub.get().setTint(Color.WHITE, getResources().getColor(R.color.action_bar_background));
|
||||
}
|
||||
|
||||
private void setInteractionState(MessageRecord messageRecord, boolean pulseHighlight) {
|
||||
@@ -432,6 +424,26 @@ public class ConversationItem extends LinearLayout
|
||||
!hasSticker(messageRecord);
|
||||
}
|
||||
|
||||
private boolean hasOnlyDocument(MessageRecord messageRecord) {
|
||||
return messageRecord.getBody().length() == 0 &&
|
||||
!hasThumbnail(messageRecord) &&
|
||||
!hasAudio(messageRecord) &&
|
||||
hasDocument(messageRecord) &&
|
||||
!hasSharedContact(messageRecord) &&
|
||||
!hasSticker(messageRecord) &&
|
||||
!hasQuote(messageRecord);
|
||||
}
|
||||
|
||||
private boolean hasOnlyText(MessageRecord messageRecord) {
|
||||
return messageRecord.getBody().length() != 0 &&
|
||||
!hasThumbnail(messageRecord) &&
|
||||
!hasAudio(messageRecord) &&
|
||||
!hasDocument(messageRecord) &&
|
||||
!hasSharedContact(messageRecord) &&
|
||||
!hasSticker(messageRecord) &&
|
||||
!hasQuote(messageRecord);
|
||||
}
|
||||
|
||||
private boolean hasDocument(MessageRecord messageRecord) {
|
||||
return messageRecord.isMms() && ((MmsMessageRecord)messageRecord).getSlideDeck().getDocumentSlide() != null;
|
||||
}
|
||||
@@ -470,12 +482,11 @@ public class ConversationItem extends LinearLayout
|
||||
bodyText.setClickable(false);
|
||||
bodyText.setFocusable(false);
|
||||
bodyText.setTextSize(TypedValue.COMPLEX_UNIT_SP, TextSecurePreferences.getMessageBodyTextSize(context));
|
||||
|
||||
if (isCaptionlessMms(messageRecord)) {
|
||||
bodyText.setVisibility(View.GONE);
|
||||
} else {
|
||||
Spannable text = MentionUtilities.highlightMentions(linkifyMessageBody(messageRecord.getDisplayBody(context), batchSelected.isEmpty()), messageRecord.isOutgoing(), messageRecord.getThreadId(), context);
|
||||
text = SearchUtil.getHighlightedSpan(locale, () -> new BackgroundColorSpan(Color.YELLOW), text, searchQuery);
|
||||
text = SearchUtil.getHighlightedSpan(locale, () -> new BackgroundColorSpan(Color.WHITE), text, searchQuery);
|
||||
text = SearchUtil.getHighlightedSpan(locale, () -> new ForegroundColorSpan(Color.BLACK), text, searchQuery);
|
||||
|
||||
if (hasExtraText(messageRecord)) {
|
||||
@@ -489,6 +500,48 @@ public class ConversationItem extends LinearLayout
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustMarginsIfNeeded(MessageRecord messageRecord) {
|
||||
LinearLayout.LayoutParams bodyTextLayoutParams = (LinearLayout.LayoutParams)bodyText.getLayoutParams();
|
||||
bodyTextLayoutParams.topMargin = 0;
|
||||
if (hasOnlyThumbnail(messageRecord)) {
|
||||
int topPadding = 0;
|
||||
if (groupSenderHolder.getVisibility() == VISIBLE) {
|
||||
topPadding = (int)getResources().getDimension(R.dimen.medium_spacing);
|
||||
}
|
||||
int bottomPadding = 0;
|
||||
if (messageRecord.getBody().length() > 0) {
|
||||
bodyTextLayoutParams.topMargin = (int)getResources().getDimension(R.dimen.medium_spacing);
|
||||
bottomPadding = (int)getResources().getDimension(R.dimen.medium_spacing);
|
||||
}
|
||||
bodyBubble.setPadding(0, topPadding, 0, bottomPadding);
|
||||
} else {
|
||||
bodyBubble.setPadding(0, (int)getResources().getDimension(R.dimen.medium_spacing), 0, (int)getResources().getDimension(R.dimen.medium_spacing));
|
||||
}
|
||||
bodyText.setLayoutParams(bodyTextLayoutParams);
|
||||
LinearLayout.LayoutParams senderHolderLayoutParams = (LinearLayout.LayoutParams)groupSenderHolder.getLayoutParams();
|
||||
if (groupSenderHolder.getVisibility() == VISIBLE && hasOnlyText(messageRecord)) {
|
||||
senderHolderLayoutParams.bottomMargin = (int)(getResources().getDisplayMetrics().density * 4);
|
||||
} else {
|
||||
senderHolderLayoutParams.bottomMargin = (int)getResources().getDimension(R.dimen.medium_spacing);
|
||||
}
|
||||
groupSenderHolder.setLayoutParams(senderHolderLayoutParams);
|
||||
if (documentViewStub.resolved()) {
|
||||
LinearLayout.LayoutParams documentViewLayoutParams = (LinearLayout.LayoutParams)documentViewStub.get().getLayoutParams();
|
||||
int bottomMargin = 0;
|
||||
if (hasOnlyDocument(messageRecord)) {
|
||||
if (footer.getVisibility() == VISIBLE) {
|
||||
bottomMargin = (int)(4 * getResources().getDisplayMetrics().density);
|
||||
} else {
|
||||
bottomMargin = (int)(-4 * getResources().getDisplayMetrics().density);
|
||||
}
|
||||
} else {
|
||||
bottomMargin = (int)(4 * getResources().getDisplayMetrics().density);
|
||||
}
|
||||
documentViewLayoutParams.bottomMargin = bottomMargin;
|
||||
documentViewStub.get().setLayoutParams(documentViewLayoutParams);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMediaAttributes(@NonNull MessageRecord messageRecord,
|
||||
@NonNull Optional<MessageRecord> previousRecord,
|
||||
@NonNull Optional<MessageRecord> nextRecord,
|
||||
@@ -745,13 +798,18 @@ public class ConversationItem extends LinearLayout
|
||||
|
||||
private void setContactPhoto(@NonNull Recipient recipient) {
|
||||
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)bodyBubble.getLayoutParams();
|
||||
float scale = getResources().getDisplayMetrics().density;
|
||||
float marginInDP = groupThread ? 44 : 8;
|
||||
int marginInPX = Math.round(marginInDP * scale);
|
||||
layoutParams.setMarginStart(marginInPX);
|
||||
int groupThreadMargin = (int)(getResources().getDimension(R.dimen.large_spacing) + getResources().getDimension(R.dimen.small_profile_picture_size));
|
||||
int defaultMargin = 0;
|
||||
String threadName = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(messageRecord.getThreadId()).getName();
|
||||
boolean isRSSFeed = threadName != null && (threadName.equals("Loki News") || threadName.equals("Loki Messenger Updates"));
|
||||
layoutParams.setMarginStart((groupThread && !isRSSFeed) ? groupThreadMargin : defaultMargin);
|
||||
bodyBubble.setLayoutParams(layoutParams);
|
||||
if (contactPhoto == null) return;
|
||||
contactPhoto.setAvatar(glideRequests, recipient, true);
|
||||
if (profilePictureView == null) return;
|
||||
profilePictureView.setHexEncodedPublicKey(recipient.getAddress().toString());
|
||||
profilePictureView.setAdditionalHexEncodedPublicKey(null);
|
||||
profilePictureView.setRSSFeed(false);
|
||||
profilePictureView.setGlide(glideRequests);
|
||||
profilePictureView.update();
|
||||
}
|
||||
|
||||
private SpannableString linkifyMessageBody(SpannableString messageBody, boolean shouldLinkifyAllLinks) {
|
||||
@@ -924,7 +982,9 @@ public class ConversationItem extends LinearLayout
|
||||
}
|
||||
|
||||
private void setAuthor(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread) {
|
||||
if (isGroupThread && !current.isOutgoing()) {
|
||||
String threadName = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(current.getThreadId()).getName();
|
||||
boolean isRSSFeed = threadName != null && (threadName.equals("Loki News") || threadName.equals("Loki Messenger Updates"));
|
||||
if (isGroupThread && !isRSSFeed && !current.isOutgoing()) {
|
||||
contactPhotoHolder.setVisibility(VISIBLE);
|
||||
|
||||
if (!previous.isPresent() || previous.get().isUpdate() || !current.getRecipient().getAddress().equals(previous.get().getRecipient().getAddress()) ||
|
||||
@@ -935,8 +995,8 @@ public class ConversationItem extends LinearLayout
|
||||
groupSenderHolder.setVisibility(GONE);
|
||||
}
|
||||
|
||||
if (!next.isPresent() || next.get().isUpdate() || !current.getRecipient().getAddress().equals(next.get().getRecipient().getAddress())) {
|
||||
contactPhoto.setVisibility(VISIBLE);
|
||||
if (!previous.isPresent() || previous.get().isUpdate() || !current.getRecipient().getAddress().equals(previous.get().getRecipient().getAddress())) {
|
||||
profilePictureView.setVisibility(VISIBLE);
|
||||
int visibility = View.GONE;
|
||||
|
||||
LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(messageRecord.getThreadId());
|
||||
@@ -947,7 +1007,7 @@ public class ConversationItem extends LinearLayout
|
||||
|
||||
moderatorIconImageView.setVisibility(visibility);
|
||||
} else {
|
||||
contactPhoto.setVisibility(GONE);
|
||||
profilePictureView.setVisibility(GONE);
|
||||
moderatorIconImageView.setVisibility(GONE);
|
||||
|
||||
}
|
||||
@@ -964,17 +1024,13 @@ public class ConversationItem extends LinearLayout
|
||||
private void setMessageShape(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread) {
|
||||
int background;
|
||||
if (isSingularMessage(current, previous, next, isGroupThread)) {
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_alone
|
||||
: R.drawable.message_bubble_background_received_alone;
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_alone : R.drawable.message_bubble_background_received_alone;
|
||||
} else if (isStartOfMessageCluster(current, previous, isGroupThread)) {
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_start
|
||||
: R.drawable.message_bubble_background_received_start;
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_start : R.drawable.message_bubble_background_received_start;
|
||||
} else if (isEndOfMessageCluster(current, next, isGroupThread)) {
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_end
|
||||
: R.drawable.message_bubble_background_received_end;
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_end : R.drawable.message_bubble_background_received_end;
|
||||
} else {
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_middle
|
||||
: R.drawable.message_bubble_background_received_middle;
|
||||
background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_middle : R.drawable.message_bubble_background_received_middle;
|
||||
}
|
||||
|
||||
bodyBubble.setBackgroundResource(background);
|
||||
|
||||
@@ -5,9 +5,6 @@ import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.Menu;
|
||||
@@ -16,10 +13,13 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class ConversationPopupActivity extends ConversationActivity {
|
||||
|
||||
private static final String TAG = ConversationPopupActivity.class.getSimpleName();
|
||||
@@ -50,7 +50,7 @@ public class ConversationPopupActivity extends ConversationActivity {
|
||||
|
||||
super.onCreate(bundle, ready);
|
||||
|
||||
titleView.setOnClickListener(null);
|
||||
// titleView.setOnClickListener(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,6 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.BindableConversationItem;
|
||||
import network.loki.messenger.R;
|
||||
import org.thoughtcrime.securesms.VerifyIdentityActivity;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||
@@ -36,6 +35,8 @@ import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class ConversationUpdateItem extends LinearLayout
|
||||
implements RecipientModifiedListener, BindableConversationItem
|
||||
{
|
||||
@@ -135,10 +136,10 @@ public class ConversationUpdateItem extends LinearLayout
|
||||
private void setTimerRecord(final MessageRecord messageRecord) {
|
||||
if (messageRecord.getExpiresIn() > 0) {
|
||||
icon.setImageResource(R.drawable.ic_timer);
|
||||
icon.setColorFilter(new PorterDuffColorFilter(Color.parseColor("#757575"), PorterDuff.Mode.MULTIPLY));
|
||||
icon.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY));
|
||||
} else {
|
||||
icon.setImageResource(R.drawable.ic_timer_disabled);
|
||||
icon.setColorFilter(new PorterDuffColorFilter(Color.parseColor("#757575"), PorterDuff.Mode.MULTIPLY));
|
||||
icon.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
|
||||
title.setText(ExpirationUtil.getExpirationDisplayValue(getContext(), (int)(messageRecord.getExpiresIn() / 1000)));
|
||||
|
||||
Reference in New Issue
Block a user