Colorize conversations.

// FREEBIE
master
Moxie Marlinspike 2015-06-23 15:10:50 -07:00
parent 64df85f3ee
commit fb9f16ad29
16 changed files with 251 additions and 95 deletions

View File

@ -6,16 +6,16 @@
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingRight="50dp">
<ImageView
android:id="@+id/contact_photo_image"
android:layout_width="@dimen/contact_selection_photo_size"
android:layout_height="@dimen/contact_selection_photo_size"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:cropToPadding="true"
android:scaleType="centerCrop"
android:contentDescription="@string/SingleContactSelectionActivity_contact_photo" />
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/contact_photo_image"
android:layout_width="@dimen/contact_selection_photo_size"
android:layout_height="@dimen/contact_selection_photo_size"
android:foreground="@drawable/contact_photo_background"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:cropToPadding="true"
android:contentDescription="@string/SingleContactSelectionActivity_contact_photo" />
<LinearLayout
android:id="@+id/number_container"

View File

@ -16,14 +16,17 @@
*/
package org.thoughtcrime.securesms;
import android.annotation.TargetApi;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
@ -40,6 +43,7 @@ import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.ViewStub;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
@ -49,6 +53,7 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.google.protobuf.ByteString;
import com.readystatesoftware.systembartint.SystemBarTintManager;
import org.thoughtcrime.securesms.TransportOptions.OnTransportChangedListener;
import org.thoughtcrime.securesms.components.AnimatingToggle;
@ -58,6 +63,7 @@ import org.thoughtcrime.securesms.components.emoji.EmojiDrawer;
import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
import org.thoughtcrime.securesms.contacts.ContactAccessor;
import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData;
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.SecurityEvent;
@ -167,6 +173,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private DynamicTheme dynamicTheme = new DynamicTheme();
private DynamicLanguage dynamicLanguage = new DynamicLanguage();
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
protected void onPreCreate() {
dynamicTheme.onCreate(this);
@ -220,6 +227,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
initializeIme();
titleView.setTitle(recipients);
setActionBarColor(recipients.getColor());
setBlockedUserState(recipients);
calculateCharactersRemaining();
@ -798,11 +806,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
public void onModified(final Recipients recipients) {
Log.w(TAG, "onModified()");
titleView.post(new Runnable() {
@Override
public void run() {
titleView.setTitle(recipients);
setBlockedUserState(recipients);
setActionBarColor(recipients.getColor());
}
});
}
@ -993,6 +1003,18 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
return future;
}
private void setActionBarColor(Optional<Integer> color) {
int colorPrimary = getResources().getColor(R.color.textsecure_primary);
int colorPrimaryDark = getResources().getColor(R.color.textsecure_primary_dark);
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color.or(colorPrimary)));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (color.isPresent()) getWindow().setStatusBarColor(ContactColors.getStatusTinted(color.get()).or(colorPrimaryDark));
else getWindow().setStatusBarColor(colorPrimaryDark);
}
}
private void setBlockedUserState(Recipients recipients) {
if (recipients.isBlocked()) {
unblockButton.setVisibility(View.VISIBLE);

View File

@ -8,6 +8,7 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
@ -27,10 +28,11 @@ public class AvatarImageView extends ImageView {
public void setAvatar(@Nullable Recipients recipients, boolean quickContactEnabled) {
if (recipients != null) {
setImageDrawable(recipients.getContactPhoto().asDrawable(getContext()));
int backgroundColor = recipients.getColor().or(ContactColors.UNKNOWN_COLOR);
setImageDrawable(recipients.getContactPhoto().asDrawable(getContext(), backgroundColor));
setAvatarClickHandler(recipients, quickContactEnabled);
} else {
setImageDrawable(ContactPhotoFactory.getDefaultContactPhoto(null).asDrawable(getContext()));
setImageDrawable(ContactPhotoFactory.getDefaultContactPhoto(null).asDrawable(getContext(), ContactColors.UNKNOWN_COLOR));
setOnClickListener(null);
}
}

View File

@ -1,29 +1,28 @@
package org.thoughtcrime.securesms.contacts;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
public class ContactSelectionListItem extends RelativeLayout implements Recipient.RecipientModifiedListener {
public class ContactSelectionListItem extends RelativeLayout implements Recipients.RecipientsModifiedListener {
private ImageView contactPhotoImage;
private TextView numberView;
private TextView nameView;
private TextView labelView;
private CheckBox checkBox;
private AvatarImageView contactPhotoImage;
private TextView numberView;
private TextView nameView;
private TextView labelView;
private CheckBox checkBox;
private long id;
private String number;
private Recipient recipient;
private long id;
private String number;
private Recipients recipients;
public ContactSelectionListItem(Context context) {
super(context);
@ -39,11 +38,12 @@ public class ContactSelectionListItem extends RelativeLayout implements Recipien
@Override
protected void onFinishInflate() {
this.contactPhotoImage = (ImageView) 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);
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);
}
public void set(long id, int type, String name, String number, String label, int color, boolean multiSelect) {
@ -51,15 +51,15 @@ public class ContactSelectionListItem extends RelativeLayout implements Recipien
this.number = number;
if (number != null) {
this.recipient = RecipientFactory.getRecipientsFromString(getContext(), number, true)
.getPrimaryRecipient();
this.recipients = RecipientFactory.getRecipientsFromString(getContext(), number, true);
this.recipients.addListener(this);
}
this.nameView.setTextColor(color);
this.numberView.setTextColor(color);
this.contactPhotoImage.setAvatar(recipients, false);
setText(type, name, number, label);
setContactPhotoImage(recipient);
if (multiSelect) this.checkBox.setVisibility(View.VISIBLE);
else this.checkBox.setVisibility(View.GONE);
@ -70,9 +70,9 @@ public class ContactSelectionListItem extends RelativeLayout implements Recipien
}
public void unbind() {
if (recipient != null) {
recipient.removeListener(this);
recipient = null;
if (recipients != null) {
recipients.removeListener(this);
recipients = null;
}
}
@ -95,28 +95,6 @@ public class ContactSelectionListItem extends RelativeLayout implements Recipien
this.nameView.setText(name);
}
private void setContactPhotoImage(@Nullable Recipient recipient) {
if (recipient!= null) {
contactPhotoImage.setImageDrawable(recipient.getContactPhoto().asDrawable(getContext()));
recipient.addListener(this);
} else {
contactPhotoImage.setImageDrawable(null);
}
}
@Override
public void onModified(final Recipient recipient) {
if (this.recipient == recipient) {
recipient.removeListener(this);
this.contactPhotoImage.post(new Runnable() {
@Override
public void run() {
contactPhotoImage.setImageDrawable(recipient.getContactPhoto().asDrawable(getContext()));
}
});
}
}
public long getContactId() {
return id;
}
@ -124,4 +102,16 @@ public class ContactSelectionListItem extends RelativeLayout implements Recipien
public String getNumber() {
return number;
}
@Override
public void onModified(final Recipients recipients) {
if (this.recipients == recipients) {
this.contactPhotoImage.post(new Runnable() {
@Override
public void run() {
contactPhotoImage.setAvatar(recipients, false);
}
});
}
}
}

View File

@ -16,7 +16,7 @@ public class BitmapContactPhoto implements ContactPhoto {
}
@Override
public Drawable asDrawable(Context context) {
public Drawable asDrawable(Context context, int background) {
return RoundedDrawable.fromBitmap(bitmap)
.setScaleType(ImageView.ScaleType.CENTER_CROP)
.setOval(true);

View File

@ -0,0 +1,107 @@
package org.thoughtcrime.securesms.contacts.avatars;
import android.support.annotation.NonNull;
import android.util.SparseIntArray;
import com.amulyakhare.textdrawable.util.ColorGenerator;
import org.whispersystems.libaxolotl.util.guava.Optional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ContactColors {
public static final int UNKNOWN_COLOR = 0xff9E9E9E;
private static final int RED_300 = 0xffE57373;
private static final int RED_700 = 0xFFD32F2F;
private static final int PINK_300 = 0xffF06292;
private static final int PINK_700 = 0xFFC2185B;
private static final int PURPLE_300 = 0xffBA68C8;
private static final int PURPLE_700 = 0xFF7B1FA2;
private static final int DEEP_PURPLE_300 = 0xff9575CD;
private static final int DEEP_PURPLE_700 = 0xFF512DA8;
private static final int INDIGO_300 = 0xff7986CB;
private static final int INDIGO_700 = 0xFF303F9F;
private static final int BLUE_300 = 0xff64B5F6;
private static final int BLUE_700 = 0xFF1976D2;
private static final int LIGHT_BLUE_300 = 0xff4FC3F7;
private static final int LIGHT_BLUE_700 = 0xFF0288D1;
private static final int CYAN_300 = 0xff4DD0E1;
private static final int CYAN_700 = 0xFF0097A7;
private static final int TEAL_300 = 0xFF4DB6AC;
private static final int TEAL_700 = 0xFF00796B;
private static final int GREEN_300 = 0xFF81C784;
private static final int GREEN_700 = 0xFF388E3C;
private static final int LIGHT_GREEN_300 = 0xFFAED581;
private static final int LIGHT_GREEN_700 = 0xFF689F38;
private static final int LIME_300 = 0xFFDCE775;
private static final int LIME_700 = 0xFFAFB42B;
private static final int YELLOW_300 = 0xFFFFF176;
private static final int YELLOW_700 = 0xFFFBC02D;
private static final int AMBER_300 = 0xFFFFD54F;
private static final int AMBER_700 = 0xFFFFA000;
private static final int ORANGE_300 = 0xFFFFB74D;
private static final int ORANGE_700 = 0xFFF57C00;
private static final int DEEP_ORANGE_300 = 0xFFFF8A65;
private static final int DEEP_ORANGE_700 = 0xFFE64A19;
private static final int BROWN_300 = 0xFFA1887F;
private static final int BROWN_700 = 0xFF5D4037;
private static final int BLUE_GREY_300 = 0xFF90A4AE;
private static final int BLUE_GREY_700 = 0xFF455A64;
private static final List<Integer> MATERIAL_300 = new ArrayList<>(Arrays.asList(
RED_300,
PINK_300,
PURPLE_300,
DEEP_PURPLE_300,
INDIGO_300,
BLUE_300,
LIGHT_BLUE_300,
CYAN_300,
TEAL_300,
GREEN_300,
LIGHT_GREEN_300,
LIME_300,
AMBER_300,
ORANGE_300,
DEEP_ORANGE_300,
BROWN_300,
BLUE_GREY_300)
);
private static final SparseIntArray MATERIAL_300_TO_700 = new SparseIntArray() {{
put(RED_300, RED_700);
put(PINK_300, PINK_700);
put(PURPLE_300, PURPLE_700);
put(DEEP_PURPLE_300, DEEP_PURPLE_700);
put(INDIGO_300, INDIGO_700);
put(BLUE_300, BLUE_700);
put(LIGHT_BLUE_300, LIGHT_BLUE_700);
put(CYAN_300, CYAN_700);
put(TEAL_300, TEAL_700);
put(GREEN_300, GREEN_700);
put(LIGHT_GREEN_300, LIGHT_GREEN_700);
put(LIME_300, LIME_700);
put(AMBER_300, AMBER_700);
put(ORANGE_300, ORANGE_700);
put(DEEP_ORANGE_300, DEEP_ORANGE_700);
put(BROWN_300, BROWN_700);
put(BLUE_GREY_300, BLUE_GREY_700);
}};
private static final ColorGenerator MATERIAL_GENERATOR = ColorGenerator.create(MATERIAL_300);
public static int generateFor(@NonNull String name) {
return MATERIAL_GENERATOR.getColor(name);
}
public static Optional<Integer> getStatusTinted(int color) {
int statusTinted = MATERIAL_300_TO_700.get(color, -1);
return statusTinted == -1 ? Optional.<Integer>absent() : Optional.of(statusTinted);
}
}

View File

@ -5,7 +5,7 @@ import android.graphics.drawable.Drawable;
public interface ContactPhoto {
public Drawable asDrawable(Context context);
public Drawable asDrawable(Context context, int background);
}

View File

@ -19,19 +19,17 @@ import java.io.InputStream;
public class ContactPhotoFactory {
private static final String TAG = ContactPhotoFactory.class.getSimpleName();
private static final int UNKNOWN_COLOR = 0xff9E9E9E;
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("#", UNKNOWN_COLOR);
else return new GeneratedContactPhoto("#");
}
public static ContactPhoto getDefaultGroupPhoto() {
return new ResourceContactPhoto(R.drawable.ic_group_white_24dp, UNKNOWN_COLOR);
return new ResourceContactPhoto(R.drawable.ic_group_white_24dp);
}
public static ContactPhoto getContactPhoto(Context context, Uri uri, String name) {

View File

@ -12,19 +12,13 @@ import org.thoughtcrime.securesms.R;
public class GeneratedContactPhoto implements ContactPhoto {
private final String name;
private final int color;
GeneratedContactPhoto(@NonNull String name) {
this(name, ColorGenerator.MATERIAL.getColor(name));
}
GeneratedContactPhoto(@NonNull String name, int color) {
this.name = name;
this.color = color;
}
@Override
public Drawable asDrawable(Context context) {
public Drawable asDrawable(Context context, int background) {
int targetSize = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size);
return TextDrawable.builder()
@ -32,6 +26,6 @@ public class GeneratedContactPhoto implements ContactPhoto {
.width(targetSize)
.height(targetSize)
.endConfig()
.buildRound(String.valueOf(name.charAt(0)), color);
.buildRound(String.valueOf(name.charAt(0)), background);
}
}

View File

@ -11,16 +11,14 @@ import com.makeramen.roundedimageview.RoundedDrawable;
public class ResourceContactPhoto implements ContactPhoto {
private final int resourceId;
private final int color;
ResourceContactPhoto(int resourceId, int color) {
ResourceContactPhoto(int resourceId) {
this.resourceId = resourceId;
this.color = color;
}
@Override
public Drawable asDrawable(Context context) {
Drawable background = TextDrawable.builder().buildRound(" ", color);
public Drawable asDrawable(Context context, int backgroundColor) {
Drawable background = TextDrawable.builder().buildRound(" ", backgroundColor);
RoundedDrawable foreground = (RoundedDrawable) RoundedDrawable.fromDrawable(context.getResources().getDrawable(resourceId));
foreground.setScaleType(ImageView.ScaleType.CENTER);

View File

@ -10,7 +10,7 @@ public class TransparentContactPhoto implements ContactPhoto {
TransparentContactPhoto() {}
@Override
public Drawable asDrawable(Context context) {
public Drawable asDrawable(Context context, int background) {
return RoundedDrawable.fromDrawable(context.getResources().getDrawable(android.R.color.transparent));
}
}

View File

@ -29,6 +29,7 @@ public class RecipientPreferenceDatabase extends Database {
private static final String NOTIFICATION = "notification";
private static final String VIBRATE = "vibrate";
private static final String MUTE_UNTIL = "mute_until";
private static final String COLOR = "color";
public enum VibrateState {
DEFAULT(0), ENABLED(1), DISABLED(2);
@ -55,7 +56,8 @@ public class RecipientPreferenceDatabase extends Database {
BLOCK + " INTEGER DEFAULT 0," +
NOTIFICATION + " TEXT DEFAULT NULL, " +
VIBRATE + " INTEGER DEFAULT " + VibrateState.DEFAULT.getId() + ", " +
MUTE_UNTIL + " INTEGER DEFAULT 0);";
MUTE_UNTIL + " INTEGER DEFAULT 0, " +
COLOR + " INTEGER DEFAULT -1);";
public RecipientPreferenceDatabase(Context context, SQLiteOpenHelper databaseHelper) {
super(context, databaseHelper);
@ -87,13 +89,16 @@ public class RecipientPreferenceDatabase extends Database {
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL));
int color = cursor.getInt(cursor.getColumnIndexOrThrow(COLOR));
Uri notificationUri = notification == null ? null : Uri.parse(notification);
Log.w(TAG, "Muted until: " + muteUntil);
return Optional.of(new RecipientsPreferences(blocked, muteUntil,
VibrateState.fromId(vibrateState),
notificationUri));
notificationUri,
color == -1 ? Optional.<Integer>absent() :
Optional.of(color)));
}
return Optional.absent();
@ -102,6 +107,12 @@ public class RecipientPreferenceDatabase extends Database {
}
}
public void setColor(Recipients recipients, int color) {
ContentValues values = new ContentValues();
values.put(COLOR, color);
updateOrInsert(recipients, values);
}
public void setBlocked(Recipients recipients, boolean blocked) {
ContentValues values = new ContentValues();
values.put(BLOCK, blocked ? 1 : 0);
@ -147,16 +158,24 @@ public class RecipientPreferenceDatabase extends Database {
}
public static class RecipientsPreferences {
private final boolean blocked;
private final long muteUntil;
private final VibrateState vibrateState;
private final Uri notification;
private final boolean blocked;
private final long muteUntil;
private final VibrateState vibrateState;
private final Uri notification;
private final Optional<Integer> color;
public RecipientsPreferences(boolean blocked, long muteUntil, VibrateState vibrateState, Uri notification) {
public RecipientsPreferences(boolean blocked, long muteUntil, VibrateState vibrateState,
Uri notification, Optional<Integer> color)
{
this.blocked = blocked;
this.muteUntil = muteUntil;
this.vibrateState = vibrateState;
this.notification = notification;
this.color = color;
}
public Optional<Integer> getColor() {
return color;
}
public boolean isBlocked() {

View File

@ -46,6 +46,7 @@ import android.util.Log;
import org.thoughtcrime.securesms.ConversationActivity;
import org.thoughtcrime.securesms.ConversationListActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
@ -192,8 +193,10 @@ public class MessageNotifier {
List<NotificationItem> notifications = notificationState.getNotifications();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Recipient recipient = notifications.get(0).getIndividualRecipient();
Drawable recipientPhoto = recipient.getContactPhoto().asDrawable(context);
Recipients recipients = notifications.get(0).getRecipients();
int largeIconTargetSize = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size);
Drawable recipientPhoto = recipient.getContactPhoto().asDrawable(context, recipients == null ? ContactColors.UNKNOWN_COLOR :
recipients.getColor().or(ContactColors.UNKNOWN_COLOR));
if (recipientPhoto != null) {
Bitmap recipientPhotoBitmap = BitmapUtil.createFromDrawable(recipientPhoto, largeIconTargetSize, largeIconTargetSize);

View File

@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.recipients;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
@ -92,7 +93,7 @@ public class Recipient {
return this.contactUri;
}
public synchronized String getName() {
public synchronized @Nullable String getName() {
return this.name;
}

View File

@ -178,12 +178,14 @@ public class RecipientProvider {
}
public static class RecipientDetails {
public final String name;
public final String number;
public final ContactPhoto avatar;
public final Uri contactUri;
@Nullable public final String name;
@NonNull public final String number;
@NonNull public final ContactPhoto avatar;
@Nullable public final Uri contactUri;
public RecipientDetails(String name, String number, Uri contactUri, ContactPhoto avatar) {
public RecipientDetails(@Nullable String name, @NonNull String number,
@Nullable Uri contactUri, @NonNull ContactPhoto avatar)
{
this.name = name;
this.number = number;
this.avatar = avatar;

View File

@ -22,6 +22,7 @@ import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Patterns;
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.database.RecipientPreferenceDatabase.RecipientsPreferences;
@ -32,6 +33,7 @@ import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.ListenableFutureTask;
import org.thoughtcrime.securesms.util.NumberUtil;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libaxolotl.util.guava.Optional;
import java.util.Arrays;
import java.util.Collections;
@ -49,10 +51,11 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
private final Set<RecipientsModifiedListener> listeners = Collections.newSetFromMap(new WeakHashMap<RecipientsModifiedListener, Boolean>());
private final List<Recipient> recipients;
private Uri ringtone = null;
private long mutedUntil = 0;
private boolean blocked = false;
private VibrateState vibrate = VibrateState.DEFAULT;
private Uri ringtone = null;
private long mutedUntil = 0;
private boolean blocked = false;
private VibrateState vibrate = VibrateState.DEFAULT;
private Optional<Integer> color = Optional.absent();
Recipients() {
this(new LinkedList<Recipient>(), (RecipientsPreferences)null);
@ -66,6 +69,7 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
mutedUntil = preferences.getMuteUntil();
vibrate = preferences.getVibrateState();
blocked = preferences.isBlocked();
color = preferences.getColor();
}
}
@ -84,6 +88,7 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
mutedUntil = result.getMuteUntil();
vibrate = result.getVibrateState();
blocked = result.isBlocked();
color = result.getColor();
localListeners = new HashSet<>(listeners);
}
@ -101,6 +106,21 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
});
}
public synchronized Optional<Integer> getColor() {
if (color.isPresent()) return color;
else if (isGroupRecipient()) return Optional.absent();
else if (recipients.get(0).getName() == null) return Optional.absent();
else return Optional.of(ContactColors.generateFor(recipients.get(0).getName()));
}
public void setColor(Optional<Integer> color) {
synchronized (this) {
this.color = color;
}
notifyListeners();
}
public synchronized @Nullable Uri getRingtone() {
return ringtone;
}