Update multi-forward work with tweaks from design.
This commit is contained in:
parent
8e2a265cf3
commit
7448183ff4
8 changed files with 50 additions and 18 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Add table
Reference in a new issue