diff --git a/res/drawable-hdpi/ic_arrow_back_white_24dp.png b/res/drawable-hdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..cd19726776 Binary files /dev/null and b/res/drawable-hdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-ldrtl-hdpi/ic_arrow_back_white_24dp.png b/res/drawable-ldrtl-hdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..f517557627 Binary files /dev/null and b/res/drawable-ldrtl-hdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-ldrtl-mdpi/ic_arrow_back_white_24dp.png b/res/drawable-ldrtl-mdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..22a1140ae2 Binary files /dev/null and b/res/drawable-ldrtl-mdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-ldrtl-xhdpi/ic_arrow_back_white_24dp.png b/res/drawable-ldrtl-xhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..d858f18e6c Binary files /dev/null and b/res/drawable-ldrtl-xhdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-ldrtl-xxhdpi/ic_arrow_back_white_24dp.png b/res/drawable-ldrtl-xxhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..614ad49a3e Binary files /dev/null and b/res/drawable-ldrtl-xxhdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-ldrtl-xxxhdpi/ic_arrow_back_white_24dp.png b/res/drawable-ldrtl-xxxhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..d409b544b7 Binary files /dev/null and b/res/drawable-ldrtl-xxxhdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-mdpi/ic_arrow_back_white_24dp.png b/res/drawable-mdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..4ef72eec99 Binary files /dev/null and b/res/drawable-mdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-xhdpi/ic_arrow_back_white_24dp.png b/res/drawable-xhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..832f5a3617 Binary files /dev/null and b/res/drawable-xhdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png b/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..32a6d91ce8 Binary files /dev/null and b/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png b/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 0000000000..e27034d678 Binary files /dev/null and b/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png differ diff --git a/res/drawable/recipient_preference_scrim_bottom.xml b/res/drawable/recipient_preference_scrim_bottom.xml new file mode 100644 index 0000000000..472ad8ba1e --- /dev/null +++ b/res/drawable/recipient_preference_scrim_bottom.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/res/drawable/recipient_preference_scrim_top.xml b/res/drawable/recipient_preference_scrim_top.xml new file mode 100644 index 0000000000..a088f60e06 --- /dev/null +++ b/res/drawable/recipient_preference_scrim_top.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/res/layout/conversation_title_view.xml b/res/layout/conversation_title_view.xml index 23d120b8c1..a9b70ff49e 100644 --- a/res/layout/conversation_title_view.xml +++ b/res/layout/conversation_title_view.xml @@ -1,52 +1,94 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_gravity="center_vertical" + android:gravity="center_vertical"> - + - + + + + + + android:id="@+id/subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="end" + android:layout_gravity="center_vertical|start" + android:gravity="center_vertical" + android:layout_toRightOf="@id/verified_indicator" + android:layout_toEndOf="@id/verified_indicator" + android:layout_below="@id/title" + android:textDirection="ltr" + android:textSize="13dp" + tools:text="(123) 123-1234" + style="@style/TextSecure.SubtitleTextStyle"/> - + \ No newline at end of file diff --git a/res/layout/recipient_preference_activity.xml b/res/layout/recipient_preference_activity.xml index ea6dfe662d..a6b67bccad 100644 --- a/res/layout/recipient_preference_activity.xml +++ b/res/layout/recipient_preference_activity.xml @@ -1,69 +1,72 @@ - + - + android:layout_height="300dp" + android:background="@color/transparent"> - + - + - + - + - + - + - + - + - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 72b4318cdd..2e50505b35 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -13,7 +13,7 @@ 200sp 2dp 2dp - 64dp + 300dp 50dp 230dp 8dp diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java index f1be5ed25e..c42953f3f8 100644 --- a/src/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationActivity.java @@ -1201,31 +1201,18 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } }); - titleView.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(ConversationActivity.this, RecipientPreferenceActivity.class); - intent.putExtra(RecipientPreferenceActivity.ADDRESS_EXTRA, recipient.getAddress()); - intent.putExtra(RecipientPreferenceActivity.CAN_HAVE_SAFETY_NUMBER_EXTRA, - isSecureText && !isSelfConversation()); + titleView.setOnClickListener(v -> { + Intent intent = new Intent(ConversationActivity.this, RecipientPreferenceActivity.class); + intent.putExtra(RecipientPreferenceActivity.ADDRESS_EXTRA, recipient.getAddress()); + intent.putExtra(RecipientPreferenceActivity.CAN_HAVE_SAFETY_NUMBER_EXTRA, + isSecureText && !isSelfConversation()); - startActivitySceneTransition(intent, titleView.findViewById(R.id.title), "recipient_name"); - } + startActivitySceneTransition(intent, titleView.findViewById(R.id.contact_photo_image), "avatar"); }); - unblockButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - handleUnblock(); - } - }); - - makeDefaultSmsButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - handleMakeDefaultSms(); - } - }); + titleView.setOnBackClickedListener(view -> onBackPressed()); + unblockButton.setOnClickListener(v -> handleUnblock()); + makeDefaultSmsButton.setOnClickListener(v -> handleMakeDefaultSms()); composeText.setOnKeyListener(composeKeyPressedListener); composeText.addTextChangedListener(composeKeyPressedListener); @@ -1243,7 +1230,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } protected void initializeActionBar() { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(false); getSupportActionBar().setCustomView(R.layout.conversation_title_view); getSupportActionBar().setDisplayShowCustomEnabled(true); getSupportActionBar().setDisplayShowTitleEnabled(false); diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java index 31e75b4b2e..5202747e5c 100644 --- a/src/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/ConversationItem.java @@ -123,7 +123,7 @@ public class ConversationItem extends LinearLayout private AlertView alertView; private @NonNull Set batchSelected = new HashSet<>(); - private @Nullable Recipient conversationRecipient; + private @NonNull Recipient conversationRecipient; private @NonNull Stub mediaThumbnailStub; private @NonNull Stub audioViewStub; private @NonNull Stub documentViewStub; @@ -404,9 +404,14 @@ public class ConversationItem extends LinearLayout } } - private void setContactPhoto(Recipient recipient) { - if (! messageRecord.isOutgoing()) { - setContactPhotoForRecipient(recipient); + private void setContactPhoto(@NonNull Recipient recipient) { + if (contactPhoto == null) return; + + if (messageRecord.isOutgoing() || !groupThread) { + contactPhoto.setVisibility(View.GONE); + } else { + contactPhoto.setAvatar(recipient, true); + contactPhoto.setVisibility(View.VISIBLE); } } @@ -547,15 +552,6 @@ public class ConversationItem extends LinearLayout } } - /// Helper Methods - - private void setContactPhotoForRecipient(final Recipient recipient) { - if (contactPhoto == null) return; - - contactPhoto.setAvatar(recipient, true); - contactPhoto.setVisibility(View.VISIBLE); - } - /// Event handlers private void handleApproveIdentity() { @@ -570,15 +566,12 @@ public class ConversationItem extends LinearLayout @Override public void onModified(final Recipient modified) { - Util.runOnMain(new Runnable() { - @Override - public void run() { - setBubbleState(messageRecord, recipient); - setContactPhoto(recipient); - setGroupMessageStatus(messageRecord, recipient); - setAudioViewTint(messageRecord, conversationRecipient); - setDocumentViewTint(messageRecord, conversationRecipient); - } + Util.runOnMain(() -> { + setBubbleState(messageRecord, recipient); + setContactPhoto(recipient); + setGroupMessageStatus(messageRecord, recipient); + setAudioViewTint(messageRecord, conversationRecipient); + setDocumentViewTint(messageRecord, conversationRecipient); }); } diff --git a/src/org/thoughtcrime/securesms/ConversationTitleView.java b/src/org/thoughtcrime/securesms/ConversationTitleView.java index 69be4d432c..6975910a85 100644 --- a/src/org/thoughtcrime/securesms/ConversationTitleView.java +++ b/src/org/thoughtcrime/securesms/ConversationTitleView.java @@ -1,24 +1,36 @@ package org.thoughtcrime.securesms; import android.content.Context; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.widget.ImageView; -import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; +import com.annimon.stream.Collectors; +import com.annimon.stream.Stream; + +import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.recipients.Recipient; +import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ViewUtil; -public class ConversationTitleView extends LinearLayout { +import java.lang.ref.WeakReference; + +public class ConversationTitleView extends RelativeLayout { private static final String TAG = ConversationTitleView.class.getSimpleName(); - private TextView title; - private TextView subtitle; - private ImageView verified; + private View content; + private ImageView back; + private AvatarImageView avatar; + private TextView title; + private TextView subtitle; + private ImageView verified; public ConversationTitleView(Context context) { this(context, null); @@ -33,9 +45,12 @@ public class ConversationTitleView extends LinearLayout { public void onFinishInflate() { super.onFinishInflate(); - this.title = (TextView) findViewById(R.id.title); - this.subtitle = (TextView) findViewById(R.id.subtitle); - this.verified = (ImageView) findViewById(R.id.verified_indicator); + this.back = ViewUtil.findById(this, R.id.up_button); + this.content = ViewUtil.findById(this, R.id.content); + this.title = ViewUtil.findById(this, R.id.title); + this.subtitle = ViewUtil.findById(this, R.id.subtitle); + this.verified = ViewUtil.findById(this, R.id.verified_indicator); + this.avatar = ViewUtil.findById(this, R.id.contact_photo_image); ViewUtil.setTextViewGravityStart(this.title, getContext()); ViewUtil.setTextViewGravityStart(this.subtitle, getContext()); @@ -52,12 +67,25 @@ public class ConversationTitleView extends LinearLayout { } else { title.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); } + + if (recipient != null) { + this.avatar.setAvatar(recipient, false); + } } public void setVerified(boolean verified) { this.verified.setVisibility(verified ? View.VISIBLE : View.GONE); } + @Override + public void setOnClickListener(@Nullable OnClickListener listener) { + this.content.setOnClickListener(listener); + } + + public void setOnBackClickedListener(@Nullable OnClickListener listener) { + this.back.setOnClickListener(listener); + } + private void setComposeTitle() { this.title.setText(R.string.ConversationActivity_compose_message); this.subtitle.setText(null); @@ -71,9 +99,15 @@ public class ConversationTitleView extends LinearLayout { } private void setGroupRecipientTitle(Recipient recipient) { + String localNumber = TextSecurePreferences.getLocalNumber(getContext()); + this.title.setText(recipient.getName()); - this.subtitle.setText(null); - this.subtitle.setVisibility(View.GONE); + this.subtitle.setText(Stream.of(recipient.getParticipants()) + .filter(r -> !r.getAddress().serialize().equals(localNumber)) + .map(Recipient::toShortString) + .collect(Collectors.joining(","))); + + this.subtitle.setVisibility(View.VISIBLE); } private void setNonContactRecipientTitle(Recipient recipient) { diff --git a/src/org/thoughtcrime/securesms/RecipientPreferenceActivity.java b/src/org/thoughtcrime/securesms/RecipientPreferenceActivity.java index 98f6955266..97dbb9eedd 100644 --- a/src/org/thoughtcrime/securesms/RecipientPreferenceActivity.java +++ b/src/org/thoughtcrime/securesms/RecipientPreferenceActivity.java @@ -5,30 +5,30 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.Color; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.os.Handler; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.provider.Settings; import android.support.annotation.NonNull; +import android.support.design.widget.CollapsingToolbarLayout; import android.support.v4.app.Fragment; import android.support.v4.preference.PreferenceFragment; import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.MenuItem; -import android.view.View; -import android.widget.TextView; +import android.view.WindowManager; +import android.widget.ImageView; import org.thoughtcrime.securesms.color.MaterialColor; import org.thoughtcrime.securesms.color.MaterialColors; -import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.Address; @@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.IdentityUtil; import org.thoughtcrime.securesms.util.Util; +import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.concurrent.ListenableFuture; import org.whispersystems.libsignal.util.guava.Optional; @@ -71,11 +72,9 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme(); private final DynamicLanguage dynamicLanguage = new DynamicLanguage(); - private AvatarImageView avatar; - private Toolbar toolbar; - private TextView title; - private TextView blockedIndicator; - private BroadcastReceiver staleReceiver; + private ImageView avatar; + private CollapsingToolbarLayout toolbarLayout; + private BroadcastReceiver staleReceiver; @Override public void onPreCreate() { @@ -125,25 +124,35 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi super.onOptionsItemSelected(item); switch (item.getItemId()) { case android.R.id.home: - super.onBackPressed(); + onBackPressed(); return true; } return false; } + @Override + public void onBackPressed() { + finish(); + overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); + } + private void initializeToolbar() { - this.toolbar = (Toolbar) findViewById(R.id.toolbar); - this.toolbar.setLogo(null); + this.toolbarLayout = ViewUtil.findById(this, R.id.collapsing_toolbar); + this.avatar = ViewUtil.findById(this, R.id.avatar); + this.toolbarLayout.setExpandedTitleColor(getResources().getColor(R.color.white)); + this.toolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.white)); + + Toolbar toolbar = ViewUtil.findById(this, R.id.toolbar); setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setDisplayShowTitleEnabled(false); + getSupportActionBar().setLogo(null); - this.avatar = (AvatarImageView) toolbar.findViewById(R.id.avatar); - this.title = (TextView) toolbar.findViewById(R.id.name); - this.blockedIndicator = (TextView) toolbar.findViewById(R.id.blocked_indicator); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + getWindow().setStatusBarColor(Color.TRANSPARENT); + } } private void initializeReceivers() { @@ -163,27 +172,15 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi registerReceiver(staleReceiver, staleFilter); } - private void setHeader(Recipient recipient) { - this.avatar.setAvatar(recipient, true); - this.title.setText(recipient.toShortString()); - this.toolbar.setBackgroundColor(recipient.getColor().toActionBarColor(this)); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - getWindow().setStatusBarColor(recipient.getColor().toStatusBarColor(this)); - } - - if (recipient.isBlocked()) this.blockedIndicator.setVisibility(View.VISIBLE); - else this.blockedIndicator.setVisibility(View.GONE); + private void setHeader(@NonNull Recipient recipient) { + this.avatar.setImageDrawable(recipient.getContactPhoto().asCallCard(this)); + this.toolbarLayout.setTitle(recipient.toShortString()); + this.toolbarLayout.setContentScrimColor(recipient.getColor().toActionBarColor(this)); } @Override public void onModified(final Recipient recipient) { - title.post(new Runnable() { - @Override - public void run() { - setHeader(recipient); - } - }); + Util.runOnMain(() -> setHeader(recipient)); } public static class RecipientPreferenceFragment