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" /> + + - -