Merge branch 'dev' into private-group-chat

This commit is contained in:
Mikunj
2020-01-31 15:29:31 +11:00
368 changed files with 14893 additions and 8531 deletions

View File

@@ -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.redesign.messaging.LokiAPIUtilities;
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,17 +465,39 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
LokiAPIUtilities.INSTANCE.populateUserHexEncodedPublicKeyCacheIfNeeded(threadId, this);
if (this.recipient.isGroupRecipient()) {
if (this.recipient.getAddress().isPublicChat()) {
Analytics.Companion.getShared().track("Public Chat Opened");
} else if (this.recipient.getAddress().isRSSFeed()) {
Analytics.Companion.getShared().track("RSS Feed Opened");
} else {
Analytics.Companion.getShared().track("Private Group Chat 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
@@ -497,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);
@@ -551,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();
}
@@ -586,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();
@@ -757,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) {
@@ -862,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();
@@ -1190,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;
}
@@ -1202,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();
@@ -1278,7 +1330,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
boolean isMediaMessage = recipient.isMmsGroupRecipient() || attachmentManager.isAttachmentPresent();
sendButton.resetAvailableTransports(isMediaMessage);
sendButton.setDefaultTransport(Type.TEXTSECURE);
/* Loki - We don't support SMS
if (!isSecureText && !isPushGroupConversation()) sendButton.disableTransport(Type.TEXTSECURE);
if (recipient.isPushGroupRecipient()) sendButton.disableTransport(Type.SMS);
@@ -1288,6 +1342,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (isSecureText || isPushGroupConversation()) sendButton.setDefaultTransport(Type.TEXTSECURE);
else sendButton.setDefaultTransport(Type.SMS);
}
*/
calculateCharactersRemaining();
supportInvalidateOptionsMenu();
@@ -1584,7 +1639,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
unverifiedBannerView.get().hide();
}
titleView.setVerified(isSecureText && identityRecords.isVerified());
// titleView.setVerified(isSecureText && identityRecords.isVerified());
future.set(true);
}
@@ -1595,7 +1650,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);
@@ -1614,8 +1669,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);
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);
@@ -1643,8 +1702,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);
});
@@ -1676,12 +1733,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);
}
@@ -1807,8 +1865,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);
@@ -2004,8 +2063,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) {
@@ -2174,9 +2233,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;
@@ -2283,8 +2339,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();
@@ -2869,6 +2925,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())) {
@@ -2893,14 +2950,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);
}
}
@@ -2945,7 +3005,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);
@@ -2960,20 +3021,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
@@ -3083,6 +3146,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
@@ -3120,17 +3305,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
public void restoreSession() {
// Loki - User clicked restore session
if (!recipient.isGroupRecipient()) {
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(this);
SmsDatabase database = DatabaseFactory.getSmsDatabase(this);
Set<String> devices = lokiThreadDatabase.getSessionRestoreDevices(threadId);
for (String device : devices) { MessageSender.sendRestoreSessionMessage(this, device); }
long messageId = database.insertMessageOutbox(threadId, new OutgoingTextMessage(recipient,"", 0, 0), false, System.currentTimeMillis(), null);
if (messageId > -1) {
database.markAsLokiSessionRestoreSent(messageId);
}
lokiThreadDatabase.removeAllSessionRestoreDevices(threadId);
updateSessionRestoreBanner();
if (recipient.isGroupRecipient()) { return; }
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(this);
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(this);
Set<String> devices = lokiThreadDatabase.getSessionRestoreDevices(threadId);
for (String device : devices) { MessageSender.sendRestoreSessionMessage(this, device); }
long messageId = smsDatabase.insertMessageOutbox(threadId, new OutgoingTextMessage(recipient,"", 0, 0), false, System.currentTimeMillis(), null);
if (messageId > -1) {
smsDatabase.markAsLokiSessionRestoreSent(messageId);
}
lokiThreadDatabase.removeAllSessionRestoreDevices(threadId);
updateSessionRestoreBanner();
}
}

View File

@@ -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
@@ -205,7 +206,6 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
if (conversationItem instanceof ConversationItem) {
((ConversationItem)conversationItem).friendRequestViewDelegate = this.friendRequestViewDelegate;
}
conversationItem.bind(messageRecord,
Optional.fromNullable(previousRecord),
Optional.fromNullable(nextRecord),

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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)));