diff --git a/app/build.gradle b/app/build.gradle index c2313674c..f6e9159e4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -70,8 +70,8 @@ dependencies { // 1.4.0 is used in order to avoid a ripple bug in material components implementation "androidx.appcompat:appcompat:1.4.0" implementation "androidx.core:core-ktx:1.9.0" - implementation "androidx.activity:activity-ktx:1.6.0" - implementation "androidx.fragment:fragment-ktx:1.5.3" + implementation "androidx.activity:activity-ktx:1.6.1" + implementation "androidx.fragment:fragment-ktx:1.5.4" // UI implementation "androidx.recyclerview:recyclerview:1.2.1" diff --git a/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt b/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt index 8879c4558..94986e412 100644 --- a/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt +++ b/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt @@ -76,9 +76,6 @@ object IntegerTable { /** RepeatMode.TRACK */ const val REPEAT_MODE_TRACK = 0xA102 - /** PlaybackMode.IN_GENRE */ - const val PLAYBACK_MODE_IN_GENRE = 0xA103 - /** PlaybackMode.IN_ARTIST */ const val PLAYBACK_MODE_IN_ARTIST = 0xA104 diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt index 72bd46675..c82b8115e 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt @@ -97,11 +97,11 @@ private class GenreDetailViewHolder private constructor(private val binding: Ite binding.detailType.text = binding.context.getString(R.string.lbl_genre) binding.detailName.text = item.resolveName(binding.context) binding.detailSubhead.isVisible = false - binding.detailInfo.text = binding.context.getString( - R.string.fmt_two, - binding.context.getPlural(R.plurals.fmt_song_count, item.songs.size), - item.durationMs.formatDurationMs(false) - ) + binding.detailInfo.text = binding.context.getString( + R.string.fmt_two, + binding.context.getPlural(R.plurals.fmt_artist_count, item.artists.size), + binding.context.getPlural(R.plurals.fmt_song_count, item.songs.size) + ) binding.detailPlayButton.setOnClickListener { listener.onPlayParent() } binding.detailShuffleButton.setOnClickListener { listener.onShuffleParent() } diff --git a/app/src/main/java/org/oxycblt/auxio/image/extractor/Components.kt b/app/src/main/java/org/oxycblt/auxio/image/extractor/Components.kt index 6e07c5104..7c1ab2f2e 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/extractor/Components.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/extractor/Components.kt @@ -110,7 +110,6 @@ private constructor( ) : BaseFetcher() { override suspend fun fetch(): FetchResult? { val results = genre.albums.mapAtMost(4) { fetchCover(context, it) } - return createMosaic(context, results, size) } 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 456a32c33..ddc174182 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/Music.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Music.kt @@ -698,13 +698,18 @@ class Genre constructor(raw: Raw, override val songs: List) : MusicParent( /** The albums of this genre. */ val albums: List + /** The artists of this genre. */ + val artists: List + init { var totalDuration = 0L val distinctAlbums = mutableSetOf() + val distinctArtists = mutableSetOf() for (song in songs) { song._link(this) distinctAlbums.add(song.album) + distinctArtists.addAll(song.artists) totalDuration += song.durationMs } @@ -714,6 +719,8 @@ class Genre constructor(raw: Raw, override val songs: List) : MusicParent( .sortedByDescending { album -> album.songs.count { it.genres.contains(this) } } + + artists = Sort(Sort.Mode.ByName, true).artists(distinctArtists) } override fun _finalize() { diff --git a/app/src/main/java/org/oxycblt/auxio/music/Tags.kt b/app/src/main/java/org/oxycblt/auxio/music/Tags.kt index f2d3309ac..3b95afadf 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/Tags.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Tags.kt @@ -41,7 +41,7 @@ import kotlin.math.min * * Unlike a typical Date within the standard library, this class just represents the ID3v2/Vorbis * date format, which is largely assumed to be a subset of ISO-8601. No validation outside of format - * validation is done. + * validation is done, and any date calculation is (fallibly) performed when displayed in the UI. * * The reasoning behind Date is that Auxio cannot trust any kind of metadata date to actually make * sense in a calendar, due to bad tagging, locale-specific issues, or simply from the limited @@ -52,9 +52,6 @@ import kotlin.math.min * The string representation of a Date is RFC 3339, with granular position depending on the presence * of particular tokens. * - * Please, **Do not use this for anything important related to time.** I cannot stress this enough. - * This code will blow up if you try to do that. - * * @author OxygenCobalt */ class Date private constructor(private val tokens: List) : Comparable { @@ -83,10 +80,15 @@ class Date private constructor(private val tokens: List) : Comparable private val second = tokens.getOrNull(5) + /** + * Resolve this date into a string. This could result in a year string formatted + * as "YYYY", or a month and year string formatted as "MMM YYYY" depending on the + * situation. + */ fun resolveDate(context: Context): String { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { return try { - resolveFullDate(context).also { logD(it) } + resolveFullDate(context) } catch (e: Exception) { logE("Failed to format a full date") logE(e.stackTraceToString()) diff --git a/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt b/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt index 068c8e1c1..f2a3bdcd7 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/AuxioSheetBehavior.kt @@ -31,7 +31,7 @@ import org.oxycblt.auxio.util.systemGestureInsetsCompat /** * Implements a reasonable enough skeleton around BottomSheetBehavior (Excluding auxio extensions in - * the vendored code because I course I have to) for normal use without absurd bugs. + * the vendored code because of course I have to) for normal use without absurd bugs. * @author OxygenCobalt */ abstract class AuxioSheetBehavior(context: Context, attributeSet: AttributeSet?) : diff --git a/app/src/main/java/org/oxycblt/auxio/ui/recycler/ViewHolders.kt b/app/src/main/java/org/oxycblt/auxio/ui/recycler/ViewHolders.kt index cc7c5c98e..50667f228 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/recycler/ViewHolders.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/recycler/ViewHolders.kt @@ -169,7 +169,11 @@ class GenreViewHolder private constructor(private val binding: ItemParentBinding binding.parentImage.bind(item) binding.parentName.text = item.resolveName(binding.context) binding.parentInfo.text = - binding.context.getPlural(R.plurals.fmt_song_count, item.songs.size) + binding.context.getString( + R.string.fmt_two, + binding.context.getPlural(R.plurals.fmt_artist_count, item.artists.size), + binding.context.getPlural(R.plurals.fmt_song_count, item.songs.size) + ) // binding.parentMenu.setOnClickListener { listener.onOpenMenu(item, it) } binding.root.setOnLongClickListener { listener.onOpenMenu(item, it) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 92e5c03d3..a369b11f5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -361,4 +361,9 @@ %d album %d albums + + + %d artist + %d artists + diff --git a/build.gradle b/build.gradle index a02a518ca..dbbe26fc2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = '1.7.20' - ext.navigation_version = "2.5.2" + ext.navigation_version = "2.5.3" repositories { google()