From 5efeb6876b72f369f901f4596ab6e6ec797c6bea Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Jun 2025 15:43:50 -0400 Subject: [PATCH] sort folders alphabetically and run image slideshows --- .../calculator/activities/PreviewActivity.kt | 51 +++++++++++++++++++ .../adapters/ImagePreviewAdapter.kt | 23 +++++++++ .../org/calculator/utils/FolderManager.kt | 2 +- app/src/main/res/drawable/ic_slideshow.xml | 9 ++++ app/src/main/res/layout/activity_preview.xml | 15 +++++- 5 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/drawable/ic_slideshow.xml diff --git a/app/src/main/java/devs/org/calculator/activities/PreviewActivity.kt b/app/src/main/java/devs/org/calculator/activities/PreviewActivity.kt index ab830e9..0335295 100644 --- a/app/src/main/java/devs/org/calculator/activities/PreviewActivity.kt +++ b/app/src/main/java/devs/org/calculator/activities/PreviewActivity.kt @@ -4,6 +4,7 @@ import android.net.Uri import android.os.Bundle import android.os.Handler import android.os.Looper +import android.view.View import android.view.WindowManager import android.widget.Toast import androidx.activity.enableEdgeToEdge @@ -21,6 +22,7 @@ import devs.org.calculator.utils.DialogUtil import devs.org.calculator.utils.FileManager import devs.org.calculator.utils.PrefsUtil import devs.org.calculator.utils.SecurityUtils +import kotlinx.coroutines.Runnable import kotlinx.coroutines.launch import java.io.File @@ -40,6 +42,22 @@ class PreviewActivity : AppCompatActivity() { private val hiddenFileRepository: HiddenFileRepository by lazy { HiddenFileRepository(AppDatabase.getDatabase(this).hiddenFileDao()) } + private var slideshowRunning = false + private val slideshowDelay = 2000L + + private val slideshowRunner = object : Runnable { + override fun run() { + if (slideshowRunning) { + if (currentPosition + 1 >= files.size) { + currentPosition = 0 + } else { + currentPosition += 1 + } + binding.viewPager.setCurrentItem(currentPosition, true) + mainHandler.postDelayed(this, slideshowDelay) + } + } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -134,6 +152,11 @@ class PreviewActivity : AppCompatActivity() { adapter = ImagePreviewAdapter(this, this) adapter.images = files + adapter.onSlideshowShouldStop = { + if (slideshowRunning) { + stopSlideshow() + } + } binding.viewPager.adapter = adapter if (currentPosition < files.size) { binding.viewPager.setCurrentItem(currentPosition, false) @@ -179,6 +202,34 @@ class PreviewActivity : AppCompatActivity() { currentPosition = position } }) + if (filetype != FileManager.FileType.IMAGE) { + binding.startSlideshow.visibility = View.GONE + } + binding.startSlideshow.setOnClickListener { + startSlideshow() + } + } + + private fun startSlideshow() { + if (!slideshowRunning) { + slideshowRunning = true + toggleToolbars() + mainHandler.postDelayed(slideshowRunner, slideshowDelay) + adapter.setImageZoomable(false) + } + } + + private fun stopSlideshow() { + slideshowRunning = false + toggleToolbars() + mainHandler.removeCallbacks(slideshowRunner) + adapter.setImageZoomable(true) + } + + private fun toggleToolbars() { + val visibility = if (slideshowRunning) View.GONE else View.VISIBLE + binding.toolbar.visibility = visibility + binding.footer.visibility = visibility } private fun handleDeleteFile() { diff --git a/app/src/main/java/devs/org/calculator/adapters/ImagePreviewAdapter.kt b/app/src/main/java/devs/org/calculator/adapters/ImagePreviewAdapter.kt index a078d7f..cfe8950 100644 --- a/app/src/main/java/devs/org/calculator/adapters/ImagePreviewAdapter.kt +++ b/app/src/main/java/devs/org/calculator/adapters/ImagePreviewAdapter.kt @@ -36,11 +36,14 @@ class ImagePreviewAdapter( private val hiddenFileRepository: HiddenFileRepository by lazy { HiddenFileRepository(AppDatabase.getDatabase(context).hiddenFileDao()) } + private var canZoomOnImages: Boolean = true var images: List get() = differ.currentList set(value) = differ.submitList(value) + var onSlideshowShouldStop: () -> Unit = {} + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder { val binding = ViewpagerItemsBinding.inflate(LayoutInflater.from(context), parent, false) return ImageViewHolder(binding) @@ -56,6 +59,11 @@ class ImagePreviewAdapter( override fun getItemCount(): Int = images.size + fun setImageZoomable(zoomable: Boolean) { + currentViewHolder?.setImageViewCanZoom(zoomable) + canZoomOnImages = zoomable + } + private fun stopAndResetCurrentAudio() { currentViewHolder?.stopAndResetAudio() currentPlayingPosition = -1 @@ -153,6 +161,11 @@ class ImagePreviewAdapter( binding.imageView.visibility = View.VISIBLE binding.videoView.visibility = View.GONE binding.audioBg.visibility = View.GONE + binding.imageView.isZoomable = canZoomOnImages + binding.imageView.doubleTapToZoom = canZoomOnImages + binding.imageView.setOnClickListener { + onSlideshowShouldStop() + } Glide.with(context) .load(uri) .error(R.drawable.encrypted) @@ -181,6 +194,11 @@ class ImagePreviewAdapter( binding.imageView.visibility = View.VISIBLE binding.audioBg.visibility = View.GONE binding.videoView.visibility = View.GONE + binding.imageView.isZoomable = canZoomOnImages + binding.imageView.doubleTapToZoom = canZoomOnImages + binding.imageView.setOnClickListener { + onSlideshowShouldStop() + } Glide.with(context) .load(uri) .error(R.drawable.encrypted) @@ -193,6 +211,11 @@ class ImagePreviewAdapter( } } + fun setImageViewCanZoom(zoomEnabled: Boolean) { + binding.imageView.doubleTapToZoom = zoomEnabled + binding.imageView.isZoomable = zoomEnabled + } + fun getFileFromUri(context: Context, uri: Uri): File? { return try { val inputStream = context.contentResolver.openInputStream(uri) diff --git a/app/src/main/java/devs/org/calculator/utils/FolderManager.kt b/app/src/main/java/devs/org/calculator/utils/FolderManager.kt index a81beeb..fd98590 100644 --- a/app/src/main/java/devs/org/calculator/utils/FolderManager.kt +++ b/app/src/main/java/devs/org/calculator/utils/FolderManager.kt @@ -39,7 +39,7 @@ class FolderManager { directory.listFiles()?.filter { it.isDirectory && it.name != ".nomedia" } ?: emptyList() } else { emptyList() - } + }.sortedBy { it.name } } fun getFilesInFolder(folder: File): List { diff --git a/app/src/main/res/drawable/ic_slideshow.xml b/app/src/main/res/drawable/ic_slideshow.xml new file mode 100644 index 0000000..5a4b5e3 --- /dev/null +++ b/app/src/main/res/drawable/ic_slideshow.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_preview.xml b/app/src/main/res/layout/activity_preview.xml index f014411..022fc89 100644 --- a/app/src/main/res/layout/activity_preview.xml +++ b/app/src/main/res/layout/activity_preview.xml @@ -14,6 +14,7 @@ android:orientation="horizontal" android:gravity="center_vertical" android:paddingLeft="15dp" + android:paddingRight="15dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" > + android:text="@string/preview_file" + android:layout_weight="1"/> +