Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit e5f57441 authored by cketti's avatar cketti Committed by GitHub
Browse files

Merge pull request #6462 from thundernest/limit_swipe_distance

Swipe actions: Limit how far list items can be dragged
parents b0636a32 ecdffa15
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
package com.fsck.k9

enum class SwipeAction {
    None,
    ToggleSelection,
    ToggleRead,
    ToggleStar,
    Archive,
    Delete,
    Spam,
    Move
enum class SwipeAction(val removesItem: Boolean) {
    None(removesItem = false),
    ToggleSelection(removesItem = false),
    ToggleRead(removesItem = false),
    ToggleStar(removesItem = false),
    Archive(removesItem = true),
    Delete(removesItem = true),
    Spam(removesItem = true),
    Move(removesItem = true)
}
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ dependencies {
    implementation "com.takisoft.preferencex:preferencex-colorpicker:${versions.preferencesFix}"
    implementation "androidx.recyclerview:recyclerview:${versions.androidxRecyclerView}"
    implementation project(':ui-utils:LinearLayoutManager')
    implementation project(':ui-utils:ItemTouchHelper')
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:${versions.androidxLifecycle}"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidxLifecycle}"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.androidxLifecycle}"
+1 −1
Original line number Diff line number Diff line
@@ -15,9 +15,9 @@ import android.widget.Toast
import androidx.appcompat.view.ActionMode
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import app.k9mail.ui.utils.itemtouchhelper.ItemTouchHelper
import app.k9mail.ui.utils.linearlayoutmanager.LinearLayoutManager
import com.fsck.k9.Account
import com.fsck.k9.Account.Expunge
+46 −8
Original line number Diff line number Diff line
@@ -10,9 +10,9 @@ import android.view.View.MeasureSpec
import android.widget.ImageView
import android.widget.TextView
import androidx.core.graphics.withTranslation
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import app.k9mail.ui.utils.itemtouchhelper.ItemTouchHelper
import com.fsck.k9.SwipeAction
import com.fsck.k9.ui.R
import kotlin.math.abs
@@ -27,12 +27,16 @@ class MessageListSwipeCallback(
    private val adapter: MessageListAdapter,
    private val listener: MessageListSwipeListener
) : ItemTouchHelper.Callback() {
    private val swipePadding = context.resources.getDimension(R.dimen.messageListSwipeIconPadding).toInt()
    private val swipeThreshold = context.resources.getDimension(R.dimen.messageListSwipeThreshold)
    private val backgroundColorPaint = Paint()

    private val swipeRightLayout: View
    private val swipeLeftLayout: View

    private var maxSwipeRightDistance: Int = -1
    private var maxSwipeLeftDistance: Int = -1

    init {
        val layoutInflater = LayoutInflater.from(context)

@@ -101,8 +105,9 @@ class MessageListSwipeCallback(
        val viewWidth = view.width
        val viewHeight = view.height

        val isViewAnimatingBack = !isCurrentlyActive && abs(dX).toInt() >= viewWidth
        val isViewAnimatingBack = !isCurrentlyActive

        if (dX != 0F) {
            canvas.withTranslation(x = view.left.toFloat(), y = view.top.toFloat()) {
                if (isViewAnimatingBack) {
                    drawBackground(dX, viewWidth, viewHeight)
@@ -111,6 +116,7 @@ class MessageListSwipeCallback(
                    drawLayout(dX, viewWidth, viewHeight, holder)
                }
            }
        }

        super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
    }
@@ -166,10 +172,42 @@ class MessageListSwipeCallback(
            val heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
            swipeLayout.measure(widthMeasureSpec, heightMeasureSpec)
            swipeLayout.layout(0, 0, width, height)

            if (swipeRight) {
                maxSwipeRightDistance = textView.right + swipePadding
            } else {
                maxSwipeLeftDistance = swipeLayout.width - textView.left + swipePadding
            }
        }

        swipeLayout.draw(this)
    }

    override fun getMaxSwipeDistance(recyclerView: RecyclerView, direction: Int): Int {
        return when (direction) {
            ItemTouchHelper.RIGHT -> if (maxSwipeRightDistance > 0) maxSwipeRightDistance else recyclerView.width
            ItemTouchHelper.LEFT -> if (maxSwipeLeftDistance > 0) maxSwipeLeftDistance else recyclerView.width
            else -> recyclerView.width
        }
    }

    override fun shouldAnimateOut(direction: Int): Boolean {
        return when (direction) {
            ItemTouchHelper.RIGHT -> swipeRightAction.removesItem
            ItemTouchHelper.LEFT -> swipeLeftAction.removesItem
            else -> error("Unsupported direction")
        }
    }

    override fun getAnimationDuration(
        recyclerView: RecyclerView,
        animationType: Int,
        animateDx: Float,
        animateDy: Float
    ): Long {
        val percentage = abs(animateDx) / recyclerView.width
        return (super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy) * percentage).toLong()
    }
}

fun interface SwipeActionSupportProvider {
+3 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@

    <TextView
        android:id="@+id/swipe_action_text"
        android:layout_width="0dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
@@ -37,8 +37,9 @@
        android:maxLines="1"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
        android:textColor="?attr/messageListSwipeIconTint"
        app:layout_constrainedWidth="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/swipe_action_icon"
        app:layout_constraintTop_toTopOf="parent"
Loading