diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt index e4da22cb3..1ded515e1 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt @@ -101,7 +101,7 @@ class MusicLoader(private val context: Context) { Albums._ID, // 0 Albums.ALBUM, // 1 Albums.ARTIST, // 2 - Albums.FIRST_YEAR, // 4 + Albums.LAST_YEAR, // 4 ), null, null, Albums.DEFAULT_SORT_ORDER @@ -114,7 +114,7 @@ class MusicLoader(private val context: Context) { val idIndex = cursor.getColumnIndexOrThrow(Albums._ID) val nameIndex = cursor.getColumnIndexOrThrow(Albums.ALBUM) val artistNameIndex = cursor.getColumnIndexOrThrow(Albums.ARTIST) - val yearIndex = cursor.getColumnIndexOrThrow(Albums.FIRST_YEAR) + val yearIndex = cursor.getColumnIndexOrThrow(Albums.LAST_YEAR) while (cursor.moveToNext()) { val id = cursor.getLong(idIndex) diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt b/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt index 8b420b70c..c664e3bdc 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt @@ -15,6 +15,7 @@ import org.oxycblt.auxio.music.Song * off the given sorting mode. * @property iconRes The icon for this [SortMode] * @author OxygenCobalt + * TODO: Make SortMode use title case [skip the/a(n)] */ enum class SortMode(@DrawableRes val iconRes: Int) { // Icons for each mode are assigned to the enums themselves @@ -32,11 +33,15 @@ enum class SortMode(@DrawableRes val iconRes: Int) { fun getSortedGenreList(genres: List): List { return when (this) { ALPHA_UP -> genres.sortedWith( - compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.resolvedName } + compareByDescending(String.CASE_INSENSITIVE_ORDER) { + it.resolvedName.sliceArticle() + } ) ALPHA_DOWN -> genres.sortedWith( - compareBy(String.CASE_INSENSITIVE_ORDER) { it.resolvedName } + compareBy(String.CASE_INSENSITIVE_ORDER) { + it.resolvedName.sliceArticle() + } ) else -> genres @@ -51,11 +56,15 @@ enum class SortMode(@DrawableRes val iconRes: Int) { fun getSortedArtistList(artists: List): List { return when (this) { ALPHA_UP -> artists.sortedWith( - compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name } + compareByDescending(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) ALPHA_DOWN -> artists.sortedWith( - compareBy(String.CASE_INSENSITIVE_ORDER) { it.name } + compareBy(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) else -> artists @@ -70,11 +79,15 @@ enum class SortMode(@DrawableRes val iconRes: Int) { fun getSortedAlbumList(albums: List): List { return when (this) { ALPHA_UP -> albums.sortedWith( - compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name } + compareByDescending(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) ALPHA_DOWN -> albums.sortedWith( - compareBy(String.CASE_INSENSITIVE_ORDER) { it.name } + compareBy(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) NUMERIC_UP -> albums.sortedBy { it.year } @@ -92,11 +105,15 @@ enum class SortMode(@DrawableRes val iconRes: Int) { fun getSortedSongList(songs: List): List { return when (this) { ALPHA_UP -> songs.sortedWith( - compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name } + compareByDescending(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) ALPHA_DOWN -> songs.sortedWith( - compareBy(String.CASE_INSENSITIVE_ORDER) { it.name } + compareBy(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) NUMERIC_UP -> songs.sortedWith(compareByDescending { it.track }) @@ -114,11 +131,15 @@ enum class SortMode(@DrawableRes val iconRes: Int) { fun getSortedArtistSongList(songs: List): List { return when (this) { ALPHA_UP -> songs.sortedWith( - compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name } + compareByDescending(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) ALPHA_DOWN -> songs.sortedWith( - compareBy(String.CASE_INSENSITIVE_ORDER) { it.name } + compareBy(String.CASE_INSENSITIVE_ORDER) { + it.name.sliceArticle() + } ) NUMERIC_UP -> { @@ -130,6 +151,7 @@ enum class SortMode(@DrawableRes val iconRes: Int) { list } + NUMERIC_DOWN -> { val list = mutableListOf() @@ -205,3 +227,24 @@ enum class SortMode(@DrawableRes val iconRes: Int) { fun ImageButton.bindSortIcon(mode: SortMode) { setImageResource(mode.iconRes) } + +/** + * Slice a string so that any preceding articles like The/A(n) are truncated. + * This is hilariously anglo-centric, but its mostly for MediaStore compat and hopefully + * shouldn't run with other languages. + */ +fun String.sliceArticle(): String { + if (length > 5 && startsWith("the ", true)) { + return slice(4..lastIndex) + } + + if (length > 4 && startsWith("an ", true)) { + return slice(3..lastIndex) + } + + if (length > 3 && startsWith("a ", true)) { + return slice(2..lastIndex) + } + + return this +} diff --git a/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt b/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt index 3aa98ed8d..056072aa5 100644 --- a/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt +++ b/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt @@ -31,6 +31,7 @@ import kotlin.math.roundToInt * fast-scrollers, this one displays indicators and a thumb instead of simply a scroll bar. * This code is fundamentally an adaptation of Reddit's IndicatorFastScroll, albeit specialized * towards Auxio. The original library is here: https://github.com/reddit/IndicatorFastScroll/ + * TODO: Make this update with data. * @author OxygenCobalt */ class FastScrollView @JvmOverloads constructor( diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt index c0ae625de..4a8914a84 100644 --- a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt @@ -12,6 +12,7 @@ import org.oxycblt.auxio.databinding.FragmentSongsBinding import org.oxycblt.auxio.logD import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.playback.PlaybackViewModel +import org.oxycblt.auxio.recycler.sliceArticle import org.oxycblt.auxio.ui.getSpans import org.oxycblt.auxio.ui.newMenu @@ -56,7 +57,8 @@ class SongsFragment : Fragment() { } binding.songFastScroll.setup(binding.songRecycler) { pos -> - val char = musicStore.songs[pos].name.first + // Get the first character [respecting articles] + val char = musicStore.songs[pos].name.sliceArticle().first().uppercaseChar() if (char.isDigit()) '#' else char } @@ -65,26 +67,4 @@ class SongsFragment : Fragment() { return binding.root } - - /** - * Dumb shortcut for getting the first letter in a string, while regarding certain - * semantics when it comes to articles. - */ - private val String.first: Char get() { - // If the name actually starts with "The"/"A"/"An", get the character *after* that word. - // Yes, this is stupidly english centric but it wont run with other languages. - if (length > 5 && startsWith("the ", true)) { - return get(4).uppercaseChar() - } - - if (length > 3 && startsWith("a ", true)) { - return get(2).uppercaseChar() - } - - if (length > 4 && startsWith("an ", true)) { - return get(3).uppercaseChar() - } - - return get(0).uppercaseChar() - } }