Skip to content

space0clouds/instagram-like-carousel-indicators

Repository files navigation

Instagram Like Carousel Indicators

.pointerInput(Unit) {
    detectDragGesturesAfterLongPress(
        onDragStart = { .. },
        onDrag = { change, dragAmount ->
            if (enableDrag) {
                change.consume()

                accumulatedDragAmount.floatValue += dragAmount.x

                if (abs(accumulatedDragAmount.floatValue) >= threshold) {
                    val destinationPage = if (accumulatedDragAmount.floatValue < 0) {
                        pagerState.currentPage + 1
                    } else {
                        pagerState.currentPage - 1
                    }.coerceIn(0, pageCount - 1)

                    if (destinationPage != currentPage) {
                        hapticFeedback.performHapticFeedback(HapticFeedbackType.TextHandleMove)

                        onPageSelected(destinationPage)
                    }

                    accumulatedDragAmount.floatValue = 0F
                }
            }
        },
        onDragEnd = { .. },
        onDragCancel = { .. },
    )
}

PointerInputScope.detectDragGesturesAfterLongPress()

suspend fun PointerInputScope.detectDragGesturesAfterLongPress(
    onDragStart: (Offset) -> Unit = { },
    onDragEnd: () -> Unit = { },
    onDragCancel: () -> Unit = { },
    onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
) {
    awaitEachGesture {
        try {
            val down = awaitFirstDown(requireUnconsumed = false)
            val drag = awaitLongPressOrCancellation(down.id)
            if (drag != null) {
                onDragStart.invoke(drag.position)

                if (
                    drag(drag.id) {
                        onDrag(it, it.positionChange())
                        it.consume()
                    }
                ) {
                    // consume up if we quit drag gracefully with the up
                    currentEvent.changes.fastForEach {
                        if (it.changedToUp()) it.consume()
                    }
                    onDragEnd()
                } else {
                    onDragCancel()
                }
            }
        } catch (c: CancellationException) {
            onDragCancel()
            throw c
        }
    }
}
suspend fun AwaitPointerEventScope.drag(
    pointerId: PointerId,
    onDrag: (PointerInputChange) -> Unit
): Boolean {
    var pointer = pointerId
    while (true) {
        val change = awaitDragOrCancellation(pointer) ?: return false

        if (change.changedToUpIgnoreConsumed()) {
            return true
        }

        onDrag(change)
        pointer = change.id
    }
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages