musikr: invert hidden setting

This commit is contained in:
Alexander Capehart 2025-03-03 20:28:49 -07:00
parent 22249cc95b
commit e046aeb671
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
12 changed files with 39 additions and 37 deletions

View file

@ -385,7 +385,7 @@ constructor(
Naming.simple() Naming.simple()
} }
val locations = musicSettings.musicLocations val locations = musicSettings.musicLocations
val ignoreHidden = musicSettings.ignoreHidden val ignoreHidden = musicSettings.withHidden
val currentRevision = musicSettings.revision val currentRevision = musicSettings.revision
val newRevision = currentRevision?.takeIf { withCache } ?: UUID.randomUUID() val newRevision = currentRevision?.takeIf { withCache } ?: UUID.randomUUID()

View file

@ -41,7 +41,7 @@ interface MusicSettings : Settings<MusicSettings.Listener> {
/** Whether to exclude non-music audio files from the music library. */ /** Whether to exclude non-music audio files from the music library. */
val excludeNonMusic: Boolean val excludeNonMusic: Boolean
/** Whether to ignore hidden files and directories during music loading. */ /** Whether to ignore hidden files and directories during music loading. */
val ignoreHidden: Boolean val withHidden: Boolean
/** Whether to be actively watching for changes in the music library. */ /** Whether to be actively watching for changes in the music library. */
val shouldBeObserving: Boolean val shouldBeObserving: Boolean
/** A [String] of characters representing the desired characters to denote multi-value tags. */ /** A [String] of characters representing the desired characters to denote multi-value tags. */
@ -92,8 +92,8 @@ class MusicSettingsImpl @Inject constructor(@ApplicationContext private val cont
override val excludeNonMusic: Boolean override val excludeNonMusic: Boolean
get() = sharedPreferences.getBoolean(getString(R.string.set_key_exclude_non_music), true) get() = sharedPreferences.getBoolean(getString(R.string.set_key_exclude_non_music), true)
override val ignoreHidden: Boolean override val withHidden: Boolean
get() = sharedPreferences.getBoolean(getString(R.string.set_key_ignore_hidden), true) get() = sharedPreferences.getBoolean(getString(R.string.set_key_with_hidden), true)
override val shouldBeObserving: Boolean override val shouldBeObserving: Boolean
get() = sharedPreferences.getBoolean(getString(R.string.set_key_observing), false) get() = sharedPreferences.getBoolean(getString(R.string.set_key_observing), false)
@ -122,7 +122,7 @@ class MusicSettingsImpl @Inject constructor(@ApplicationContext private val cont
} }
getString(R.string.set_key_separators), getString(R.string.set_key_separators),
getString(R.string.set_key_auto_sort_names), getString(R.string.set_key_auto_sort_names),
getString(R.string.set_key_ignore_hidden), getString(R.string.set_key_with_hidden),
getString(R.string.set_key_exclude_non_music) -> { getString(R.string.set_key_exclude_non_music) -> {
L.d("Dispatching indexing setting change for $key") L.d("Dispatching indexing setting change for $key")
listener.onIndexingSettingChanged() listener.onIndexingSettingChanged()

View file

@ -67,7 +67,7 @@ class MusicPreferenceFragment : BasePreferenceFragment(R.xml.preferences_music)
true true
} }
} }
if (preference.key == getString(R.string.set_key_ignore_hidden)) { if (preference.key == getString(R.string.set_key_with_hidden)) {
L.d("Configuring ignore hidden files setting") L.d("Configuring ignore hidden files setting")
preference.onPreferenceChangeListener = preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, _ -> Preference.OnPreferenceChangeListener { _, _ ->

View file

@ -334,6 +334,6 @@
<string name="lng_empty_genres">Os seus gêneros aparecerão aqui.</string> <string name="lng_empty_genres">Os seus gêneros aparecerão aqui.</string>
<string name="set_cover_mode_save_space">Economizar espaço</string> <string name="set_cover_mode_save_space">Economizar espaço</string>
<string name="set_locations_new">Nova pasta</string> <string name="set_locations_new">Nova pasta</string>
<string name="set_ignore_hidden_desc">Ignorar arquivos e pastas que estão ocultos (por exemplo, .cache)</string> <string name="set_with_hidden_desc">Ignorar arquivos e pastas que estão ocultos (por exemplo, .cache)</string>
<string name="set_ignore_hidden">Ignorar arquivos ocultos</string> <string name="set_with_hidden">Ignorar arquivos ocultos</string>
</resources> </resources>

View file

@ -18,7 +18,7 @@
<string name="set_key_square_covers" translatable="false">auxio_square_covers</string> <string name="set_key_square_covers" translatable="false">auxio_square_covers</string>
<string name="set_key_music_dirs_include" translatable="false">auxio_include_dirs</string> <string name="set_key_music_dirs_include" translatable="false">auxio_include_dirs</string>
<string name="set_key_exclude_non_music" translatable="false">auxio_exclude_non_music</string> <string name="set_key_exclude_non_music" translatable="false">auxio_exclude_non_music</string>
<string name="set_key_ignore_hidden" translatable="false">auxio_ignore_hidden</string> <string name="set_key_with_hidden" translatable="false">auxio_with_hidden</string>
<string name="set_key_music_locations" translatable="false">auxio_music_locations2</string> <string name="set_key_music_locations" translatable="false">auxio_music_locations2</string>
<string name="set_key_separators" translatable="false">auxio_separators</string> <string name="set_key_separators" translatable="false">auxio_separators</string>
<string name="set_key_auto_sort_names" translatable="false">auxio_auto_sort_names</string> <string name="set_key_auto_sort_names" translatable="false">auxio_auto_sort_names</string>

View file

@ -267,8 +267,8 @@
<string name="set_observing_desc">Reload the music library whenever it changes (requires persistent notification)</string> <string name="set_observing_desc">Reload the music library whenever it changes (requires persistent notification)</string>
<string name="set_exclude_non_music">Exclude non-music</string> <string name="set_exclude_non_music">Exclude non-music</string>
<string name="set_exclude_non_music_desc">Ignore audio files that are not music, such as podcasts</string> <string name="set_exclude_non_music_desc">Ignore audio files that are not music, such as podcasts</string>
<string name="set_ignore_hidden">Ignore hidden files</string> <string name="set_with_hidden">Include hidden files</string>
<string name="set_ignore_hidden_desc">Skip files and folders that are hidden (ex. .cache)</string> <string name="set_with_hidden_desc">Include audio files that are hidden (ex. .cache)</string>
<string name="set_separators">Multi-value separators</string> <string name="set_separators">Multi-value separators</string>
<string name="set_separators_desc">Configure characters that denote multiple tag values</string> <string name="set_separators_desc">Configure characters that denote multiple tag values</string>
<string name="set_separators_comma">Comma (,)</string> <string name="set_separators_comma">Comma (,)</string>

View file

@ -17,9 +17,9 @@
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="true" app:defaultValue="true"
app:key="@string/set_key_ignore_hidden" app:key="@string/set_key_with_hidden"
app:summary="@string/set_ignore_hidden_desc" app:summary="@string/set_with_hidden_desc"
app:title="@string/set_ignore_hidden" /> app:title="@string/set_with_hidden" />
<org.oxycblt.auxio.settings.ui.WrappedDialogPreference <org.oxycblt.auxio.settings.ui.WrappedDialogPreference
app:key="@string/set_key_separators" app:key="@string/set_key_separators"

View file

@ -56,6 +56,6 @@ data class Interpretation(
/** 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). */ /** Whether to include hidden files and directories (those starting with a dot). */
val ignoreHidden: Boolean val withHidden: Boolean
) )

View file

@ -71,7 +71,7 @@ interface Musikr {
fun new(context: Context, storage: Storage, interpretation: Interpretation): Musikr = fun new(context: Context, storage: Storage, interpretation: Interpretation): Musikr =
MusikrImpl( MusikrImpl(
storage, storage,
ExploreStep.from(context, storage), ExploreStep.from(context, storage, interpretation),
ExtractStep.from(context, storage), ExtractStep.from(context, storage),
EvaluateStep.new(storage, interpretation)) EvaluateStep.new(storage, interpretation))
} }

View file

@ -91,15 +91,7 @@ class MutableFSCovers(private val context: Context) : FSCovers(context), Mutable
} }
val coverNames = val coverNames =
listOf( listOf("cover", "folder", "album", "albumart", "front", "artwork", "art", "folder")
"cover",
"folder",
"album",
"albumart",
"front",
"artwork",
"art",
"folder")
val filenameWithoutExt = filename.substringBeforeLast(".") val filenameWithoutExt = filename.substringBeforeLast(".")
val extension = filename.substringAfterLast(".", "") val extension = filename.substringAfterLast(".", "")

View file

@ -31,10 +31,11 @@ import org.oxycblt.musikr.fs.MusicLocation
import org.oxycblt.musikr.fs.Path import org.oxycblt.musikr.fs.Path
internal interface DeviceFS { internal interface DeviceFS {
fun explore(locations: Flow<MusicLocation>, ignoreHidden: Boolean): Flow<DeviceNode> fun explore(locations: Flow<MusicLocation>): Flow<DeviceNode>
companion object { companion object {
fun from(context: Context): DeviceFS = DeviceFSImpl(context.contentResolverSafe) fun from(context: Context, withHidden: Boolean): DeviceFS =
DeviceFSImpl(context.contentResolverSafe, withHidden)
} }
} }
@ -60,8 +61,11 @@ data class DeviceFile(
) : DeviceNode ) : DeviceNode
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
private class DeviceFSImpl(private val contentResolver: ContentResolver) : DeviceFS { private class DeviceFSImpl(
override fun explore(locations: Flow<MusicLocation>, ignoreHidden: Boolean): Flow<DeviceNode> = private val contentResolver: ContentResolver,
private val withHidden: Boolean
) : DeviceFS {
override fun explore(locations: Flow<MusicLocation>): Flow<DeviceNode> =
locations.flatMapMerge { location -> locations.flatMapMerge { location ->
// Create a root directory for each location // Create a root directory for each location
val rootDirectory = val rootDirectory =
@ -76,7 +80,7 @@ private class DeviceFSImpl(private val contentResolver: ContentResolver) : Devic
DocumentsContract.getTreeDocumentId(location.uri), DocumentsContract.getTreeDocumentId(location.uri),
location.path, location.path,
rootDirectory, rootDirectory,
ignoreHidden) withHidden)
// Return a flow that emits the root directory // Return a flow that emits the root directory
flow { emit(rootDirectory) } flow { emit(rootDirectory) }
@ -88,7 +92,7 @@ private class DeviceFSImpl(private val contentResolver: ContentResolver) : Devic
treeDocumentId: String, treeDocumentId: String,
relativePath: Path, relativePath: Path,
parent: DeviceDirectory, parent: DeviceDirectory,
ignoreHidden: Boolean withHidden: Boolean
): Flow<DeviceNode> = flow { ): Flow<DeviceNode> = flow {
contentResolver.useQuery( contentResolver.useQuery(
DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, treeDocumentId), DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, treeDocumentId),
@ -108,7 +112,7 @@ private class DeviceFSImpl(private val contentResolver: ContentResolver) : Devic
val displayName = cursor.getString(displayNameIndex) val displayName = cursor.getString(displayNameIndex)
// Skip hidden files/directories if ignoreHidden is true // Skip hidden files/directories if ignoreHidden is true
if (ignoreHidden && displayName.startsWith(".")) { if (!withHidden && displayName.startsWith(".")) {
continue continue
} }
@ -129,7 +133,7 @@ private class DeviceFSImpl(private val contentResolver: ContentResolver) : Devic
// Set up the children flow for this directory // Set up the children flow for this directory
directory.children = directory.children =
exploreDirectoryImpl( exploreDirectoryImpl(
contentResolver, rootUri, childId, newPath, directory, ignoreHidden) contentResolver, rootUri, childId, newPath, directory, withHidden)
// Emit the directory node // Emit the directory node
emit(directory) emit(directory)

View file

@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.merge
import org.oxycblt.musikr.Interpretation
import org.oxycblt.musikr.Storage import org.oxycblt.musikr.Storage
import org.oxycblt.musikr.cache.Cache import org.oxycblt.musikr.cache.Cache
import org.oxycblt.musikr.cache.CacheResult import org.oxycblt.musikr.cache.CacheResult
@ -48,9 +49,12 @@ internal interface ExploreStep {
fun explore(locations: List<MusicLocation>): Flow<Explored> fun explore(locations: List<MusicLocation>): Flow<Explored>
companion object { companion object {
fun from(context: Context, storage: Storage): ExploreStep = fun from(context: Context, storage: Storage, interpretation: Interpretation): ExploreStep =
ExploreStepImpl( ExploreStepImpl(
DeviceFS.from(context), storage.cache, storage.covers, storage.storedPlaylists) DeviceFS.from(context, interpretation.withHidden),
storage.cache,
storage.covers,
storage.storedPlaylists)
} }
} }
@ -65,7 +69,9 @@ private class ExploreStepImpl(
val addingMs = System.currentTimeMillis() val addingMs = System.currentTimeMillis()
return merge( return merge(
deviceFS deviceFS
.explore(locations.asFlow()) .explore(
locations.asFlow(),
)
.flattenFilter { it.mimeType.startsWith("audio/") || it.mimeType == M3U.MIME_TYPE } .flattenFilter { it.mimeType.startsWith("audio/") || it.mimeType == M3U.MIME_TYPE }
.distribute(8) .distribute(8)
.distributedMap { file -> .distributedMap { file ->