diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index 6fc4b1782c..6c44905b98 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -292,10 +292,10 @@ public class ConversationListFragment extends MainFragment implements ActionMode viewModel.setFiltered(false, source); break; case OPENING: + ViewUtil.setMinimumHeight(collapsingToolbarLayout, openHeight); viewModel.setFiltered(true, source); break; case OPEN_APEX: - ViewUtil.setMinimumHeight(collapsingToolbarLayout, openHeight); if (source == ConversationFilterSource.DRAG) { SignalStore.uiHints().incrementNeverDisplayPullToFilterTip(); } @@ -1619,6 +1619,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode public int getSwipeDirs(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { if (viewHolder.itemView instanceof ConversationListItemAction || viewHolder instanceof ConversationListAdapter.HeaderViewHolder || + viewHolder instanceof ClearFilterViewHolder || actionMode != null || viewHolder.itemView.isSelected() || activeAdapter == searchAdapter) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/ConversationListFilterPullView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/ConversationListFilterPullView.kt index 123d5935ff..f8675128ac 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/ConversationListFilterPullView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/ConversationListFilterPullView.kt @@ -43,6 +43,9 @@ class ConversationListFilterPullView @JvmOverloads constructor( private const val ANIMATE_HELP_TEXT_VELOCITY_THRESHOLD = 1f private const val ANIMATE_HELP_TEXT_THRESHOLD = 30 private const val ANIMATE_HELP_TEXT_START_FRACTION = 0.35f + + private const val CANCEL_THRESHOLD = 0.92f + private val COLOR_EVALUATOR = ArgbEvaluatorCompat.getInstance() } @@ -106,7 +109,7 @@ class ConversationListFilterPullView @JvmOverloads constructor( if (state == FilterPullState.CLOSED && progress <= 0) { setState(FilterPullState.CLOSED, ConversationFilterSource.DRAG) - } else if (state == FilterPullState.CLOSED && progress >= 1f) { + } else if ((state == FilterPullState.CLOSED || state == FilterPullState.CANCELING) && progress >= 1f) { setState(FilterPullState.OPEN_APEX, ConversationFilterSource.DRAG) vibrate() resetHelpText() @@ -115,6 +118,15 @@ class ConversationListFilterPullView @JvmOverloads constructor( setState(FilterPullState.CLOSE_APEX, ConversationFilterSource.DRAG) vibrate() animatePillColor() + } else if (state == FilterPullState.OPEN_APEX && progress <= CANCEL_THRESHOLD) { + setState(FilterPullState.CANCELING, ConversationFilterSource.DRAG) + vibrate() + } + + if (state == FilterPullState.CANCELING) { + binding.filterCircle.alpha = FilterLerp.getCircleCancelAlphaLerp(progress) + } else { + binding.filterCircle.alpha = 1f } if (state == FilterPullState.CLOSED && animateHelpText < ANIMATE_HELP_TEXT_THRESHOLD) { @@ -151,7 +163,7 @@ class ConversationListFilterPullView @JvmOverloads constructor( fun onUserDragFinished() { if (state == FilterPullState.OPEN_APEX) { open(ConversationFilterSource.DRAG) - } else if (state == FilterPullState.CLOSE_APEX) { + } else if (state == FilterPullState.CLOSE_APEX || state == FilterPullState.CANCELING) { close(ConversationFilterSource.DRAG) } } @@ -257,7 +269,7 @@ class ConversationListFilterPullView @JvmOverloads constructor( private fun FilterPullState.toLatestSettledState(): FilterPullState { return when (this) { - FilterPullState.CLOSED, FilterPullState.OPEN_APEX, FilterPullState.OPENING -> FilterPullState.CLOSED + FilterPullState.CLOSED, FilterPullState.OPEN_APEX, FilterPullState.OPENING, FilterPullState.CANCELING -> FilterPullState.CLOSED FilterPullState.OPEN, FilterPullState.CLOSE_APEX, FilterPullState.CLOSING -> FilterPullState.OPEN } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterCircleView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterCircleView.kt index 8556e4f8b1..e22bf5fd05 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterCircleView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterCircleView.kt @@ -175,13 +175,13 @@ class FilterCircleView @JvmOverloads constructor( private fun evaluateBottomOffset(progress: Float, state: FilterPullState): Float { return when (state) { - FilterPullState.OPEN_APEX, FilterPullState.OPENING, FilterPullState.OPEN, FilterPullState.CLOSE_APEX -> FilterLerp.getOpenCircleBottomPadLerp(progress) + FilterPullState.OPENING, FilterPullState.OPEN, FilterPullState.CLOSE_APEX, FilterPullState.CANCELING, FilterPullState.OPEN_APEX -> FilterLerp.getOpenCircleBottomPadLerp(progress) FilterPullState.CLOSED, FilterPullState.CLOSING -> FilterLerp.getClosedCircleBottomPadLerp(progress) } } private fun checkColorAnimators(state: FilterPullState) { - if (state != FilterPullState.CLOSED) { + if (state != FilterPullState.CLOSED && state != FilterPullState.CANCELING) { if (circleColorAnimator == null) { circleColorAnimator = ValueAnimator .ofInt(circleBackgroundColor, circleActiveBackgroundColor).apply { @@ -248,6 +248,7 @@ class FilterCircleView @JvmOverloads constructor( val circleAlpha = when (state) { FilterPullState.CLOSED -> 255 FilterPullState.OPEN_APEX -> 255 + FilterPullState.CANCELING -> 255 FilterPullState.OPENING -> 255 FilterPullState.OPEN -> 0 FilterPullState.CLOSE_APEX -> 0 diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterLerp.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterLerp.kt index 9168bbe8be..b7d9c3d887 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterLerp.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterLerp.kt @@ -43,6 +43,11 @@ object FilterLerp { Point(0.7f * FILTER_APEX / 100, 1f) ) + private val CIRCLE_CANCEL_ALPHA_LERP = getFn( + Point(0.61f, 1f), + Point(0.43f, 0f) + ) + private fun helpTextAlphaLerp(@FloatRange(from = 0.0, to = 1.0) startFraction: Float) = getFn( Point(startFraction, 0f), Point(1f, 1f) @@ -56,6 +61,10 @@ object FilterLerp { return Util.clamp(getLerp(fraction, PILL_CLOSE_APEX_ALPHA_LERP), 0f, 1f) } + fun getCircleCancelAlphaLerp(fraction: Float): Float { + return Util.clamp(getLerp(fraction, CIRCLE_CANCEL_ALPHA_LERP), 0f, 1f) + } + /** * Get the LERP for the "Filter enabled" pill. */ diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterPullState.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterPullState.kt index 23122fff9d..68541e925b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterPullState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/chatfilter/FilterPullState.kt @@ -16,6 +16,12 @@ enum class FilterPullState { */ OPEN_APEX, + /** + * The filter has been dragged all the way to the apex, but the user started to drag back instead of + * releasing the filter. + */ + CANCELING, + /** * The filter is being activated and the animation is running. */