diff --git a/CHANGELOG.md b/CHANGELOG.md
index e02157491..d9ba4c489 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,8 +9,8 @@
- Added support for multiple genres
- Artists and album artists are now both given UI entires
- Upgraded music ID management:
- - Use MD5 for default UUIDS
- - Added support for MusicBrainz IDs (MBIDs
+ - Added support for MusicBrainz IDs (MBIDs)
+ - Use the more unique MD5 hash of metadata when MBIDs can't be used
- Added toggle to load non-music (Such as podcasts)
- Music loader now caches parsed metadata for faster load times
diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
index b35b28869..4afdb7b43 100644
--- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
+++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
@@ -18,7 +18,6 @@
package org.oxycblt.auxio
import android.content.Intent
-import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
@@ -108,11 +107,7 @@ class MainActivity : AppCompatActivity() {
private fun setupTheme() {
val settings = Settings(this)
- // Disable theme customization above Android 12, as it's far enough in as a version to
- // the point where most phones should have an option for light/dark theming.
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
- AppCompatDelegate.setDefaultNightMode(settings.theme)
- }
+ AppCompatDelegate.setDefaultNightMode(settings.theme)
// The black theme has a completely separate set of styles since style attributes cannot
// be modified at runtime.
diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
index 6b2dd70d0..622b54953 100644
--- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
@@ -34,9 +34,9 @@ import com.google.android.material.transition.MaterialFadeThrough
import org.oxycblt.auxio.databinding.FragmentMainBinding
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song
+import org.oxycblt.auxio.playback.PlaybackSheetBehavior
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.queue.QueueSheetBehavior
-import org.oxycblt.auxio.playback.PlaybackSheetBehavior
import org.oxycblt.auxio.ui.MainNavigationAction
import org.oxycblt.auxio.ui.NavigationViewModel
import org.oxycblt.auxio.ui.fragment.ViewBindingFragment
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt
index 61ffc7bf1..5ebac30cf 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt
@@ -121,15 +121,16 @@ private class ArtistDetailViewHolder private constructor(private val binding: It
binding.context.getPlural(R.plurals.fmt_song_count, item.songs.size)
)
- binding.detailPlayButton.isEnabled = true
- binding.detailShuffleButton.isEnabled = true
+ binding.detailPlayButton.isVisible = true
+ binding.detailShuffleButton.isVisible = true
} else {
- // The artist is a
+ // The artist does not have any songs, so playback, genre info, and song counts
+ // make no sense.
binding.detailSubhead.isVisible = false
binding.detailInfo.text =
binding.context.getPlural(R.plurals.fmt_album_count, item.albums.size)
- binding.detailPlayButton.isEnabled = false
- binding.detailShuffleButton.isEnabled = false
+ binding.detailPlayButton.isVisible = false
+ binding.detailShuffleButton.isVisible = false
}
binding.detailPlayButton.setOnClickListener { listener.onPlayParent() }
diff --git a/app/src/main/java/org/oxycblt/auxio/music/extractor/MediaStoreExtractor.kt b/app/src/main/java/org/oxycblt/auxio/music/extractor/MediaStoreExtractor.kt
index fac336783..17fe17a07 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/extractor/MediaStoreExtractor.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/extractor/MediaStoreExtractor.kt
@@ -41,9 +41,9 @@ import java.io.File
/*
* This file acts as the base for most the black magic required to get a remotely sensible music
- * indexing system while still optimizing for time. I would recommend you leave this file now
- * before you lose your sanity trying to understand the hoops I had to jump through for this system,
- * but if you really want to stay, here's a debrief on why this code is so awful.
+ * indexing system from MediaStore while still optimizing for time. I would recommend you leave
+ * this file now before you lose your sanity trying to understand the hoops I had to jump through
+ * for this system, but if you really want to stay, here's a debrief on why this code is so awful.
*
* MediaStore is not a good API. It is not even a bad API. Calling it a bad API is an insult to
* other bad android APIs, like CoordinatorLayout or InputMethodManager. No. MediaStore is a crime
@@ -51,7 +51,7 @@ import java.io.File
*
* You think that if you wanted to query a song's genre from a media database, you could just put
* "genre" in the query and it would return it, right? But not with MediaStore! No, that's too
- * straightforward for this contract that was dropped on it's head as a baby. So instead, you have
+ * straightforward for this database that was dropped on it's head as a baby. So instead, you have
* to query for each genre, query all the songs in each genre, and then iterate through those songs
* to link every song with their genre. This is not documented anywhere, and the O(mom im scared)
* algorithm you have to run to get it working single-handedly DOUBLES Auxio's query times. At no
@@ -281,13 +281,13 @@ abstract class MediaStoreExtractor(private val context: Context, private val cac
arrayOf(
// These columns are guaranteed to work on all versions of android
MediaStore.Audio.AudioColumns._ID,
- MediaStore.Audio.AudioColumns.TITLE,
- MediaStore.Audio.AudioColumns.DISPLAY_NAME,
- MediaStore.Audio.AudioColumns.MIME_TYPE,
- MediaStore.Audio.AudioColumns.SIZE,
MediaStore.Audio.AudioColumns.DATE_ADDED,
MediaStore.Audio.AudioColumns.DATE_MODIFIED,
+ MediaStore.Audio.AudioColumns.DISPLAY_NAME,
+ MediaStore.Audio.AudioColumns.SIZE,
MediaStore.Audio.AudioColumns.DURATION,
+ MediaStore.Audio.AudioColumns.MIME_TYPE,
+ MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.YEAR,
MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.AudioColumns.ALBUM_ID,
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 3c2b760cb..76eaa391f 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt
@@ -83,7 +83,7 @@ class Settings(private val context: Context, private val callback: Callback? = n
fun Int.migratePlaybackMode() =
when (this) {
// Genre playback mode was retried in 3.0.0
- IntegerTable.PLAYBACK_MODE_ALL_SONGS, IntegerTable.PLAYBACK_MODE_IN_GENRE -> MusicMode.SONGS
+ IntegerTable.PLAYBACK_MODE_ALL_SONGS -> MusicMode.SONGS
IntegerTable.PLAYBACK_MODE_IN_ARTIST -> MusicMode.ARTISTS
IntegerTable.PLAYBACK_MODE_IN_ALBUM -> MusicMode.ALBUMS
else -> null
@@ -147,7 +147,7 @@ class Settings(private val context: Context, private val callback: Callback? = n
/** The current accent. */
var accent: Accent
- get() = Accent.from(inner.getInt(context.getString(R.string.set_accent), Accent.DEFAULT))
+ get() = Accent.from(inner.getInt(context.getString(R.string.set_key_accent), Accent.DEFAULT))
set(value) {
inner.edit {
putInt(context.getString(R.string.set_key_accent), value.index)
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/prefs/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/prefs/SettingsListFragment.kt
index 54a2c60de..af4181792 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/prefs/SettingsListFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/prefs/SettingsListFragment.kt
@@ -34,6 +34,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.settings.Settings
+import org.oxycblt.auxio.settings.SettingsFragmentDirections
import org.oxycblt.auxio.ui.NavigationViewModel
import org.oxycblt.auxio.util.androidActivityViewModels
import org.oxycblt.auxio.util.isNight
diff --git a/app/src/main/res/drawable/ic_auxio_24.xml b/app/src/main/res/drawable/ic_auxio_24.xml
index bd9772abf..6f558124c 100644
--- a/app/src/main/res/drawable/ic_auxio_24.xml
+++ b/app/src/main/res/drawable/ic_auxio_24.xml
@@ -5,6 +5,10 @@
android:viewportWidth="24"
android:viewportHeight="24">
+ android:fillColor="@android:color/transparent"
+ android:pathData="M 13,4.0000207 17,8 M 12.999969,4.0004121 V 17.000315 m 0,-0.0002940 -3.0000004,3 -2.9999997,-3 2.9999997,-3 M 7.021336,16.939069"
+ android:strokeWidth="2"
+ android:strokeColor="@android:color/white"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round" />
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
index 62833f782..1b921bb38 100644
--- a/app/src/main/res/drawable/ic_launcher_foreground.xml
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -1,15 +1,20 @@
-
-
-
+ android:viewportHeight="108">
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_pre_amp.xml b/app/src/main/res/layout/dialog_pre_amp.xml
index 715987d77..af49dd3ea 100644
--- a/app/src/main/res/layout/dialog_pre_amp.xml
+++ b/app/src/main/res/layout/dialog_pre_amp.xml
@@ -41,7 +41,7 @@
android:layout_marginEnd="@dimen/spacing_large"
android:gravity="center"
android:minWidth="@dimen/size_pre_amp_ticker"
- android:textAppearance="@style/TextAppearance.Auxio.LabelMedium"
+ android:textAppearance="@style/TextAppearance.Auxio.BodySmall"
app:layout_constraintBottom_toBottomOf="@+id/with_tags_slider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/with_tags_slider"
@@ -78,7 +78,7 @@
android:layout_marginEnd="@dimen/spacing_large"
android:gravity="center"
android:minWidth="@dimen/size_pre_amp_ticker"
- android:textAppearance="@style/TextAppearance.Auxio.LabelMedium"
+ android:textAppearance="@style/TextAppearance.Auxio.BodySmall"
app:layout_constraintBottom_toBottomOf="@+id/without_tags_slider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/without_tags_slider"
diff --git a/app/src/main/res/layout/dialog_separators.xml b/app/src/main/res/layout/dialog_separators.xml
index 17740d56a..057659958 100644
--- a/app/src/main/res/layout/dialog_separators.xml
+++ b/app/src/main/res/layout/dialog_separators.xml
@@ -1,10 +1,10 @@
+ android:orientation="vertical">
@@ -31,8 +31,8 @@
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:paddingStart="@dimen/spacing_medium"
- android:textAlignment="viewStart"
android:text="@string/set_separators_and"
+ android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.Auxio.BodyLarge"
tools:ignore="RtlSymmetry" />
@@ -43,8 +43,8 @@
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:paddingStart="@dimen/spacing_medium"
- android:textAlignment="viewStart"
android:text="@string/set_separators_slash"
+ android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.Auxio.BodyLarge"
tools:ignore="RtlSymmetry" />
@@ -55,8 +55,8 @@
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:paddingStart="@dimen/spacing_medium"
- android:textAlignment="viewStart"
android:text="@string/set_separators_plus"
+ android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.Auxio.BodyLarge"
tools:ignore="RtlSymmetry" />
@@ -67,19 +67,19 @@
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:paddingStart="@dimen/spacing_medium"
- android:textAlignment="viewStart"
android:text="@string/set_separators_and"
+ android:textAlignment="viewStart"
android:textAppearance="@style/TextAppearance.Auxio.BodyLarge"
tools:ignore="RtlSymmetry" />
+ android:text="@string/set_separators_warning"
+ android:textAppearance="@style/TextAppearance.Auxio.BodySmall" />
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index 50ec88623..6f3b755bf 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,6 +1,6 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
index 781e663cb..fa150b646 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
index 367e6e64f..a7b5a986e 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 773fe436d..d293743cd 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index b099dc269..88a954ec0 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 2346b17ff..98b7615a9 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/navigation/nav_main.xml b/app/src/main/res/navigation/nav_main.xml
index f0a7f06a1..549dac63e 100644
--- a/app/src/main/res/navigation/nav_main.xml
+++ b/app/src/main/res/navigation/nav_main.xml
@@ -50,7 +50,7 @@
android:id="@+id/settings_fragment"
android:name="org.oxycblt.auxio.settings.SettingsFragment"
android:label="fragment_settings"
- tools:layout="@layout/fragment_settings" >
+ tools:layout="@layout/fragment_settings">
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2c93da56f..dd11aad0f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -237,7 +237,7 @@
Ignore audio files that are not music, such as podcasts
Multi-value separators
Configure characters that denote multiple tag values
- Warning: Using this setting may result in some tags being incorrectly interpreted as having multiple values. You can resolve this by escaping unwanted separator characters with a backslash (\\).
+ Warning: Using this setting may result in some tags being incorrectly interpreted as having multiple values. You can resolve this by prefixing unwanted separator characters with a backslash (\\).
Comma (,)
Semicolon (;)
Slash (/)
diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml
index f53463333..232af0d6b 100644
--- a/app/src/main/res/xml/prefs_main.xml
+++ b/app/src/main/res/xml/prefs_main.xml
@@ -153,17 +153,17 @@
app:summary="@string/set_observing_desc"
app:title="@string/set_observing" />
+
+
-
-