sort folders alphabetically and run image slideshows
This commit is contained in:
@@ -4,6 +4,7 @@ import android.net.Uri
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.enableEdgeToEdge
|
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.FileManager
|
||||||
import devs.org.calculator.utils.PrefsUtil
|
import devs.org.calculator.utils.PrefsUtil
|
||||||
import devs.org.calculator.utils.SecurityUtils
|
import devs.org.calculator.utils.SecurityUtils
|
||||||
|
import kotlinx.coroutines.Runnable
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -40,6 +42,22 @@ class PreviewActivity : AppCompatActivity() {
|
|||||||
private val hiddenFileRepository: HiddenFileRepository by lazy {
|
private val hiddenFileRepository: HiddenFileRepository by lazy {
|
||||||
HiddenFileRepository(AppDatabase.getDatabase(this).hiddenFileDao())
|
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?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -134,6 +152,11 @@ class PreviewActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
adapter = ImagePreviewAdapter(this, this)
|
adapter = ImagePreviewAdapter(this, this)
|
||||||
adapter.images = files
|
adapter.images = files
|
||||||
|
adapter.onSlideshowShouldStop = {
|
||||||
|
if (slideshowRunning) {
|
||||||
|
stopSlideshow()
|
||||||
|
}
|
||||||
|
}
|
||||||
binding.viewPager.adapter = adapter
|
binding.viewPager.adapter = adapter
|
||||||
if (currentPosition < files.size) {
|
if (currentPosition < files.size) {
|
||||||
binding.viewPager.setCurrentItem(currentPosition, false)
|
binding.viewPager.setCurrentItem(currentPosition, false)
|
||||||
@@ -179,6 +202,34 @@ class PreviewActivity : AppCompatActivity() {
|
|||||||
currentPosition = position
|
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() {
|
private fun handleDeleteFile() {
|
||||||
|
|||||||
@@ -36,11 +36,14 @@ class ImagePreviewAdapter(
|
|||||||
private val hiddenFileRepository: HiddenFileRepository by lazy {
|
private val hiddenFileRepository: HiddenFileRepository by lazy {
|
||||||
HiddenFileRepository(AppDatabase.getDatabase(context).hiddenFileDao())
|
HiddenFileRepository(AppDatabase.getDatabase(context).hiddenFileDao())
|
||||||
}
|
}
|
||||||
|
private var canZoomOnImages: Boolean = true
|
||||||
|
|
||||||
var images: List<File>
|
var images: List<File>
|
||||||
get() = differ.currentList
|
get() = differ.currentList
|
||||||
set(value) = differ.submitList(value)
|
set(value) = differ.submitList(value)
|
||||||
|
|
||||||
|
var onSlideshowShouldStop: () -> Unit = {}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
|
||||||
val binding = ViewpagerItemsBinding.inflate(LayoutInflater.from(context), parent, false)
|
val binding = ViewpagerItemsBinding.inflate(LayoutInflater.from(context), parent, false)
|
||||||
return ImageViewHolder(binding)
|
return ImageViewHolder(binding)
|
||||||
@@ -56,6 +59,11 @@ class ImagePreviewAdapter(
|
|||||||
|
|
||||||
override fun getItemCount(): Int = images.size
|
override fun getItemCount(): Int = images.size
|
||||||
|
|
||||||
|
fun setImageZoomable(zoomable: Boolean) {
|
||||||
|
currentViewHolder?.setImageViewCanZoom(zoomable)
|
||||||
|
canZoomOnImages = zoomable
|
||||||
|
}
|
||||||
|
|
||||||
private fun stopAndResetCurrentAudio() {
|
private fun stopAndResetCurrentAudio() {
|
||||||
currentViewHolder?.stopAndResetAudio()
|
currentViewHolder?.stopAndResetAudio()
|
||||||
currentPlayingPosition = -1
|
currentPlayingPosition = -1
|
||||||
@@ -153,6 +161,11 @@ class ImagePreviewAdapter(
|
|||||||
binding.imageView.visibility = View.VISIBLE
|
binding.imageView.visibility = View.VISIBLE
|
||||||
binding.videoView.visibility = View.GONE
|
binding.videoView.visibility = View.GONE
|
||||||
binding.audioBg.visibility = View.GONE
|
binding.audioBg.visibility = View.GONE
|
||||||
|
binding.imageView.isZoomable = canZoomOnImages
|
||||||
|
binding.imageView.doubleTapToZoom = canZoomOnImages
|
||||||
|
binding.imageView.setOnClickListener {
|
||||||
|
onSlideshowShouldStop()
|
||||||
|
}
|
||||||
Glide.with(context)
|
Glide.with(context)
|
||||||
.load(uri)
|
.load(uri)
|
||||||
.error(R.drawable.encrypted)
|
.error(R.drawable.encrypted)
|
||||||
@@ -181,6 +194,11 @@ class ImagePreviewAdapter(
|
|||||||
binding.imageView.visibility = View.VISIBLE
|
binding.imageView.visibility = View.VISIBLE
|
||||||
binding.audioBg.visibility = View.GONE
|
binding.audioBg.visibility = View.GONE
|
||||||
binding.videoView.visibility = View.GONE
|
binding.videoView.visibility = View.GONE
|
||||||
|
binding.imageView.isZoomable = canZoomOnImages
|
||||||
|
binding.imageView.doubleTapToZoom = canZoomOnImages
|
||||||
|
binding.imageView.setOnClickListener {
|
||||||
|
onSlideshowShouldStop()
|
||||||
|
}
|
||||||
Glide.with(context)
|
Glide.with(context)
|
||||||
.load(uri)
|
.load(uri)
|
||||||
.error(R.drawable.encrypted)
|
.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? {
|
fun getFileFromUri(context: Context, uri: Uri): File? {
|
||||||
return try {
|
return try {
|
||||||
val inputStream = context.contentResolver.openInputStream(uri)
|
val inputStream = context.contentResolver.openInputStream(uri)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class FolderManager {
|
|||||||
directory.listFiles()?.filter { it.isDirectory && it.name != ".nomedia" } ?: emptyList()
|
directory.listFiles()?.filter { it.isDirectory && it.name != ".nomedia" } ?: emptyList()
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}.sortedBy { it.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFilesInFolder(folder: File): List<File> {
|
fun getFilesInFolder(folder: File): List<File> {
|
||||||
|
|||||||
9
app/src/main/res/drawable/ic_slideshow.xml
Normal file
9
app/src/main/res/drawable/ic_slideshow.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:width="24dp">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/svgTintColor"
|
||||||
|
android:pathData="M10,8v8l5,-4 -5,-4zM19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM19,19L5,19L5,5h14v14z"/>
|
||||||
|
</vector>
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:paddingLeft="15dp"
|
android:paddingLeft="15dp"
|
||||||
|
android:paddingRight="15dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" >
|
app:layout_constraintTop_toTopOf="parent" >
|
||||||
<androidx.appcompat.widget.AppCompatImageButton
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
@@ -26,11 +27,20 @@
|
|||||||
android:id="@+id/back"/>
|
android:id="@+id/back"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:textSize="22sp"
|
android:textSize="22sp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:text="@string/preview_file"/>
|
android:text="@string/preview_file"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@drawable/ic_slideshow"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:background="#00000000"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:id="@+id/start_slideshow"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
@@ -44,6 +54,7 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/footer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
|
|||||||
Reference in New Issue
Block a user