diff --git a/app/src/main/java/org/oxycblt/auxio/music/Music.kt b/app/src/main/java/org/oxycblt/auxio/music/Music.kt
index ed9c87944..df165045c 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/Music.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/Music.kt
@@ -30,7 +30,6 @@ import org.oxycblt.auxio.music.ui.MusicMode
import org.oxycblt.auxio.music.ui.Sort
import org.oxycblt.auxio.ui.recycler.Item
import org.oxycblt.auxio.util.inRangeOrNull
-import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.nonZeroOrNull
import org.oxycblt.auxio.util.unlikelyToBeNull
import java.security.MessageDigest
@@ -95,6 +94,11 @@ sealed class Music : Item {
* external sources, as it can persist across app restarts and does not need to encode useless
* information about the relationships between items.
*
+ * Note: While the core of a UID is a UUID. The whole is not technically a UUID, with
+ * string representation in particular having multiple extensions to increase uniqueness.
+ * Please don't try to do anything interesting with this and just assume it's a black box
+ * that can only be compared, serialized, and deserialized.
+ *
* TODO: MusicBrainz tags
*
* @author OxygenCobalt
@@ -113,8 +117,6 @@ sealed class Music : Item {
result = 31 * result + mode.hashCode()
result = 31 * result + uuid.hashCode()
hashCode = result
-
- logD(this)
}
override fun hashCode() = hashCode
@@ -131,8 +133,8 @@ sealed class Music : Item {
FORMAT_AUXIO
}
- // Instead of making new string values for the mode, just append it's intCode
- // in front of the UUID. So I guess it's technically not a true UUID, but whatever.
+ // Instead of making new string values for the mode, be lazy and just append it's
+ // intCode in front of the UUID.
return "$format:${mode.intCode.toString(16)}-$uuid"
}
diff --git a/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheLayer.kt b/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheLayer.kt
index 75965476f..5102b74e8 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheLayer.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/extractor/CacheLayer.kt
@@ -24,6 +24,9 @@ class CacheLayer {
fun init() {
}
+ // FIXME: Make the raw datatype use raw values, with most parsing being done in the song
+ // constructor to ensure cache coherency
+
/**
* Write a list of newly-indexed raw songs to the database.
*/
diff --git a/app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirAdapter.kt b/app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirAdapter.kt
similarity index 98%
rename from app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirAdapter.kt
rename to app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirAdapter.kt
index 8b3156dab..f39b64fad 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirAdapter.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.music.dirs
+package org.oxycblt.auxio.music.settings
import android.view.View
import android.view.ViewGroup
diff --git a/app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirs.kt b/app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirs.kt
similarity index 95%
rename from app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirs.kt
rename to app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirs.kt
index 748bd43c1..61db8e10c 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirs.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirs.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.music.dirs
+package org.oxycblt.auxio.music.settings
import org.oxycblt.auxio.music.Directory
diff --git a/app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirsDialog.kt b/app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirsDialog.kt
similarity index 99%
rename from app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirsDialog.kt
rename to app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirsDialog.kt
index 0cb79bd92..cdb53db14 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/dirs/MusicDirsDialog.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/settings/MusicDirsDialog.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.music.dirs
+package org.oxycblt.auxio.music.settings
import android.net.Uri
import android.os.Bundle
diff --git a/app/src/main/java/org/oxycblt/auxio/music/settings/SeparatorsDialog.kt b/app/src/main/java/org/oxycblt/auxio/music/settings/SeparatorsDialog.kt
new file mode 100644
index 000000000..755899521
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/auxio/music/settings/SeparatorsDialog.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2022 Auxio Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.oxycblt.auxio.music.settings
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import androidx.appcompat.app.AlertDialog
+import androidx.core.view.children
+import com.google.android.material.checkbox.MaterialCheckBox
+import org.oxycblt.auxio.BuildConfig
+import org.oxycblt.auxio.R
+import org.oxycblt.auxio.databinding.DialogSeparatorsBinding
+import org.oxycblt.auxio.settings.Settings
+import org.oxycblt.auxio.ui.fragment.ViewBindingDialogFragment
+import org.oxycblt.auxio.util.context
+
+class SeparatorsDialog : ViewBindingDialogFragment() {
+ private val settings: Settings by lifecycleObject { binding -> Settings(binding.context) }
+
+ override fun onCreateBinding(inflater: LayoutInflater) =
+ DialogSeparatorsBinding.inflate(inflater)
+
+ override fun onConfigDialog(builder: AlertDialog.Builder) {
+ builder
+ .setTitle(R.string.set_separators)
+ .setNegativeButton(R.string.lbl_cancel, null)
+ .setPositiveButton(R.string.lbl_save) { _, _ ->
+ var separators = ""
+ val binding = requireBinding()
+ if (binding.separatorComma.isChecked) separators += SEPARATOR_COMMA
+ if (binding.separatorSemicolon.isChecked) separators += SEPARATOR_SEMICOLON
+ if (binding.separatorSlash.isChecked) separators += SEPARATOR_SLASH
+ if (binding.separatorPlus.isChecked) separators += SEPARATOR_PLUS
+ if (binding.separatorAnd.isChecked) separators += SEPARATOR_AND
+ settings.separators = separators
+ }
+ }
+
+ override fun onBindingCreated(binding: DialogSeparatorsBinding, savedInstanceState: Bundle?) {
+ for (child in binding.separatorGroup.children) {
+ (child as MaterialCheckBox).isChecked = false
+ }
+
+ settings.separators?.forEach {
+ when (it) {
+ SEPARATOR_COMMA -> binding.separatorComma.isChecked = true
+ SEPARATOR_SEMICOLON -> binding.separatorSemicolon.isChecked = true
+ SEPARATOR_SLASH -> binding.separatorSlash.isChecked = true
+ SEPARATOR_PLUS -> binding.separatorPlus.isChecked = true
+ SEPARATOR_AND -> binding.separatorAnd.isChecked = true
+ else -> error("Unexpected separator in settings data")
+ }
+ }
+ }
+
+ companion object {
+ const val TAG = BuildConfig.APPLICATION_ID + ".tag.EXCLUDED"
+
+ private const val SEPARATOR_COMMA = ','
+ private const val SEPARATOR_SEMICOLON = ';'
+ private const val SEPARATOR_SLASH = '/'
+ private const val SEPARATOR_PLUS = '+'
+ private const val SEPARATOR_AND = '&'
+ }
+}
diff --git a/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt b/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt
index 90272be9d..a5065d7f1 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/system/IndexerService.kt
@@ -226,7 +226,8 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback {
override fun onSettingChanged(key: String) {
when (key) {
getString(R.string.set_key_music_dirs),
- getString(R.string.set_key_music_dirs_include) -> onStartIndexing()
+ getString(R.string.set_key_music_dirs_include),
+ getString(R.string.set_key_separators) -> onStartIndexing()
getString(R.string.set_key_observing) -> {
if (!indexer.isIndexing) {
updateIdleSession()
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt
index a26cad628..5195cf60e 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt
@@ -28,7 +28,7 @@ import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R
import org.oxycblt.auxio.home.tabs.Tab
import org.oxycblt.auxio.music.Directory
-import org.oxycblt.auxio.music.dirs.MusicDirs
+import org.oxycblt.auxio.music.settings.MusicDirs
import org.oxycblt.auxio.music.ui.MusicMode
import org.oxycblt.auxio.music.ui.Sort
import org.oxycblt.auxio.playback.BarAction
@@ -301,7 +301,7 @@ class Settings(private val context: Context, private val callback: Callback? = n
inner.getString(context.getString(R.string.set_key_separators), null)?.ifEmpty { null }
set(value) {
inner.edit {
- putString(context.getString(R.string.set_key_separators), value)
+ putString(context.getString(R.string.set_key_separators), value?.ifEmpty { null })
apply()
}
}
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
index 4fa3cf5fe..fbfeda4a6 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
@@ -32,7 +32,8 @@ import coil.Coil
import org.oxycblt.auxio.R
import org.oxycblt.auxio.home.tabs.TabCustomizeDialog
import org.oxycblt.auxio.music.MusicViewModel
-import org.oxycblt.auxio.music.dirs.MusicDirsDialog
+import org.oxycblt.auxio.music.settings.MusicDirsDialog
+import org.oxycblt.auxio.music.settings.SeparatorsDialog
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.replaygain.PreAmpCustomizeDialog
import org.oxycblt.auxio.settings.ui.IntListPreference
@@ -107,6 +108,8 @@ class SettingsListFragment : PreferenceFragmentCompat() {
.show(childFragmentManager, PreAmpCustomizeDialog.TAG)
context.getString(R.string.set_key_music_dirs) ->
MusicDirsDialog().show(childFragmentManager, MusicDirsDialog.TAG)
+ getString(R.string.set_key_separators) ->
+ SeparatorsDialog().show(childFragmentManager, SeparatorsDialog.TAG)
else -> error("Unexpected dialog key ${preference.key}")
}
}
diff --git a/app/src/main/res/layout/dialog_separators.xml b/app/src/main/res/layout/dialog_separators.xml
new file mode 100644
index 000000000..05262399d
--- /dev/null
+++ b/app/src/main/res/layout/dialog_separators.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9f650ee07..8e33d337e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -214,6 +214,8 @@
Content
Reload music
May wipe playback state
+ Automatic reloading
+ Reload your music library whenever it changes (Experimental)
Music folders
Manage where music should be loaded from
@@ -224,8 +226,13 @@
Include
Music will only be loaded from the folders you add.
- Automatic reloading
- Reload your music library whenever it changes (Experimental)
+ Multi-value separators
+ Configure the characters that denote multiple values in tags
+ Comma (,)
+ Semicolon (;)
+ Slash (/)
+ Plus (+)
+ Ampersand (&)
No music found
diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml
index 7d4df744f..948cecc4c 100644
--- a/app/src/main/res/xml/prefs_main.xml
+++ b/app/src/main/res/xml/prefs_main.xml
@@ -148,16 +148,21 @@
app:summary="@string/set_reindex_desc"
app:title="@string/set_reindex" />
-
-
+
+
+
+
\ No newline at end of file