From 7cc1a9ce178e6009b63ef3f854469284895de55b Mon Sep 17 00:00:00 2001
From: tibbi <tibor@kaputa.sk>
Date: Sat, 30 Sep 2017 22:06:32 +0200
Subject: [PATCH] move the media fetching related functions in a separate class

---
 .../asynctasks/GetDirectoriesAsynctask.kt     |   4 +-
 .../gallery/asynctasks/GetMediaAsynctask.kt   |   7 +-
 .../gallery/extensions/context.kt             | 302 +----------------
 .../gallery/helpers/MediaFetcher.kt           | 311 ++++++++++++++++++
 4 files changed, 318 insertions(+), 306 deletions(-)
 create mode 100644 app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt

diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt
index a6450aac1..44a1921dc 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetDirectoriesAsynctask.kt
@@ -10,8 +10,8 @@ import com.simplemobiletools.commons.helpers.SORT_DESCENDING
 import com.simplemobiletools.gallery.R
 import com.simplemobiletools.gallery.extensions.config
 import com.simplemobiletools.gallery.extensions.containsNoMedia
-import com.simplemobiletools.gallery.extensions.getMediaByDirectories
 import com.simplemobiletools.gallery.extensions.sumByLong
+import com.simplemobiletools.gallery.helpers.MediaFetcher
 import com.simplemobiletools.gallery.models.Directory
 import com.simplemobiletools.gallery.models.Medium
 import java.io.File
@@ -24,7 +24,7 @@ class GetDirectoriesAsynctask(val context: Context, val isPickVideo: Boolean, va
             return ArrayList()
 
         val config = context.config
-        val groupedMedia = context.getMediaByDirectories(isPickVideo, isPickImage)
+        val groupedMedia = MediaFetcher(context).getMediaByDirectories(isPickVideo, isPickImage)
         val directories = ArrayList<Directory>()
         val hidden = context.resources.getString(R.string.hidden)
         val albumCovers = config.parseAlbumCovers()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt
index 13002eb86..f0016b7f1 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/asynctasks/GetMediaAsynctask.kt
@@ -3,8 +3,7 @@ package com.simplemobiletools.gallery.asynctasks
 import android.content.Context
 import android.os.AsyncTask
 import com.simplemobiletools.gallery.extensions.config
-import com.simplemobiletools.gallery.extensions.getFilesFrom
-import com.simplemobiletools.gallery.extensions.getMediaByDirectories
+import com.simplemobiletools.gallery.helpers.MediaFetcher
 import com.simplemobiletools.gallery.models.Medium
 import java.util.*
 
@@ -14,7 +13,7 @@ class GetMediaAsynctask(val context: Context, val mPath: String, val isPickVideo
 
     override fun doInBackground(vararg params: Void): ArrayList<Medium> {
         return if (showAll) {
-            val mediaMap = context.getMediaByDirectories(isPickVideo, isPickImage)
+            val mediaMap = MediaFetcher(context).getMediaByDirectories(isPickVideo, isPickImage)
             val media = ArrayList<Medium>()
             for ((path, curMedia) in mediaMap) {
                 media.addAll(curMedia)
@@ -24,7 +23,7 @@ class GetMediaAsynctask(val context: Context, val mPath: String, val isPickVideo
             media.sort()
             media
         } else {
-            context.getFilesFrom(mPath, isPickImage, isPickVideo)
+            MediaFetcher(context).getFilesFrom(mPath, isPickImage, isPickVideo)
         }
     }
 
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt
index ac943fe25..c04c3371e 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt
@@ -10,20 +10,10 @@ import android.net.Uri
 import android.os.Build
 import android.provider.MediaStore
 import android.view.WindowManager
-import com.simplemobiletools.commons.extensions.*
-import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
-import com.simplemobiletools.commons.helpers.SORT_BY_NAME
-import com.simplemobiletools.commons.helpers.SORT_BY_SIZE
-import com.simplemobiletools.commons.helpers.SORT_DESCENDING
+import com.simplemobiletools.commons.extensions.humanizePath
 import com.simplemobiletools.gallery.activities.SettingsActivity
-import com.simplemobiletools.gallery.helpers.*
+import com.simplemobiletools.gallery.helpers.Config
 import com.simplemobiletools.gallery.models.Directory
-import com.simplemobiletools.gallery.models.Medium
-import java.io.File
-import java.util.LinkedHashMap
-import kotlin.collections.ArrayList
-import kotlin.collections.component1
-import kotlin.collections.component2
 
 val Context.portrait get() = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
 val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager
@@ -81,225 +71,6 @@ fun Context.launchSettings() {
 
 val Context.config: Config get() = Config.newInstance(this)
 
-fun Context.getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean): ArrayList<Medium> {
-    val projection = arrayOf(MediaStore.Images.Media._ID,
-            MediaStore.Images.Media.DISPLAY_NAME,
-            MediaStore.Images.Media.DATE_TAKEN,
-            MediaStore.Images.Media.DATE_MODIFIED,
-            MediaStore.Images.Media.DATA,
-            MediaStore.Images.Media.SIZE)
-    val uri = MediaStore.Files.getContentUri("external")
-    val selection = getSelectionQuery(curPath)
-    val selectionArgs = getSelectionArgsQuery(curPath)
-
-    return try {
-        val cur = contentResolver.query(uri, projection, selection, selectionArgs, getSortingForFolder(curPath))
-        parseCursor(this, cur, isPickImage, isPickVideo, curPath)
-    } catch (e: Exception) {
-        ArrayList()
-    }
-}
-
-fun Context.getSelectionQuery(path: String): String {
-    val dataQuery = "${MediaStore.Images.Media.DATA} LIKE ?"
-    return if (path.isEmpty()) {
-        var query = "($dataQuery)"
-        if (hasExternalSDCard()) {
-            query += " OR ($dataQuery)"
-        }
-        query
-    } else {
-        "($dataQuery AND ${MediaStore.Images.Media.DATA} NOT LIKE ?)"
-    }
-}
-
-fun Context.getSelectionArgsQuery(path: String): Array<String> {
-    return if (path.isEmpty()) {
-        if (hasExternalSDCard()) arrayOf("$internalStoragePath/%", "$sdCardPath/%") else arrayOf("$internalStoragePath/%")
-    } else {
-        arrayOf("$path/%", "$path/%/%")
-    }
-}
-
-private fun parseCursor(context: Context, cur: Cursor, isPickImage: Boolean, isPickVideo: Boolean, curPath: String): ArrayList<Medium> {
-    val curMedia = ArrayList<Medium>()
-    val config = context.config
-    val filterMedia = config.filterMedia
-    val showHidden = config.shouldShowHidden
-    val includedFolders = config.includedFolders.map { "${it.trimEnd('/')}/" }
-    val excludedFolders = config.excludedFolders.map { "${it.trimEnd('/')}/" }
-    val noMediaFolders = context.getNoMediaFolders()
-    val isThirdPartyIntent = config.isThirdPartyIntent
-
-    cur.use {
-        if (cur.moveToFirst()) {
-            do {
-                try {
-                    val path = cur.getStringValue(MediaStore.Images.Media.DATA)
-
-                    var filename = cur.getStringValue(MediaStore.Images.Media.DISPLAY_NAME) ?: ""
-                    if (filename.isEmpty())
-                        filename = path.getFilenameFromPath()
-
-                    val isImage = filename.isImageFast()
-                    val isVideo = if (isImage) false else filename.isVideoFast()
-                    val isGif = if (isImage || isVideo) false else filename.isGif()
-
-                    if (!isImage && !isVideo && !isGif)
-                        continue
-
-                    if (isVideo && (isPickImage || filterMedia and VIDEOS == 0))
-                        continue
-
-                    if (isImage && (isPickVideo || filterMedia and IMAGES == 0))
-                        continue
-
-                    if (isGif && filterMedia and GIFS == 0)
-                        continue
-
-                    if (!showHidden && filename.startsWith('.'))
-                        continue
-
-                    var size = cur.getLongValue(MediaStore.Images.Media.SIZE)
-                    val file = File(path)
-                    if (size == 0L) {
-                        size = file.length()
-                    }
-
-                    if (size <= 0L)
-                        continue
-
-                    var isExcluded = false
-                    excludedFolders.forEach {
-                        if (path.startsWith(it)) {
-                            isExcluded = true
-                            includedFolders.forEach {
-                                if (path.startsWith(it)) {
-                                    isExcluded = false
-                                }
-                            }
-                        }
-                    }
-
-                    if (!isExcluded && !showHidden) {
-                        noMediaFolders.forEach {
-                            if (path.startsWith(it)) {
-                                isExcluded = true
-                            }
-                        }
-                    }
-
-                    if (!isExcluded && !showHidden && path.contains("/.")) {
-                        isExcluded = true
-                    }
-
-                    if (!isExcluded || isThirdPartyIntent) {
-                        if (!file.exists())
-                            continue
-
-                        val dateTaken = cur.getLongValue(MediaStore.Images.Media.DATE_TAKEN)
-                        val dateModified = cur.getIntValue(MediaStore.Images.Media.DATE_MODIFIED) * 1000L
-
-                        val medium = Medium(filename, path, isVideo, dateModified, dateTaken, size)
-                        curMedia.add(medium)
-                    }
-                } catch (e: Exception) {
-                    continue
-                }
-            } while (cur.moveToNext())
-        }
-    }
-
-    config.includedFolders.filter { it.isNotEmpty() && (curPath.isEmpty() || it == curPath) }.forEach {
-        getMediaInFolder(it, curMedia, isPickImage, isPickVideo, filterMedia)
-    }
-
-    if (isThirdPartyIntent && curPath.isNotEmpty() && curMedia.isEmpty()) {
-        getMediaInFolder(curPath, curMedia, isPickImage, isPickVideo, filterMedia)
-    }
-
-    Medium.sorting = config.getFileSorting(curPath)
-    curMedia.sort()
-
-    return curMedia
-}
-
-private fun getMediaInFolder(folder: String, curMedia: ArrayList<Medium>, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int) {
-    val files = File(folder).listFiles() ?: return
-    for (file in files) {
-        val filename = file.name
-        val isImage = filename.isImageFast()
-        val isVideo = if (isImage) false else filename.isVideoFast()
-        val isGif = if (isImage || isVideo) false else filename.isGif()
-
-        if (!isImage && !isVideo)
-            continue
-
-        if (isVideo && (isPickImage || filterMedia and VIDEOS == 0))
-            continue
-
-        if (isImage && (isPickVideo || filterMedia and IMAGES == 0))
-            continue
-
-        if (isGif && filterMedia and GIFS == 0)
-            continue
-
-        val size = file.length()
-        if (size <= 0L)
-            continue
-
-        val dateTaken = file.lastModified()
-        val dateModified = file.lastModified()
-
-        val medium = Medium(filename, file.absolutePath, isVideo, dateModified, dateTaken, size)
-        val isAlreadyAdded = curMedia.any { it.path == file.absolutePath }
-        if (!isAlreadyAdded)
-            curMedia.add(medium)
-    }
-}
-
-fun Context.getSortingForFolder(path: String): String {
-    val sorting = config.getFileSorting(path)
-    val sortValue = when {
-        sorting and SORT_BY_NAME > 0 -> MediaStore.Images.Media.DISPLAY_NAME
-        sorting and SORT_BY_SIZE > 0 -> MediaStore.Images.Media.SIZE
-        sorting and SORT_BY_DATE_MODIFIED > 0 -> MediaStore.Images.Media.DATE_MODIFIED
-        else -> MediaStore.Images.Media.DATE_TAKEN
-    }
-
-    return if (sorting and SORT_DESCENDING > 0)
-        "$sortValue DESC"
-    else
-        "$sortValue ASC"
-}
-
-fun Context.getNoMediaFolders(): ArrayList<String> {
-    val folders = ArrayList<String>()
-    val noMediaCondition = "${MediaStore.Files.FileColumns.MEDIA_TYPE} = ${MediaStore.Files.FileColumns.MEDIA_TYPE_NONE}"
-
-    val uri = MediaStore.Files.getContentUri("external")
-    val columns = arrayOf(MediaStore.Files.FileColumns.DATA)
-    val where = "$noMediaCondition AND ${MediaStore.Files.FileColumns.TITLE} LIKE ?"
-    val args = arrayOf("%$NOMEDIA%")
-    var cursor: Cursor? = null
-
-    try {
-        cursor = contentResolver.query(uri, columns, where, args, null)
-        if (cursor?.moveToFirst() == true) {
-            do {
-                val path = cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)) ?: continue
-                val noMediaFile = File(path)
-                if (noMediaFile.exists())
-                    folders.add("${noMediaFile.parent}/")
-            } while (cursor.moveToNext())
-        }
-    } finally {
-        cursor?.close()
-    }
-
-    return folders
-}
-
 fun Context.movePinnedDirectoriesToFront(dirs: ArrayList<Directory>): ArrayList<Directory> {
     val foundFolders = ArrayList<Directory>()
     val pinnedFolders = config.pinnedFolders
@@ -310,75 +81,6 @@ fun Context.movePinnedDirectoriesToFront(dirs: ArrayList<Directory>): ArrayList<
     return dirs
 }
 
-fun Context.getMediaByDirectories(isPickVideo: Boolean, isPickImage: Boolean): HashMap<String, ArrayList<Medium>> {
-    val media = getFilesFrom("", isPickImage, isPickVideo)
-    val excludedPaths = config.excludedFolders
-    val includedPaths = config.includedFolders
-    val showHidden = config.shouldShowHidden
-    val directories = groupDirectories(media)
-
-    val removePaths = ArrayList<String>()
-    for ((path, curMedia) in directories) {
-        // make sure the path has uppercase letters wherever appropriate
-        val groupPath = File(curMedia.first().path).parent
-        if (!File(groupPath).exists() || !shouldFolderBeVisible(groupPath, excludedPaths, includedPaths, showHidden)) {
-            removePaths.add(groupPath.toLowerCase())
-        }
-    }
-
-    removePaths.forEach {
-        directories.remove(it)
-    }
-
-    return directories
-}
-
-private fun groupDirectories(media: ArrayList<Medium>): HashMap<String, ArrayList<Medium>> {
-    val directories = LinkedHashMap<String, ArrayList<Medium>>()
-    for (medium in media) {
-        val parentDir = File(medium.path).parent?.toLowerCase() ?: continue
-        if (directories.containsKey(parentDir)) {
-            directories[parentDir]!!.add(medium)
-        } else {
-            directories.put(parentDir, arrayListOf(medium))
-        }
-    }
-    return directories
-}
-
-private fun shouldFolderBeVisible(path: String, excludedPaths: MutableSet<String>, includedPaths: MutableSet<String>, showHidden: Boolean): Boolean {
-    val file = File(path)
-    return if (includedPaths.contains(path)) {
-        true
-    } else if (isThisOrParentExcluded(path, excludedPaths, includedPaths)) {
-        false
-    } else if (!showHidden && file.isDirectory && file.canonicalFile == file.absoluteFile) {
-        var containsNoMediaOrDot = file.containsNoMedia() || path.contains("/.")
-        if (!containsNoMediaOrDot) {
-            containsNoMediaOrDot = checkParentHasNoMedia(file.parentFile)
-        }
-        !containsNoMediaOrDot
-    } else {
-        true
-    }
-}
-
-private fun checkParentHasNoMedia(file: File): Boolean {
-    var curFile = file
-    while (true) {
-        if (curFile.containsNoMedia()) {
-            return true
-        }
-        curFile = curFile.parentFile
-        if (curFile.absolutePath == "/")
-            break
-    }
-    return false
-}
-
-private fun isThisOrParentExcluded(path: String, excludedPaths: MutableSet<String>, includedPaths: MutableSet<String>) =
-        includedPaths.none { path.startsWith(it) } && excludedPaths.any { path.startsWith(it) }
-
 @Suppress("UNCHECKED_CAST")
 fun Context.getSortedDirectories(source: ArrayList<Directory>): ArrayList<Directory> {
     Directory.sorting = config.directorySorting
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt
new file mode 100644
index 000000000..7bb0d0e8f
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt
@@ -0,0 +1,311 @@
+package com.simplemobiletools.gallery.helpers
+
+import android.content.Context
+import android.database.Cursor
+import android.provider.MediaStore
+import android.util.Log
+import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
+import com.simplemobiletools.commons.helpers.SORT_BY_NAME
+import com.simplemobiletools.commons.helpers.SORT_BY_SIZE
+import com.simplemobiletools.commons.helpers.SORT_DESCENDING
+import com.simplemobiletools.gallery.extensions.config
+import com.simplemobiletools.gallery.extensions.containsNoMedia
+import com.simplemobiletools.gallery.models.Medium
+import java.io.File
+import java.util.LinkedHashMap
+import kotlin.collections.ArrayList
+import kotlin.collections.component1
+import kotlin.collections.component2
+
+class MediaFetcher(val context: Context) {
+    fun getMediaByDirectories(isPickVideo: Boolean, isPickImage: Boolean): HashMap<String, ArrayList<Medium>> {
+        val media = getFilesFrom("", isPickImage, isPickVideo)
+        val excludedPaths = context.config.excludedFolders
+        val includedPaths = context.config.includedFolders
+        val showHidden = context.config.shouldShowHidden
+        val directories = groupDirectories(media)
+
+        val removePaths = ArrayList<String>()
+        for ((path, curMedia) in directories) {
+            // make sure the path has uppercase letters wherever appropriate
+            val groupPath = File(curMedia.first().path).parent
+            if (!File(groupPath).exists() || !shouldFolderBeVisible(groupPath, excludedPaths, includedPaths, showHidden)) {
+                removePaths.add(groupPath.toLowerCase())
+            }
+        }
+
+        removePaths.forEach {
+            directories.remove(it)
+        }
+
+        return directories
+    }
+
+    fun getFilesFrom(curPath: String, isPickImage: Boolean, isPickVideo: Boolean): ArrayList<Medium> {
+        val projection = arrayOf(MediaStore.Images.Media._ID,
+                MediaStore.Images.Media.DISPLAY_NAME,
+                MediaStore.Images.Media.DATE_TAKEN,
+                MediaStore.Images.Media.DATE_MODIFIED,
+                MediaStore.Images.Media.DATA,
+                MediaStore.Images.Media.SIZE)
+        val uri = MediaStore.Files.getContentUri("external")
+        val selection = getSelectionQuery(curPath)
+        val selectionArgs = getSelectionArgsQuery(curPath)
+
+        return try {
+            val cur = context.contentResolver.query(uri, projection, selection, selectionArgs, getSortingForFolder(curPath))
+            parseCursor(context, cur, isPickImage, isPickVideo, curPath)
+        } catch (e: Exception) {
+            ArrayList()
+        }
+    }
+
+    private fun getSelectionQuery(path: String): String {
+        val dataQuery = "${MediaStore.Images.Media.DATA} LIKE ?"
+        return if (path.isEmpty()) {
+            var query = "($dataQuery)"
+            if (context.hasExternalSDCard()) {
+                query += " OR ($dataQuery)"
+            }
+            query
+        } else {
+            "($dataQuery AND ${MediaStore.Images.Media.DATA} NOT LIKE ?)"
+        }
+    }
+
+    private fun getSelectionArgsQuery(path: String): Array<String> {
+        return if (path.isEmpty()) {
+            if (context.hasExternalSDCard()) arrayOf("${context.internalStoragePath}/%", "${context.sdCardPath}/%") else arrayOf("${context.internalStoragePath}/%")
+        } else {
+            arrayOf("$path/%", "$path/%/%")
+        }
+    }
+
+    private fun parseCursor(context: Context, cur: Cursor, isPickImage: Boolean, isPickVideo: Boolean, curPath: String): ArrayList<Medium> {
+        val curMedia = ArrayList<Medium>()
+        val config = context.config
+        val filterMedia = config.filterMedia
+        val showHidden = config.shouldShowHidden
+        val includedFolders = config.includedFolders.map { "${it.trimEnd('/')}/" }
+        val excludedFolders = config.excludedFolders.map { "${it.trimEnd('/')}/" }
+        val noMediaFolders = getNoMediaFolders()
+        val isThirdPartyIntent = config.isThirdPartyIntent
+
+        cur.use {
+            if (cur.moveToFirst()) {
+                do {
+                    try {
+                        val path = cur.getStringValue(MediaStore.Images.Media.DATA)
+
+                        Log.e("DEBUG", "checking $path")
+                        var filename = cur.getStringValue(MediaStore.Images.Media.DISPLAY_NAME) ?: ""
+                        if (filename.isEmpty())
+                            filename = path.getFilenameFromPath()
+
+                        val isImage = filename.isImageFast()
+                        val isVideo = if (isImage) false else filename.isVideoFast()
+                        val isGif = if (isImage || isVideo) false else filename.isGif()
+
+                        if (!isImage && !isVideo && !isGif)
+                            continue
+
+                        if (isVideo && (isPickImage || filterMedia and VIDEOS == 0))
+                            continue
+
+                        if (isImage && (isPickVideo || filterMedia and IMAGES == 0))
+                            continue
+
+                        if (isGif && filterMedia and GIFS == 0)
+                            continue
+
+                        if (!showHidden && filename.startsWith('.'))
+                            continue
+
+                        var size = cur.getLongValue(MediaStore.Images.Media.SIZE)
+                        val file = File(path)
+                        if (size == 0L) {
+                            size = file.length()
+                        }
+
+                        if (size <= 0L)
+                            continue
+
+                        var isExcluded = false
+                        excludedFolders.forEach {
+                            if (path.startsWith(it)) {
+                                isExcluded = true
+                                includedFolders.forEach {
+                                    if (path.startsWith(it)) {
+                                        isExcluded = false
+                                    }
+                                }
+                            }
+                        }
+
+                        if (!isExcluded && !showHidden) {
+                            noMediaFolders.forEach {
+                                if (path.startsWith(it)) {
+                                    isExcluded = true
+                                }
+                            }
+                        }
+
+                        if (!isExcluded && !showHidden && path.contains("/.")) {
+                            isExcluded = true
+                        }
+
+                        if (!isExcluded || isThirdPartyIntent) {
+                            if (!file.exists())
+                                continue
+
+                            val dateTaken = cur.getLongValue(MediaStore.Images.Media.DATE_TAKEN)
+                            val dateModified = cur.getIntValue(MediaStore.Images.Media.DATE_MODIFIED) * 1000L
+
+                            val medium = Medium(filename, path, isVideo, dateModified, dateTaken, size)
+                            curMedia.add(medium)
+                        }
+                    } catch (e: Exception) {
+                        continue
+                    }
+                } while (cur.moveToNext())
+            }
+        }
+
+        config.includedFolders.filter { it.isNotEmpty() && (curPath.isEmpty() || it == curPath) }.forEach {
+            getMediaInFolder(it, curMedia, isPickImage, isPickVideo, filterMedia)
+        }
+
+        if (isThirdPartyIntent && curPath.isNotEmpty() && curMedia.isEmpty()) {
+            getMediaInFolder(curPath, curMedia, isPickImage, isPickVideo, filterMedia)
+        }
+
+        Medium.sorting = config.getFileSorting(curPath)
+        curMedia.sort()
+
+        return curMedia
+    }
+
+    private fun groupDirectories(media: ArrayList<Medium>): HashMap<String, ArrayList<Medium>> {
+        val directories = LinkedHashMap<String, ArrayList<Medium>>()
+        for (medium in media) {
+            val parentDir = File(medium.path).parent?.toLowerCase() ?: continue
+            if (directories.containsKey(parentDir)) {
+                directories[parentDir]!!.add(medium)
+            } else {
+                directories.put(parentDir, arrayListOf(medium))
+            }
+        }
+        return directories
+    }
+
+    private fun shouldFolderBeVisible(path: String, excludedPaths: MutableSet<String>, includedPaths: MutableSet<String>, showHidden: Boolean): Boolean {
+        val file = File(path)
+        return if (includedPaths.contains(path)) {
+            true
+        } else if (isThisOrParentExcluded(path, excludedPaths, includedPaths)) {
+            false
+        } else if (!showHidden && file.isDirectory && file.canonicalFile == file.absoluteFile) {
+            var containsNoMediaOrDot = file.containsNoMedia() || path.contains("/.")
+            if (!containsNoMediaOrDot) {
+                containsNoMediaOrDot = checkParentHasNoMedia(file.parentFile)
+            }
+            !containsNoMediaOrDot
+        } else {
+            true
+        }
+    }
+
+    private fun checkParentHasNoMedia(file: File): Boolean {
+        var curFile = file
+        while (true) {
+            if (curFile.containsNoMedia()) {
+                return true
+            }
+            curFile = curFile.parentFile
+            if (curFile.absolutePath == "/")
+                break
+        }
+        return false
+    }
+
+    private fun isThisOrParentExcluded(path: String, excludedPaths: MutableSet<String>, includedPaths: MutableSet<String>) =
+            includedPaths.none { path.startsWith(it) } && excludedPaths.any { path.startsWith(it) }
+
+
+    private fun getMediaInFolder(folder: String, curMedia: ArrayList<Medium>, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int) {
+        val files = File(folder).listFiles() ?: return
+        for (file in files) {
+            val filename = file.name
+            val isImage = filename.isImageFast()
+            val isVideo = if (isImage) false else filename.isVideoFast()
+            val isGif = if (isImage || isVideo) false else filename.isGif()
+
+            if (!isImage && !isVideo)
+                continue
+
+            if (isVideo && (isPickImage || filterMedia and VIDEOS == 0))
+                continue
+
+            if (isImage && (isPickVideo || filterMedia and IMAGES == 0))
+                continue
+
+            if (isGif && filterMedia and GIFS == 0)
+                continue
+
+            val size = file.length()
+            if (size <= 0L)
+                continue
+
+            val dateTaken = file.lastModified()
+            val dateModified = file.lastModified()
+
+            val medium = Medium(filename, file.absolutePath, isVideo, dateModified, dateTaken, size)
+            val isAlreadyAdded = curMedia.any { it.path == file.absolutePath }
+            if (!isAlreadyAdded)
+                curMedia.add(medium)
+        }
+    }
+
+    private fun getSortingForFolder(path: String): String {
+        val sorting = context.config.getFileSorting(path)
+        val sortValue = when {
+            sorting and SORT_BY_NAME > 0 -> MediaStore.Images.Media.DISPLAY_NAME
+            sorting and SORT_BY_SIZE > 0 -> MediaStore.Images.Media.SIZE
+            sorting and SORT_BY_DATE_MODIFIED > 0 -> MediaStore.Images.Media.DATE_MODIFIED
+            else -> MediaStore.Images.Media.DATE_TAKEN
+        }
+
+        return if (sorting and SORT_DESCENDING > 0)
+            "$sortValue DESC"
+        else
+            "$sortValue ASC"
+    }
+
+    private fun getNoMediaFolders(): ArrayList<String> {
+        val folders = ArrayList<String>()
+        val noMediaCondition = "${MediaStore.Files.FileColumns.MEDIA_TYPE} = ${MediaStore.Files.FileColumns.MEDIA_TYPE_NONE}"
+
+        val uri = MediaStore.Files.getContentUri("external")
+        val columns = arrayOf(MediaStore.Files.FileColumns.DATA)
+        val where = "$noMediaCondition AND ${MediaStore.Files.FileColumns.TITLE} LIKE ?"
+        val args = arrayOf("%$NOMEDIA%")
+        var cursor: Cursor? = null
+
+        try {
+            cursor = context.contentResolver.query(uri, columns, where, args, null)
+            if (cursor?.moveToFirst() == true) {
+                do {
+                    val path = cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)) ?: continue
+                    val noMediaFile = File(path)
+                    if (noMediaFile.exists())
+                        folders.add("${noMediaFile.parent}/")
+                } while (cursor.moveToNext())
+            }
+        } finally {
+            cursor?.close()
+        }
+
+        return folders
+    }
+}