diff --git a/app/src/main/java/org/thoughtcrime/securesms/MuteDialog.java b/app/src/main/java/org/thoughtcrime/securesms/MuteDialog.java index 7964aea735..7541f5672c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MuteDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/MuteDialog.java @@ -7,6 +7,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import java.util.concurrent.TimeUnit; public class MuteDialog extends AlertDialog { @@ -29,7 +31,7 @@ public class MuteDialog extends AlertDialog { } public static void show(final Context context, final @NonNull MuteSelectionListener listener, @Nullable Runnable cancelListener) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); + AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context); builder.setTitle(R.string.MuteDialog_mute_notifications); builder.setItems(R.array.mute_durations, new DialogInterface.OnClickListener() { @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/WipeDownTransition.kt b/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/WipeDownTransition.kt index bc1fb2bcc6..746a5feb9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/WipeDownTransition.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/WipeDownTransition.kt @@ -11,6 +11,7 @@ import android.util.AttributeSet import android.view.View import android.view.ViewGroup import androidx.annotation.RequiresApi +import androidx.core.animation.addListener import androidx.fragment.app.FragmentContainerView private const val BOUNDS = "signal.wipedowntransition.bottom" @@ -51,6 +52,12 @@ class WipeDownTransition(context: Context, attrs: AttributeSet?) : Transition(co val startBottom: Rect = startValues.values[BOUNDS] as? Rect ?: Rect().apply { view.getLocalVisibleRect(this) } val endBottom: Rect = endValues.values[BOUNDS] as? Rect ?: Rect().apply { view.getLocalVisibleRect(this) } - return ObjectAnimator.ofObject(view, "clipBounds", RectEvaluator(), startBottom, endBottom) + return ObjectAnimator.ofObject(view, "clipBounds", RectEvaluator(), startBottom, endBottom).apply { + addListener( + onEnd = { + view.clipBounds = null + } + ) + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java b/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java index 218bfa42a5..a0475e709e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/FromTextView.java @@ -72,8 +72,8 @@ public class FromTextView extends EmojiTextView { setText(builder); - if (recipient.isBlocked()) setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_block_grey600_18dp, 0, 0, 0); - else if (recipient.isMuted()) setCompoundDrawablesWithIntrinsicBounds(getMuted(), null, null, null); + if (recipient.isBlocked()) setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_block_grey600_18dp, 0, 0, 0); + else if (recipient.isMuted()) setCompoundDrawablesRelativeWithIntrinsicBounds(getMuted(), null, null, null); else setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsActivity.kt index d200a50d36..9aa5c7c390 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsActivity.kt @@ -31,7 +31,7 @@ class ConversationSettingsActivity : DSLSettingsActivity(), ConversationSettings override fun finish() { super.finish() - overridePendingTransition(0, R.anim.fade_out) + overridePendingTransition(0, R.anim.slide_fade_to_bottom) } companion object { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt index b31f1e21d6..d902f9fe7f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt @@ -432,6 +432,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( customPref( SharedMediaPreference.Model( mediaCursor = state.sharedMedia, + mediaIds = state.sharedMediaIds, onMediaRecordClick = { mediaRecord, isLtr -> startActivityForResult( MediaPreviewActivity.intentFromMediaRecord(requireContext(), mediaRecord, isLtr), diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt index 099d79b339..58754b3982 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt @@ -15,6 +15,7 @@ data class ConversationSettingsState( val disappearingMessagesLifespan: Int = 0, val canModifyBlockedState: Boolean = false, val sharedMedia: Cursor? = null, + val sharedMediaIds: List = listOf(), private val sharedMediaLoaded: Boolean = false, private val specificSettingsState: SpecificSettingsState, ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt index 19139293e4..ff37d6aaa0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt @@ -10,12 +10,14 @@ import org.signal.core.util.ThreadUtil import org.signal.core.util.concurrent.SignalExecutors import org.thoughtcrime.securesms.components.settings.conversation.preferences.ButtonStripPreference import org.thoughtcrime.securesms.components.settings.conversation.preferences.LegacyGroupPreference +import org.thoughtcrime.securesms.database.AttachmentDatabase import org.thoughtcrime.securesms.database.RecipientDatabase import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.groups.LiveGroup import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.recipients.RecipientUtil +import org.thoughtcrime.securesms.util.CursorUtil import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.SingleLiveEvent import org.thoughtcrime.securesms.util.livedata.LiveDataUtil @@ -58,7 +60,19 @@ sealed class ConversationSettingsViewModel( openedMediaCursors.add(cursor.get()) } - state.copy(sharedMedia = cursor.orNull(), sharedMediaLoaded = true) + val ids: List = cursor.transform> { + val result = mutableListOf() + while (it.moveToNext()) { + result.add(CursorUtil.requireLong(it, AttachmentDatabase.ROW_ID)) + } + result + }.or(listOf()) + + state.copy( + sharedMedia = cursor.orNull(), + sharedMediaIds = ids, + sharedMediaLoaded = true + ) } else { cursor.orNull().ensureClosed() state.copy(sharedMedia = null) @@ -125,7 +139,7 @@ sealed class ConversationSettingsViewModel( isAudioAvailable = !recipient.isGroup && !recipient.isSelf, isAudioSecure = recipient.registered == RecipientDatabase.RegisteredState.REGISTERED, isMuted = recipient.isMuted, - isMuteAvailable = true, + isMuteAvailable = !recipient.isSelf, isSearchAvailable = true ), disappearingMessagesLifespan = recipient.expireMessages, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt index 7b7c3fd69a..bf9386910a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt @@ -22,10 +22,16 @@ object SharedMediaPreference { class Model( val mediaCursor: Cursor, + val mediaIds: List, val onMediaRecordClick: (MediaDatabase.MediaRecord, Boolean) -> Unit ) : PreferenceModel() { override fun areItemsTheSame(newItem: Model): Boolean { - return newItem.mediaCursor == mediaCursor + return true + } + + override fun areContentsTheSame(newItem: Model): Boolean { + return super.areContentsTheSame(newItem) && + mediaIds == newItem.mediaIds } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java index 816730ff1b..d40bb343a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java @@ -52,7 +52,7 @@ import kotlin.Unit; */ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogFragment { - public static final int REQUEST_CODE_ADD_CONTACT = 1111; + public static final int REQUEST_CODE_SYSTEM_CONTACT_SHEET = 1111; private static final String ARGS_RECIPIENT_ID = "RECIPIENT_ID"; private static final String ARGS_GROUP_ID = "GROUP_ID"; @@ -65,6 +65,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF private Button blockButton; private Button unblockButton; private Button addContactButton; + private Button contactDetailsButton; private Button addToGroupButton; private Button viewSafetyNumberButton; private Button makeGroupAdminButton; @@ -73,6 +74,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF private ProgressBar adminActionBusy; private View noteToSelfDescription; private View buttonStrip; + private View interactionsContainer; public static BottomSheetDialogFragment create(@NonNull RecipientId recipientId, @Nullable GroupId groupId) @@ -110,6 +112,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF blockButton = view.findViewById(R.id.rbs_block_button); unblockButton = view.findViewById(R.id.rbs_unblock_button); addContactButton = view.findViewById(R.id.rbs_add_contact_button); + contactDetailsButton = view.findViewById(R.id.rbs_contact_details_button); addToGroupButton = view.findViewById(R.id.rbs_add_to_group_button); viewSafetyNumberButton = view.findViewById(R.id.rbs_view_safety_number_button); makeGroupAdminButton = view.findViewById(R.id.rbs_make_group_admin_button); @@ -118,6 +121,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF adminActionBusy = view.findViewById(R.id.rbs_admin_action_busy); noteToSelfDescription = view.findViewById(R.id.rbs_note_to_self_description); buttonStrip = view.findViewById(R.id.button_strip); + interactionsContainer = view.findViewById(R.id.interactions_container); return view; } @@ -135,6 +139,8 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF viewModel = ViewModelProviders.of(this, factory).get(RecipientDialogViewModel.class); viewModel.getRecipient().observe(getViewLifecycleOwner(), recipient -> { + interactionsContainer.setVisibility(recipient.isSelf() ? View.GONE : View.VISIBLE); + avatar.setFallbackPhotoProvider(new Recipient.FallbackPhotoProvider() { @Override public @NonNull FallbackContactPhoto getPhotoForLocalNumber() { @@ -232,9 +238,18 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF } else { addContactButton.setVisibility(View.VISIBLE); addContactButton.setOnClickListener(v -> { - startActivityForResult(RecipientExporter.export(recipient).asAddContactIntent(), REQUEST_CODE_ADD_CONTACT); + startActivityForResult(RecipientExporter.export(recipient).asAddContactIntent(), REQUEST_CODE_SYSTEM_CONTACT_SHEET); }); } + + if (recipient.isSystemContact() && !recipient.isGroup() && !recipient.isSelf()) { + contactDetailsButton.setVisibility(View.VISIBLE); + contactDetailsButton.setOnClickListener(v -> { + startActivityForResult(new Intent(Intent.ACTION_VIEW, recipient.getContactUri()), REQUEST_CODE_SYSTEM_CONTACT_SHEET); + }); + } else { + contactDetailsButton.setVisibility(View.GONE); + } }); viewModel.getCanAddToAGroup().observe(getViewLifecycleOwner(), canAdd -> { @@ -288,8 +303,8 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_ADD_CONTACT) { - viewModel.onAddedToContacts(); + if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_SYSTEM_CONTACT_SHEET) { + viewModel.refreshRecipient(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java index e1c38734cc..ed7bcea08c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogViewModel.java @@ -195,7 +195,7 @@ final class RecipientDialogViewModel extends ViewModel { .show(); } - void onAddedToContacts() { + void refreshRecipient() { recipientDialogRepository.refreshRecipient(); } diff --git a/app/src/main/res/layout/chat_wallpaper_selection_fragment.xml b/app/src/main/res/layout/chat_wallpaper_selection_fragment.xml index 39dff30b69..3515b4183d 100644 --- a/app/src/main/res/layout/chat_wallpaper_selection_fragment.xml +++ b/app/src/main/res/layout/chat_wallpaper_selection_fragment.xml @@ -27,6 +27,7 @@ android:textAppearance="@style/Signal.Text.Body" android:textColor="@color/signal_text_primary" app:drawableStartCompat="@drawable/ic_photo_album_24" + app:drawableTint="@color/signal_icon_tint_primary" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/recipient_bottom_sheet.xml b/app/src/main/res/layout/recipient_bottom_sheet.xml index da346e4a30..d12564c933 100644 --- a/app/src/main/res/layout/recipient_bottom_sheet.xml +++ b/app/src/main/res/layout/recipient_bottom_sheet.xml @@ -96,6 +96,7 @@ tools:visibility="visible" /> +