musikr: add option to ignore hidden files/directories
This commit is contained in:
parent
ddeba2c496
commit
e2b0601d4c
2 changed files with 17 additions and 6 deletions
|
@ -53,5 +53,8 @@ data class Interpretation(
|
|||
val naming: Naming,
|
||||
|
||||
/** What separators delimit multi-value audio tags. */
|
||||
val separators: Separators
|
||||
val separators: Separators,
|
||||
|
||||
/** Whether to ignore hidden files and directories (those starting with a dot). */
|
||||
val ignoreHidden: Boolean = true
|
||||
)
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.oxycblt.musikr.fs.MusicLocation
|
|||
import org.oxycblt.musikr.fs.Path
|
||||
|
||||
internal interface DeviceFiles {
|
||||
fun explore(locations: Flow<MusicLocation>): Flow<DeviceFile>
|
||||
fun explore(locations: Flow<MusicLocation>, ignoreHidden: Boolean = true): Flow<DeviceFile>
|
||||
|
||||
companion object {
|
||||
fun from(context: Context): DeviceFiles = DeviceFilesImpl(context.contentResolverSafe)
|
||||
|
@ -43,20 +43,22 @@ internal interface DeviceFiles {
|
|||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private class DeviceFilesImpl(private val contentResolver: ContentResolver) : DeviceFiles {
|
||||
override fun explore(locations: Flow<MusicLocation>): Flow<DeviceFile> =
|
||||
override fun explore(locations: Flow<MusicLocation>, ignoreHidden: Boolean): Flow<DeviceFile> =
|
||||
locations.flatMapMerge { location ->
|
||||
exploreImpl(
|
||||
contentResolver,
|
||||
location.uri,
|
||||
DocumentsContract.getTreeDocumentId(location.uri),
|
||||
location.path)
|
||||
location.path,
|
||||
ignoreHidden)
|
||||
}
|
||||
|
||||
private fun exploreImpl(
|
||||
contentResolver: ContentResolver,
|
||||
rootUri: Uri,
|
||||
treeDocumentId: String,
|
||||
relativePath: Path
|
||||
relativePath: Path,
|
||||
ignoreHidden: Boolean
|
||||
): Flow<DeviceFile> = flow {
|
||||
contentResolver.useQuery(
|
||||
DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, treeDocumentId),
|
||||
|
@ -74,12 +76,18 @@ private class DeviceFilesImpl(private val contentResolver: ContentResolver) : De
|
|||
while (cursor.moveToNext()) {
|
||||
val childId = cursor.getString(childUriIndex)
|
||||
val displayName = cursor.getString(displayNameIndex)
|
||||
|
||||
// Skip hidden files/directories if ignoreHidden is true
|
||||
if (ignoreHidden && displayName.startsWith(".")) {
|
||||
continue
|
||||
}
|
||||
|
||||
val newPath = relativePath.file(displayName)
|
||||
val mimeType = cursor.getString(mimeTypeIndex)
|
||||
if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
|
||||
// This does NOT block the current coroutine. Instead, we will
|
||||
// evaluate this flow in parallel later to maximize throughput.
|
||||
recursive.add(exploreImpl(contentResolver, rootUri, childId, newPath))
|
||||
recursive.add(exploreImpl(contentResolver, rootUri, childId, newPath, ignoreHidden))
|
||||
} else if (mimeType.startsWith("audio/") && mimeType != "audio/x-mpegurl") {
|
||||
// Immediately emit all files given that it's just an O(1) op.
|
||||
// This also just makes sure the outer flow has a reason to exist
|
||||
|
|
Loading…
Reference in a new issue