Skip to content

Commit

Permalink
Background file viewer playlist creation
Browse files Browse the repository at this point in the history
  • Loading branch information
hardcore-sushi committed Nov 14, 2024
1 parent 07f5f8b commit f901495
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import sushi.hardcore.droidfs.BaseActivity
import sushi.hardcore.droidfs.FileTypes
import sushi.hardcore.droidfs.R
import sushi.hardcore.droidfs.VolumeManagerApp
import sushi.hardcore.droidfs.explorers.ExplorerElement
import sushi.hardcore.droidfs.filesystems.EncryptedVolume
import sushi.hardcore.droidfs.util.IntentUtils
import sushi.hardcore.droidfs.util.PathUtils
import sushi.hardcore.droidfs.util.finishOnClose
import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder
Expand All @@ -32,9 +33,8 @@ abstract class FileViewerActivity: BaseActivity() {
private lateinit var originalParentPath: String
private lateinit var windowInsetsController: WindowInsetsControllerCompat
private var windowTypeMask = 0
private var foldersFirst = true
private var wasMapped = false
protected val mappedPlaylist = mutableListOf<ExplorerElement>()
protected val playlist = mutableListOf<ExplorerElement>()
private val playlistMutex = Mutex()
protected var currentPlaylistIndex = -1
private val isLegacyFullscreen = Build.VERSION.SDK_INT <= Build.VERSION_CODES.R

Expand All @@ -46,7 +46,6 @@ abstract class FileViewerActivity: BaseActivity() {
intent.getIntExtra("volumeId", -1)
)!!
finishOnClose(encryptedVolume)
foldersFirst = sharedPrefs.getBoolean("folders_first", true)
windowInsetsController = WindowInsetsControllerCompat(window, window.decorView)
windowInsetsController.addOnControllableInsetsChangedListener { _, typeMask ->
windowTypeMask = typeMask
Expand Down Expand Up @@ -131,48 +130,53 @@ abstract class FileViewerActivity: BaseActivity() {
}
}

protected fun createPlaylist() {
if (!wasMapped){
encryptedVolume.recursiveMapFiles(originalParentPath)?.let { elements ->
for (e in elements) {
if (e.isRegularFile) {
if (FileTypes.isExtensionType(getFileType(), e.name) || filePath == e.fullPath) {
mappedPlaylist.add(e)
}
}
}
protected suspend fun createPlaylist() {
playlistMutex.withLock {
if (currentPlaylistIndex != -1) {
// playlist already initialized
return
}
val sortOrder = intent.getStringExtra("sortOrder") ?: "name"
ExplorerElement.sortBy(sortOrder, foldersFirst, mappedPlaylist)
//find current index
for ((i, e) in mappedPlaylist.withIndex()){
if (filePath == e.fullPath){
currentPlaylistIndex = i
break
withContext(Dispatchers.IO) {
encryptedVolume.recursiveMapFiles(originalParentPath)?.filterTo(playlist) { e ->
e.isRegularFile && (FileTypes.isExtensionType(getFileType(), e.name) || filePath == e.fullPath)
}
val sortOrder = intent.getStringExtra("sortOrder") ?: "name"
val foldersFirst = sharedPrefs.getBoolean("folders_first", true)
ExplorerElement.sortBy(sortOrder, foldersFirst, playlist)
currentPlaylistIndex = playlist.indexOfFirst { it.fullPath == filePath }
}
wasMapped = true
}
}

protected fun playlistNext(forward: Boolean) {
private fun updateCurrentItem() {
filePath = playlist[currentPlaylistIndex].fullPath
}

protected suspend fun playlistNext(forward: Boolean) {
createPlaylist()
currentPlaylistIndex = if (forward) {
(currentPlaylistIndex+1)%mappedPlaylist.size
(currentPlaylistIndex + 1).mod(playlist.size)
} else {
var x = (currentPlaylistIndex-1)%mappedPlaylist.size
if (x < 0) {
x += mappedPlaylist.size
}
x
(currentPlaylistIndex - 1).mod(playlist.size)
}
filePath = mappedPlaylist[currentPlaylistIndex].fullPath
updateCurrentItem()
}

protected fun refreshPlaylist() {
mappedPlaylist.clear()
wasMapped = false
createPlaylist()
protected suspend fun deleteCurrentFile(): Boolean {
createPlaylist() // ensure we know the current position in the playlist
return if (encryptedVolume.deleteFile(filePath)) {
playlist.removeAt(currentPlaylistIndex)
if (playlist.size != 0) {
if (currentPlaylistIndex == playlist.size) {
// deleted the last element of the playlist, go back to the first
currentPlaylistIndex = 0
}
updateCurrentItem()
}
true
} else {
false
}
}

protected fun goBackToExplorer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import android.widget.Toast
import androidx.activity.addCallback
import androidx.activity.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import kotlinx.coroutines.launch
import sushi.hardcore.droidfs.Constants
import sushi.hardcore.droidfs.R
import sushi.hardcore.droidfs.databinding.ActivityImageViewerBinding
Expand Down Expand Up @@ -105,22 +107,21 @@ class ImageViewer: FileViewerActivity() {
.keepFullScreen()
.setTitle(R.string.warning)
.setPositiveButton(R.string.ok) { _, _ ->
createPlaylist() //be sure the playlist is created before deleting if there is only one image
if (encryptedVolume.deleteFile(filePath)) {
playlistNext(true)
refreshPlaylist()
if (mappedPlaylist.size == 0) { //deleted all images of the playlist
goBackToExplorer()
lifecycleScope.launch {
if (deleteCurrentFile()) {
if (playlist.size == 0) { // no more image left
goBackToExplorer()
} else {
loadImage(true)
}
} else {
loadImage(true)
CustomAlertDialogBuilder(this@ImageViewer, theme)
.keepFullScreen()
.setTitle(R.string.error)
.setMessage(getString(R.string.remove_failed, fileName))
.setPositiveButton(R.string.ok, null)
.show()
}
} else {
CustomAlertDialogBuilder(this, theme)
.keepFullScreen()
.setTitle(R.string.error)
.setMessage(getString(R.string.remove_failed, fileName))
.setPositiveButton(R.string.ok, null)
.show()
}
}
.setNegativeButton(R.string.cancel, null)
Expand Down Expand Up @@ -198,14 +199,16 @@ class ImageViewer: FileViewerActivity() {
rotateImage()
}

private fun swipeImage(deltaX: Float, slideshowSwipe: Boolean = false){
playlistNext(deltaX < 0)
loadImage(true)
if (slideshowActive) {
if (!slideshowSwipe) { //reset slideshow delay if user swipes
handler.removeCallbacks(slideshowNext)
private fun swipeImage(deltaX: Float, slideshowSwipe: Boolean = false) {
lifecycleScope.launch {
playlistNext(deltaX < 0)
loadImage(true)
if (slideshowActive) {
if (!slideshowSwipe) { // reset slideshow delay if user swipes
handler.removeCallbacks(slideshowNext)
}
handler.postDelayed(slideshowNext, Constants.SLIDESHOW_DELAY)
}
handler.postDelayed(slideshowNext, Constants.SLIDESHOW_DELAY)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sushi.hardcore.droidfs.file_viewers

import android.view.WindowManager
import androidx.annotation.OptIn
import androidx.lifecycle.lifecycleScope
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
Expand All @@ -11,6 +12,7 @@ import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.MediaSource
import androidx.media3.exoplayer.source.ProgressiveMediaSource
import androidx.media3.extractor.DefaultExtractorsFactory
import kotlinx.coroutines.launch
import sushi.hardcore.droidfs.Constants
import sushi.hardcore.droidfs.R
import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder
Expand Down Expand Up @@ -39,12 +41,16 @@ abstract class MediaPlayer: FileViewerActivity() {
private fun initializePlayer(){
player = ExoPlayer.Builder(this).setSeekForwardIncrementMs(5000).build()
bindPlayer(player)
createPlaylist()
for (e in mappedPlaylist) {
player.addMediaSource(createMediaSource(e.fullPath))
player.addMediaSource(createMediaSource(filePath))
lifecycleScope.launch {
createPlaylist()
playlist.forEachIndexed { index, e ->
if (index != currentPlaylistIndex) {
player.addMediaSource(index, createMediaSource(e.fullPath))
}
}
}
player.repeatMode = Player.REPEAT_MODE_ALL
player.seekToDefaultPosition(currentPlaylistIndex)
player.playWhenReady = true
player.addListener(object : Player.Listener{
override fun onVideoSizeChanged(videoSize: VideoSize) {
Expand All @@ -67,9 +73,11 @@ abstract class MediaPlayer: FileViewerActivity() {
}

override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
if (player.repeatMode != Player.REPEAT_MODE_ONE) {
playlistNext(player.currentMediaItemIndex == (currentPlaylistIndex + 1) % mappedPlaylist.size)
refreshFileName()
if (player.repeatMode != Player.REPEAT_MODE_ONE && currentPlaylistIndex != -1) {
lifecycleScope.launch {
playlistNext(player.currentMediaItemIndex == (currentPlaylistIndex + 1) % player.mediaItemCount)
refreshFileName()
}
}
}
})
Expand Down

0 comments on commit f901495

Please sign in to comment.