diff --git a/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenImageActivity.kt b/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenImageActivity.kt index be907c02d4..17b6e0b01b 100644 --- a/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenImageActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenImageActivity.kt @@ -5,6 +5,7 @@ * SPDX-FileCopyrightText: 2021 Andy Scherzinger * SPDX-FileCopyrightText: 2021 Marcel Hibbe * SPDX-FileCopyrightText: 2021 Dariusz Olszewski + * SPDX-FileCopyrightText: 2026 Enrique López-Mañas * SPDX-License-Identifier: GPL-3.0-or-later */ package com.nextcloud.talk.fullscreenfile @@ -12,6 +13,7 @@ package com.nextcloud.talk.fullscreenfile import android.content.Intent import android.os.Bundle import android.util.Log +import com.nextcloud.talk.ui.SwipeToCloseLayout import android.view.Menu import android.view.MenuItem import android.view.View @@ -133,6 +135,12 @@ class FullScreenImageActivity : AppCompatActivity() { binding.photoView.visibility = View.VISIBLE displayImage(path) } + + binding.swipeToCloseLayout.setOnSwipeToCloseListener(object : SwipeToCloseLayout.OnSwipeToCloseListener { + override fun onSwipeToClose() { + finish() + } + }) } private fun displayImage(path: String) { diff --git a/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenMediaActivity.kt b/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenMediaActivity.kt index 6d6c0caf6b..0ccf3e6477 100644 --- a/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenMediaActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/fullscreenfile/FullScreenMediaActivity.kt @@ -5,6 +5,7 @@ * SPDX-FileCopyrightText: 2023 Parneet Singh * SPDX-FileCopyrightText: 2021 Andy Scherzinger * SPDX-FileCopyrightText: 2021 Marcel Hibbe + * SPDX-FileCopyrightText: 2026 Enrique López-Mañas * SPDX-License-Identifier: GPL-3.0-or-later */ package com.nextcloud.talk.fullscreenfile @@ -39,6 +40,7 @@ import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.databinding.ActivityFullScreenMediaBinding +import com.nextcloud.talk.ui.SwipeToCloseLayout import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment import com.nextcloud.talk.utils.Mimetype.VIDEO_PREFIX_GENERIC import java.io.File @@ -135,6 +137,12 @@ class FullScreenMediaActivity : AppCompatActivity() { } } ) + + binding.swipeToCloseLayout.setOnSwipeToCloseListener(object : SwipeToCloseLayout.OnSwipeToCloseListener { + override fun onSwipeToClose() { + finish() + } + }) } override fun onStart() { diff --git a/app/src/main/java/com/nextcloud/talk/ui/SwipeToCloseLayout.kt b/app/src/main/java/com/nextcloud/talk/ui/SwipeToCloseLayout.kt new file mode 100644 index 0000000000..10ab956048 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/ui/SwipeToCloseLayout.kt @@ -0,0 +1,92 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2026 Enrique López-Mañas + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package com.nextcloud.talk.ui + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import android.view.View +import android.widget.FrameLayout +import androidx.customview.widget.ViewDragHelper +import kotlin.math.abs + +class SwipeToCloseLayout @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr) { + + private var dragHelper: ViewDragHelper + private var swipeListener: OnSwipeToCloseListener? = null + + interface OnSwipeToCloseListener { + fun onSwipeToClose() + } + + init { + dragHelper = ViewDragHelper.create(this, 1.0f, DragCallback()) + } + + fun setOnSwipeToCloseListener(listener: OnSwipeToCloseListener) { + this.swipeListener = listener + } + + override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { + val action = ev.actionMasked + if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { + dragHelper.cancel() + return false + } + return dragHelper.shouldInterceptTouchEvent(ev) + } + + override fun onTouchEvent(ev: MotionEvent): Boolean { + dragHelper.processTouchEvent(ev) + return true + } + + private inner class DragCallback : ViewDragHelper.Callback() { + override fun tryCaptureView(child: View, pointerId: Int): Boolean { + return true // Capture any child view + } + + override fun getViewVerticalDragRange(child: View): Int { + return height + } + + override fun clampViewPositionVertical(child: View, therapeutic: Int, dy: Int): Int { + return therapeutic + } + + override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) { + val totalDragDistance = abs(releasedChild.top) + if (totalDragDistance > height * DRAG_THRESHOLD || abs(yvel) > dragHelper.minVelocity) { + swipeListener?.onSwipeToClose() + } else { + dragHelper.settleCapturedViewAt(0, 0) + invalidate() + } + } + + override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) { + val progress = 1f - (abs(top).toFloat() / height) + alpha = progress.coerceIn(MIN_ALPHA, MAX_ALPHA) + } + } + + override fun computeScroll() { + if (dragHelper.continueSettling(true)) { + postInvalidateOnAnimation() + } + } + + companion object { + private const val DRAG_THRESHOLD = 0.3f + private const val MIN_ALPHA = 0.5f + private const val MAX_ALPHA = 1.0f + } +} diff --git a/app/src/main/res/layout/activity_full_screen_image.xml b/app/src/main/res/layout/activity_full_screen_image.xml index 688b5e7072..4c98c772c6 100644 --- a/app/src/main/res/layout/activity_full_screen_image.xml +++ b/app/src/main/res/layout/activity_full_screen_image.xml @@ -5,12 +5,13 @@ ~ SPDX-FileCopyrightText: 2021 Andy Scherzinger ~ SPDX-FileCopyrightText: 2021 Marcel Hibbe ~ SPDX-FileCopyrightText: 2021 Dariusz Olszewski + ~ SPDX-FileCopyrightText: 2026 Enrique López-Mañas ~ SPDX-License-Identifier: GPL-3.0-or-later --> - @@ -35,4 +36,4 @@ android:layout_height="match_parent" android:visibility="invisible" /> - + diff --git a/app/src/main/res/layout/activity_full_screen_media.xml b/app/src/main/res/layout/activity_full_screen_media.xml index 5481092c82..cbf8f6f875 100644 --- a/app/src/main/res/layout/activity_full_screen_media.xml +++ b/app/src/main/res/layout/activity_full_screen_media.xml @@ -4,11 +4,13 @@ ~ ~ SPDX-FileCopyrightText: 2021 Andy Scherzinger ~ SPDX-FileCopyrightText: 2021 Marcel Hibbe + ~ SPDX-FileCopyrightText: 2026 Enrique López-Mañas ~ SPDX-License-Identifier: GPL-3.0-or-later --> - @@ -28,4 +30,4 @@ app:show_buffering="when_playing" app:show_shuffle_button="true" /> - \ No newline at end of file + \ No newline at end of file