music: update album type display
Only display album types within the artist and album detail menus. Displaying it elsewhere cluttered the UI somewhat.
This commit is contained in:
parent
30920b399a
commit
24062aa623
8 changed files with 14 additions and 28 deletions
|
@ -20,7 +20,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
compileSdkVersion 32
|
compileSdkVersion 32
|
||||||
buildToolsVersion "32.0.0"
|
buildToolsVersion '33.0.0'
|
||||||
|
|
||||||
// ExoPlayer, AndroidX, and Material Components all need Java 8 to compile.
|
// ExoPlayer, AndroidX, and Material Components all need Java 8 to compile.
|
||||||
|
|
||||||
|
|
|
@ -326,8 +326,8 @@ data class Genre(override val rawName: String?, override val songs: List<Song>)
|
||||||
* or reject valid-ish dates.
|
* or reject valid-ish dates.
|
||||||
*
|
*
|
||||||
* Date instances are immutable and their internal implementation is hidden. To instantiate one, use
|
* Date instances are immutable and their internal implementation is hidden. To instantiate one, use
|
||||||
* [from] or [from]. The string representation of a Date is RFC 3339, with granular position
|
* [from]. The string representation of a Date is RFC 3339, with granular position depending on the
|
||||||
* depending on the presence of particular tokens.
|
* presence of particular tokens.
|
||||||
*
|
*
|
||||||
* Please, **Do not use this for anything important related to time.** I cannot stress this enough.
|
* Please, **Do not use this for anything important related to time.** I cannot stress this enough.
|
||||||
* This class will blow up if you try to do that.
|
* This class will blow up if you try to do that.
|
||||||
|
@ -389,7 +389,6 @@ class Date private constructor(private val tokens: List<Int>) : Comparable<Date>
|
||||||
override fun toString() = StringBuilder().appendDate().toString()
|
override fun toString() = StringBuilder().appendDate().toString()
|
||||||
|
|
||||||
private fun StringBuilder.appendDate(): StringBuilder {
|
private fun StringBuilder.appendDate(): StringBuilder {
|
||||||
// RFC 3339 does not allow partial precision.
|
|
||||||
append(year.toFixedString(4))
|
append(year.toFixedString(4))
|
||||||
append("-${(month ?: return this).toFixedString(2)}")
|
append("-${(month ?: return this).toFixedString(2)}")
|
||||||
append("-${(day ?: return this).toFixedString(2)}")
|
append("-${(day ?: return this).toFixedString(2)}")
|
||||||
|
|
|
@ -534,10 +534,7 @@ open class Api29MediaStoreBackend : BaseApi29MediaStoreBackend() {
|
||||||
private var trackIndex = -1
|
private var trackIndex = -1
|
||||||
|
|
||||||
override val projection: Array<String>
|
override val projection: Array<String>
|
||||||
get() =
|
get() = super.projection + arrayOf(MediaStore.Audio.AudioColumns.TRACK)
|
||||||
super.projection +
|
|
||||||
arrayOf(
|
|
||||||
MediaStore.Audio.AudioColumns.TRACK, MediaStore.Audio.AudioColumns.DATE_TAKEN)
|
|
||||||
|
|
||||||
override fun buildAudio(context: Context, cursor: Cursor): Audio {
|
override fun buildAudio(context: Context, cursor: Cursor): Audio {
|
||||||
val audio = super.buildAudio(context, cursor)
|
val audio = super.buildAudio(context, cursor)
|
||||||
|
@ -588,7 +585,6 @@ class Api30MediaStoreBackend : BaseApi29MediaStoreBackend() {
|
||||||
// the tag itself, which is to say that it is formatted as NN/TT tracks, where
|
// the tag itself, which is to say that it is formatted as NN/TT tracks, where
|
||||||
// N is the number and T is the total. Parse the number while leaving out the
|
// N is the number and T is the total. Parse the number while leaving out the
|
||||||
// total, as we have no use for it.
|
// total, as we have no use for it.
|
||||||
|
|
||||||
cursor.getStringOrNull(trackIndex)?.parsePositionNum()?.let { audio.track = it }
|
cursor.getStringOrNull(trackIndex)?.parsePositionNum()?.let { audio.track = it }
|
||||||
cursor.getStringOrNull(discIndex)?.parsePositionNum()?.let { audio.disc = it }
|
cursor.getStringOrNull(discIndex)?.parsePositionNum()?.let { audio.disc = it }
|
||||||
|
|
||||||
|
|
|
@ -145,19 +145,18 @@ class SearchViewModel(application: Application) :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Album>.filterAlbumsBy(value: String) =
|
private fun List<Album>.filterAlbumsBy(value: String) =
|
||||||
baseFilterBy(value) { it.rawSortName?.contains(value) == true }
|
baseFilterBy(value) { it.rawSortName?.contains(value, ignoreCase = true) == true }
|
||||||
|
|
||||||
private fun List<Artist>.filterArtistsBy(value: String) =
|
private fun List<Artist>.filterArtistsBy(value: String) =
|
||||||
baseFilterBy(value) { it.rawSortName?.contains(value) == true }
|
baseFilterBy(value) { it.rawSortName?.contains(value, ignoreCase = true) == true }
|
||||||
|
|
||||||
private fun List<Genre>.filterGenresBy(value: String) = baseFilterBy(value) { false }
|
private fun List<Genre>.filterGenresBy(value: String) = baseFilterBy(value) { false }
|
||||||
|
|
||||||
private inline fun <T : Music> List<T>.baseFilterBy(value: String, additional: (T) -> Boolean) =
|
private inline fun <T : Music> List<T>.baseFilterBy(value: String, additional: (T) -> Boolean) =
|
||||||
filter {
|
filter {
|
||||||
// The basic comparison is first by the *normalized* name, as that allows a
|
// The basic comparison is first by the *normalized* name, as that allows a
|
||||||
// non-unicode
|
// non-unicode search to match with some unicode characters. If that fails,
|
||||||
// search to match with some unicode characters. If that fails, filter impls have
|
// filter impls have fallback values, primarily around sort tags or file names.
|
||||||
// fallback values, primarily around sort tags or file names.
|
|
||||||
it.resolveNameNormalized(application).contains(value, ignoreCase = true) ||
|
it.resolveNameNormalized(application).contains(value, ignoreCase = true) ||
|
||||||
additional(it)
|
additional(it)
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ class AboutFragment : ViewBindingFragment<FragmentAboutBinding>() {
|
||||||
// No app installed to open the link
|
// No app installed to open the link
|
||||||
requireContext().showToast(R.string.err_no_app)
|
requireContext().showToast(R.string.err_no_app)
|
||||||
}
|
}
|
||||||
} else {
|
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||||
// On older versions of android, opening links from an ACTION_VIEW intent might
|
// On older versions of android, opening links from an ACTION_VIEW intent might
|
||||||
// not work in all cases, especially when no default app was set. If that is the
|
// not work in all cases, especially when no default app was set. If that is the
|
||||||
// case, we will try to manually handle these cases before we try to launch the
|
// case, we will try to manually handle these cases before we try to launch the
|
||||||
|
|
|
@ -82,15 +82,7 @@ private constructor(
|
||||||
override fun bind(item: Album, listener: MenuItemListener) {
|
override fun bind(item: Album, listener: MenuItemListener) {
|
||||||
binding.parentImage.bind(item)
|
binding.parentImage.bind(item)
|
||||||
binding.parentName.textSafe = item.resolveName(binding.context)
|
binding.parentName.textSafe = item.resolveName(binding.context)
|
||||||
|
binding.parentInfo.textSafe = item.artist.resolveName(binding.context)
|
||||||
val artistName = item.artist.resolveName(binding.context)
|
|
||||||
binding.parentInfo.textSafe =
|
|
||||||
if (item.type != null) {
|
|
||||||
binding.context.getString(
|
|
||||||
R.string.fmt_two, binding.context.getString(item.type.string), artistName)
|
|
||||||
} else {
|
|
||||||
artistName
|
|
||||||
}
|
|
||||||
binding.root.apply {
|
binding.root.apply {
|
||||||
setOnClickListener { listener.onItemClick(item) }
|
setOnClickListener { listener.onItemClick(item) }
|
||||||
setOnLongClickListener { view ->
|
setOnLongClickListener { view ->
|
||||||
|
|
|
@ -138,13 +138,13 @@ private fun RemoteViews.applyPlayPauseControls(
|
||||||
context: Context,
|
context: Context,
|
||||||
state: WidgetComponent.WidgetState
|
state: WidgetComponent.WidgetState
|
||||||
): RemoteViews {
|
): RemoteViews {
|
||||||
|
// Controls are timeline elements, override the layout direction to RTL
|
||||||
|
setInt(R.id.widget_controls, "setLayoutDirection", View.LAYOUT_DIRECTION_LTR)
|
||||||
|
|
||||||
setOnClickPendingIntent(
|
setOnClickPendingIntent(
|
||||||
R.id.widget_play_pause,
|
R.id.widget_play_pause,
|
||||||
context.newBroadcastPendingIntent(PlaybackService.ACTION_PLAY_PAUSE))
|
context.newBroadcastPendingIntent(PlaybackService.ACTION_PLAY_PAUSE))
|
||||||
|
|
||||||
// Controls are timeline elements, override the layout direction to RTL
|
|
||||||
setInt(R.id.widget_controls, "setLayoutDirection", View.LAYOUT_DIRECTION_LTR)
|
|
||||||
|
|
||||||
setImageViewResource(
|
setImageViewResource(
|
||||||
R.id.widget_play_pause,
|
R.id.widget_play_pause,
|
||||||
if (state.isPlaying) {
|
if (state.isPlaying) {
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources />
|
Loading…
Reference in a new issue