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