diff --git a/changelog.d/3444.bugfix b/changelog.d/3444.bugfix new file mode 100644 index 0000000000..bf397da5b7 --- /dev/null +++ b/changelog.d/3444.bugfix @@ -0,0 +1 @@ +Attachment picker UI improvements \ No newline at end of file diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml index 864f3d3d7f..9fbf8958da 100644 --- a/library/ui-styles/src/main/res/values/dimens.xml +++ b/library/ui-styles/src/main/res/values/dimens.xml @@ -42,4 +42,9 @@ 8dp + + + 56dp + 52dp + 1dp \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt index ccc07ef118..c56b3ac832 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt @@ -26,24 +26,18 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewAnimationUtils import android.view.animation.Animation -import android.view.animation.AnimationSet -import android.view.animation.OvershootInterpolator -import android.view.animation.ScaleAnimation import android.view.animation.TranslateAnimation import android.widget.ImageButton import android.widget.LinearLayout import android.widget.PopupWindow import androidx.core.view.doOnNextLayout import androidx.core.view.isVisible -import com.amulyakhare.textdrawable.TextDrawable -import com.amulyakhare.textdrawable.util.ColorGenerator import im.vector.app.R -import im.vector.app.core.extensions.getMeasurements +import im.vector.app.core.epoxy.onClick import im.vector.app.core.utils.PERMISSIONS_EMPTY import im.vector.app.core.utils.PERMISSIONS_FOR_PICKING_CONTACT import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.databinding.ViewAttachmentTypeSelectorBinding -import im.vector.app.features.attachments.AttachmentTypeSelectorView.Callback import kotlin.math.max private const val ANIMATION_DURATION = 250 @@ -52,17 +46,16 @@ private const val ANIMATION_DURATION = 250 * This class is the view presenting choices for picking attachments. * It will return result through [Callback]. */ + class AttachmentTypeSelectorView(context: Context, inflater: LayoutInflater, - var callback: Callback?) : - PopupWindow(context) { + var callback: Callback? +) : PopupWindow(context) { interface Callback { fun onTypeSelected(type: Type) } - private val iconColorGenerator = ColorGenerator.MATERIAL - private val views: ViewAttachmentTypeSelectorBinding private var anchor: View? = null @@ -85,35 +78,40 @@ class AttachmentTypeSelectorView(context: Context, inputMethodMode = INPUT_METHOD_NOT_NEEDED isFocusable = true isTouchable = true + + views.attachmentCloseButton.onClick { + dismiss() + } } - fun show(anchor: View, isKeyboardOpen: Boolean) { + private fun animateOpen() { + views.attachmentCloseButton.animate() + .setDuration(200) + .rotation(135f) + } + + private fun animateClose() { + views.attachmentCloseButton.animate() + .setDuration(200) + .rotation(0f) + } + + fun show(anchor: View) { + animateOpen() + this.anchor = anchor val anchorCoordinates = IntArray(2) anchor.getLocationOnScreen(anchorCoordinates) - if (isKeyboardOpen) { - showAtLocation(anchor, Gravity.NO_GRAVITY, 0, anchorCoordinates[1] + anchor.height) - } else { - val contentViewHeight = if (contentView.height == 0) { - contentView.getMeasurements().second - } else { - contentView.height - } - showAtLocation(anchor, Gravity.NO_GRAVITY, 0, anchorCoordinates[1] - contentViewHeight) - } + showAtLocation(anchor, Gravity.NO_GRAVITY, 0, anchorCoordinates[1]) + contentView.doOnNextLayout { animateWindowInCircular(anchor, contentView) } - animateButtonIn(views.attachmentGalleryButton, ANIMATION_DURATION / 2) - animateButtonIn(views.attachmentCameraButton, ANIMATION_DURATION / 4) - animateButtonIn(views.attachmentFileButton, ANIMATION_DURATION / 2) - animateButtonIn(views.attachmentAudioButton, 0) - animateButtonIn(views.attachmentContactButton, ANIMATION_DURATION / 4) - animateButtonIn(views.attachmentStickersButton, ANIMATION_DURATION / 2) - animateButtonIn(views.attachmentPollButton, ANIMATION_DURATION / 4) } override fun dismiss() { + animateClose() + val capturedAnchor = anchor if (capturedAnchor != null) { animateWindowOutCircular(capturedAnchor, contentView) @@ -124,28 +122,18 @@ class AttachmentTypeSelectorView(context: Context, fun setAttachmentVisibility(type: Type, isVisible: Boolean) { when (type) { - Type.CAMERA -> views.attachmentCameraButtonContainer - Type.GALLERY -> views.attachmentGalleryButtonContainer - Type.FILE -> views.attachmentFileButtonContainer - Type.STICKER -> views.attachmentStickersButtonContainer - Type.AUDIO -> views.attachmentAudioButtonContainer - Type.CONTACT -> views.attachmentContactButtonContainer - Type.POLL -> views.attachmentPollButtonContainer + Type.CAMERA -> views.attachmentCameraButton + Type.GALLERY -> views.attachmentGalleryButton + Type.FILE -> views.attachmentFileButton + Type.STICKER -> views.attachmentStickersButton + Type.AUDIO -> views.attachmentAudioButton + Type.CONTACT -> views.attachmentContactButton + Type.POLL -> views.attachmentPollButton }.let { it.isVisible = isVisible } } - private fun animateButtonIn(button: View, delay: Int) { - val animation = AnimationSet(true) - val scale = ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.0f) - animation.addAnimation(scale) - animation.interpolator = OvershootInterpolator(1f) - animation.duration = ANIMATION_DURATION.toLong() - animation.startOffset = delay.toLong() - button.startAnimation(animation) - } - private fun animateWindowInCircular(anchor: View, contentView: View) { val coordinates = getClickCoordinates(anchor, contentView) val animator = ViewAnimationUtils.createCircularReveal(contentView, @@ -157,12 +145,6 @@ class AttachmentTypeSelectorView(context: Context, animator.start() } - private fun animateWindowInTranslate(contentView: View) { - val animation = TranslateAnimation(0f, 0f, contentView.height.toFloat(), 0f) - animation.duration = ANIMATION_DURATION.toLong() - getContentView().startAnimation(animation) - } - private fun animateWindowOutCircular(anchor: View, contentView: View) { val coordinates = getClickCoordinates(anchor, contentView) val animator = ViewAnimationUtils.createCircularReveal(getContentView(), @@ -207,7 +189,6 @@ class AttachmentTypeSelectorView(context: Context, } private fun ImageButton.configure(type: Type): ImageButton { - this.background = TextDrawable.builder().buildRound("", iconColorGenerator.getColor(type.ordinal)) this.setOnClickListener(TypeClickListener(type)) return this } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index a77899a8b0..35f33e4f75 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -1367,7 +1367,7 @@ class RoomDetailFragment @Inject constructor( attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@RoomDetailFragment) attachmentTypeSelector.setAttachmentVisibility(AttachmentTypeSelectorView.Type.POLL, vectorPreferences.labsEnablePolls()) } - attachmentTypeSelector.show(views.composerLayout.views.attachmentButton, keyboardStateUtils.isKeyboardShowing) + attachmentTypeSelector.show(views.composerLayout.views.attachmentButton) } override fun onSendMessage(text: CharSequence) { diff --git a/vector/src/main/res/drawable-hdpi/ic_attachment_stickers_white_24dp.png b/vector/src/main/res/drawable-hdpi/ic_attachment_stickers_white_24dp.png deleted file mode 100644 index d27e8f406e..0000000000 Binary files a/vector/src/main/res/drawable-hdpi/ic_attachment_stickers_white_24dp.png and /dev/null differ diff --git a/vector/src/main/res/drawable-mdpi/ic_attachment_stickers_white_24dp.png b/vector/src/main/res/drawable-mdpi/ic_attachment_stickers_white_24dp.png deleted file mode 100644 index 40d78cf9e2..0000000000 Binary files a/vector/src/main/res/drawable-mdpi/ic_attachment_stickers_white_24dp.png and /dev/null differ diff --git a/vector/src/main/res/drawable-xhdpi/ic_attachment_stickers_white_24dp.png b/vector/src/main/res/drawable-xhdpi/ic_attachment_stickers_white_24dp.png deleted file mode 100644 index 46e23b9cdc..0000000000 Binary files a/vector/src/main/res/drawable-xhdpi/ic_attachment_stickers_white_24dp.png and /dev/null differ diff --git a/vector/src/main/res/drawable-xxhdpi/ic_attachment_stickers_white_24dp.png b/vector/src/main/res/drawable-xxhdpi/ic_attachment_stickers_white_24dp.png deleted file mode 100644 index 4058b25495..0000000000 Binary files a/vector/src/main/res/drawable-xxhdpi/ic_attachment_stickers_white_24dp.png and /dev/null differ diff --git a/vector/src/main/res/drawable-xxxhdpi/ic_attachment_stickers_white_24dp.png b/vector/src/main/res/drawable-xxxhdpi/ic_attachment_stickers_white_24dp.png deleted file mode 100644 index c5b2435646..0000000000 Binary files a/vector/src/main/res/drawable-xxxhdpi/ic_attachment_stickers_white_24dp.png and /dev/null differ diff --git a/vector/src/main/res/drawable/ic_attachment_camera.xml b/vector/src/main/res/drawable/ic_attachment_camera.xml new file mode 100644 index 0000000000..8c7bedb3cf --- /dev/null +++ b/vector/src/main/res/drawable/ic_attachment_camera.xml @@ -0,0 +1,13 @@ + + + + diff --git a/vector/src/main/res/drawable/ic_attachment_camera_white_24dp.xml b/vector/src/main/res/drawable/ic_attachment_camera_white_24dp.xml deleted file mode 100644 index 5c2920d252..0000000000 --- a/vector/src/main/res/drawable/ic_attachment_camera_white_24dp.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/vector/src/main/res/drawable/ic_attachment_file.xml b/vector/src/main/res/drawable/ic_attachment_file.xml new file mode 100644 index 0000000000..b3545e54a6 --- /dev/null +++ b/vector/src/main/res/drawable/ic_attachment_file.xml @@ -0,0 +1,13 @@ + + + diff --git a/vector/src/main/res/drawable/ic_attachment_file_white_24dp.xml b/vector/src/main/res/drawable/ic_attachment_file_white_24dp.xml deleted file mode 100644 index 4e6b9458f8..0000000000 --- a/vector/src/main/res/drawable/ic_attachment_file_white_24dp.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/vector/src/main/res/drawable/ic_attachment_gallery.xml b/vector/src/main/res/drawable/ic_attachment_gallery.xml new file mode 100644 index 0000000000..0f3432544f --- /dev/null +++ b/vector/src/main/res/drawable/ic_attachment_gallery.xml @@ -0,0 +1,12 @@ + + + diff --git a/vector/src/main/res/drawable/ic_attachment_gallery_white_24dp.xml b/vector/src/main/res/drawable/ic_attachment_gallery_white_24dp.xml deleted file mode 100644 index d4e68f125b..0000000000 --- a/vector/src/main/res/drawable/ic_attachment_gallery_white_24dp.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/vector/src/main/res/drawable/ic_attachment_location.xml b/vector/src/main/res/drawable/ic_attachment_location.xml new file mode 100644 index 0000000000..c2c8093e1d --- /dev/null +++ b/vector/src/main/res/drawable/ic_attachment_location.xml @@ -0,0 +1,9 @@ + + + diff --git a/vector/src/main/res/drawable/ic_attachment_poll_white_24dp.xml b/vector/src/main/res/drawable/ic_attachment_poll.xml similarity index 93% rename from vector/src/main/res/drawable/ic_attachment_poll_white_24dp.xml rename to vector/src/main/res/drawable/ic_attachment_poll.xml index 8cbcc6e47c..320dccb7fc 100644 --- a/vector/src/main/res/drawable/ic_attachment_poll_white_24dp.xml +++ b/vector/src/main/res/drawable/ic_attachment_poll.xml @@ -5,6 +5,6 @@ android:viewportHeight="24"> diff --git a/vector/src/main/res/drawable/ic_attachment_sticker.xml b/vector/src/main/res/drawable/ic_attachment_sticker.xml new file mode 100644 index 0000000000..eb59eaa75d --- /dev/null +++ b/vector/src/main/res/drawable/ic_attachment_sticker.xml @@ -0,0 +1,13 @@ + + + diff --git a/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml b/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml index 3378878ac6..7e926b860c 100644 --- a/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml +++ b/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml @@ -108,9 +108,9 @@ - + android:layout_height="@dimen/composer_min_height" + android:background="?android:colorBackground"> - + + + android:layout_marginStart="4dp" + android:scrollbars="none" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/attachmentCloseButton" + app:layout_constraintTop_toTopOf="parent"> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> - + - + - + - + - + - + + - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/vector/src/main/res/layout/view_voice_message_recorder.xml b/vector/src/main/res/layout/view_voice_message_recorder.xml index 53be4f07f6..9f8e58d724 100644 --- a/vector/src/main/res/layout/view_voice_message_recorder.xml +++ b/vector/src/main/res/layout/view_voice_message_recorder.xml @@ -34,7 +34,7 @@