Update multi-forward work with tweaks from design.

This commit is contained in:
Alex Hart 2021-08-13 13:25:43 -03:00 committed by Cody Henthorne
parent 8e2a265cf3
commit 7448183ff4
8 changed files with 50 additions and 18 deletions

View file

@ -15,6 +15,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.widget.TextViewCompat;
@ -101,7 +102,6 @@ public final class ContactFilterView extends FrameLayout {
expandTapArea(toggleContainer, dialpadToggle);
applyAttributes(searchText, context, attrs, defStyleAttr);
searchText.requestFocus();
}
private void applyAttributes(@NonNull EditText searchText,
@ -121,6 +121,11 @@ public final class ContactFilterView extends FrameLayout {
if (!attributes.getBoolean(R.styleable.ContactFilterToolbar_showDialpad, true)) {
dialpadToggle.setVisibility(GONE);
}
if (attributes.getBoolean(R.styleable.ContactFilterToolbar_cfv_autoFocus, true)) {
searchText.requestFocus();
}
attributes.recycle();
}
@ -137,6 +142,10 @@ public final class ContactFilterView extends FrameLayout {
this.listener = listener;
}
public void setOnSearchInputFocusChangedListener(@Nullable OnFocusChangeListener listener) {
searchText.setOnFocusChangeListener(listener);
}
public void setHint(@StringRes int hint) {
searchText.setHint(hint);
}

View file

@ -19,6 +19,8 @@ import org.thoughtcrime.securesms.util.ViewUtil
*/
abstract class FixedRoundedCornerBottomSheetDialogFragment : BottomSheetDialogFragment() {
protected open val peekHeightPercentage: Float = 0.5f
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.Widget_Signal_FixedRoundedCorners)
@ -27,7 +29,7 @@ abstract class FixedRoundedCornerBottomSheetDialogFragment : BottomSheetDialogFr
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
dialog.behavior.peekHeight = (resources.displayMetrics.heightPixels * 0.50).toInt()
dialog.behavior.peekHeight = (resources.displayMetrics.heightPixels * peekHeightPercentage).toInt()
val shapeAppearanceModel = ShapeAppearanceModel.builder()
.setTopLeftCorner(CornerFamily.ROUNDED, ViewUtil.dpToPx(requireContext(), 18).toFloat())

View file

@ -541,8 +541,11 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
} else if (multiselectPart instanceof MultiselectPart.Text && hasThumbnail(messageRecord)) {
Projection projection = Projection.relativeToViewRoot(mediaThumbnailStub.require(), null);
return (int) projection.getY() + projection.getHeight();
} else {
} else if (hasNoBubble(messageRecord)) {
return getTop();
} else {
Projection projection = Projection.relativeToViewRoot(bodyBubble, null);
return (int) projection.getY();
}
}
@ -551,8 +554,11 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
if (multiselectPart instanceof MultiselectPart.Attachments && hasThumbnail(messageRecord)) {
Projection projection = Projection.relativeToViewRoot(mediaThumbnailStub.require(), null);
return (int) projection.getY() + projection.getHeight();
} else {
} else if (hasNoBubble(messageRecord)) {
return getBottom();
} else {
Projection projection = Projection.relativeToViewRoot(bodyBubble, null);
return (int) projection.getY() + projection.getHeight();
}
}

View file

@ -29,7 +29,6 @@ class MultiselectItemDecoration(context: Context, private val chatWallpaperProvi
private val path = Path()
private val rect = Rect()
private val gutter = ViewUtil.dpToPx(48)
private val paddingBottom = ViewUtil.dpToPx(9)
private val paddingStart = ViewUtil.dpToPx(17)
private val circleRadius = ViewUtil.dpToPx(11)
private val checkDrawable = requireNotNull(AppCompatResources.getDrawable(context, R.drawable.ic_check_circle_solid_24)).apply {
@ -37,7 +36,6 @@ class MultiselectItemDecoration(context: Context, private val chatWallpaperProvi
}
private val photoCircleRadius = ViewUtil.dpToPx(12)
private val photoCirclePaddingStart = ViewUtil.dpToPx(16)
private val photoCirclePaddingBottom = ViewUtil.dpToPx(8)
private val transparentBlack20 = ContextCompat.getColor(context, R.color.transparent_black_20)
private val transparentWhite20 = ContextCompat.getColor(context, R.color.transparent_white_20)
@ -155,15 +153,16 @@ class MultiselectItemDecoration(context: Context, private val chatWallpaperProvi
val parts: MultiselectCollection = child.conversationMessage.multiselectCollection
parts.toSet().forEach {
val boundary = child.getBottomBoundaryOfMultiselectPart(it)
val topBoundary = child.getTopBoundaryOfMultiselectPart(it)
val bottomBoundary = child.getBottomBoundaryOfMultiselectPart(it)
if (drawCircleBehindSelector) {
drawPhotoCircle(canvas, parent, boundary)
drawPhotoCircle(canvas, parent, topBoundary, bottomBoundary)
}
if (adapter.selectedItems.contains(it)) {
drawSelectedCircle(canvas, parent, boundary)
drawSelectedCircle(canvas, parent, topBoundary, bottomBoundary)
} else {
drawUnselectedCircle(canvas, parent, boundary)
drawUnselectedCircle(canvas, parent, topBoundary, bottomBoundary)
}
}
}
@ -173,14 +172,14 @@ class MultiselectItemDecoration(context: Context, private val chatWallpaperProvi
* Draws an extra circle behind the selection circle. This is to make it easier to see and
* is specifically for when a photo wallpaper is being used.
*/
private fun drawPhotoCircle(canvas: Canvas, parent: RecyclerView, bottomBoundary: Int) {
private fun drawPhotoCircle(canvas: Canvas, parent: RecyclerView, topBoundary: Int, bottomBoundary: Int) {
val centerX: Float = if (ViewUtil.isLtr(parent)) {
photoCirclePaddingStart + photoCircleRadius
} else {
parent.right - photoCircleRadius - photoCirclePaddingStart
}.toFloat()
val centerY: Float = bottomBoundary - photoCircleRadius - photoCirclePaddingBottom.toFloat()
val centerY: Float = topBoundary + (bottomBoundary - topBoundary).toFloat() / 2
canvas.drawCircle(centerX, centerY, photoCircleRadius.toFloat(), photoCirclePaint)
}
@ -188,14 +187,14 @@ class MultiselectItemDecoration(context: Context, private val chatWallpaperProvi
/**
* Draws the checkmark for selected content
*/
private fun drawSelectedCircle(canvas: Canvas, parent: RecyclerView, bottomBoundary: Int) {
private fun drawSelectedCircle(canvas: Canvas, parent: RecyclerView, topBoundary: Int, bottomBoundary: Int) {
val topX: Float = if (ViewUtil.isLtr(parent)) {
paddingStart
} else {
parent.right - paddingStart - circleRadius * 2
}.toFloat()
val topY: Float = bottomBoundary - circleRadius * 2 - paddingBottom.toFloat()
val topY: Float = topBoundary + (bottomBoundary - topBoundary).toFloat() / 2 - circleRadius
canvas.save()
canvas.translate(topX, topY)
@ -206,14 +205,14 @@ class MultiselectItemDecoration(context: Context, private val chatWallpaperProvi
/**
* Draws the empty circle for unselected content
*/
private fun drawUnselectedCircle(c: Canvas, parent: RecyclerView, bottomBoundary: Int) {
private fun drawUnselectedCircle(c: Canvas, parent: RecyclerView, topBoundary: Int, bottomBoundary: Int) {
val centerX: Float = if (ViewUtil.isLtr(parent)) {
paddingStart + circleRadius
} else {
parent.right - circleRadius - paddingStart
}.toFloat()
val centerY: Float = bottomBoundary - circleRadius - paddingBottom.toFloat()
val centerY: Float = topBoundary + (bottomBoundary - topBoundary).toFloat() / 2
c.drawCircle(centerX, centerY, circleRadius.toFloat(), unselectedPaint)
}

View file

@ -12,6 +12,8 @@ import androidx.core.view.isVisible
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.ContactSelectionListFragment
import org.thoughtcrime.securesms.R
@ -35,9 +37,12 @@ private val TAG = Log.tag(MultiselectForwardFragment::class.java)
class MultiselectForwardFragment : FixedRoundedCornerBottomSheetDialogFragment(), ContactSelectionListFragment.OnContactSelectedListener, ContactSelectionListFragment.OnSelectionLimitReachedListener {
override val peekHeightPercentage: Float = 0.67f
private val viewModel: MultiselectForwardViewModel by viewModels(factoryProducer = this::createViewModelFactory)
private lateinit var selectionFragment: ContactSelectionListFragment
private lateinit var contactFilterView: ContactFilterView
private fun createViewModelFactory(): MultiselectForwardViewModel.Factory {
return MultiselectForwardViewModel.Factory(getMultiShareArgs(), MultiselectForwardRepository(requireContext()))
@ -70,7 +75,13 @@ class MultiselectForwardFragment : FixedRoundedCornerBottomSheetDialogFragment()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
selectionFragment = childFragmentManager.findFragmentById(R.id.contact_selection_list_fragment) as ContactSelectionListFragment
val contactFilterView: ContactFilterView = view.findViewById(R.id.contact_filter_edit_text)
contactFilterView = view.findViewById(R.id.contact_filter_edit_text)
contactFilterView.setOnSearchInputFocusChangedListener { _, hasFocus ->
if (hasFocus) {
(requireDialog() as BottomSheetDialog).behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
contactFilterView.setOnFilterChangedListener {
if (it.isNullOrEmpty()) {
@ -145,6 +156,7 @@ class MultiselectForwardFragment : FixedRoundedCornerBottomSheetDialogFragment()
if (recipientId.isPresent) {
viewModel.addSelectedContact(recipientId, null)
callback.accept(true)
contactFilterView.clear()
} else {
Log.w(TAG, "Rejecting non-present recipient. Can't forward to an unknown contact.")
callback.accept(false)

View file

@ -2,6 +2,7 @@
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<View
@ -28,7 +29,8 @@
android:layout_marginLeft="@dimen/dsl_settings_gutter"
android:layout_marginTop="17dp"
android:layout_marginRight="@dimen/dsl_settings_gutter"
android:minHeight="44dp" />
android:minHeight="44dp"
app:cfv_autoFocus="false" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/contact_selection_list_fragment"

View file

@ -44,6 +44,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dsl_settings_gutter"
android:layout_marginEnd="@dimen/dsl_settings_gutter"
android:layout_marginBottom="8dp"
android:background="@drawable/rounded_rectangle_secondary"
android:hint="@string/MultiselectForwardFragment__add_a_message"
android:minHeight="44dp"

View file

@ -227,6 +227,7 @@
<declare-styleable name="ContactFilterToolbar">
<attr name="searchTextStyle" format="reference" />
<attr name="showDialpad" format="boolean" />
<attr name="cfv_autoFocus" format="boolean" />
</declare-styleable>
<declare-styleable name="SquareImageView">