mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 20:28:26 +00:00
Use Glide for all contact photo caching
// FREEBIE
This commit is contained in:
parent
10f224ede5
commit
b80408bcb4
@ -4,6 +4,7 @@ import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -12,6 +13,7 @@ import java.util.Set;
|
||||
public interface BindableConversationItem extends Unbindable {
|
||||
void bind(@NonNull MasterSecret masterSecret,
|
||||
@NonNull MessageRecord messageRecord,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Locale locale,
|
||||
@NonNull Set<MessageRecord> batchSelected,
|
||||
@NonNull Recipient recipients);
|
||||
|
@ -4,6 +4,7 @@ import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@ -11,5 +12,6 @@ import java.util.Set;
|
||||
public interface BindableConversationListItem extends Unbindable {
|
||||
|
||||
public void bind(@NonNull MasterSecret masterSecret, @NonNull ThreadRecord thread,
|
||||
@NonNull Locale locale, @NonNull Set<Long> selectedThreads, boolean batchMode);
|
||||
@NonNull GlideRequests glideRequests, @NonNull Locale locale,
|
||||
@NonNull Set<Long> selectedThreads, boolean batchMode);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
@ -19,6 +20,8 @@ import android.widget.ListView;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.loaders.BlockedContactsLoader;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.preferences.BlockedContactListItem;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
@ -72,7 +75,7 @@ public class BlockedContactsActivity extends PassphraseRequiredActionBarActivity
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
setListAdapter(new BlockedContactAdapter(getActivity(), null));
|
||||
setListAdapter(new BlockedContactAdapter(getActivity(), GlideApp.with(this), null));
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
@ -112,8 +115,11 @@ public class BlockedContactsActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
private static class BlockedContactAdapter extends CursorAdapter {
|
||||
|
||||
public BlockedContactAdapter(Context context, Cursor c) {
|
||||
private final GlideRequests glideRequests;
|
||||
|
||||
BlockedContactAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, @Nullable Cursor c) {
|
||||
super(context, c);
|
||||
this.glideRequests = glideRequests;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -127,7 +133,7 @@ public class BlockedContactsActivity extends PassphraseRequiredActionBarActivity
|
||||
String address = cursor.getString(1);
|
||||
Recipient recipient = Recipient.from(context, Address.fromSerialized(address), true);
|
||||
|
||||
((BlockedContactListItem) view).set(recipient);
|
||||
((BlockedContactListItem) view).set(glideRequests, recipient);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2015 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListItem;
|
||||
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader;
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
@ -119,6 +120,7 @@ public class ContactSelectionListFragment extends Fragment
|
||||
|
||||
private void initializeCursor() {
|
||||
ContactSelectionListAdapter adapter = new ContactSelectionListAdapter(getActivity(),
|
||||
GlideApp.with(this),
|
||||
null,
|
||||
new ListClickListener(),
|
||||
isMulti());
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -117,6 +117,8 @@ import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager.MediaType;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.LocationSlide;
|
||||
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
|
||||
@ -208,6 +210,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private static final int SMS_DEFAULT = 10;
|
||||
|
||||
private MasterSecret masterSecret;
|
||||
private GlideRequests glideRequests;
|
||||
protected ComposeText composeText;
|
||||
private AnimatingToggle buttonToggle;
|
||||
private SendButton sendButton;
|
||||
@ -287,7 +290,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
if (!Util.isEmpty(composeText) || attachmentManager.isAttachmentPresent()) {
|
||||
saveDraft();
|
||||
attachmentManager.clear(false);
|
||||
attachmentManager.clear(glideRequests, false);
|
||||
composeText.setText("");
|
||||
}
|
||||
|
||||
@ -323,7 +326,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
initializeIdentityRecords();
|
||||
composeText.setTransport(sendButton.getSelectedTransport());
|
||||
|
||||
titleView.setTitle(recipient);
|
||||
titleView.setTitle(glideRequests, recipient);
|
||||
setActionBarColor(recipient.getColor());
|
||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||
setGroupShareProfileReminder(recipient);
|
||||
@ -409,9 +412,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
addAttachmentContactInfo(data.getData());
|
||||
break;
|
||||
case GROUP_EDIT:
|
||||
recipient = Recipient.from(this, (Address)data.getParcelableExtra(GroupCreateActivity.GROUP_ADDRESS_EXTRA), true);
|
||||
recipient = Recipient.from(this, data.getParcelableExtra(GroupCreateActivity.GROUP_ADDRESS_EXTRA), true);
|
||||
recipient.addListener(this);
|
||||
titleView.setTitle(recipient);
|
||||
titleView.setTitle(glideRequests, recipient);
|
||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||
supportInvalidateOptionsMenu();
|
||||
break;
|
||||
@ -1239,6 +1242,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
||||
archived = getIntent().getBooleanExtra(IS_ARCHIVED_EXTRA, false);
|
||||
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
|
||||
glideRequests = GlideApp.with(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
LinearLayout conversationContainer = ViewUtil.findById(this, R.id.conversation_container);
|
||||
@ -1263,7 +1267,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
@Override
|
||||
public void onModified(final Recipient recipient) {
|
||||
Util.runOnMain(() -> {
|
||||
titleView.setTitle(recipient);
|
||||
titleView.setTitle(glideRequests, recipient);
|
||||
titleView.setVerified(identityRecords.isVerified());
|
||||
setBlockedUserState(recipient, isSecureText, isDefaultSms);
|
||||
setActionBarColor(recipient.getColor());
|
||||
@ -1338,7 +1342,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
private void setMedia(@Nullable Uri uri, @NonNull MediaType mediaType) {
|
||||
if (uri == null) return;
|
||||
attachmentManager.setMedia(masterSecret, uri, mediaType, getCurrentMediaConstraints());
|
||||
attachmentManager.setMedia(masterSecret, glideRequests, uri, mediaType, getCurrentMediaConstraints());
|
||||
}
|
||||
|
||||
private void addAttachmentContactInfo(Uri contactUri) {
|
||||
@ -1631,7 +1635,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessage);
|
||||
}
|
||||
|
||||
attachmentManager.clear(false);
|
||||
attachmentManager.clear(glideRequests, false);
|
||||
composeText.setText("");
|
||||
final long id = fragment.stageOutgoingMessage(outgoingMessage);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -40,6 +40,7 @@ import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
@ -92,6 +93,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
|
||||
private final @Nullable ItemClickListener clickListener;
|
||||
private final @NonNull MasterSecret masterSecret;
|
||||
private final @NonNull GlideRequests glideRequests;
|
||||
private final @NonNull Locale locale;
|
||||
private final @NonNull Recipient recipient;
|
||||
private final @NonNull MmsSmsDatabase db;
|
||||
@ -130,7 +132,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
|
||||
|
||||
public interface ItemClickListener {
|
||||
interface ItemClickListener {
|
||||
void onItemClick(MessageRecord item);
|
||||
void onItemLongClick(MessageRecord item);
|
||||
}
|
||||
@ -141,6 +143,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
super(context, cursor);
|
||||
try {
|
||||
this.masterSecret = null;
|
||||
this.glideRequests = null;
|
||||
this.locale = null;
|
||||
this.clickListener = null;
|
||||
this.recipient = null;
|
||||
@ -155,6 +158,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
|
||||
public ConversationAdapter(@NonNull Context context,
|
||||
@NonNull MasterSecret masterSecret,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Locale locale,
|
||||
@Nullable ItemClickListener clickListener,
|
||||
@Nullable Cursor cursor,
|
||||
@ -164,6 +168,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
|
||||
try {
|
||||
this.masterSecret = masterSecret;
|
||||
this.glideRequests = glideRequests;
|
||||
this.locale = locale;
|
||||
this.clickListener = clickListener;
|
||||
this.recipient = recipient;
|
||||
@ -188,7 +193,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
@Override
|
||||
protected void onBindItemViewHolder(ViewHolder viewHolder, @NonNull MessageRecord messageRecord) {
|
||||
long start = System.currentTimeMillis();
|
||||
viewHolder.getView().bind(masterSecret, messageRecord, locale, batchSelected, recipient);
|
||||
viewHolder.getView().bind(masterSecret, messageRecord, glideRequests, locale, batchSelected, recipient);
|
||||
Log.w(TAG, "Bind time: " + (System.currentTimeMillis() - start));
|
||||
}
|
||||
|
||||
@ -196,22 +201,16 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
public ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
|
||||
long start = System.currentTimeMillis();
|
||||
final V itemView = ViewUtil.inflate(inflater, parent, getLayoutForViewType(viewType));
|
||||
itemView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemClick(itemView.getMessageRecord());
|
||||
}
|
||||
itemView.setOnClickListener(view -> {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemClick(itemView.getMessageRecord());
|
||||
}
|
||||
});
|
||||
itemView.setOnLongClickListener(new OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemLongClick(itemView.getMessageRecord());
|
||||
}
|
||||
return true;
|
||||
itemView.setOnLongClickListener(view -> {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemLongClick(itemView.getMessageRecord());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
Log.w(TAG, "Inflate time: " + (System.currentTimeMillis() - start));
|
||||
return new ViewHolder(itemView);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2015 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -60,6 +60,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.profiles.UnknownSenderView;
|
||||
@ -69,7 +70,6 @@ import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask.Attachment;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
|
||||
@ -122,12 +122,7 @@ public class ConversationFragment extends Fragment
|
||||
scrollToBottomButton = ViewUtil.findById(view, R.id.scroll_to_bottom_button);
|
||||
scrollDateHeader = ViewUtil.findById(view, R.id.scroll_date_header);
|
||||
|
||||
scrollToBottomButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
scrollToBottom();
|
||||
}
|
||||
});
|
||||
scrollToBottomButton.setOnClickListener(v -> scrollToBottom());
|
||||
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, true);
|
||||
list.setHasFixedSize(false);
|
||||
@ -185,7 +180,7 @@ public class ConversationFragment extends Fragment
|
||||
}
|
||||
|
||||
private void initializeResources() {
|
||||
this.recipient = Recipient.from(getActivity(), (Address) getActivity().getIntent().getParcelableExtra(ConversationActivity.ADDRESS_EXTRA), true);
|
||||
this.recipient = Recipient.from(getActivity(), getActivity().getIntent().getParcelableExtra(ConversationActivity.ADDRESS_EXTRA), true);
|
||||
this.threadId = this.getActivity().getIntent().getLongExtra(ConversationActivity.THREAD_ID_EXTRA, -1);
|
||||
this.lastSeen = this.getActivity().getIntent().getLongExtra(ConversationActivity.LAST_SEEN_EXTRA, -1);
|
||||
this.firstLoad = true;
|
||||
@ -197,7 +192,7 @@ public class ConversationFragment extends Fragment
|
||||
|
||||
private void initializeListAdapter() {
|
||||
if (this.recipient != null && this.threadId != -1) {
|
||||
ConversationAdapter adapter = new ConversationAdapter(getActivity(), masterSecret, locale, selectionClickListener, null, this.recipient);
|
||||
ConversationAdapter adapter = new ConversationAdapter(getActivity(), masterSecret, GlideApp.with(this), locale, selectionClickListener, null, this.recipient);
|
||||
list.setAdapter(adapter);
|
||||
list.addItemDecoration(new StickyHeaderDecoration(adapter, false, false));
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -39,7 +39,6 @@ import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewStub;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
@ -67,6 +66,7 @@ import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
|
||||
import org.thoughtcrime.securesms.jobs.MmsDownloadJob;
|
||||
import org.thoughtcrime.securesms.jobs.MmsSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.SmsSendJob;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.SlideClickListener;
|
||||
@ -107,6 +107,7 @@ public class ConversationItem extends LinearLayout
|
||||
private Locale locale;
|
||||
private boolean groupThread;
|
||||
private Recipient recipient;
|
||||
private GlideRequests glideRequests;
|
||||
|
||||
protected View bodyBubble;
|
||||
private TextView bodyText;
|
||||
@ -155,22 +156,22 @@ public class ConversationItem extends LinearLayout
|
||||
|
||||
initializeAttributes();
|
||||
|
||||
this.bodyText = (TextView) findViewById(R.id.conversation_item_body);
|
||||
this.dateText = (TextView) findViewById(R.id.conversation_item_date);
|
||||
this.simInfoText = (TextView) findViewById(R.id.sim_info);
|
||||
this.indicatorText = (TextView) findViewById(R.id.indicator_text);
|
||||
this.groupSender = (TextView) findViewById(R.id.group_message_sender);
|
||||
this.groupSenderProfileName = (TextView) findViewById(R.id.group_message_sender_profile);
|
||||
this.insecureImage = (ImageView) findViewById(R.id.insecure_indicator);
|
||||
this.deliveryStatusIndicator = (DeliveryStatusView) findViewById(R.id.delivery_status);
|
||||
this.alertView = (AlertView) findViewById(R.id.indicators_parent);
|
||||
this.contactPhoto = (AvatarImageView) findViewById(R.id.contact_photo);
|
||||
this.bodyBubble = findViewById(R.id.body_bubble);
|
||||
this.mediaThumbnailStub = new Stub<>((ViewStub) findViewById(R.id.image_view_stub));
|
||||
this.audioViewStub = new Stub<>((ViewStub) findViewById(R.id.audio_view_stub));
|
||||
this.documentViewStub = new Stub<>((ViewStub) findViewById(R.id.document_view_stub));
|
||||
this.expirationTimer = (ExpirationTimerView) findViewById(R.id.expiration_indicator);
|
||||
this.groupSenderHolder = findViewById(R.id.group_sender_holder);
|
||||
this.bodyText = findViewById(R.id.conversation_item_body);
|
||||
this.dateText = findViewById(R.id.conversation_item_date);
|
||||
this.simInfoText = findViewById(R.id.sim_info);
|
||||
this.indicatorText = findViewById(R.id.indicator_text);
|
||||
this.groupSender = findViewById(R.id.group_message_sender);
|
||||
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
|
||||
this.insecureImage = findViewById(R.id.insecure_indicator);
|
||||
this.deliveryStatusIndicator = findViewById(R.id.delivery_status);
|
||||
this.alertView = findViewById(R.id.indicators_parent);
|
||||
this.contactPhoto = findViewById(R.id.contact_photo);
|
||||
this.bodyBubble = findViewById(R.id.body_bubble);
|
||||
this.mediaThumbnailStub = new Stub<>(findViewById(R.id.image_view_stub));
|
||||
this.audioViewStub = new Stub<>(findViewById(R.id.audio_view_stub));
|
||||
this.documentViewStub = new Stub<>(findViewById(R.id.document_view_stub));
|
||||
this.expirationTimer = findViewById(R.id.expiration_indicator);
|
||||
this.groupSenderHolder = findViewById(R.id.group_sender_holder);
|
||||
|
||||
setOnClickListener(new ClickListener(null));
|
||||
|
||||
@ -183,6 +184,7 @@ public class ConversationItem extends LinearLayout
|
||||
@Override
|
||||
public void bind(@NonNull MasterSecret masterSecret,
|
||||
@NonNull MessageRecord messageRecord,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Locale locale,
|
||||
@NonNull Set<MessageRecord> batchSelected,
|
||||
@NonNull Recipient conversationRecipient)
|
||||
@ -190,6 +192,7 @@ public class ConversationItem extends LinearLayout
|
||||
this.masterSecret = masterSecret;
|
||||
this.messageRecord = messageRecord;
|
||||
this.locale = locale;
|
||||
this.glideRequests = glideRequests;
|
||||
this.batchSelected = batchSelected;
|
||||
this.conversationRecipient = conversationRecipient;
|
||||
this.groupThread = conversationRecipient.isGroupRecipient();
|
||||
@ -386,7 +389,7 @@ public class ConversationItem extends LinearLayout
|
||||
if (documentViewStub.resolved()) documentViewStub.get().setVisibility(View.GONE);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
mediaThumbnailStub.get().setImageResource(masterSecret,
|
||||
mediaThumbnailStub.get().setImageResource(masterSecret, glideRequests,
|
||||
((MmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide(),
|
||||
showControls, false);
|
||||
mediaThumbnailStub.get().setThumbnailClickListener(new ThumbnailClickListener());
|
||||
@ -409,7 +412,7 @@ public class ConversationItem extends LinearLayout
|
||||
if (messageRecord.isOutgoing() || !groupThread) {
|
||||
contactPhoto.setVisibility(View.GONE);
|
||||
} else {
|
||||
contactPhoto.setAvatar(recipient, true);
|
||||
contactPhoto.setAvatar(glideRequests, recipient, true);
|
||||
contactPhoto.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -23,17 +23,15 @@ import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
@ -48,18 +46,19 @@ import java.util.Set;
|
||||
*
|
||||
* @author Moxie Marlinspike
|
||||
*/
|
||||
public class ConversationListAdapter extends CursorRecyclerViewAdapter<ConversationListAdapter.ViewHolder> {
|
||||
class ConversationListAdapter extends CursorRecyclerViewAdapter<ConversationListAdapter.ViewHolder> {
|
||||
|
||||
private static final int MESSAGE_TYPE_SWITCH_ARCHIVE = 1;
|
||||
private static final int MESSAGE_TYPE_THREAD = 2;
|
||||
|
||||
private final ThreadDatabase threadDatabase;
|
||||
private final MasterSecret masterSecret;
|
||||
private final MasterCipher masterCipher;
|
||||
private final Locale locale;
|
||||
private final LayoutInflater inflater;
|
||||
private final ItemClickListener clickListener;
|
||||
private final @NonNull MessageDigest digest;
|
||||
private final @NonNull ThreadDatabase threadDatabase;
|
||||
private final @NonNull MasterSecret masterSecret;
|
||||
private final @NonNull MasterCipher masterCipher;
|
||||
private final @NonNull GlideRequests glideRequests;
|
||||
private final @NonNull Locale locale;
|
||||
private final @NonNull LayoutInflater inflater;
|
||||
private final @Nullable ItemClickListener clickListener;
|
||||
private final @NonNull MessageDigest digest;
|
||||
|
||||
private final Set<Long> batchSet = Collections.synchronizedSet(new HashSet<Long>());
|
||||
private boolean batchMode = false;
|
||||
@ -82,16 +81,18 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
||||
return Conversions.byteArrayToLong(digest.digest(record.getRecipient().getAddress().serialize().getBytes()));
|
||||
}
|
||||
|
||||
public ConversationListAdapter(@NonNull Context context,
|
||||
@NonNull MasterSecret masterSecret,
|
||||
@NonNull Locale locale,
|
||||
@Nullable Cursor cursor,
|
||||
@Nullable ItemClickListener clickListener)
|
||||
ConversationListAdapter(@NonNull Context context,
|
||||
@NonNull MasterSecret masterSecret,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Locale locale,
|
||||
@Nullable Cursor cursor,
|
||||
@Nullable ItemClickListener clickListener)
|
||||
{
|
||||
super(context, cursor);
|
||||
try {
|
||||
this.masterSecret = masterSecret;
|
||||
this.masterCipher = new MasterCipher(masterSecret);
|
||||
this.glideRequests = glideRequests;
|
||||
this.threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
this.locale = locale;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
@ -109,11 +110,8 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
||||
ConversationListItemAction action = (ConversationListItemAction)inflater.inflate(R.layout.conversation_list_item_action,
|
||||
parent, false);
|
||||
|
||||
action.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (clickListener != null) clickListener.onSwitchToArchive();
|
||||
}
|
||||
action.setOnClickListener(v -> {
|
||||
if (clickListener != null) clickListener.onSwitchToArchive();
|
||||
});
|
||||
|
||||
return new ViewHolder(action);
|
||||
@ -121,19 +119,13 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
||||
final ConversationListItem item = (ConversationListItem)inflater.inflate(R.layout.conversation_list_item_view,
|
||||
parent, false);
|
||||
|
||||
item.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (clickListener != null) clickListener.onItemClick(item);
|
||||
}
|
||||
item.setOnClickListener(view -> {
|
||||
if (clickListener != null) clickListener.onItemClick(item);
|
||||
});
|
||||
|
||||
item.setOnLongClickListener(new OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
if (clickListener != null) clickListener.onItemLongClick(item);
|
||||
return true;
|
||||
}
|
||||
item.setOnLongClickListener(view -> {
|
||||
if (clickListener != null) clickListener.onItemLongClick(item);
|
||||
return true;
|
||||
});
|
||||
|
||||
return new ViewHolder(item);
|
||||
@ -147,7 +139,7 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
||||
|
||||
@Override
|
||||
public void onBindItemViewHolder(ViewHolder viewHolder, @NonNull Cursor cursor) {
|
||||
viewHolder.getItem().bind(masterSecret, getThreadRecord(cursor), locale, batchSet, batchMode);
|
||||
viewHolder.getItem().bind(masterSecret, getThreadRecord(cursor), glideRequests, locale, batchSet, batchMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -195,7 +187,7 @@ public class ConversationListAdapter extends CursorRecyclerViewAdapter<Conversat
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public interface ItemClickListener {
|
||||
interface ItemClickListener {
|
||||
void onItemClick(ConversationListItem item);
|
||||
void onItemLongClick(ConversationListItem item);
|
||||
void onSwitchToArchive();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2015 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -67,6 +67,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||
import org.thoughtcrime.securesms.database.loaders.ConversationListLoader;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.notifications.MarkReadReceiver;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
@ -201,7 +202,7 @@ public class ConversationListFragment extends Fragment
|
||||
}
|
||||
|
||||
private void initializeListAdapter() {
|
||||
list.setAdapter(new ConversationListAdapter(getActivity(), masterSecret, locale, null, this));
|
||||
list.setAdapter(new ConversationListAdapter(getActivity(), masterSecret, GlideApp.with(this), locale, null, this));
|
||||
getLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.components.FromTextView;
|
||||
import org.thoughtcrime.securesms.components.ThumbnailView;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
@ -68,6 +69,7 @@ public class ConversationListItem extends RelativeLayout
|
||||
private Set<Long> selectedThreads;
|
||||
private Recipient recipient;
|
||||
private long threadId;
|
||||
private GlideRequests glideRequests;
|
||||
private TextView subjectView;
|
||||
private FromTextView fromView;
|
||||
private TextView dateView;
|
||||
@ -98,13 +100,13 @@ public class ConversationListItem extends RelativeLayout
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
this.subjectView = (TextView) findViewById(R.id.subject);
|
||||
this.fromView = (FromTextView) findViewById(R.id.from);
|
||||
this.dateView = (TextView) findViewById(R.id.date);
|
||||
this.deliveryStatusIndicator = (DeliveryStatusView) findViewById(R.id.delivery_status);
|
||||
this.alertView = (AlertView) findViewById(R.id.indicators_parent);
|
||||
this.contactPhotoImage = (AvatarImageView) findViewById(R.id.contact_photo_image);
|
||||
this.thumbnailView = (ThumbnailView) findViewById(R.id.thumbnail);
|
||||
this.subjectView = findViewById(R.id.subject);
|
||||
this.fromView = findViewById(R.id.from);
|
||||
this.dateView = findViewById(R.id.date);
|
||||
this.deliveryStatusIndicator = findViewById(R.id.delivery_status);
|
||||
this.alertView = findViewById(R.id.indicators_parent);
|
||||
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
|
||||
this.thumbnailView = findViewById(R.id.thumbnail);
|
||||
this.archivedView = ViewUtil.findById(this, R.id.archived);
|
||||
thumbnailView.setClickable(false);
|
||||
|
||||
@ -112,12 +114,15 @@ public class ConversationListItem extends RelativeLayout
|
||||
ViewUtil.setTextViewGravityStart(this.subjectView, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(@NonNull MasterSecret masterSecret, @NonNull ThreadRecord thread,
|
||||
@NonNull Locale locale, @NonNull Set<Long> selectedThreads, boolean batchMode)
|
||||
@NonNull GlideRequests glideRequests, @NonNull Locale locale,
|
||||
@NonNull Set<Long> selectedThreads, boolean batchMode)
|
||||
{
|
||||
this.selectedThreads = selectedThreads;
|
||||
this.recipient = thread.getRecipient();
|
||||
this.threadId = thread.getThreadId();
|
||||
this.glideRequests = glideRequests;
|
||||
this.read = thread.isRead();
|
||||
this.distributionType = thread.getDistributionType();
|
||||
this.lastSeen = thread.getLastSeen();
|
||||
@ -145,7 +150,7 @@ public class ConversationListItem extends RelativeLayout
|
||||
setBatchState(batchMode);
|
||||
setBackground(thread);
|
||||
setRippleColor(recipient);
|
||||
this.contactPhotoImage.setAvatar(recipient, true);
|
||||
this.contactPhotoImage.setAvatar(glideRequests, recipient, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -180,7 +185,7 @@ public class ConversationListItem extends RelativeLayout
|
||||
private void setThumbnailSnippet(MasterSecret masterSecret, ThreadRecord thread) {
|
||||
if (thread.getSnippetUri() != null) {
|
||||
this.thumbnailView.setVisibility(View.VISIBLE);
|
||||
this.thumbnailView.setImageResource(masterSecret, thread.getSnippetUri());
|
||||
this.thumbnailView.setImageResource(masterSecret, glideRequests, thread.getSnippetUri());
|
||||
|
||||
LayoutParams subjectParams = (RelativeLayout.LayoutParams)this.subjectView.getLayoutParams();
|
||||
subjectParams.addRule(RelativeLayout.LEFT_OF, R.id.thumbnail);
|
||||
@ -238,7 +243,7 @@ public class ConversationListItem extends RelativeLayout
|
||||
public void onModified(final Recipient recipient) {
|
||||
Util.runOnMain(() -> {
|
||||
fromView.setText(recipient, read);
|
||||
contactPhotoImage.setAvatar(recipient, true);
|
||||
contactPhotoImage.setAvatar(glideRequests, recipient, true);
|
||||
setRippleColor(recipient);
|
||||
});
|
||||
}
|
||||
@ -250,7 +255,7 @@ public class ConversationListItem extends RelativeLayout
|
||||
private final View deliveryStatusView;
|
||||
private final View dateView;
|
||||
|
||||
public ThumbnailPositioner(View thumbnailView, View archivedView, View deliveryStatusView, View dateView) {
|
||||
ThumbnailPositioner(View thumbnailView, View archivedView, View deliveryStatusView, View dateView) {
|
||||
this.thumbnailView = thumbnailView;
|
||||
this.archivedView = archivedView;
|
||||
this.deliveryStatusView = deliveryStatusView;
|
||||
|
@ -10,6 +10,7 @@ import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -39,7 +40,7 @@ public class ConversationListItemAction extends LinearLayout implements Bindable
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(@NonNull MasterSecret masterSecret, @NonNull ThreadRecord thread, @NonNull Locale locale, @NonNull Set<Long> selectedThreads, boolean batchMode) {
|
||||
public void bind(@NonNull MasterSecret masterSecret, @NonNull ThreadRecord thread, @NonNull GlideRequests glideRequests, @NonNull Locale locale, @NonNull Set<Long> selectedThreads, boolean batchMode) {
|
||||
this.description.setText(getContext().getString(R.string.ConversationListItemAction_archived_conversations_d, thread.getCount()));
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import com.annimon.stream.Collectors;
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
@ -56,7 +57,7 @@ public class ConversationTitleView extends RelativeLayout {
|
||||
ViewUtil.setTextViewGravityStart(this.subtitle, getContext());
|
||||
}
|
||||
|
||||
public void setTitle(@Nullable Recipient recipient) {
|
||||
public void setTitle(@NonNull GlideRequests glideRequests, @Nullable Recipient recipient) {
|
||||
if (recipient == null) setComposeTitle();
|
||||
else setRecipientTitle(recipient);
|
||||
|
||||
@ -69,7 +70,7 @@ public class ConversationTitleView extends RelativeLayout {
|
||||
}
|
||||
|
||||
if (recipient != null) {
|
||||
this.avatar.setAvatar(recipient, false);
|
||||
this.avatar.setAvatar(glideRequests, recipient, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
@ -69,6 +70,7 @@ public class ConversationUpdateItem extends LinearLayout
|
||||
@Override
|
||||
public void bind(@NonNull MasterSecret masterSecret,
|
||||
@NonNull MessageRecord messageRecord,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Locale locale,
|
||||
@NonNull Set<MessageRecord> batchSelected,
|
||||
@NonNull Recipient conversationRecipient)
|
||||
|
@ -17,7 +17,6 @@ import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
@ -33,12 +32,12 @@ import com.soundcloud.android.crop.Crop;
|
||||
import org.thoughtcrime.securesms.components.InputAwareLayout;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceProfileKeyUpdateJob;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints;
|
||||
import org.thoughtcrime.securesms.profiles.SystemProfileUtil;
|
||||
@ -56,6 +55,7 @@ import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -135,8 +135,7 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
|
||||
if (data != null && data.getBooleanExtra("delete", false)) {
|
||||
avatarBytes = null;
|
||||
avatar.setImageDrawable(ContactPhotoFactory.getResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp)
|
||||
.asDrawable(this, getResources().getColor(R.color.grey_400)));
|
||||
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp).asDrawable(this, getResources().getColor(R.color.grey_400)));
|
||||
} else {
|
||||
new Crop(inputFile).output(outputFile).asSquare().start(this);
|
||||
}
|
||||
@ -145,13 +144,30 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
break;
|
||||
case Crop.REQUEST_CROP:
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
try {
|
||||
avatarBytes = BitmapUtil.createScaledBytes(this, Crop.getOutput(data), new ProfileMediaConstraints());
|
||||
avatar.setImageDrawable(ContactPhotoFactory.getGroupContactPhoto(avatarBytes).asDrawable(this, 0));
|
||||
} catch (BitmapDecodingException e) {
|
||||
Log.w(TAG, e);
|
||||
Toast.makeText(this, R.string.CreateProfileActivity_error_setting_profile_photo, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
new AsyncTask<Void, Void, byte[]>() {
|
||||
@Override
|
||||
protected byte[] doInBackground(Void... params) {
|
||||
try {
|
||||
return BitmapUtil.createScaledBytes(CreateProfileActivity.this, Crop.getOutput(data), new ProfileMediaConstraints());
|
||||
} catch (BitmapDecodingException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(byte[] result) {
|
||||
if (result != null) {
|
||||
avatarBytes = result;
|
||||
GlideApp.with(CreateProfileActivity.this)
|
||||
.load(avatarBytes)
|
||||
.circleCrop()
|
||||
.into(avatar);
|
||||
} else {
|
||||
Toast.makeText(CreateProfileActivity.this, R.string.CreateProfileActivity_error_setting_profile_photo, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -170,8 +186,7 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
this.reveal = ViewUtil.findById(this, R.id.reveal);
|
||||
this.nextIntent = getIntent().getParcelableExtra(NEXT_INTENT);
|
||||
|
||||
this.avatar.setImageDrawable(ContactPhotoFactory.getResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp)
|
||||
.asDrawable(this, getResources().getColor(R.color.grey_400)));
|
||||
this.avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp).asDrawable(this, getResources().getColor(R.color.grey_400)));
|
||||
|
||||
this.avatar.setOnClickListener(view -> {
|
||||
try {
|
||||
@ -251,12 +266,11 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
Address ourAddress = Address.fromSerialized(TextSecurePreferences.getLocalNumber(this));
|
||||
|
||||
if (AvatarHelper.getAvatarFile(this, ourAddress).exists() && AvatarHelper.getAvatarFile(this, ourAddress).length() > 0) {
|
||||
new AsyncTask<Void, Void, Pair<byte[], ContactPhoto>>() {
|
||||
new AsyncTask<Void, Void, byte[]>() {
|
||||
@Override
|
||||
protected Pair<byte[], ContactPhoto> doInBackground(Void... params) {
|
||||
protected byte[] doInBackground(Void... params) {
|
||||
try {
|
||||
byte[] data =Util.readFully(AvatarHelper.getInputStreamFor(CreateProfileActivity.this, ourAddress));
|
||||
return new Pair<>(data, ContactPhotoFactory.getSignalAvatarContactPhoto(CreateProfileActivity.this, ourAddress, null, getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size)));
|
||||
return Util.readFully(AvatarHelper.getInputStreamFor(CreateProfileActivity.this, ourAddress));
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
@ -264,10 +278,13 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Pair<byte[], ContactPhoto> result) {
|
||||
protected void onPostExecute(byte[] result) {
|
||||
if (result != null) {
|
||||
avatarBytes = result.first;
|
||||
avatar.setImageDrawable(result.second.asDrawable(CreateProfileActivity.this, 0));
|
||||
avatarBytes = result;
|
||||
GlideApp.with(CreateProfileActivity.this)
|
||||
.load(result)
|
||||
.circleCrop()
|
||||
.into(avatar);
|
||||
}
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
@ -277,7 +294,10 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
public void onSuccess(byte[] result) {
|
||||
if (result != null) {
|
||||
avatarBytes = result;
|
||||
avatar.setImageDrawable(ContactPhotoFactory.getGroupContactPhoto(result).asDrawable(CreateProfileActivity.this, 0));
|
||||
GlideApp.with(CreateProfileActivity.this)
|
||||
.load(result)
|
||||
.circleCrop()
|
||||
.into(avatar);
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,6 +396,7 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
||||
try {
|
||||
accountManager.setProfileAvatar(profileKey, avatar);
|
||||
AvatarHelper.setAvatar(CreateProfileActivity.this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(context)), avatarBytes);
|
||||
TextSecurePreferences.setProfileAvatarId(CreateProfileActivity.this, new SecureRandom().nextInt());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
|
@ -38,9 +38,7 @@ import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.soundcloud.android.crop.Crop;
|
||||
@ -49,7 +47,7 @@ import org.thoughtcrime.securesms.components.PushRecipientsPanel;
|
||||
import org.thoughtcrime.securesms.components.PushRecipientsPanel.RecipientsPanelChangedListener;
|
||||
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
@ -193,8 +191,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
recipientsEditor.setHint(R.string.recipients_panel__add_members);
|
||||
recipientsPanel.setPanelChangeListener(this);
|
||||
findViewById(R.id.contacts_button).setOnClickListener(new AddRecipientButtonListener());
|
||||
avatar.setImageDrawable(ContactPhotoFactory.getDefaultGroupPhoto()
|
||||
.asDrawable(this, ContactColors.UNKNOWN_COLOR.toConversationColor(this)));
|
||||
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_group_white_24dp).asDrawable(this, ContactColors.UNKNOWN_COLOR.toConversationColor(this)));
|
||||
avatar.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2015 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -18,6 +18,7 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -30,16 +31,19 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord;
|
||||
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class MediaGalleryAdapter extends StickyHeaderGridAdapter {
|
||||
class MediaGalleryAdapter extends StickyHeaderGridAdapter {
|
||||
|
||||
private static final String TAG = MediaGalleryAdapter.class.getSimpleName();
|
||||
|
||||
private final Context context;
|
||||
private final MasterSecret masterSecret;
|
||||
private final GlideRequests glideRequests;
|
||||
private final Locale locale;
|
||||
private final Address address;
|
||||
|
||||
@ -50,7 +54,7 @@ public class MediaGalleryAdapter extends StickyHeaderGridAdapter {
|
||||
|
||||
ViewHolder(View v) {
|
||||
super(v);
|
||||
imageView = (ThumbnailView) v.findViewById(R.id.image);
|
||||
imageView = v.findViewById(R.id.image);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,16 +63,19 @@ public class MediaGalleryAdapter extends StickyHeaderGridAdapter {
|
||||
|
||||
HeaderHolder(View itemView) {
|
||||
super(itemView);
|
||||
textView = (TextView) itemView.findViewById(R.id.text);
|
||||
textView = itemView.findViewById(R.id.text);
|
||||
}
|
||||
}
|
||||
|
||||
public MediaGalleryAdapter(Context context, MasterSecret masterSecret, BucketedThreadMedia media, Locale locale, Address address) {
|
||||
this.context = context;
|
||||
this.masterSecret = masterSecret;
|
||||
this.locale = locale;
|
||||
this.media = media;
|
||||
this.address = address;
|
||||
MediaGalleryAdapter(@NonNull Context context, @NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests,
|
||||
BucketedThreadMedia media, Locale locale, Address address)
|
||||
{
|
||||
this.context = context;
|
||||
this.masterSecret = masterSecret;
|
||||
this.glideRequests = glideRequests;
|
||||
this.locale = locale;
|
||||
this.media = media;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public void setMedia(BucketedThreadMedia media) {
|
||||
@ -98,7 +105,7 @@ public class MediaGalleryAdapter extends StickyHeaderGridAdapter {
|
||||
Slide slide = MediaUtil.getSlideForAttachment(context, mediaRecord.getAttachment());
|
||||
|
||||
if (slide != null) {
|
||||
thumbnailView.setImageResource(masterSecret, slide, false, false);
|
||||
thumbnailView.setImageResource(masterSecret, glideRequests, slide, false, false);
|
||||
}
|
||||
|
||||
thumbnailView.setOnClickListener(new OnMediaClickListener(mediaRecord));
|
||||
|
@ -45,6 +45,7 @@ import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader;
|
||||
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
|
||||
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
@ -204,7 +205,7 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity
|
||||
this.noMedia = ViewUtil.findById(view, R.id.no_images);
|
||||
this.gridManager = new StickyHeaderGridLayoutManager(getResources().getInteger(R.integer.media_overview_cols));
|
||||
|
||||
this.recyclerView.setAdapter(new MediaGalleryAdapter(getContext(), masterSecret, new BucketedThreadMedia(getContext()), locale, recipient.getAddress()));
|
||||
this.recyclerView.setAdapter(new MediaGalleryAdapter(getContext(), masterSecret, GlideApp.with(this), new BucketedThreadMedia(getContext()), locale, recipient.getAddress()));
|
||||
this.recyclerView.setLayoutManager(gridManager);
|
||||
this.recyclerView.setHasFixedSize(true);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -17,7 +17,6 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
@ -36,6 +35,7 @@ import android.widget.Toast;
|
||||
import org.thoughtcrime.securesms.components.ZoomingImageView;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.VideoSlide;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
@ -143,8 +143,8 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
image = (ZoomingImageView) findViewById(R.id.image);
|
||||
video = (VideoPlayer) findViewById(R.id.video_player);
|
||||
image = findViewById(R.id.image);
|
||||
video = findViewById(R.id.video_player);
|
||||
}
|
||||
|
||||
private void initializeResources() {
|
||||
@ -177,7 +177,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
if (mediaType != null && mediaType.startsWith("image/")) {
|
||||
image.setVisibility(View.VISIBLE);
|
||||
video.setVisibility(View.GONE);
|
||||
image.setImageUri(masterSecret, mediaUri, mediaType);
|
||||
image.setImageUri(masterSecret, GlideApp.with(this), mediaUri, mediaType);
|
||||
} else if (mediaType != null && mediaType.startsWith("video/")) {
|
||||
image.setVisibility(View.GONE);
|
||||
video.setVisibility(View.VISIBLE);
|
||||
@ -210,13 +210,10 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
||||
}
|
||||
|
||||
private void saveToDisk() {
|
||||
SaveAttachmentTask.showWarningDialog(this, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
SaveAttachmentTask saveTask = new SaveAttachmentTask(MediaPreviewActivity.this, masterSecret, image);
|
||||
long saveDate = (date > 0) ? date : System.currentTimeMillis();
|
||||
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Attachment(mediaUri, mediaType, saveDate, null));
|
||||
}
|
||||
SaveAttachmentTask.showWarningDialog(this, (dialogInterface, i) -> {
|
||||
SaveAttachmentTask saveTask = new SaveAttachmentTask(MediaPreviewActivity.this, masterSecret, image);
|
||||
long saveDate = (date > 0) ? date : System.currentTimeMillis();
|
||||
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Attachment(mediaUri, mediaType, saveDate, null));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,8 @@ import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.loaders.MessageDetailsLoader;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
@ -78,6 +80,7 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
|
||||
public final static String ADDRESS_EXTRA = "address";
|
||||
|
||||
private MasterSecret masterSecret;
|
||||
private GlideRequests glideRequests;
|
||||
private long threadId;
|
||||
private boolean isPushGroup;
|
||||
private ConversationItem conversationItem;
|
||||
@ -166,6 +169,7 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
|
||||
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
|
||||
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
||||
isPushGroup = getIntent().getBooleanExtra(IS_PUSH_GROUP_EXTRA, false);
|
||||
glideRequests = GlideApp.with(this);
|
||||
itemParent = (ViewGroup) header.findViewById(R.id.item_container);
|
||||
recipientsList = (ListView ) findViewById(R.id.recipients_list);
|
||||
metadataContainer = header.findViewById(R.id.metadata_container);
|
||||
@ -249,9 +253,8 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
|
||||
toFromRes = R.string.message_details_header__from;
|
||||
}
|
||||
toFrom.setText(toFromRes);
|
||||
conversationItem.bind(masterSecret, messageRecord, dynamicLanguage.getCurrentLocale(), new HashSet<>(), recipient);
|
||||
recipientsList.setAdapter(new MessageDetailsRecipientAdapter(this, masterSecret, messageRecord,
|
||||
recipients, isPushGroup));
|
||||
conversationItem.bind(masterSecret, messageRecord, glideRequests, dynamicLanguage.getCurrentLocale(), new HashSet<>(), recipient);
|
||||
recipientsList.setAdapter(new MessageDetailsRecipientAdapter(this, masterSecret, glideRequests, messageRecord, recipients, isPushGroup));
|
||||
}
|
||||
|
||||
private void inflateMessageViewIfAbsent(MessageRecord messageRecord) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -9,6 +10,7 @@ import android.widget.BaseAdapter;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
|
||||
@ -20,18 +22,21 @@ class MessageDetailsRecipientAdapter extends BaseAdapter implements AbsListView.
|
||||
|
||||
private final Context context;
|
||||
private final MasterSecret masterSecret;
|
||||
private final GlideRequests glideRequests;
|
||||
private final MessageRecord record;
|
||||
private final List<RecipientDeliveryStatus> members;
|
||||
private final boolean isPushGroup;
|
||||
|
||||
MessageDetailsRecipientAdapter(Context context, MasterSecret masterSecret, MessageRecord record,
|
||||
List<RecipientDeliveryStatus> members, boolean isPushGroup)
|
||||
MessageDetailsRecipientAdapter(@NonNull Context context, @NonNull MasterSecret masterSecret,
|
||||
@NonNull GlideRequests glideRequests, @NonNull MessageRecord record,
|
||||
@NonNull List<RecipientDeliveryStatus> members, boolean isPushGroup)
|
||||
{
|
||||
this.context = context;
|
||||
this.masterSecret = masterSecret;
|
||||
this.record = record;
|
||||
this.isPushGroup = isPushGroup;
|
||||
this.members = members;
|
||||
this.context = context;
|
||||
this.masterSecret = masterSecret;
|
||||
this.glideRequests = glideRequests;
|
||||
this.record = record;
|
||||
this.isPushGroup = isPushGroup;
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -61,7 +66,7 @@ class MessageDetailsRecipientAdapter extends BaseAdapter implements AbsListView.
|
||||
|
||||
RecipientDeliveryStatus member = members.get(position);
|
||||
|
||||
((MessageRecipientListItem)convertView).set(masterSecret, record, member, isPushGroup);
|
||||
((MessageRecipientListItem)convertView).set(masterSecret, glideRequests, record, member, isPushGroup);
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
@ -51,6 +52,7 @@ public class MessageRecipientListItem extends RelativeLayout
|
||||
private final static String TAG = MessageRecipientListItem.class.getSimpleName();
|
||||
|
||||
private RecipientDeliveryStatus member;
|
||||
private GlideRequests glideRequests;
|
||||
private FromTextView fromView;
|
||||
private TextView errorDescription;
|
||||
private TextView actionDescription;
|
||||
@ -70,25 +72,27 @@ public class MessageRecipientListItem extends RelativeLayout
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
this.fromView = (FromTextView) findViewById(R.id.from);
|
||||
this.errorDescription = (TextView) findViewById(R.id.error_description);
|
||||
this.actionDescription = (TextView) findViewById(R.id.action_description);
|
||||
this.contactPhotoImage = (AvatarImageView) findViewById(R.id.contact_photo_image);
|
||||
this.conflictButton = (Button) findViewById(R.id.conflict_button);
|
||||
this.resendButton = (Button) findViewById(R.id.resend_button);
|
||||
this.deliveryStatusView = (DeliveryStatusView) findViewById(R.id.delivery_status);
|
||||
this.fromView = findViewById(R.id.from);
|
||||
this.errorDescription = findViewById(R.id.error_description);
|
||||
this.actionDescription = findViewById(R.id.action_description);
|
||||
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
|
||||
this.conflictButton = findViewById(R.id.conflict_button);
|
||||
this.resendButton = findViewById(R.id.resend_button);
|
||||
this.deliveryStatusView = findViewById(R.id.delivery_status);
|
||||
}
|
||||
|
||||
public void set(final MasterSecret masterSecret,
|
||||
final GlideRequests glideRequests,
|
||||
final MessageRecord record,
|
||||
final RecipientDeliveryStatus member,
|
||||
final boolean isPushGroup)
|
||||
{
|
||||
this.member = member;
|
||||
this.glideRequests = glideRequests;
|
||||
this.member = member;
|
||||
|
||||
member.getRecipient().addListener(this);
|
||||
fromView.setText(member.getRecipient());
|
||||
contactPhotoImage.setAvatar(member.getRecipient(), false);
|
||||
contactPhotoImage.setAvatar(glideRequests, member.getRecipient(), false);
|
||||
setIssueIndicators(masterSecret, record, isPushGroup);
|
||||
}
|
||||
|
||||
@ -177,7 +181,7 @@ public class MessageRecipientListItem extends RelativeLayout
|
||||
public void onModified(final Recipient recipient) {
|
||||
Util.runOnMain(() -> {
|
||||
fromView.setText(recipient);
|
||||
contactPhotoImage.setAvatar(recipient, false);
|
||||
contactPhotoImage.setAvatar(glideRequests, recipient, false);
|
||||
});
|
||||
}
|
||||
|
||||
@ -187,7 +191,7 @@ public class MessageRecipientListItem extends RelativeLayout
|
||||
private final MessageRecord record;
|
||||
private final NetworkFailure failure;
|
||||
|
||||
public ResendAsyncTask(MasterSecret masterSecret, MessageRecord record, NetworkFailure failure) {
|
||||
ResendAsyncTask(MasterSecret masterSecret, MessageRecord record, NetworkFailure failure) {
|
||||
this.context = getContext().getApplicationContext();
|
||||
this.masterSecret = masterSecret;
|
||||
this.record = record;
|
||||
|
@ -13,7 +13,6 @@ import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
@ -27,7 +26,6 @@ import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@ -35,11 +33,11 @@ import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.color.MaterialColors;
|
||||
import org.thoughtcrime.securesms.components.ThreadPhotoRailView;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
@ -52,9 +50,11 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.preferences.CorrectedPreferenceFragment;
|
||||
import org.thoughtcrime.securesms.preferences.widgets.AdvancedRingtonePreference;
|
||||
import org.thoughtcrime.securesms.preferences.widgets.ColorPickerPreference;
|
||||
import org.thoughtcrime.securesms.preferences.CorrectedPreferenceFragment;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
@ -88,6 +88,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
|
||||
private ImageView avatar;
|
||||
private MasterSecret masterSecret;
|
||||
private GlideRequests glideRequests;
|
||||
private Address address;
|
||||
private TextView threadPhotoRailLabel;
|
||||
private ThreadPhotoRailView threadPhotoRailView;
|
||||
@ -103,8 +104,9 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
@Override
|
||||
public void onCreate(Bundle instanceState, @NonNull MasterSecret masterSecret) {
|
||||
setContentView(R.layout.recipient_preference_activity);
|
||||
this.masterSecret = masterSecret;
|
||||
this.address = getIntent().getParcelableExtra(ADDRESS_EXTRA);
|
||||
this.masterSecret = masterSecret;
|
||||
this.glideRequests = GlideApp.with(this);
|
||||
this.address = getIntent().getParcelableExtra(ADDRESS_EXTRA);
|
||||
|
||||
Recipient recipient = Recipient.from(this, address, true);
|
||||
|
||||
@ -208,39 +210,17 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
}
|
||||
|
||||
private void setHeader(@NonNull Recipient recipient) {
|
||||
new AsyncTask<Void, Void, ContactPhoto>() {
|
||||
@Override
|
||||
protected @NonNull ContactPhoto doInBackground(Void... params) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
WindowManager windowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
|
||||
Uri contentUri = ContactsContract.Contacts.lookupContact(getContentResolver(), recipient.getContactUri());
|
||||
windowManager.getDefaultDisplay().getMetrics(metrics);
|
||||
glideRequests.load(recipient.getContactPhoto())
|
||||
.fallback(recipient.getFallbackContactPhoto().asCallCard(this))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.into(this.avatar);
|
||||
|
||||
if (recipient.isGroupRecipient()) {
|
||||
Optional<GroupDatabase.GroupRecord> groupRecord = DatabaseFactory.getGroupDatabase(RecipientPreferenceActivity.this).getGroup(recipient.getAddress().toGroupString());
|
||||
if (recipient.getContactPhoto() == null) this.avatar.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
else this.avatar.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
|
||||
if (groupRecord.isPresent() && groupRecord.get().getAvatar() != null) {
|
||||
return ContactPhotoFactory.getGroupContactPhoto(groupRecord.get().getAvatar());
|
||||
} else {
|
||||
return ContactPhotoFactory.getDefaultGroupPhoto();
|
||||
}
|
||||
} else {
|
||||
return ContactPhotoFactory.getContactPhoto(RecipientPreferenceActivity.this, contentUri,
|
||||
recipient.getAddress(), recipient.getName(),
|
||||
metrics.widthPixels);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onPostExecute(@NonNull ContactPhoto contactPhoto) {
|
||||
if (contactPhoto.isGenerated() || contactPhoto.isResource()) avatar.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
else avatar.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
|
||||
avatar.setImageDrawable(contactPhoto.asCallCard(RecipientPreferenceActivity.this));
|
||||
avatar.setBackgroundColor(recipient.getColor().toActionBarColor(RecipientPreferenceActivity.this));
|
||||
toolbarLayout.setTitle(recipient.toShortString());
|
||||
toolbarLayout.setContentScrimColor(recipient.getColor().toActionBarColor(RecipientPreferenceActivity.this));
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
this.avatar.setBackgroundColor(recipient.getColor().toActionBarColor(this));
|
||||
this.toolbarLayout.setTitle(recipient.toShortString());
|
||||
this.toolbarLayout.setContentScrimColor(recipient.getColor().toActionBarColor(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -263,7 +243,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
this.threadPhotoRailView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
this.threadPhotoRailView.setCursor(data, masterSecret);
|
||||
this.threadPhotoRailView.setCursor(masterSecret, glideRequests, data);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(ADDRESS_EXTRA, address);
|
||||
@ -272,7 +252,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
this.threadPhotoRailView.setCursor(null, masterSecret);
|
||||
this.threadPhotoRailView.setCursor(masterSecret, glideRequests, null);
|
||||
}
|
||||
|
||||
public static class RecipientPreferenceFragment
|
||||
@ -325,9 +305,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
}
|
||||
|
||||
private void initializeRecipients() {
|
||||
this.recipient = Recipient.from(getActivity(),
|
||||
(Address)getArguments().getParcelable(ADDRESS_EXTRA),
|
||||
true);
|
||||
this.recipient = Recipient.from(getActivity(), getArguments().getParcelable(ADDRESS_EXTRA), true);
|
||||
|
||||
this.recipient.addListener(this);
|
||||
|
||||
@ -335,7 +313,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
recipient.removeListener(RecipientPreferenceFragment.this);
|
||||
recipient = Recipient.from(getActivity(), (Address)getArguments().getParcelable(ADDRESS_EXTRA), true);
|
||||
recipient = Recipient.from(getActivity(), getArguments().getParcelable(ADDRESS_EXTRA), true);
|
||||
onModified(recipient);
|
||||
}
|
||||
};
|
||||
@ -508,12 +486,7 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
||||
}
|
||||
|
||||
private void handleMute() {
|
||||
MuteDialog.show(getActivity(), new MuteDialog.MuteSelectionListener() {
|
||||
@Override
|
||||
public void onMuted(long until) {
|
||||
setMuted(recipient, until);
|
||||
}
|
||||
});
|
||||
MuteDialog.show(getActivity(), until -> setMuted(recipient, until));
|
||||
|
||||
setSummaries(recipient);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -30,6 +30,7 @@ import android.widget.ListView;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.loaders.ConversationListLoader;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
/**
|
||||
@ -78,7 +79,7 @@ public class ShareFragment extends ListFragment implements LoaderManager.LoaderC
|
||||
}
|
||||
|
||||
private void initializeListAdapter() {
|
||||
this.setListAdapter(new ShareListAdapter(getActivity(), null, masterSecret));
|
||||
this.setListAdapter(new ShareListAdapter(getActivity(), masterSecret, GlideApp.with(this), null));
|
||||
getListView().setRecyclerListener((ShareListAdapter) getListAdapter());
|
||||
getLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -18,37 +18,42 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
|
||||
/**
|
||||
* A CursorAdapter for building a list of open conversations
|
||||
*
|
||||
* @author Jake McGinty
|
||||
*/
|
||||
public class ShareListAdapter extends CursorAdapter implements AbsListView.RecyclerListener {
|
||||
class ShareListAdapter extends CursorAdapter implements AbsListView.RecyclerListener {
|
||||
|
||||
private final ThreadDatabase threadDatabase;
|
||||
private final GlideRequests glideRequests;
|
||||
private final MasterCipher masterCipher;
|
||||
private final Context context;
|
||||
private final LayoutInflater inflater;
|
||||
|
||||
public ShareListAdapter(Context context, Cursor cursor, MasterSecret masterSecret) {
|
||||
ShareListAdapter(@NonNull Context context, @Nullable MasterSecret masterSecret,
|
||||
@NonNull GlideRequests glideRequests, @Nullable Cursor cursor)
|
||||
{
|
||||
super(context, cursor, 0);
|
||||
|
||||
if (masterSecret != null) this.masterCipher = new MasterCipher(masterSecret);
|
||||
else this.masterCipher = null;
|
||||
|
||||
this.context = context;
|
||||
this.glideRequests = glideRequests;
|
||||
this.threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
}
|
||||
@ -64,7 +69,7 @@ public class ShareListAdapter extends CursorAdapter implements AbsListView.Recyc
|
||||
ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor, masterCipher);
|
||||
ThreadRecord record = reader.getCurrent();
|
||||
|
||||
((ShareListItem)view).set(record);
|
||||
((ShareListItem)view).set(glideRequests, record);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -18,13 +18,14 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.FromTextView;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@ -39,10 +40,11 @@ public class ShareListItem extends RelativeLayout
|
||||
{
|
||||
private final static String TAG = ShareListItem.class.getSimpleName();
|
||||
|
||||
private Context context;
|
||||
private Recipient recipient;
|
||||
private long threadId;
|
||||
private FromTextView fromView;
|
||||
private Context context;
|
||||
private GlideRequests glideRequests;
|
||||
private Recipient recipient;
|
||||
private long threadId;
|
||||
private FromTextView fromView;
|
||||
|
||||
private AvatarImageView contactPhotoImage;
|
||||
|
||||
@ -61,11 +63,12 @@ public class ShareListItem extends RelativeLayout
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
this.fromView = (FromTextView) findViewById(R.id.from);
|
||||
this.contactPhotoImage = (AvatarImageView) findViewById(R.id.contact_photo_image);
|
||||
this.fromView = findViewById(R.id.from);
|
||||
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
|
||||
}
|
||||
|
||||
public void set(ThreadRecord thread) {
|
||||
public void set(@NonNull GlideRequests glideRequests, @NonNull ThreadRecord thread) {
|
||||
this.glideRequests = glideRequests;
|
||||
this.recipient = thread.getRecipient();
|
||||
this.threadId = thread.getThreadId();
|
||||
this.distributionType = thread.getDistributionType();
|
||||
@ -74,7 +77,7 @@ public class ShareListItem extends RelativeLayout
|
||||
this.fromView.setText(recipient);
|
||||
|
||||
setBackground();
|
||||
this.contactPhotoImage.setAvatar(this.recipient, false);
|
||||
this.contactPhotoImage.setAvatar(glideRequests, this.recipient, false);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
@ -106,7 +109,7 @@ public class ShareListItem extends RelativeLayout
|
||||
public void onModified(final Recipient recipient) {
|
||||
Util.runOnMain(() -> {
|
||||
fromView.setText(recipient);
|
||||
contactPhotoImage.setAvatar(recipient, false);
|
||||
contactPhotoImage.setAvatar(glideRequests, recipient, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,19 +4,21 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
public class AvatarImageView extends ImageView {
|
||||
public class AvatarImageView extends AppCompatImageView {
|
||||
|
||||
private static final String TAG = AvatarImageView.class.getSimpleName();
|
||||
|
||||
@ -45,17 +47,24 @@ public class AvatarImageView extends ImageView {
|
||||
super.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
public void setAvatar(final @Nullable Recipient recipient, boolean quickContactEnabled) {
|
||||
public void setAvatar(@NonNull GlideRequests requestManager, @Nullable Recipient recipient, boolean quickContactEnabled) {
|
||||
if (recipient != null) {
|
||||
MaterialColor backgroundColor = recipient.getColor();
|
||||
setImageDrawable(recipient.getContactPhoto().asDrawable(getContext(), backgroundColor.toConversationColor(getContext()), inverted));
|
||||
requestManager.load(recipient.getContactPhoto())
|
||||
.fallback(recipient.getFallbackContactPhotoDrawable(getContext(), inverted))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.circleCrop()
|
||||
.into(this);
|
||||
setAvatarClickHandler(recipient, quickContactEnabled);
|
||||
} else {
|
||||
setImageDrawable(ContactPhotoFactory.getDefaultContactPhoto(null).asDrawable(getContext(), ContactColors.UNKNOWN_COLOR.toConversationColor(getContext()), inverted));
|
||||
setImageDrawable(new GeneratedContactPhoto("#").asDrawable(getContext(), ContactColors.UNKNOWN_COLOR.toConversationColor(getContext()), inverted));
|
||||
super.setOnClickListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear(@NonNull GlideRequests glideRequests) {
|
||||
glideRequests.clear(this);
|
||||
}
|
||||
|
||||
private void setAvatarClickHandler(final Recipient recipient, boolean quickContactEnabled) {
|
||||
if (!recipient.isGroupRecipient() && quickContactEnabled) {
|
||||
super.setOnClickListener(v -> {
|
||||
@ -76,4 +85,5 @@ public class AvatarImageView extends ImageView {
|
||||
super.setOnClickListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo
|
||||
|
||||
Key signature = new MediaStoreSignature(mimeType, dateModified, orientation);
|
||||
|
||||
GlideApp.with(getContext())
|
||||
GlideApp.with(getContext().getApplicationContext())
|
||||
.load(uri)
|
||||
.signature(signature)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
|
@ -3,11 +3,8 @@ package org.thoughtcrime.securesms.components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
@ -19,19 +16,15 @@ import android.widget.FrameLayout;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||
import org.thoughtcrime.securesms.database.MediaDatabase;
|
||||
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
public class ThreadPhotoRailView extends FrameLayout {
|
||||
|
||||
public static final String ADDRESS_EXTRA = "address";
|
||||
public static final String MASTER_SECRET_EXTRA = "master_secret";
|
||||
|
||||
@NonNull private final RecyclerView recyclerView;
|
||||
@Nullable private OnItemClickedListener listener;
|
||||
|
||||
@ -62,25 +55,28 @@ public class ThreadPhotoRailView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
public void setCursor(@Nullable Cursor cursor, @NonNull MasterSecret masterSecret) {
|
||||
this.recyclerView.setAdapter(new ThreadPhotoRailAdapter(getContext(), masterSecret, cursor, this.listener));
|
||||
public void setCursor(@NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests, @Nullable Cursor cursor) {
|
||||
this.recyclerView.setAdapter(new ThreadPhotoRailAdapter(getContext(), masterSecret, glideRequests, cursor, this.listener));
|
||||
}
|
||||
|
||||
private static class ThreadPhotoRailAdapter extends CursorRecyclerViewAdapter<ThreadPhotoRailAdapter.ThreadPhotoViewHolder> {
|
||||
|
||||
private static final String TAG = ThreadPhotoRailAdapter.class.getName();
|
||||
|
||||
private final MasterSecret masterSecret;
|
||||
@NonNull private final MasterSecret masterSecret;
|
||||
@NonNull private final GlideRequests glideRequests;
|
||||
|
||||
@Nullable private OnItemClickedListener clickedListener;
|
||||
|
||||
private ThreadPhotoRailAdapter(@NonNull Context context,
|
||||
@NonNull MasterSecret masterSecret,
|
||||
@NonNull Cursor cursor,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@Nullable Cursor cursor,
|
||||
@Nullable OnItemClickedListener listener)
|
||||
{
|
||||
super(context, cursor);
|
||||
this.masterSecret = masterSecret;
|
||||
this.glideRequests = glideRequests;
|
||||
this.clickedListener = listener;
|
||||
}
|
||||
|
||||
@ -99,7 +95,7 @@ public class ThreadPhotoRailView extends FrameLayout {
|
||||
Slide slide = MediaUtil.getSlideForAttachment(getContext(), mediaRecord.getAttachment());
|
||||
|
||||
if (slide != null) {
|
||||
imageView.setImageResource(masterSecret, slide, false, false);
|
||||
imageView.setImageResource(masterSecret, glideRequests, slide, false, false);
|
||||
}
|
||||
|
||||
imageView.setOnClickListener(v -> {
|
||||
|
@ -1,13 +1,9 @@
|
||||
package org.thoughtcrime.securesms.components;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@ -15,7 +11,6 @@ import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.RequestBuilder;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
@ -25,7 +20,7 @@ import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.SlideClickListener;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@ -102,7 +97,9 @@ public class ThumbnailView extends FrameLayout {
|
||||
this.backgroundColorHint = color;
|
||||
}
|
||||
|
||||
public void setImageResource(@NonNull MasterSecret masterSecret, @NonNull Slide slide, boolean showControls, boolean isPreview) {
|
||||
public void setImageResource(@NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests,
|
||||
@NonNull Slide slide, boolean showControls, boolean isPreview)
|
||||
{
|
||||
if (showControls) {
|
||||
getTransferControls().setSlide(slide);
|
||||
getTransferControls().setDownloadClickListener(new DownloadClickDispatcher());
|
||||
@ -131,31 +128,25 @@ public class ThumbnailView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isContextValid()) {
|
||||
Log.w(TAG, "Not loading slide, context is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.w(TAG, "loading part with id " + slide.asAttachment().getDataUri()
|
||||
+ ", progress " + slide.getTransferState() + ", fast preflight id: " +
|
||||
slide.asAttachment().getFastPreflightId());
|
||||
|
||||
this.slide = slide;
|
||||
|
||||
if (slide.getThumbnailUri() != null) buildThumbnailGlideRequest(slide, masterSecret).into(image);
|
||||
else if (slide.hasPlaceholder()) buildPlaceholderGlideRequest(slide).into(image);
|
||||
else Glide.with(getContext()).clear(image);
|
||||
if (slide.getThumbnailUri() != null) buildThumbnailGlideRequest(masterSecret, glideRequests, slide).into(image);
|
||||
else if (slide.hasPlaceholder()) buildPlaceholderGlideRequest(glideRequests, slide).into(image);
|
||||
else glideRequests.clear(image);
|
||||
}
|
||||
|
||||
public void setImageResource(@NonNull MasterSecret masterSecret, @NonNull Uri uri) {
|
||||
public void setImageResource(@NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests, @NonNull Uri uri) {
|
||||
if (transferControls.isPresent()) getTransferControls().setVisibility(View.GONE);
|
||||
|
||||
GlideApp.with(getContext())
|
||||
.load(new DecryptableUri(masterSecret, uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.transform(new RoundedCorners(radius))
|
||||
.transition(withCrossFade())
|
||||
.into(image);
|
||||
glideRequests.load(new DecryptableUri(masterSecret, uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.transform(new RoundedCorners(radius))
|
||||
.transition(withCrossFade())
|
||||
.into(image);
|
||||
}
|
||||
|
||||
public void setThumbnailClickListener(SlideClickListener listener) {
|
||||
@ -166,9 +157,12 @@ public class ThumbnailView extends FrameLayout {
|
||||
this.downloadClickListener = listener;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (isContextValid()) Glide.with(getContext()).clear(image);
|
||||
if (transferControls.isPresent()) getTransferControls().clear();
|
||||
public void clear(GlideRequests glideRequests) {
|
||||
glideRequests.clear(image);
|
||||
|
||||
if (transferControls.isPresent()) {
|
||||
getTransferControls().clear();
|
||||
}
|
||||
|
||||
slide = null;
|
||||
}
|
||||
@ -177,30 +171,21 @@ public class ThumbnailView extends FrameLayout {
|
||||
getTransferControls().showProgressSpinner();
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.JELLY_BEAN_MR1)
|
||||
private boolean isContextValid() {
|
||||
return !(getContext() instanceof Activity) ||
|
||||
VERSION.SDK_INT < VERSION_CODES.JELLY_BEAN_MR1 ||
|
||||
!((Activity)getContext()).isDestroyed();
|
||||
}
|
||||
|
||||
private RequestBuilder buildThumbnailGlideRequest(@NonNull Slide slide, @NonNull MasterSecret masterSecret) {
|
||||
RequestBuilder builder = GlideApp.with(getContext())
|
||||
.load(new DecryptableUri(masterSecret, slide.getThumbnailUri()))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.transform(new RoundedCorners(radius))
|
||||
.transition(withCrossFade());
|
||||
private RequestBuilder buildThumbnailGlideRequest(@NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests, @NonNull Slide slide) {
|
||||
RequestBuilder builder = glideRequests.load(new DecryptableUri(masterSecret, slide.getThumbnailUri()))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.transform(new RoundedCorners(radius))
|
||||
.transition(withCrossFade());
|
||||
|
||||
if (slide.isInProgress()) return builder;
|
||||
else return builder.apply(RequestOptions.errorOf(R.drawable.ic_missing_thumbnail_picture));
|
||||
}
|
||||
|
||||
private RequestBuilder buildPlaceholderGlideRequest(Slide slide) {
|
||||
return GlideApp.with(getContext())
|
||||
.asBitmap()
|
||||
.load(slide.getPlaceholderRes(getContext().getTheme()))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.fitCenter();
|
||||
private RequestBuilder buildPlaceholderGlideRequest(@NonNull GlideRequests glideRequests, @NonNull Slide slide) {
|
||||
return glideRequests.asBitmap()
|
||||
.load(slide.getPlaceholderRes(getContext().getTheme()))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.fitCenter();
|
||||
}
|
||||
|
||||
private class ThumbnailClickDispatcher implements View.OnClickListener {
|
||||
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.components;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@ -21,7 +22,7 @@ import org.thoughtcrime.securesms.components.subsampling.AttachmentBitmapDecoder
|
||||
import org.thoughtcrime.securesms.components.subsampling.AttachmentRegionDecoder;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
@ -59,7 +60,9 @@ public class ZoomingImageView extends FrameLayout {
|
||||
this.subsamplingImageView.setOrientation(SubsamplingScaleImageView.ORIENTATION_USE_EXIF);
|
||||
}
|
||||
|
||||
public void setImageUri(final MasterSecret masterSecret, final Uri uri, final String contentType) {
|
||||
public void setImageUri(@NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests,
|
||||
@NonNull Uri uri, @NonNull String contentType)
|
||||
{
|
||||
final Context context = getContext();
|
||||
final int maxTextureSize = BitmapUtil.getMaxTextureSize();
|
||||
|
||||
@ -84,7 +87,7 @@ public class ZoomingImageView extends FrameLayout {
|
||||
|
||||
if (dimensions == null || (dimensions.first <= maxTextureSize && dimensions.second <= maxTextureSize)) {
|
||||
Log.w(TAG, "Loading in standard image view...");
|
||||
setImageViewUri(masterSecret, uri);
|
||||
setImageViewUri(masterSecret, glideRequests, uri);
|
||||
} else {
|
||||
Log.w(TAG, "Loading in subsampling image view...");
|
||||
setSubsamplingImageViewUri(uri);
|
||||
@ -93,19 +96,18 @@ public class ZoomingImageView extends FrameLayout {
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void setImageViewUri(MasterSecret masterSecret, Uri uri) {
|
||||
private void setImageViewUri(@NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests, @NonNull Uri uri) {
|
||||
photoView.setVisibility(View.VISIBLE);
|
||||
subsamplingImageView.setVisibility(View.GONE);
|
||||
|
||||
GlideApp.with(getContext())
|
||||
.load(new DecryptableUri(masterSecret, uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontTransform()
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.into(photoView);
|
||||
glideRequests.load(new DecryptableUri(masterSecret, uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontTransform()
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.into(photoView);
|
||||
}
|
||||
|
||||
private void setSubsamplingImageViewUri(Uri uri) {
|
||||
private void setSubsamplingImageViewUri(@NonNull Uri uri) {
|
||||
subsamplingImageView.setVisibility(View.VISIBLE);
|
||||
photoView.setVisibility(View.GONE);
|
||||
|
||||
|
@ -18,9 +18,6 @@
|
||||
package org.thoughtcrime.securesms.components.webrtc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
@ -30,20 +27,19 @@ import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.service.WebRtcCallService;
|
||||
@ -285,24 +281,11 @@ public class WebRtcCallScreen extends FrameLayout implements RecipientModifiedLi
|
||||
this.recipient = recipient;
|
||||
this.recipient.addListener(this);
|
||||
|
||||
final Context context = getContext();
|
||||
|
||||
new AsyncTask<Void, Void, ContactPhoto>() {
|
||||
@Override
|
||||
protected ContactPhoto doInBackground(Void... params) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Uri contentUri = ContactsContract.Contacts.lookupContact(context.getContentResolver(),
|
||||
recipient.getContactUri());
|
||||
windowManager.getDefaultDisplay().getMetrics(metrics);
|
||||
return ContactPhotoFactory.getContactPhoto(context, contentUri, recipient.getAddress(), null, metrics.widthPixels);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final ContactPhoto contactPhoto) {
|
||||
WebRtcCallScreen.this.photo.setImageDrawable(contactPhoto.asCallCard(context));
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
GlideApp.with(getContext().getApplicationContext())
|
||||
.load(recipient.getContactPhoto())
|
||||
.fallback(recipient.getFallbackContactPhoto().asCallCard(getContext()))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.into(this.photo);
|
||||
|
||||
this.name.setText(recipient.getName());
|
||||
|
||||
|
@ -29,16 +29,17 @@ import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.RecyclerViewFastScroller.FastScrollAdapter;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration.StickyHeaderAdapter;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter.HeaderViewHolder;
|
||||
import org.thoughtcrime.securesms.contacts.ContactSelectionListAdapter.ViewHolder;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration.StickyHeaderAdapter;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -62,6 +63,7 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
|
||||
private final LayoutInflater li;
|
||||
private final TypedArray drawables;
|
||||
private final ItemClickListener clickListener;
|
||||
private final GlideRequests glideRequests;
|
||||
|
||||
private final HashMap<Long, String> selectedContacts = new HashMap<>();
|
||||
|
||||
@ -70,11 +72,8 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
|
||||
@Nullable final ItemClickListener clickListener)
|
||||
{
|
||||
super(itemView);
|
||||
itemView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (clickListener != null) clickListener.onItemClick(getView());
|
||||
}
|
||||
itemView.setOnClickListener(v -> {
|
||||
if (clickListener != null) clickListener.onItemClick(getView());
|
||||
});
|
||||
}
|
||||
|
||||
@ -90,14 +89,16 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
|
||||
}
|
||||
|
||||
public ContactSelectionListAdapter(@NonNull Context context,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@Nullable Cursor cursor,
|
||||
@Nullable ItemClickListener clickListener,
|
||||
boolean multiSelect)
|
||||
{
|
||||
super(context, cursor);
|
||||
this.li = LayoutInflater.from(context);
|
||||
this.drawables = context.obtainStyledAttributes(STYLE_ATTRIBUTES);
|
||||
this.multiSelect = multiSelect;
|
||||
this.li = LayoutInflater.from(context);
|
||||
this.glideRequests = glideRequests;
|
||||
this.drawables = context.obtainStyledAttributes(STYLE_ATTRIBUTES);
|
||||
this.multiSelect = multiSelect;
|
||||
this.clickListener = clickListener;
|
||||
}
|
||||
|
||||
@ -127,8 +128,8 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
|
||||
int color = (contactType == ContactsDatabase.PUSH_TYPE) ? drawables.getColor(0, 0xa0000000) :
|
||||
drawables.getColor(1, 0xff000000);
|
||||
|
||||
viewHolder.getView().unbind();
|
||||
viewHolder.getView().set(id, contactType, name, number, labelText, color, multiSelect);
|
||||
viewHolder.getView().unbind(glideRequests);
|
||||
viewHolder.getView().set(glideRequests, id, contactType, name, number, labelText, color, multiSelect);
|
||||
viewHolder.getView().setChecked(selectedContacts.containsKey(id));
|
||||
}
|
||||
|
||||
@ -142,6 +143,11 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
|
||||
((TextView)viewHolder.itemView).setText(getSpannedHeaderString(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemViewRecycled(ViewHolder holder) {
|
||||
holder.getView().unbind(glideRequests);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getBubbleText(int position) {
|
||||
return getHeaderString(position);
|
||||
|
@ -1,9 +1,9 @@
|
||||
package org.thoughtcrime.securesms.contacts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
@ -12,6 +12,8 @@ import android.widget.TextView;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequest;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@ -27,9 +29,10 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientM
|
||||
private TextView labelView;
|
||||
private CheckBox checkBox;
|
||||
|
||||
private long id;
|
||||
private String number;
|
||||
private Recipient recipient;
|
||||
private long id;
|
||||
private String number;
|
||||
private Recipient recipient;
|
||||
private GlideRequests glideRequests;
|
||||
|
||||
public ContactSelectionListItem(Context context) {
|
||||
super(context);
|
||||
@ -42,22 +45,23 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientM
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
this.contactPhotoImage = (AvatarImageView) findViewById(R.id.contact_photo_image);
|
||||
this.numberView = (TextView) findViewById(R.id.number);
|
||||
this.labelView = (TextView) findViewById(R.id.label);
|
||||
this.nameView = (TextView) findViewById(R.id.name);
|
||||
this.checkBox = (CheckBox) findViewById(R.id.check_box);
|
||||
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
|
||||
this.numberView = findViewById(R.id.number);
|
||||
this.labelView = findViewById(R.id.label);
|
||||
this.nameView = findViewById(R.id.name);
|
||||
this.checkBox = findViewById(R.id.check_box);
|
||||
|
||||
ViewUtil.setTextViewGravityStart(this.nameView, getContext());
|
||||
}
|
||||
|
||||
public void set(long id, int type, String name, String number, String label, int color, boolean multiSelect) {
|
||||
this.id = id;
|
||||
this.number = number;
|
||||
public void set(@NonNull GlideRequests glideRequests, long id, int type, String name, String number, String label, int color, boolean multiSelect) {
|
||||
this.glideRequests = glideRequests;
|
||||
this.id = id;
|
||||
this.number = number;
|
||||
|
||||
if (type == ContactsDatabase.NEW_TYPE) {
|
||||
this.recipient = null;
|
||||
this.contactPhotoImage.setAvatar(Recipient.from(getContext(), Address.UNKNOWN, true), false);
|
||||
this.contactPhotoImage.setAvatar(glideRequests, Recipient.from(getContext(), Address.UNKNOWN, true), false);
|
||||
} else if (!TextUtils.isEmpty(number)) {
|
||||
Address address = Address.fromExternal(getContext(), number);
|
||||
this.recipient = Recipient.from(getContext(), address, true);
|
||||
@ -70,7 +74,7 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientM
|
||||
|
||||
this.nameView.setTextColor(color);
|
||||
this.numberView.setTextColor(color);
|
||||
this.contactPhotoImage.setAvatar(recipient, false);
|
||||
this.contactPhotoImage.setAvatar(glideRequests, recipient, false);
|
||||
|
||||
setText(type, name, number, label);
|
||||
|
||||
@ -82,11 +86,13 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientM
|
||||
this.checkBox.setChecked(selected);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
public void unbind(GlideRequests glideRequests) {
|
||||
if (recipient != null) {
|
||||
recipient.removeListener(this);
|
||||
recipient = null;
|
||||
}
|
||||
|
||||
contactPhotoImage.clear(glideRequests);
|
||||
}
|
||||
|
||||
private void setText(int type, String name, String number, String label) {
|
||||
@ -120,7 +126,7 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientM
|
||||
public void onModified(final Recipient recipient) {
|
||||
if (this.recipient == recipient) {
|
||||
Util.runOnMain(() -> {
|
||||
contactPhotoImage.setAvatar(recipient, false);
|
||||
contactPhotoImage.setAvatar(glideRequests, recipient, false);
|
||||
nameView.setText(recipient.toShortString());
|
||||
});
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.makeramen.roundedimageview.RoundedDrawable;
|
||||
|
||||
public class BitmapContactPhoto implements ContactPhoto {
|
||||
|
||||
private final Bitmap bitmap;
|
||||
|
||||
BitmapContactPhoto(Bitmap bitmap) {
|
||||
this.bitmap = bitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable asDrawable(Context context, int color) {
|
||||
return asDrawable(context, color, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable asDrawable(Context context, int color, boolean inverted) {
|
||||
return RoundedDrawable.fromBitmap(bitmap)
|
||||
.setScaleType(ImageView.ScaleType.CENTER_CROP)
|
||||
.setOval(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable asCallCard(Context context) {
|
||||
return new BitmapDrawable(context.getResources(), bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGenerated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResource() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public interface ContactPhoto {
|
||||
|
||||
public Drawable asDrawable(Context context, int color);
|
||||
public Drawable asDrawable(Context context, int color, boolean inverted);
|
||||
public Drawable asCallCard(Context context);
|
||||
public boolean isGenerated();
|
||||
public boolean isResource();
|
||||
import com.bumptech.glide.load.Key;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface ContactPhoto extends Key {
|
||||
|
||||
InputStream openInputStream(Context context) throws IOException;
|
||||
|
||||
}
|
||||
|
@ -1,108 +0,0 @@
|
||||
package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.WorkerThread;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.mms.ContactPhotoUriLoader.ContactPhotoUri;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarPhotoUriLoader.AvatarPhotoUri;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class ContactPhotoFactory {
|
||||
|
||||
private static final String TAG = ContactPhotoFactory.class.getSimpleName();
|
||||
|
||||
public static ContactPhoto getLoadingPhoto() {
|
||||
return new TransparentContactPhoto();
|
||||
}
|
||||
|
||||
public static ContactPhoto getDefaultContactPhoto(@Nullable String name) {
|
||||
if (!TextUtils.isEmpty(name)) return new GeneratedContactPhoto(name);
|
||||
else return new GeneratedContactPhoto("#");
|
||||
}
|
||||
|
||||
public static ContactPhoto getResourceContactPhoto(@DrawableRes int resourceId) {
|
||||
return new ResourceContactPhoto(resourceId);
|
||||
}
|
||||
|
||||
public static ContactPhoto getDefaultGroupPhoto() {
|
||||
return new ResourceContactPhoto(R.drawable.ic_group_white_24dp, R.drawable.ic_group_large);
|
||||
}
|
||||
|
||||
public static ContactPhoto getContactPhoto(@NonNull Context context, @Nullable Uri uri, @NonNull Address address, @Nullable String name) {
|
||||
int targetSize = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size);
|
||||
return getContactPhoto(context, uri, address, name, targetSize);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static ContactPhoto getContactPhoto(@NonNull Context context,
|
||||
@Nullable Uri uri,
|
||||
@NonNull Address address,
|
||||
@Nullable String name,
|
||||
int targetSize)
|
||||
{
|
||||
if (uri == null) return getSignalAvatarContactPhoto(context, address, name, targetSize);
|
||||
|
||||
try {
|
||||
Bitmap bitmap = GlideApp.with(context)
|
||||
.asBitmap()
|
||||
.load(new ContactPhotoUri(uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.centerCrop()
|
||||
.submit(targetSize, targetSize)
|
||||
.get();
|
||||
return new BitmapContactPhoto(bitmap);
|
||||
} catch (ExecutionException e) {
|
||||
return getSignalAvatarContactPhoto(context, address, name, targetSize);
|
||||
} catch (InterruptedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ContactPhoto getGroupContactPhoto(@Nullable byte[] avatar) {
|
||||
if (avatar == null) return getDefaultGroupPhoto();
|
||||
|
||||
return new BitmapContactPhoto(BitmapFactory.decodeByteArray(avatar, 0, avatar.length));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static ContactPhoto getSignalAvatarContactPhoto(@NonNull Context context,
|
||||
@NonNull Address address,
|
||||
@Nullable String name,
|
||||
int targetSize)
|
||||
{
|
||||
try {
|
||||
Bitmap bitmap = GlideApp.with(context)
|
||||
.asBitmap()
|
||||
.load(new AvatarPhotoUri(address))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.centerCrop()
|
||||
.submit(targetSize, targetSize)
|
||||
.get();
|
||||
|
||||
return new BitmapContactPhoto(bitmap);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.w(TAG, e);
|
||||
// XXX This is a temporary fix for #7016 until we upgrade to Glide 4 as a next step
|
||||
return getDefaultContactPhoto(name);
|
||||
} catch (ExecutionException e) {
|
||||
return getDefaultContactPhoto(name);
|
||||
} catch (InterruptedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public interface FallbackContactPhoto {
|
||||
|
||||
public Drawable asDrawable(Context context, int color);
|
||||
public Drawable asDrawable(Context context, int color, boolean inverted);
|
||||
public Drawable asCallCard(Context context);
|
||||
|
||||
}
|
@ -11,11 +11,15 @@ import com.amulyakhare.textdrawable.TextDrawable;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public class GeneratedContactPhoto implements ContactPhoto {
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class GeneratedContactPhoto implements FallbackContactPhoto {
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("[^\\p{L}\\p{Nd}\\p{P}\\p{S}]+");
|
||||
|
||||
private final String name;
|
||||
|
||||
GeneratedContactPhoto(@NonNull String name) {
|
||||
public GeneratedContactPhoto(@NonNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ -38,7 +42,7 @@ public class GeneratedContactPhoto implements ContactPhoto {
|
||||
}
|
||||
|
||||
private String getCharacter(String name) {
|
||||
String cleanedName = name.replaceFirst("[^\\p{L}\\p{Nd}\\p{P}\\p{S}]+", "");
|
||||
String cleanedName = PATTERN.matcher(name).replaceFirst("");
|
||||
|
||||
if (cleanedName.isEmpty()) {
|
||||
return "#";
|
||||
@ -52,14 +56,4 @@ public class GeneratedContactPhoto implements ContactPhoto {
|
||||
return AppCompatResources.getDrawable(context, R.drawable.ic_person_large);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGenerated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResource() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class GroupRecordContactPhoto implements ContactPhoto {
|
||||
|
||||
private final @NonNull Address address;
|
||||
private final long avatarId;
|
||||
|
||||
public GroupRecordContactPhoto(@NonNull Address address, long avatarId) {
|
||||
this.address = address;
|
||||
this.avatarId = avatarId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream(Context context) throws IOException {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
Optional<GroupDatabase.GroupRecord> groupRecord = groupDatabase.getGroup(address.toGroupString());
|
||||
|
||||
if (groupRecord.isPresent() && groupRecord.get().getAvatar() != null) {
|
||||
return new ByteArrayInputStream(groupRecord.get().getAvatar());
|
||||
}
|
||||
|
||||
throw new IOException("Couldn't load avatar for group: " + address.toGroupString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(MessageDigest messageDigest) {
|
||||
messageDigest.update(address.serialize().getBytes());
|
||||
messageDigest.update(Conversions.longToByteArray(avatarId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof GroupRecordContactPhoto)) return false;
|
||||
|
||||
GroupRecordContactPhoto that = (GroupRecordContactPhoto)other;
|
||||
return this.address.equals(that.address) && this.avatarId == that.avatarId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.address.hashCode() ^ (int) avatarId;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class ProfileContactPhoto implements ContactPhoto {
|
||||
|
||||
private final @NonNull Address address;
|
||||
private final @NonNull String avatarObject;
|
||||
|
||||
public ProfileContactPhoto(@NonNull Address address, @NonNull String avatarObject) {
|
||||
this.address = address;
|
||||
this.avatarObject = avatarObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream(Context context) throws IOException {
|
||||
return AvatarHelper.getInputStreamFor(context, address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(MessageDigest messageDigest) {
|
||||
messageDigest.update(address.serialize().getBytes());
|
||||
messageDigest.update(avatarObject.getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof ProfileContactPhoto)) return false;
|
||||
|
||||
ProfileContactPhoto that = (ProfileContactPhoto)other;
|
||||
|
||||
return this.address.equals(that.address) && this.avatarObject.equals(that.avatarObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode() ^ avatarObject.hashCode();
|
||||
}
|
||||
}
|
@ -12,16 +12,16 @@ import android.widget.ImageView;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.makeramen.roundedimageview.RoundedDrawable;
|
||||
|
||||
public class ResourceContactPhoto implements ContactPhoto {
|
||||
public class ResourceContactPhoto implements FallbackContactPhoto {
|
||||
|
||||
private final int resourceId;
|
||||
private final int callCardResourceId;
|
||||
|
||||
ResourceContactPhoto(@DrawableRes int resourceId) {
|
||||
public ResourceContactPhoto(@DrawableRes int resourceId) {
|
||||
this(resourceId, resourceId);
|
||||
}
|
||||
|
||||
ResourceContactPhoto(@DrawableRes int resourceId, @DrawableRes int callCardResourceId) {
|
||||
public ResourceContactPhoto(@DrawableRes int resourceId, @DrawableRes int callCardResourceId) {
|
||||
this.resourceId = resourceId;
|
||||
this.callCardResourceId = callCardResourceId;
|
||||
}
|
||||
@ -50,16 +50,6 @@ public class ResourceContactPhoto implements ContactPhoto {
|
||||
return AppCompatResources.getDrawable(context, callCardResourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGenerated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class ExpandingLayerDrawable extends LayerDrawable {
|
||||
public ExpandingLayerDrawable(Drawable[] layers) {
|
||||
super(layers);
|
||||
|
@ -0,0 +1,54 @@
|
||||
package org.thoughtcrime.securesms.contacts.avatars;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class SystemContactPhoto implements ContactPhoto {
|
||||
|
||||
private final @NonNull Address address;
|
||||
private final @NonNull Uri contactPhotoUri;
|
||||
private final long lastModifiedTime;
|
||||
|
||||
public SystemContactPhoto(@NonNull Address address, @NonNull Uri contactPhotoUri, long lastModifiedTime) {
|
||||
this.address = address;
|
||||
this.contactPhotoUri = contactPhotoUri;
|
||||
this.lastModifiedTime = lastModifiedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream(Context context) throws FileNotFoundException {
|
||||
return context.getContentResolver().openInputStream(contactPhotoUri);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(MessageDigest messageDigest) {
|
||||
messageDigest.update(address.serialize().getBytes());
|
||||
messageDigest.update(contactPhotoUri.toString().getBytes());
|
||||
messageDigest.update(Conversions.longToByteArray(lastModifiedTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof SystemContactPhoto)) return false;
|
||||
|
||||
SystemContactPhoto that = (SystemContactPhoto)other;
|
||||
|
||||
return this.address.equals(that.address) && this.contactPhotoUri.equals(that.contactPhotoUri) && this.lastModifiedTime == that.lastModifiedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode() ^ contactPhotoUri.hashCode() ^ (int)lastModifiedTime;
|
||||
}
|
||||
|
||||
}
|
@ -8,9 +8,9 @@ import com.makeramen.roundedimageview.RoundedDrawable;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public class TransparentContactPhoto implements ContactPhoto {
|
||||
public class TransparentContactPhoto implements FallbackContactPhoto {
|
||||
|
||||
TransparentContactPhoto() {}
|
||||
public TransparentContactPhoto() {}
|
||||
|
||||
@Override
|
||||
public Drawable asDrawable(Context context, int color) {
|
||||
@ -27,13 +27,4 @@ public class TransparentContactPhoto implements ContactPhoto {
|
||||
return ContextCompat.getDrawable(context, R.drawable.ic_contact_picture_large);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGenerated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResource() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import android.util.Log;
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
@ -467,7 +466,7 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
|
||||
public Optional<Integer> getDefaultSubscriptionId() {
|
||||
return defaultSubscriptionId != -1 ? Optional.of(defaultSubscriptionId) : Optional.<Integer>absent();
|
||||
return defaultSubscriptionId != -1 ? Optional.of(defaultSubscriptionId) : Optional.absent();
|
||||
}
|
||||
|
||||
public int getExpireMessages() {
|
||||
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.giph.model.GiphyImage;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
@ -33,12 +34,14 @@ import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
public class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHolder> {
|
||||
class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHolder> {
|
||||
|
||||
private static final String TAG = GiphyAdapter.class.getSimpleName();
|
||||
|
||||
private final Context context;
|
||||
private final GlideRequests glideRequests;
|
||||
|
||||
private List<GiphyImage> images;
|
||||
private Context context;
|
||||
private OnItemClickListener listener;
|
||||
|
||||
class GiphyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, RequestListener<Drawable> {
|
||||
@ -73,7 +76,6 @@ public class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHol
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -108,9 +110,10 @@ public class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHol
|
||||
}
|
||||
}
|
||||
|
||||
GiphyAdapter(Context context, List<GiphyImage> images) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.images = images;
|
||||
GiphyAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, @NonNull List<GiphyImage> images) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.glideRequests = glideRequests;
|
||||
this.images = images;
|
||||
}
|
||||
|
||||
public void setImages(@NonNull List<GiphyImage> images) {
|
||||
@ -145,21 +148,19 @@ public class GiphyAdapter extends RecyclerView.Adapter<GiphyAdapter.GiphyViewHol
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL);
|
||||
|
||||
if (Util.isLowMemory(context)) {
|
||||
GlideApp.with(context)
|
||||
.load(image.getStillUrl())
|
||||
.placeholder(new ColorDrawable(Util.getRandomElement(MaterialColor.values()).toConversationColor(context)))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.into(holder.thumbnail);
|
||||
glideRequests.load(image.getStillUrl())
|
||||
.placeholder(new ColorDrawable(Util.getRandomElement(MaterialColor.values()).toConversationColor(context)))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.into(holder.thumbnail);
|
||||
|
||||
holder.setModelReady();
|
||||
} else {
|
||||
GlideApp.with(context)
|
||||
.load(image.getGifUrl())
|
||||
.thumbnail(thumbnailRequest)
|
||||
.placeholder(new ColorDrawable(Util.getRandomElement(MaterialColor.values()).toConversationColor(context)))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.listener(holder)
|
||||
.into(holder.thumbnail);
|
||||
glideRequests.load(image.getGifUrl())
|
||||
.thumbnail(thumbnailRequest)
|
||||
.placeholder(new ColorDrawable(Util.getRandomElement(MaterialColor.values()).toConversationColor(context)))
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.listener(holder)
|
||||
.into(holder.thumbnail);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.giph.model.GiphyImage;
|
||||
import org.thoughtcrime.securesms.giph.net.GiphyLoader;
|
||||
import org.thoughtcrime.securesms.giph.util.InfiniteScrollListener;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@ -52,7 +53,7 @@ public abstract class GiphyFragment extends Fragment implements LoaderManager.Lo
|
||||
public void onActivityCreated(Bundle bundle) {
|
||||
super.onActivityCreated(bundle);
|
||||
|
||||
this.giphyAdapter = new GiphyAdapter(getActivity(), new LinkedList<GiphyImage>());
|
||||
this.giphyAdapter = new GiphyAdapter(getActivity(), GlideApp.with(this), new LinkedList<>());
|
||||
this.giphyAdapter.setListener(this);
|
||||
|
||||
this.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.thoughtcrime.securesms.profiles;
|
||||
package org.thoughtcrime.securesms.glide;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
@ -8,27 +8,27 @@ import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
class AvatarPhotoUriFetcher implements DataFetcher<InputStream> {
|
||||
class ContactPhotoFetcher implements DataFetcher<InputStream> {
|
||||
|
||||
private final Context context;
|
||||
private final Address address;
|
||||
private final Context context;
|
||||
private final ContactPhoto contactPhoto;
|
||||
|
||||
private InputStream inputStream;
|
||||
|
||||
AvatarPhotoUriFetcher(@NonNull Context context, @NonNull Address address) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.address = address;
|
||||
ContactPhotoFetcher(@NonNull Context context, @NonNull ContactPhoto contactPhoto) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.contactPhoto = contactPhoto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(Priority priority, DataCallback<? super InputStream> callback) {
|
||||
try {
|
||||
inputStream = AvatarHelper.getInputStreamFor(context, address);
|
||||
inputStream = contactPhoto.openInputStream(context);
|
||||
callback.onDataReady(inputStream);
|
||||
} catch (IOException e) {
|
||||
callback.onLoadFailed(e);
|
50
src/org/thoughtcrime/securesms/glide/ContactPhotoLoader.java
Normal file
50
src/org/thoughtcrime/securesms/glide/ContactPhotoLoader.java
Normal file
@ -0,0 +1,50 @@
|
||||
package org.thoughtcrime.securesms.glide;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ContactPhotoLoader implements ModelLoader<ContactPhoto, InputStream> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
private ContactPhotoLoader(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(ContactPhoto contactPhoto, int width, int height, Options options) {
|
||||
return new LoadData<>(contactPhoto, new ContactPhotoFetcher(context, contactPhoto));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(ContactPhoto contactPhoto) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class Factory implements ModelLoaderFactory<ContactPhoto, InputStream> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public Factory(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelLoader<ContactPhoto, InputStream> build(MultiModelLoaderFactory multiFactory) {
|
||||
return new ContactPhotoLoader(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {}
|
||||
}
|
||||
}
|
@ -5,8 +5,7 @@ import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
@ -85,8 +84,8 @@ public class RetrieveProfileAvatarJob extends ContextJob implements InjectableTy
|
||||
|
||||
database.setProfileAvatar(recipient, profileAvatar);
|
||||
|
||||
if (recipient.resolve().getContactPhoto().isGenerated()) {
|
||||
recipient.setContactPhoto(ContactPhotoFactory.getSignalAvatarContactPhoto(context, recipient.getAddress(), recipient.getName(), context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size)));
|
||||
if (recipient.resolve().getContactPhoto() == null) {
|
||||
recipient.setContactPhoto(new ProfileContactPhoto(recipient.getAddress(), profileAvatar));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -108,14 +108,14 @@ public class AttachmentManager {
|
||||
|
||||
}
|
||||
|
||||
public void clear(boolean animate) {
|
||||
public void clear(@NonNull GlideRequests glideRequests, boolean animate) {
|
||||
if (attachmentViewStub.resolved()) {
|
||||
|
||||
if (animate) {
|
||||
ViewUtil.fadeOut(attachmentViewStub.get(), 200).addListener(new Listener<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
thumbnail.clear();
|
||||
thumbnail.clear(glideRequests);
|
||||
attachmentViewStub.get().setVisibility(View.GONE);
|
||||
attachmentListener.onAttachmentChanged();
|
||||
}
|
||||
@ -125,7 +125,7 @@ public class AttachmentManager {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
thumbnail.clear();
|
||||
thumbnail.clear(glideRequests);
|
||||
attachmentViewStub.get().setVisibility(View.GONE);
|
||||
attachmentListener.onAttachmentChanged();
|
||||
}
|
||||
@ -200,6 +200,7 @@ public class AttachmentManager {
|
||||
}
|
||||
|
||||
public void setMedia(@NonNull final MasterSecret masterSecret,
|
||||
@NonNull final GlideRequests glideRequests,
|
||||
@NonNull final Uri uri,
|
||||
@NonNull final MediaType mediaType,
|
||||
@NonNull final MediaConstraints constraints)
|
||||
@ -209,7 +210,7 @@ public class AttachmentManager {
|
||||
new AsyncTask<Void, Void, Slide>() {
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
thumbnail.clear();
|
||||
thumbnail.clear(glideRequests);
|
||||
thumbnail.showProgressSpinner();
|
||||
attachmentViewStub.get().setVisibility(View.VISIBLE);
|
||||
}
|
||||
@ -254,7 +255,7 @@ public class AttachmentManager {
|
||||
documentView.setDocument((DocumentSlide) slide, false);
|
||||
removableMediaView.display(documentView, false);
|
||||
} else {
|
||||
thumbnail.setImageResource(masterSecret, slide, false, true);
|
||||
thumbnail.setImageResource(masterSecret, glideRequests, slide, false, true);
|
||||
removableMediaView.display(thumbnail, mediaType == MediaType.IMAGE);
|
||||
}
|
||||
|
||||
@ -433,7 +434,7 @@ public class AttachmentManager {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
cleanup();
|
||||
clear(true);
|
||||
clear(GlideApp.with(context.getApplicationContext()), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,82 +0,0 @@
|
||||
package org.thoughtcrime.securesms.mms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.data.StreamLocalUriFetcher;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
||||
|
||||
import org.thoughtcrime.securesms.mms.ContactPhotoUriLoader.ContactPhotoUri;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class ContactPhotoUriLoader implements ModelLoader<ContactPhotoUri, InputStream> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
private ContactPhotoUriLoader(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(ContactPhotoUri contactPhotoUri, int width, int height, Options options) {
|
||||
return new LoadData<>(contactPhotoUri, new StreamLocalUriFetcher(context.getContentResolver(), contactPhotoUri.uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(ContactPhotoUri contactPhotoUri) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static class Factory implements ModelLoaderFactory<ContactPhotoUri, InputStream> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
Factory(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelLoader<ContactPhotoUri, InputStream> build(MultiModelLoaderFactory multiFactory) {
|
||||
return new ContactPhotoUriLoader(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
public static class ContactPhotoUri implements Key {
|
||||
public @NonNull Uri uri;
|
||||
|
||||
public ContactPhotoUri(@NonNull Uri uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(MessageDigest messageDigest) {
|
||||
messageDigest.update(uri.toString().getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof ContactPhotoUri)) return false;
|
||||
|
||||
return this.uri.equals(((ContactPhotoUri)other).uri);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return uri.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,11 @@ import com.bumptech.glide.load.engine.cache.DiskCacheAdapter;
|
||||
import com.bumptech.glide.load.model.GlideUrl;
|
||||
import com.bumptech.glide.module.AppGlideModule;
|
||||
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.glide.ContactPhotoLoader;
|
||||
import org.thoughtcrime.securesms.glide.OkHttpUrlLoader;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
|
||||
import org.thoughtcrime.securesms.mms.ContactPhotoUriLoader.ContactPhotoUri;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarPhotoUriLoader;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarPhotoUriLoader.AvatarPhotoUri;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@ -37,11 +36,10 @@ public class SignalGlideModule extends AppGlideModule {
|
||||
|
||||
@Override
|
||||
public void registerComponents(Context context, Glide glide, Registry registry) {
|
||||
registry.append(ContactPhoto.class, InputStream.class, new ContactPhotoLoader.Factory(context));
|
||||
registry.append(DecryptableUri.class, InputStream.class, new DecryptableStreamUriLoader.Factory(context));
|
||||
registry.append(ContactPhotoUri.class, InputStream.class, new ContactPhotoUriLoader.Factory(context));
|
||||
registry.append(AttachmentModel.class, InputStream.class, new AttachmentStreamUriLoader.Factory());
|
||||
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
|
||||
registry.append(AvatarPhotoUri.class, InputStream.class, new AvatarPhotoUriLoader.Factory(context));
|
||||
}
|
||||
|
||||
public static class NoopDiskCacheFactory implements DiskCache.Factory {
|
||||
|
@ -13,12 +13,15 @@ import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationCompat.Action;
|
||||
import android.support.v4.app.RemoteInput;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
@ -64,13 +67,29 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
|
||||
addPerson(recipient.getContactUri().toString());
|
||||
}
|
||||
|
||||
setLargeIcon(recipient.getContactPhoto()
|
||||
.asDrawable(context, recipient.getColor()
|
||||
.toConversationColor(context)));
|
||||
ContactPhoto contactPhoto = recipient.getContactPhoto();
|
||||
FallbackContactPhoto fallbackContactPhoto = recipient.getFallbackContactPhoto();
|
||||
|
||||
if (contactPhoto != null) {
|
||||
try {
|
||||
setLargeIcon(GlideApp.with(context.getApplicationContext())
|
||||
.load(contactPhoto)
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.circleCrop()
|
||||
.submit(context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
|
||||
context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_height))
|
||||
.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log.w(TAG, e);
|
||||
setLargeIcon(fallbackContactPhoto.asDrawable(context, recipient.getColor().toConversationColor(context)));
|
||||
}
|
||||
} else {
|
||||
setLargeIcon(fallbackContactPhoto.asDrawable(context, recipient.getColor().toConversationColor(context)));
|
||||
}
|
||||
|
||||
} else {
|
||||
setContentTitle(context.getString(R.string.SingleRecipientNotificationBuilder_signal));
|
||||
setLargeIcon(ContactPhotoFactory.getDefaultContactPhoto("Unknown")
|
||||
.asDrawable(context, ContactColors.UNKNOWN_COLOR.toConversationColor(context)));
|
||||
setLargeIcon(new GeneratedContactPhoto("Unknown").asDrawable(context, ContactColors.UNKNOWN_COLOR.toConversationColor(context)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +244,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
Uri uri = slideDeck.getThumbnailSlide().getThumbnailUri();
|
||||
|
||||
return GlideApp.with(context)
|
||||
return GlideApp.with(context.getApplicationContext())
|
||||
.asBitmap()
|
||||
.load(new DecryptableStreamUriLoader.DecryptableUri(masterSecret, uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
|
@ -1,12 +1,14 @@
|
||||
package org.thoughtcrime.securesms.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@ -15,6 +17,7 @@ public class BlockedContactListItem extends RelativeLayout implements RecipientM
|
||||
|
||||
private AvatarImageView contactPhotoImage;
|
||||
private TextView nameView;
|
||||
private GlideRequests glideRequests;
|
||||
private Recipient recipient;
|
||||
|
||||
public BlockedContactListItem(Context context) {
|
||||
@ -32,12 +35,13 @@ public class BlockedContactListItem extends RelativeLayout implements RecipientM
|
||||
@Override
|
||||
public void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
this.contactPhotoImage = (AvatarImageView)findViewById(R.id.contact_photo_image);
|
||||
this.nameView = (TextView) findViewById(R.id.name);
|
||||
this.contactPhotoImage = findViewById(R.id.contact_photo_image);
|
||||
this.nameView = findViewById(R.id.name);
|
||||
}
|
||||
|
||||
public void set(Recipient recipients) {
|
||||
this.recipient = recipients;
|
||||
public void set(@NonNull GlideRequests glideRequests, @NonNull Recipient recipients) {
|
||||
this.glideRequests = glideRequests;
|
||||
this.recipient = recipients;
|
||||
|
||||
onModified(recipients);
|
||||
recipients.addListener(this);
|
||||
@ -48,12 +52,9 @@ public class BlockedContactListItem extends RelativeLayout implements RecipientM
|
||||
final AvatarImageView contactPhotoImage = this.contactPhotoImage;
|
||||
final TextView nameView = this.nameView;
|
||||
|
||||
Util.runOnMain(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
contactPhotoImage.setAvatar(recipients, false);
|
||||
nameView.setText(recipients.toShortString());
|
||||
}
|
||||
Util.runOnMain(() -> {
|
||||
contactPhotoImage.setAvatar(glideRequests, recipients, false);
|
||||
nameView.setText(recipients.toShortString());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,26 +2,23 @@ package org.thoughtcrime.securesms.preferences.widgets;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
public class ProfilePreference extends Preference {
|
||||
|
||||
@ -70,24 +67,12 @@ public class ProfilePreference extends Preference {
|
||||
final Address localAddress = Address.fromSerialized(TextSecurePreferences.getLocalNumber(getContext()));
|
||||
final String profileName = TextSecurePreferences.getProfileName(getContext());
|
||||
|
||||
new AsyncTask<Void, Void, Drawable>() {
|
||||
@Override
|
||||
protected @NonNull Drawable doInBackground(Void... params) {
|
||||
if (AvatarHelper.getAvatarFile(getContext(), localAddress).exists()) {
|
||||
return ContactPhotoFactory.getSignalAvatarContactPhoto(getContext(), localAddress, profileName,
|
||||
getContext().getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size))
|
||||
.asDrawable(getContext(), 0);
|
||||
} else {
|
||||
return ContactPhotoFactory.getResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp)
|
||||
.asDrawable(getContext(), getContext().getResources().getColor(R.color.grey_400));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(@NonNull Drawable contactPhoto) {
|
||||
avatarView.setImageDrawable(contactPhoto);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
GlideApp.with(getContext().getApplicationContext())
|
||||
.load(new ProfileContactPhoto(localAddress, String.valueOf(TextSecurePreferences.getProfileAvatarId(getContext()))))
|
||||
.error(new ResourceContactPhoto(R.drawable.ic_camera_alt_white_24dp).asDrawable(getContext(), getContext().getResources().getColor(R.color.grey_400)))
|
||||
.circleCrop()
|
||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
.into(avatarView);
|
||||
|
||||
if (!TextUtils.isEmpty(profileName)) {
|
||||
profileNameView.setText(profileName);
|
||||
|
@ -1,80 +0,0 @@
|
||||
package org.thoughtcrime.securesms.profiles;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
||||
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class AvatarPhotoUriLoader implements ModelLoader<AvatarPhotoUriLoader.AvatarPhotoUri, InputStream> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
private AvatarPhotoUriLoader(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(AvatarPhotoUri avatarPhotoUri, int width, int height, Options options) {
|
||||
return new LoadData<>(avatarPhotoUri, new AvatarPhotoUriFetcher(context, avatarPhotoUri.address));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(AvatarPhotoUri avatarPhotoUri) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class Factory implements ModelLoaderFactory<AvatarPhotoUri, InputStream> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public Factory(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelLoader<AvatarPhotoUri, InputStream> build(MultiModelLoaderFactory multiFactory) {
|
||||
return new AvatarPhotoUriLoader(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {}
|
||||
}
|
||||
|
||||
public static class AvatarPhotoUri implements Key {
|
||||
public @NonNull Address address;
|
||||
|
||||
public AvatarPhotoUri(@NonNull Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiskCacheKey(MessageDigest messageDigest) {
|
||||
messageDigest.update(address.serialize().getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof AvatarPhotoUri)) return false;
|
||||
|
||||
return this.address.equals(((AvatarPhotoUri)other).address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.recipients;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
@ -26,7 +27,8 @@ import android.util.Log;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.TransparentContactPhoto;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||
@ -62,15 +64,16 @@ public class Recipient implements RecipientModifiedListener {
|
||||
private boolean stale;
|
||||
private boolean resolving;
|
||||
|
||||
private ContactPhoto contactPhoto;
|
||||
private Uri contactUri;
|
||||
private @Nullable Uri ringtone = null;
|
||||
private long mutedUntil = 0;
|
||||
private boolean blocked = false;
|
||||
private VibrateState vibrate = VibrateState.DEFAULT;
|
||||
private int expireMessages = 0;
|
||||
private Optional<Integer> defaultSubscriptionId = Optional.absent();
|
||||
private @NonNull RegisteredState registered = RegisteredState.UNKNOWN;
|
||||
private @Nullable ContactPhoto contactPhoto;
|
||||
private @NonNull FallbackContactPhoto fallbackContactPhoto;
|
||||
private Uri contactUri;
|
||||
private @Nullable Uri ringtone = null;
|
||||
private long mutedUntil = 0;
|
||||
private boolean blocked = false;
|
||||
private VibrateState vibrate = VibrateState.DEFAULT;
|
||||
private int expireMessages = 0;
|
||||
private Optional<Integer> defaultSubscriptionId = Optional.absent();
|
||||
private @NonNull RegisteredState registered = RegisteredState.UNKNOWN;
|
||||
|
||||
private @Nullable MaterialColor color;
|
||||
private boolean seenInviteReminder;
|
||||
@ -101,15 +104,16 @@ public class Recipient implements RecipientModifiedListener {
|
||||
@NonNull Optional<RecipientDetails> details,
|
||||
@NonNull ListenableFutureTask<RecipientDetails> future)
|
||||
{
|
||||
this.address = address;
|
||||
this.contactPhoto = ContactPhotoFactory.getLoadingPhoto();
|
||||
this.color = null;
|
||||
this.resolving = true;
|
||||
this.address = address;
|
||||
this.fallbackContactPhoto = new TransparentContactPhoto();
|
||||
this.color = null;
|
||||
this.resolving = true;
|
||||
|
||||
if (stale != null) {
|
||||
this.name = stale.name;
|
||||
this.contactUri = stale.contactUri;
|
||||
this.contactPhoto = stale.contactPhoto;
|
||||
this.fallbackContactPhoto = stale.fallbackContactPhoto;
|
||||
this.color = stale.color;
|
||||
this.customLabel = stale.customLabel;
|
||||
this.ringtone = stale.ringtone;
|
||||
@ -132,6 +136,7 @@ public class Recipient implements RecipientModifiedListener {
|
||||
if (details.isPresent()) {
|
||||
this.name = details.get().name;
|
||||
this.contactPhoto = details.get().avatar;
|
||||
this.fallbackContactPhoto = details.get().fallbackAvatar;
|
||||
this.color = details.get().color;
|
||||
this.ringtone = details.get().ringtone;
|
||||
this.mutedUntil = details.get().mutedUntil;
|
||||
@ -158,6 +163,7 @@ public class Recipient implements RecipientModifiedListener {
|
||||
Recipient.this.name = result.name;
|
||||
Recipient.this.contactUri = result.contactUri;
|
||||
Recipient.this.contactPhoto = result.avatar;
|
||||
Recipient.this.fallbackContactPhoto = result.fallbackAvatar;
|
||||
Recipient.this.color = result.color;
|
||||
Recipient.this.customLabel = result.customLabel;
|
||||
Recipient.this.ringtone = result.ringtone;
|
||||
@ -202,6 +208,7 @@ public class Recipient implements RecipientModifiedListener {
|
||||
this.contactUri = details.contactUri;
|
||||
this.name = details.name;
|
||||
this.contactPhoto = details.avatar;
|
||||
this.fallbackContactPhoto = details.fallbackAvatar;
|
||||
this.color = details.color;
|
||||
this.customLabel = details.customLabel;
|
||||
this.ringtone = details.ringtone;
|
||||
@ -345,7 +352,15 @@ public class Recipient implements RecipientModifiedListener {
|
||||
return (getName() == null ? address.serialize() : getName());
|
||||
}
|
||||
|
||||
public synchronized @NonNull ContactPhoto getContactPhoto() {
|
||||
public synchronized @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted) {
|
||||
return getFallbackContactPhoto().asDrawable(context, getColor().toConversationColor(context), inverted);
|
||||
}
|
||||
|
||||
public synchronized @NonNull FallbackContactPhoto getFallbackContactPhoto() {
|
||||
return fallbackContactPhoto;
|
||||
}
|
||||
|
||||
public synchronized @Nullable ContactPhoto getContactPhoto() {
|
||||
return contactPhoto;
|
||||
}
|
||||
|
||||
@ -361,7 +376,7 @@ public class Recipient implements RecipientModifiedListener {
|
||||
return ringtone;
|
||||
}
|
||||
|
||||
public void setRingtone(Uri ringtone) {
|
||||
public void setRingtone(@Nullable Uri ringtone) {
|
||||
synchronized (this) {
|
||||
this.ringtone = ringtone;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2011 Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -29,11 +29,16 @@ import android.util.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.GroupRecordContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.SystemContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.TransparentContactPhoto;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||
@ -61,13 +66,12 @@ class RecipientProvider {
|
||||
PhoneLookup.LOOKUP_KEY,
|
||||
PhoneLookup._ID,
|
||||
PhoneLookup.NUMBER,
|
||||
PhoneLookup.LABEL
|
||||
PhoneLookup.LABEL,
|
||||
PhoneLookup.PHOTO_URI
|
||||
};
|
||||
|
||||
private static final Map<String, RecipientDetails> STATIC_DETAILS = new HashMap<String, RecipientDetails>() {{
|
||||
put("262966", new RecipientDetails("Amazon", null, null,
|
||||
ContactPhotoFactory.getResourceContactPhoto(R.drawable.ic_amazon),
|
||||
false, null, null));
|
||||
put("262966", new RecipientDetails("Amazon", null, null, null, new ResourceContactPhoto(R.drawable.ic_amazon), false, null, null));
|
||||
}};
|
||||
|
||||
@NonNull Recipient getRecipient(Context context, Address address, Optional<RecipientSettings> settings, Optional<GroupRecord> groupRecord, boolean asynchronous) {
|
||||
@ -100,7 +104,7 @@ class RecipientProvider {
|
||||
if (address.isGroup() && settings.isPresent() && groupRecord.isPresent()) {
|
||||
return Optional.of(getGroupRecipientDetails(context, address, groupRecord, settings, true));
|
||||
} else if (!address.isGroup() && settings.isPresent()) {
|
||||
return Optional.of(new RecipientDetails(null, null, null, ContactPhotoFactory.getLoadingPhoto(), !TextUtils.isEmpty(settings.get().getSystemDisplayName()), settings.get(), null));
|
||||
return Optional.of(new RecipientDetails(null, null, null, null, new TransparentContactPhoto(), !TextUtils.isEmpty(settings.get().getSystemDisplayName()), settings.get(), null));
|
||||
}
|
||||
|
||||
return Optional.absent();
|
||||
@ -126,10 +130,17 @@ class RecipientProvider {
|
||||
}
|
||||
|
||||
private @NonNull RecipientDetails getIndividualRecipientDetails(Context context, @NonNull Address address, Optional<RecipientSettings> settings) {
|
||||
ContactPhoto contactPhoto = null;
|
||||
FallbackContactPhoto fallbackContactPhoto = new GeneratedContactPhoto("#");
|
||||
|
||||
if (!settings.isPresent()) {
|
||||
settings = DatabaseFactory.getRecipientDatabase(context).getRecipientSettings(address);
|
||||
}
|
||||
|
||||
if (settings.isPresent() && !TextUtils.isEmpty(settings.get().getProfileAvatar())) {
|
||||
contactPhoto = new ProfileContactPhoto(address, settings.get().getProfileAvatar());
|
||||
}
|
||||
|
||||
if (address.isPhone() && !TextUtils.isEmpty(address.toPhoneString())) {
|
||||
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address.toPhoneString()));
|
||||
Cursor cursor = context.getContentResolver().query(uri, CALLER_ID_PROJECTION, null, null, null);
|
||||
@ -138,14 +149,19 @@ class RecipientProvider {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
final String resultNumber = cursor.getString(3);
|
||||
if (resultNumber != null) {
|
||||
Uri contactUri = Contacts.getLookupUri(cursor.getLong(2), cursor.getString(1));
|
||||
String name = resultNumber.equals(cursor.getString(0)) ? null : cursor.getString(0);
|
||||
ContactPhoto contactPhoto = ContactPhotoFactory.getContactPhoto(context,
|
||||
Uri.withAppendedPath(Contacts.CONTENT_URI, cursor.getLong(2) + ""),
|
||||
address,
|
||||
name);
|
||||
Uri contactUri = Contacts.getLookupUri(cursor.getLong(2), cursor.getString(1));
|
||||
String name = resultNumber.equals(cursor.getString(0)) ? null : cursor.getString(0);
|
||||
String photoUri = cursor.getString(5);
|
||||
|
||||
return new RecipientDetails(cursor.getString(0), cursor.getString(4), contactUri, contactPhoto, true, settings.orNull(), null);
|
||||
if (!TextUtils.isEmpty(photoUri)) {
|
||||
contactPhoto = new SystemContactPhoto(address, Uri.parse(photoUri), 0);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(name)) {
|
||||
fallbackContactPhoto = new GeneratedContactPhoto(name);
|
||||
}
|
||||
|
||||
return new RecipientDetails(cursor.getString(0), cursor.getString(4), contactUri, contactPhoto, fallbackContactPhoto, true, settings.orNull(), null);
|
||||
} else {
|
||||
Log.w(TAG, "resultNumber is null");
|
||||
}
|
||||
@ -157,10 +173,13 @@ class RecipientProvider {
|
||||
}
|
||||
|
||||
if (STATIC_DETAILS.containsKey(address.serialize())) return STATIC_DETAILS.get(address.serialize());
|
||||
else return new RecipientDetails(null, null, null, ContactPhotoFactory.getSignalAvatarContactPhoto(context, address, null, context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size)), false, settings.orNull(), null);
|
||||
else return new RecipientDetails(null, null, null, contactPhoto, fallbackContactPhoto, false, settings.orNull(), null);
|
||||
}
|
||||
|
||||
private @NonNull RecipientDetails getGroupRecipientDetails(Context context, Address groupId, Optional<GroupRecord> groupRecord, Optional<RecipientSettings> settings, boolean asynchronous) {
|
||||
ContactPhoto contactPhoto = null;
|
||||
FallbackContactPhoto fallbackContactPhoto = new ResourceContactPhoto(R.drawable.ic_group_white_24dp, R.drawable.ic_group_large);
|
||||
|
||||
if (!groupRecord.isPresent()) {
|
||||
groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId.toGroupString());
|
||||
}
|
||||
@ -170,7 +189,6 @@ class RecipientProvider {
|
||||
}
|
||||
|
||||
if (groupRecord.isPresent()) {
|
||||
ContactPhoto contactPhoto = ContactPhotoFactory.getGroupContactPhoto(groupRecord.get().getAvatar());
|
||||
String title = groupRecord.get().getTitle();
|
||||
List<Address> memberAddresses = groupRecord.get().getMembers();
|
||||
List<Recipient> members = new LinkedList<>();
|
||||
@ -183,40 +201,47 @@ class RecipientProvider {
|
||||
title = context.getString(R.string.RecipientProvider_unnamed_group);;
|
||||
}
|
||||
|
||||
return new RecipientDetails(title, null, null, contactPhoto, false, settings.orNull(), members);
|
||||
if (groupRecord.get().getAvatar() != null) {
|
||||
contactPhoto = new GroupRecordContactPhoto(groupId, groupRecord.get().getAvatarId());
|
||||
}
|
||||
|
||||
return new RecipientDetails(title, null, null, contactPhoto, fallbackContactPhoto, false, settings.orNull(), members);
|
||||
}
|
||||
|
||||
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), null, null, ContactPhotoFactory.getDefaultGroupPhoto(), false, settings.orNull(), null);
|
||||
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), null, null, contactPhoto, fallbackContactPhoto, false, settings.orNull(), null);
|
||||
}
|
||||
|
||||
static class RecipientDetails {
|
||||
@Nullable public final String name;
|
||||
@Nullable public final String customLabel;
|
||||
@NonNull public final ContactPhoto avatar;
|
||||
@Nullable public final Uri contactUri;
|
||||
@Nullable public final MaterialColor color;
|
||||
@Nullable public final Uri ringtone;
|
||||
public final long mutedUntil;
|
||||
@Nullable public final VibrateState vibrateState;
|
||||
public final boolean blocked;
|
||||
public final int expireMessages;
|
||||
@NonNull public final List<Recipient> participants;
|
||||
@Nullable public final String profileName;
|
||||
public final boolean seenInviteReminder;
|
||||
public final Optional<Integer> defaultSubscriptionId;
|
||||
@NonNull public final RegisteredState registered;
|
||||
@Nullable public final byte[] profileKey;
|
||||
@Nullable public final String profileAvatar;
|
||||
public final boolean profileSharing;
|
||||
public final boolean systemContact;
|
||||
@Nullable public final String name;
|
||||
@Nullable public final String customLabel;
|
||||
@Nullable public final ContactPhoto avatar;
|
||||
@NonNull public final FallbackContactPhoto fallbackAvatar;
|
||||
@Nullable public final Uri contactUri;
|
||||
@Nullable public final MaterialColor color;
|
||||
@Nullable public final Uri ringtone;
|
||||
public final long mutedUntil;
|
||||
@Nullable public final VibrateState vibrateState;
|
||||
public final boolean blocked;
|
||||
public final int expireMessages;
|
||||
@NonNull public final List<Recipient> participants;
|
||||
@Nullable public final String profileName;
|
||||
public final boolean seenInviteReminder;
|
||||
public final Optional<Integer> defaultSubscriptionId;
|
||||
@NonNull public final RegisteredState registered;
|
||||
@Nullable public final byte[] profileKey;
|
||||
@Nullable public final String profileAvatar;
|
||||
public final boolean profileSharing;
|
||||
public final boolean systemContact;
|
||||
|
||||
public RecipientDetails(@Nullable String name, @Nullable String customLabel,
|
||||
@Nullable Uri contactUri, @NonNull ContactPhoto avatar,
|
||||
@Nullable Uri contactUri, @Nullable ContactPhoto avatar,
|
||||
@NonNull FallbackContactPhoto fallbackAvatar,
|
||||
boolean systemContact, @Nullable RecipientSettings settings,
|
||||
@Nullable List<Recipient> participants)
|
||||
{
|
||||
this.customLabel = customLabel;
|
||||
this.avatar = avatar;
|
||||
this.fallbackAvatar = fallbackAvatar;
|
||||
this.contactUri = contactUri;
|
||||
this.color = settings != null ? settings.getColor() : null;
|
||||
this.ringtone = settings != null ? settings.getRingtone() : null;
|
||||
|
@ -18,6 +18,8 @@ import android.view.View;
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
|
||||
import org.thoughtcrime.securesms.scribbles.viewmodel.Font;
|
||||
import org.thoughtcrime.securesms.scribbles.viewmodel.Layer;
|
||||
@ -48,22 +50,24 @@ public class ScribbleActivity extends PassphraseRequiredActionBarActivity implem
|
||||
private ScribbleToolbar toolbar;
|
||||
private ScribbleView scribbleView;
|
||||
private MasterSecret masterSecret;
|
||||
private GlideRequests glideRequests;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState, @NonNull MasterSecret masterSecret) {
|
||||
setContentView(R.layout.scribble_activity);
|
||||
|
||||
this.masterSecret = masterSecret;
|
||||
this.scribbleView = (ScribbleView) findViewById(R.id.scribble_view);
|
||||
this.toolbar = (ScribbleToolbar) findViewById(R.id.toolbar);
|
||||
this.colorPicker = (VerticalSlideColorPicker) findViewById(R.id.scribble_color_picker);
|
||||
this.masterSecret = masterSecret;
|
||||
this.glideRequests = GlideApp.with(this);
|
||||
this.scribbleView = findViewById(R.id.scribble_view);
|
||||
this.toolbar = findViewById(R.id.toolbar);
|
||||
this.colorPicker = findViewById(R.id.scribble_color_picker);
|
||||
|
||||
this.toolbar.setListener(this);
|
||||
this.toolbar.setToolColor(Color.RED);
|
||||
|
||||
scribbleView.setMotionViewCallback(motionViewCallback);
|
||||
scribbleView.setDrawingMode(false);
|
||||
scribbleView.setImage(getIntent().getData(), masterSecret);
|
||||
scribbleView.setImage(masterSecret, glideRequests, getIntent().getData());
|
||||
|
||||
colorPicker.setOnColorChangeListener(this);
|
||||
colorPicker.setVisibility(View.GONE);
|
||||
@ -214,7 +218,7 @@ public class ScribbleActivity extends PassphraseRequiredActionBarActivity implem
|
||||
|
||||
@Override
|
||||
public void onSave() {
|
||||
ListenableFuture<Bitmap> future = scribbleView.getRenderedImage();
|
||||
ListenableFuture<Bitmap> future = scribbleView.getRenderedImage(glideRequests);
|
||||
|
||||
future.addListener(new ListenableFuture.Listener<Bitmap>() {
|
||||
@Override
|
||||
|
@ -35,11 +35,13 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
|
||||
public class StickerSelectFragment extends Fragment implements LoaderManager.LoaderCallbacks<String[]> {
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
private String assetDirectory;
|
||||
private RecyclerView recyclerView;
|
||||
private GlideRequests glideRequests;
|
||||
private String assetDirectory;
|
||||
private StickerSelectionListener listener;
|
||||
|
||||
public static StickerSelectFragment newInstance(String assetDirectory) {
|
||||
@ -67,6 +69,7 @@ public class StickerSelectFragment extends Fragment implements LoaderManager.Loa
|
||||
public void onActivityCreated(Bundle bundle) {
|
||||
super.onActivityCreated(bundle);
|
||||
|
||||
this.glideRequests = GlideApp.with(this);
|
||||
this.assetDirectory = getArguments().getString("assetDirectory");
|
||||
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
@ -80,7 +83,7 @@ public class StickerSelectFragment extends Fragment implements LoaderManager.Loa
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<String[]> loader, String[] data) {
|
||||
recyclerView.setAdapter(new StickersAdapter(getActivity(), data));
|
||||
recyclerView.setAdapter(new StickersAdapter(getActivity(), glideRequests, data));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,12 +97,12 @@ public class StickerSelectFragment extends Fragment implements LoaderManager.Loa
|
||||
|
||||
class StickersAdapter extends RecyclerView.Adapter<StickersAdapter.StickerViewHolder> {
|
||||
|
||||
private final Context context;
|
||||
private final GlideRequests glideRequests;
|
||||
private final String[] stickerFiles;
|
||||
private final LayoutInflater layoutInflater;
|
||||
|
||||
StickersAdapter(@NonNull Context context, @NonNull String[] stickerFiles) {
|
||||
this.context = context;
|
||||
StickersAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, @NonNull String[] stickerFiles) {
|
||||
this.glideRequests = glideRequests;
|
||||
this.stickerFiles = stickerFiles;
|
||||
this.layoutInflater = LayoutInflater.from(context);
|
||||
}
|
||||
@ -113,10 +116,9 @@ public class StickerSelectFragment extends Fragment implements LoaderManager.Loa
|
||||
public void onBindViewHolder(StickerViewHolder holder, int position) {
|
||||
holder.fileName = stickerFiles[position];
|
||||
|
||||
GlideApp.with(context)
|
||||
.load(Uri.parse("file:///android_asset/" + holder.fileName))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.into(holder.image);
|
||||
glideRequests.load(Uri.parse("file:///android_asset/" + holder.fileName))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.into(holder.image);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -127,7 +129,7 @@ public class StickerSelectFragment extends Fragment implements LoaderManager.Loa
|
||||
@Override
|
||||
public void onViewRecycled(StickerViewHolder holder) {
|
||||
super.onViewRecycled(holder);
|
||||
GlideApp.with(context).clear(holder.image);
|
||||
glideRequests.clear(holder.image);
|
||||
}
|
||||
|
||||
private void onStickerSelected(String fileName) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2016 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@ -36,7 +36,7 @@ import com.bumptech.glide.request.target.Target;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.scribbles.widget.entity.MotionEntity;
|
||||
import org.thoughtcrime.securesms.scribbles.widget.entity.TextEntity;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@ -77,18 +77,17 @@ public class ScribbleView extends FrameLayout {
|
||||
initialize(context);
|
||||
}
|
||||
|
||||
public void setImage(@NonNull Uri uri, @NonNull MasterSecret masterSecret) {
|
||||
public void setImage(@NonNull MasterSecret masterSecret, @NonNull GlideRequests glideRequests, @NonNull Uri uri) {
|
||||
this.imageUri = uri;
|
||||
this.masterSecret = masterSecret;
|
||||
|
||||
GlideApp.with(getContext())
|
||||
.load(new DecryptableUri(masterSecret, uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.fitCenter()
|
||||
.into(imageView);
|
||||
glideRequests.load(new DecryptableUri(masterSecret, uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.fitCenter()
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
public @NonNull ListenableFuture<Bitmap> getRenderedImage() {
|
||||
public @NonNull ListenableFuture<Bitmap> getRenderedImage(@NonNull GlideRequests glideRequests) {
|
||||
final SettableFuture<Bitmap> future = new SettableFuture<>();
|
||||
final Context context = getContext();
|
||||
final boolean isLowMemory = Util.isLowMemory(context);
|
||||
@ -110,13 +109,12 @@ public class ScribbleView extends FrameLayout {
|
||||
height = 768;
|
||||
}
|
||||
|
||||
return GlideApp.with(context)
|
||||
.asBitmap()
|
||||
.load(new DecryptableUri(masterSecret, imageUri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.into(width, height)
|
||||
.get();
|
||||
return glideRequests.asBitmap()
|
||||
.load(new DecryptableUri(masterSecret, imageUri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.into(width, height)
|
||||
.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
@ -143,9 +141,9 @@ public class ScribbleView extends FrameLayout {
|
||||
private void initialize(@NonNull Context context) {
|
||||
inflate(context, R.layout.scribble_view, this);
|
||||
|
||||
this.imageView = (ImageView) findViewById(R.id.image_view);
|
||||
this.motionView = (MotionView) findViewById(R.id.motion_view);
|
||||
this.canvasView = (CanvasView) findViewById(R.id.canvas_view);
|
||||
this.imageView = findViewById(R.id.image_view);
|
||||
this.motionView = findViewById(R.id.motion_view);
|
||||
this.canvasView = findViewById(R.id.canvas_view);
|
||||
}
|
||||
|
||||
public void setMotionViewCallback(MotionView.MotionViewCallback callback) {
|
||||
|
@ -5,7 +5,6 @@ import android.content.ComponentName;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@ -20,11 +19,13 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public class DirectShareService extends ChooserTargetService {
|
||||
@ -48,22 +49,40 @@ public class DirectShareService extends ChooserTargetService {
|
||||
ThreadRecord record;
|
||||
|
||||
while ((record = reader.getNext()) != null && results.size() < 10) {
|
||||
Recipient recipient = Recipient.from(this, record.getRecipient().getAddress(), false);
|
||||
String name = recipient.toShortString();
|
||||
Drawable drawable = recipient.getContactPhoto().asDrawable(this, recipient.getColor().toConversationColor(this));
|
||||
Bitmap avatar = BitmapUtil.createFromDrawable(drawable, 500, 500);
|
||||
try {
|
||||
Recipient recipient = Recipient.from(this, record.getRecipient().getAddress(), false);
|
||||
String name = recipient.toShortString();
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.writeParcelable(recipient.getAddress(), 0);
|
||||
Bitmap avatar;
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putLong(ShareActivity.EXTRA_THREAD_ID, record.getThreadId());
|
||||
bundle.putByteArray(ShareActivity.EXTRA_ADDRESS_MARSHALLED, parcel.marshall());
|
||||
bundle.putInt(ShareActivity.EXTRA_DISTRIBUTION_TYPE, record.getDistributionType());
|
||||
bundle.setClassLoader(getClassLoader());
|
||||
if (recipient.getContactPhoto() != null) {
|
||||
avatar = GlideApp.with(this)
|
||||
.asBitmap()
|
||||
.load(recipient.getContactPhoto())
|
||||
.circleCrop()
|
||||
.submit(getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
|
||||
getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width))
|
||||
.get();
|
||||
} else {
|
||||
avatar = BitmapUtil.createFromDrawable(recipient.getFallbackContactPhotoDrawable(this, false),
|
||||
getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
|
||||
getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_height));
|
||||
}
|
||||
|
||||
results.add(new ChooserTarget(name, Icon.createWithBitmap(avatar), 1.0f, componentName, bundle));
|
||||
parcel.recycle();
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.writeParcelable(recipient.getAddress(), 0);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putLong(ShareActivity.EXTRA_THREAD_ID, record.getThreadId());
|
||||
bundle.putByteArray(ShareActivity.EXTRA_ADDRESS_MARSHALLED, parcel.marshall());
|
||||
bundle.putInt(ShareActivity.EXTRA_DISTRIBUTION_TYPE, record.getDistributionType());
|
||||
bundle.setClassLoader(getClassLoader());
|
||||
|
||||
results.add(new ChooserTarget(name, Icon.createWithBitmap(avatar), 1.0f, componentName, bundle));
|
||||
parcel.recycle();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
|
@ -10,8 +10,8 @@ import android.graphics.Rect;
|
||||
import android.graphics.YuvImage;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.*;
|
||||
import android.support.annotation.WorkerThread;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
@ -42,6 +42,7 @@ public class BitmapUtil {
|
||||
private static final int MAX_COMPRESSION_ATTEMPTS = 5;
|
||||
private static final int MIN_COMPRESSION_QUALITY_DECREASE = 5;
|
||||
|
||||
@android.support.annotation.WorkerThread
|
||||
public static <T> byte[] createScaledBytes(Context context, T model, MediaConstraints constraints)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
@ -50,7 +51,7 @@ public class BitmapUtil {
|
||||
int attempts = 0;
|
||||
byte[] bytes;
|
||||
|
||||
Bitmap scaledBitmap = GlideApp.with(context)
|
||||
Bitmap scaledBitmap = GlideApp.with(context.getApplicationContext())
|
||||
.asBitmap()
|
||||
.load(model)
|
||||
.downsample(DownsampleStrategy.AT_MOST)
|
||||
@ -91,11 +92,12 @@ public class BitmapUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static <T> Bitmap createScaledBitmap(Context context, T model, int maxWidth, int maxHeight)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
try {
|
||||
return GlideApp.with(context)
|
||||
return GlideApp.with(context.getApplicationContext())
|
||||
.asBitmap()
|
||||
.load(model)
|
||||
.downsample(DownsampleStrategy.AT_MOST)
|
||||
@ -106,11 +108,12 @@ public class BitmapUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static <T> Bitmap createScaledBitmap(Context context, T model, float scale)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
try {
|
||||
return GlideApp.with(context)
|
||||
return GlideApp.with(context.getApplicationContext())
|
||||
.asBitmap()
|
||||
.load(model)
|
||||
.sizeMultiplier(scale)
|
||||
|
@ -66,7 +66,7 @@ public class MediaUtil {
|
||||
{
|
||||
try {
|
||||
int maxSize = context.getResources().getDimensionPixelSize(R.dimen.media_bubble_height);
|
||||
return GlideApp.with(context)
|
||||
return GlideApp.with(context.getApplicationContext())
|
||||
.asBitmap()
|
||||
.load(new DecryptableUri(masterSecret, uri))
|
||||
.centerCrop()
|
||||
|
@ -112,6 +112,7 @@ public class TextSecurePreferences {
|
||||
private static final String ALWAYS_RELAY_CALLS_PREF = "pref_turn_only";
|
||||
private static final String PROFILE_KEY_PREF = "pref_profile_key";
|
||||
private static final String PROFILE_NAME_PREF = "pref_profile_name";
|
||||
private static final String PROFILE_AVATAR_ID_PREF = "pref_profile_avatar_id";
|
||||
public static final String READ_RECEIPTS_PREF = "pref_read_receipts";
|
||||
public static final String INCOGNITO_KEYBORAD_PREF = "pref_incognito_keyboard";
|
||||
|
||||
@ -143,6 +144,14 @@ public class TextSecurePreferences {
|
||||
return getStringPreference(context, PROFILE_NAME_PREF, null);
|
||||
}
|
||||
|
||||
public static void setProfileAvatarId(Context context, int id) {
|
||||
setIntegerPrefrence(context, PROFILE_AVATAR_ID_PREF, id);
|
||||
}
|
||||
|
||||
public static int getProfileAvatarId(Context context) {
|
||||
return getIntegerPreference(context, PROFILE_AVATAR_ID_PREF, 0);
|
||||
}
|
||||
|
||||
public static int getNotificationPriority(Context context) {
|
||||
return Integer.valueOf(getStringPreference(context, NOTIFICATION_PRIORITY_PREF, String.valueOf(NotificationCompat.PRIORITY_HIGH)));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user