mirror of
https://github.com/FossifyOrg/Gallery.git
synced 2024-11-26 06:28:00 +01:00
Make subfolder grouping follow file structure
This changes subfolder grouping to follow file hierarchy to prevent unreliable behavior with middle folders missing media. This fixes #1886
This commit is contained in:
parent
345f314a44
commit
11aa25ad45
1 changed files with 64 additions and 76 deletions
|
@ -195,37 +195,22 @@ fun Context.getDirsToShow(dirs: ArrayList<Directory>, allDirs: ArrayList<Directo
|
||||||
|
|
||||||
fun Context.getDirectParentSubfolders(dirs: ArrayList<Directory>, currentPathPrefix: String): ArrayList<Directory> {
|
fun Context.getDirectParentSubfolders(dirs: ArrayList<Directory>, currentPathPrefix: String): ArrayList<Directory> {
|
||||||
val folders = dirs.map { it.path }.sorted().toMutableSet() as HashSet<String>
|
val folders = dirs.map { it.path }.sorted().toMutableSet() as HashSet<String>
|
||||||
val currentPaths = LinkedHashSet<String>()
|
// Sort by path length, to ensure that parents get processed first
|
||||||
val foldersWithoutMediaFiles = ArrayList<String>()
|
val foldersByPathLength = dirs.filter { currentPathPrefix.isEmpty() || (it.path.startsWith(currentPathPrefix, true) && it.path != currentPathPrefix) }.sortedBy { it.path.length }
|
||||||
var newDirId = 1000L
|
var newDirId = 1000L
|
||||||
|
val groups = mutableMapOf<String, MutableList<Directory>>()
|
||||||
|
|
||||||
for (path in folders) {
|
for (folder in foldersByPathLength) {
|
||||||
if (path == RECYCLE_BIN || path == FAVORITES) {
|
val parent = groups.keys.firstOrNull { folder.path.startsWith(it, true) }
|
||||||
continue
|
if (parent != null) {
|
||||||
}
|
// If we have parent in top level groups
|
||||||
|
// Add this folder to that group,
|
||||||
if (currentPathPrefix.isNotEmpty()) {
|
// but also add all folders in between which may not have media files
|
||||||
if (!path.startsWith(currentPathPrefix, true)) {
|
groups.getOrPut(parent, ::mutableListOf).apply {
|
||||||
continue
|
var midParent = File(folder.path).parent
|
||||||
}
|
while (midParent != null && none { it.path.equals(midParent, true) }) {
|
||||||
|
|
||||||
if (!File(path).parent.equals(currentPathPrefix, true)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPathPrefix.isNotEmpty() && path.equals(currentPathPrefix, true) || File(path).parent.equals(currentPathPrefix, true)) {
|
|
||||||
currentPaths.add(path)
|
|
||||||
} else if (folders.any { !it.equals(path, true) && (File(path).parent.equals(it, true) || File(it).parent.equals(File(path).parent, true)) }) {
|
|
||||||
// if we have folders like
|
|
||||||
// /storage/emulated/0/Pictures/Images and
|
|
||||||
// /storage/emulated/0/Pictures/Screenshots,
|
|
||||||
// but /storage/emulated/0/Pictures is empty, still Pictures with the first folders thumbnails and proper other info
|
|
||||||
val parent = File(path).parent
|
|
||||||
if (parent != null && !folders.contains(parent) && dirs.none { it.path.equals(parent, true) }) {
|
|
||||||
currentPaths.add(parent)
|
|
||||||
val isSortingAscending = config.sorting.isSortingAscending()
|
val isSortingAscending = config.sorting.isSortingAscending()
|
||||||
val subDirs = dirs.filter { File(it.path).parent.equals(File(path).parent, true) } as ArrayList<Directory>
|
val subDirs = dirs.filter { File(it.path).parent.equals(midParent, true) } as ArrayList<Directory>
|
||||||
if (subDirs.isNotEmpty()) {
|
if (subDirs.isNotEmpty()) {
|
||||||
val lastModified = if (isSortingAscending) {
|
val lastModified = if (isSortingAscending) {
|
||||||
subDirs.minByOrNull { it.modified }?.modified
|
subDirs.minByOrNull { it.modified }?.modified
|
||||||
|
@ -246,38 +231,46 @@ fun Context.getDirectParentSubfolders(dirs: ArrayList<Directory>, currentPathPre
|
||||||
|
|
||||||
val directory = Directory(
|
val directory = Directory(
|
||||||
newDirId++,
|
newDirId++,
|
||||||
parent,
|
midParent,
|
||||||
subDirs.first().tmb,
|
subDirs.first().tmb,
|
||||||
getFolderNameFromPath(parent),
|
getFolderNameFromPath(midParent),
|
||||||
subDirs.sumBy { it.mediaCnt },
|
subDirs.sumBy { it.mediaCnt },
|
||||||
lastModified,
|
lastModified,
|
||||||
dateTaken,
|
dateTaken,
|
||||||
subDirs.sumByLong { it.size },
|
subDirs.sumByLong { it.size },
|
||||||
getPathLocation(parent),
|
getPathLocation(midParent),
|
||||||
mediaTypes,
|
mediaTypes,
|
||||||
""
|
""
|
||||||
)
|
)
|
||||||
|
|
||||||
directory.containsMediaFilesDirectly = false
|
directory.containsMediaFilesDirectly = false
|
||||||
dirs.add(directory)
|
dirs.add(directory)
|
||||||
currentPaths.add(parent)
|
add(directory)
|
||||||
foldersWithoutMediaFiles.add(parent)
|
|
||||||
}
|
}
|
||||||
|
midParent = File(midParent).parent
|
||||||
|
}
|
||||||
|
add(folder)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
currentPaths.add(path)
|
// If we have don't have parent in top level groups
|
||||||
|
// Set this folder as top level group if it is direct child
|
||||||
|
if (currentPathPrefix.isEmpty() || File(folder.path).parent.equals(currentPathPrefix, true)) {
|
||||||
|
groups.getOrPut(folder.path, ::mutableListOf).add(folder)
|
||||||
|
} else {
|
||||||
|
// Otherwise find its parent which is a direct child of current path prefix
|
||||||
|
// And create a group for it
|
||||||
|
var firstVisibleParent = File(folder.path).parent
|
||||||
|
while (firstVisibleParent != null && !File(firstVisibleParent).parent.equals(currentPathPrefix, true)) {
|
||||||
|
firstVisibleParent = File(firstVisibleParent).parent
|
||||||
|
}
|
||||||
|
if (firstVisibleParent != null) {
|
||||||
|
groups.getOrPut(firstVisibleParent, ::mutableListOf).add(folder)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var areDirectSubfoldersAvailable = false
|
val currentPaths = groups.keys.toMutableList()
|
||||||
currentPaths.forEach {
|
|
||||||
val path = it
|
|
||||||
currentPaths.forEach {
|
|
||||||
if (!foldersWithoutMediaFiles.contains(it) && !it.equals(path, true) && File(it).parent?.equals(path, true) == true) {
|
|
||||||
areDirectSubfoldersAvailable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPathPrefix.isEmpty() && folders.contains(RECYCLE_BIN)) {
|
if (currentPathPrefix.isEmpty() && folders.contains(RECYCLE_BIN)) {
|
||||||
currentPaths.add(RECYCLE_BIN)
|
currentPaths.add(RECYCLE_BIN)
|
||||||
|
@ -294,12 +287,7 @@ fun Context.getDirectParentSubfolders(dirs: ArrayList<Directory>, currentPathPre
|
||||||
folders.clear()
|
folders.clear()
|
||||||
folders.addAll(currentPaths)
|
folders.addAll(currentPaths)
|
||||||
|
|
||||||
val dirsToShow = dirs.filter { folders.contains(it.path) } as ArrayList<Directory>
|
return dirs.filter { folders.contains(it.path) } as ArrayList<Directory>
|
||||||
return if (areDirectSubfoldersAvailable) {
|
|
||||||
getDirectParentSubfolders(dirsToShow, currentPathPrefix)
|
|
||||||
} else {
|
|
||||||
dirsToShow
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.updateSubfolderCounts(children: ArrayList<Directory>, parentDirs: ArrayList<Directory>) {
|
fun Context.updateSubfolderCounts(children: ArrayList<Directory>, parentDirs: ArrayList<Directory>) {
|
||||||
|
|
Loading…
Reference in a new issue