diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt index 43dded9c6..12991e916 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt @@ -62,7 +62,7 @@ import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.music.IndexingProgress import org.oxycblt.auxio.music.IndexingState import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.NoAudioPermissionException import org.oxycblt.auxio.music.NoMusicException @@ -173,7 +173,7 @@ class HomeFragment : // --- VIEWMODEL SETUP --- collect(homeModel.recreateTabs.flow, ::handleRecreate) - collectImmediately(homeModel.currentTabMode, ::updateCurrentTab) + collectImmediately(homeModel.currentTabType, ::updateCurrentTab) collectImmediately(homeModel.songsList, homeModel.isFastScrolling, ::updateFab) collect(listModel.menu.flow, ::handleMenu) collectImmediately(listModel.selected, ::updateSelection) @@ -245,7 +245,7 @@ class HomeFragment : item.isChecked = true homeModel.setSortForCurrentTab( homeModel - .getSortForTab(homeModel.currentTabMode.value) + .getSortForTab(homeModel.currentTabType.value) .withDirection(Sort.Direction.ASCENDING)) true } @@ -254,7 +254,7 @@ class HomeFragment : item.isChecked = true homeModel.setSortForCurrentTab( homeModel - .getSortForTab(homeModel.currentTabMode.value) + .getSortForTab(homeModel.currentTabType.value) .withDirection(Sort.Direction.DESCENDING)) true } @@ -265,7 +265,7 @@ class HomeFragment : logD("Updating sort mode") item.isChecked = true homeModel.setSortForCurrentTab( - homeModel.getSortForTab(homeModel.currentTabMode.value).withMode(newMode)) + homeModel.getSortForTab(homeModel.currentTabType.value).withMode(newMode)) true } else { logW("Unexpected menu item selected") @@ -277,10 +277,10 @@ class HomeFragment : private fun setupPager(binding: FragmentHomeBinding) { binding.homePager.adapter = - HomePagerAdapter(homeModel.currentTabModes, childFragmentManager, viewLifecycleOwner) + HomePagerAdapter(homeModel.currentTabTypes, childFragmentManager, viewLifecycleOwner) val toolbarParams = binding.homeToolbar.layoutParams as AppBarLayout.LayoutParams - if (homeModel.currentTabModes.size == 1) { + if (homeModel.currentTabTypes.size == 1) { // A single tab makes the tab layout redundant, hide it and disable the collapsing // behavior. logD("Single tab shown, disabling TabLayout") @@ -298,22 +298,22 @@ class HomeFragment : TabLayoutMediator( binding.homeTabs, binding.homePager, - AdaptiveTabStrategy(requireContext(), homeModel.currentTabModes)) + AdaptiveTabStrategy(requireContext(), homeModel.currentTabTypes)) .attach() } - private fun updateCurrentTab(tabMode: MusicMode) { + private fun updateCurrentTab(tabType: MusicType) { val binding = requireBinding() // Update the sort options to align with those allowed by the tab val isVisible: (Int) -> Boolean = - when (tabMode) { + when (tabType) { // Disallow sorting by count for songs - MusicMode.SONGS -> { + MusicType.SONGS -> { logD("Using song-specific menu options") ({ id -> id != R.id.option_sort_count }) } // Disallow sorting by album for albums - MusicMode.ALBUMS -> { + MusicType.ALBUMS -> { logD("Using album-specific menu options") ({ id -> id != R.id.option_sort_album }) } @@ -332,7 +332,7 @@ class HomeFragment : val sortMenu = unlikelyToBeNull(binding.homeNormalToolbar.menu.findItem(R.id.submenu_sorting).subMenu) - val toHighlight = homeModel.getSortForTab(tabMode) + val toHighlight = homeModel.getSortForTab(tabType) for (option in sortMenu) { val isCurrentMode = option.itemId == toHighlight.mode.itemId @@ -364,15 +364,15 @@ class HomeFragment : // scrolling state. This prevents the lift state from being confused as one // goes between different tabs. binding.homeAppbar.liftOnScrollTargetViewId = - when (tabMode) { - MusicMode.SONGS -> R.id.home_song_recycler - MusicMode.ALBUMS -> R.id.home_album_recycler - MusicMode.ARTISTS -> R.id.home_artist_recycler - MusicMode.GENRES -> R.id.home_genre_recycler - MusicMode.PLAYLISTS -> R.id.home_playlist_recycler + when (tabType) { + MusicType.SONGS -> R.id.home_song_recycler + MusicType.ALBUMS -> R.id.home_album_recycler + MusicType.ARTISTS -> R.id.home_artist_recycler + MusicType.GENRES -> R.id.home_genre_recycler + MusicType.PLAYLISTS -> R.id.home_playlist_recycler } - if (tabMode != MusicMode.PLAYLISTS) { + if (tabType != MusicType.PLAYLISTS) { logD("Flipping to shuffle button") binding.homeFab.flipTo(R.drawable.ic_shuffle_off_24, R.string.desc_shuffle_all) { playbackModel.shuffleAll() @@ -632,18 +632,18 @@ class HomeFragment : * [FragmentStateAdapter]. */ private class HomePagerAdapter( - private val tabs: List, + private val tabs: List, fragmentManager: FragmentManager, lifecycleOwner: LifecycleOwner ) : FragmentStateAdapter(fragmentManager, lifecycleOwner.lifecycle) { override fun getItemCount() = tabs.size override fun createFragment(position: Int): Fragment = when (tabs[position]) { - MusicMode.SONGS -> SongListFragment() - MusicMode.ALBUMS -> AlbumListFragment() - MusicMode.ARTISTS -> ArtistListFragment() - MusicMode.GENRES -> GenreListFragment() - MusicMode.PLAYLISTS -> PlaylistListFragment() + MusicType.SONGS -> SongListFragment() + MusicType.ALBUMS -> AlbumListFragment() + MusicType.ARTISTS -> ArtistListFragment() + MusicType.GENRES -> GenreListFragment() + MusicType.PLAYLISTS -> PlaylistListFragment() } } diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeSettings.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeSettings.kt index 4e468ec95..5fc218cfe 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeSettings.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeSettings.kt @@ -24,7 +24,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import org.oxycblt.auxio.R import org.oxycblt.auxio.home.tabs.Tab -import org.oxycblt.auxio.music.MusicMode +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.unlikelyToBeNull @@ -75,9 +75,9 @@ class HomeSettingsImpl @Inject constructor(@ApplicationContext context: Context) logD("Old tabs: $oldTabs") // The playlist tab is now parsed, but it needs to be made visible. - val playlistIndex = oldTabs.indexOfFirst { it.mode == MusicMode.PLAYLISTS } + val playlistIndex = oldTabs.indexOfFirst { it.type == MusicType.PLAYLISTS } check(playlistIndex > -1) // This should exist, otherwise we are in big trouble - oldTabs[playlistIndex] = Tab.Visible(MusicMode.PLAYLISTS) + oldTabs[playlistIndex] = Tab.Visible(MusicType.PLAYLISTS) logD("New tabs: $oldTabs") sharedPreferences.edit { diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt index 538dcb541..eb5efc322 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt @@ -29,9 +29,9 @@ import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Genre -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicRepository import org.oxycblt.auxio.music.MusicSettings +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.Playlist import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaySong @@ -108,15 +108,15 @@ constructor( get() = playbackSettings.playInListWith /** - * A list of [MusicMode] corresponding to the current [Tab] configuration, excluding invisible + * A list of [MusicType] corresponding to the current [Tab] configuration, excluding invisible * [Tab]s. */ - var currentTabModes = makeTabModes() + var currentTabTypes = makeTabTypes() private set - private val _currentTabMode = MutableStateFlow(currentTabModes[0]) - /** The [MusicMode] of the currently shown [Tab]. */ - val currentTabMode: StateFlow = _currentTabMode + private val _currentTabType = MutableStateFlow(currentTabTypes[0]) + /** The [MusicType] of the currently shown [Tab]. */ + val currentTabType: StateFlow = _currentTabType private val _shouldRecreate = MutableEvent() /** @@ -177,8 +177,8 @@ constructor( override fun onTabsChanged() { // Tabs changed, update the current tabs and set up a re-create event. - currentTabModes = makeTabModes() - logD("Updating tabs: ${currentTabMode.value}") + currentTabTypes = makeTabTypes() + logD("Updating tabs: ${currentTabType.value}") _shouldRecreate.put(Unit) } @@ -192,16 +192,16 @@ constructor( /** * Get the preferred [Sort] for a given [Tab]. * - * @param tabMode The [MusicMode] of the [Tab] desired. + * @param tabType The [MusicType] of the [Tab] desired. * @return The [Sort] preferred for that [Tab] */ - fun getSortForTab(tabMode: MusicMode) = - when (tabMode) { - MusicMode.SONGS -> musicSettings.songSort - MusicMode.ALBUMS -> musicSettings.albumSort - MusicMode.ARTISTS -> musicSettings.artistSort - MusicMode.GENRES -> musicSettings.genreSort - MusicMode.PLAYLISTS -> musicSettings.playlistSort + fun getSortForTab(tabType: MusicType) = + when (tabType) { + MusicType.SONGS -> musicSettings.songSort + MusicType.ALBUMS -> musicSettings.albumSort + MusicType.ARTISTS -> musicSettings.artistSort + MusicType.GENRES -> musicSettings.genreSort + MusicType.PLAYLISTS -> musicSettings.playlistSort } /** @@ -211,33 +211,33 @@ constructor( */ fun setSortForCurrentTab(sort: Sort) { // Can simply re-sort the current list of items without having to access the library. - when (val mode = _currentTabMode.value) { - MusicMode.SONGS -> { - logD("Updating song [$mode] sort mode to $sort") + when (val type = _currentTabType.value) { + MusicType.SONGS -> { + logD("Updating song [$type] sort mode to $sort") musicSettings.songSort = sort _songsInstructions.put(UpdateInstructions.Replace(0)) _songsList.value = sort.songs(_songsList.value) } - MusicMode.ALBUMS -> { - logD("Updating album [$mode] sort mode to $sort") + MusicType.ALBUMS -> { + logD("Updating album [$type] sort mode to $sort") musicSettings.albumSort = sort _albumsInstructions.put(UpdateInstructions.Replace(0)) _albumsLists.value = sort.albums(_albumsLists.value) } - MusicMode.ARTISTS -> { - logD("Updating artist [$mode] sort mode to $sort") + MusicType.ARTISTS -> { + logD("Updating artist [$type] sort mode to $sort") musicSettings.artistSort = sort _artistsInstructions.put(UpdateInstructions.Replace(0)) _artistsList.value = sort.artists(_artistsList.value) } - MusicMode.GENRES -> { - logD("Updating genre [$mode] sort mode to $sort") + MusicType.GENRES -> { + logD("Updating genre [$type] sort mode to $sort") musicSettings.genreSort = sort _genresInstructions.put(UpdateInstructions.Replace(0)) _genresList.value = sort.genres(_genresList.value) } - MusicMode.PLAYLISTS -> { - logD("Updating playlist [$mode] sort mode to $sort") + MusicType.PLAYLISTS -> { + logD("Updating playlist [$type] sort mode to $sort") musicSettings.playlistSort = sort _playlistsInstructions.put(UpdateInstructions.Replace(0)) _playlistsList.value = sort.playlists(_playlistsList.value) @@ -246,13 +246,13 @@ constructor( } /** - * Update [currentTabMode] to reflect a new ViewPager2 position + * Update [currentTabType] to reflect a new ViewPager2 position * * @param pagerPos The new position of the ViewPager2 instance. */ fun synchronizeTabPosition(pagerPos: Int) { - logD("Updating current tab to ${currentTabModes[pagerPos]}") - _currentTabMode.value = currentTabModes[pagerPos] + logD("Updating current tab to ${currentTabTypes[pagerPos]}") + _currentTabType.value = currentTabTypes[pagerPos] } /** @@ -266,11 +266,11 @@ constructor( } /** - * Create a list of [MusicMode]s representing a simpler version of the [Tab] configuration. + * Create a list of [MusicType]s representing a simpler version of the [Tab] configuration. * - * @return A list of the [MusicMode]s for each visible [Tab] in the configuration, ordered in + * @return A list of the [MusicType]s for each visible [Tab] in the configuration, ordered in * the same way as the configuration. */ - private fun makeTabModes() = - homeSettings.homeTabs.filterIsInstance().map { it.mode } + private fun makeTabTypes() = + homeSettings.homeTabs.filterIsInstance().map { it.type } } diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt index 984551733..ce8fcfb20 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt @@ -39,8 +39,8 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.recycler.AlbumViewHolder import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicParent +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel @@ -99,7 +99,7 @@ class AlbumListFragment : override fun getPopup(pos: Int): String? { val album = homeModel.albumsList.value[pos] // Change how we display the popup depending on the current sort mode. - return when (homeModel.getSortForTab(MusicMode.ALBUMS).mode) { + return when (homeModel.getSortForTab(MusicType.ALBUMS).mode) { // By Name -> Use Name is Sort.Mode.ByName -> album.name.thumb diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt index ab9928003..8cda450e7 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt @@ -37,8 +37,8 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.recycler.ArtistViewHolder import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicParent +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel @@ -94,7 +94,7 @@ class ArtistListFragment : override fun getPopup(pos: Int): String? { val artist = homeModel.artistsList.value[pos] // Change how we display the popup depending on the current sort mode. - return when (homeModel.getSortForTab(MusicMode.ARTISTS).mode) { + return when (homeModel.getSortForTab(MusicType.ARTISTS).mode) { // By Name -> Use Name is Sort.Mode.ByName -> artist.name.thumb diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt index 2ecd73f90..bba02ff20 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt @@ -37,8 +37,8 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.recycler.GenreViewHolder import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicParent +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel @@ -93,7 +93,7 @@ class GenreListFragment : override fun getPopup(pos: Int): String? { val genre = homeModel.genresList.value[pos] // Change how we display the popup depending on the current sort mode. - return when (homeModel.getSortForTab(MusicMode.GENRES).mode) { + return when (homeModel.getSortForTab(MusicType.GENRES).mode) { // By Name -> Use Name is Sort.Mode.ByName -> genre.name.thumb diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/PlaylistListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/PlaylistListFragment.kt index 299ceb39c..164b0da92 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/PlaylistListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/PlaylistListFragment.kt @@ -35,8 +35,8 @@ import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.recycler.PlaylistViewHolder import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicParent +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Playlist import org.oxycblt.auxio.music.Song @@ -91,7 +91,7 @@ class PlaylistListFragment : override fun getPopup(pos: Int): String? { val playlist = homeModel.playlistsList.value[pos] // Change how we display the popup depending on the current sort mode. - return when (homeModel.getSortForTab(MusicMode.GENRES).mode) { + return when (homeModel.getSortForTab(MusicType.GENRES).mode) { // By Name -> Use Name is Sort.Mode.ByName -> playlist.name.thumb diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt index 74bd833ed..3b2782525 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt @@ -37,8 +37,8 @@ import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.recycler.SongViewHolder import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicParent +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.PlaybackViewModel @@ -98,7 +98,7 @@ class SongListFragment : // Change how we display the popup depending on the current sort mode. // Note: We don't use the more correct individual artist name here, as sorts are largely // based off the names of the parent objects and not the child objects. - return when (homeModel.getSortForTab(MusicMode.SONGS).mode) { + return when (homeModel.getSortForTab(MusicType.SONGS).mode) { // Name -> Use name is Sort.Mode.ByName -> song.name.thumb diff --git a/app/src/main/java/org/oxycblt/auxio/home/tabs/AdaptiveTabStrategy.kt b/app/src/main/java/org/oxycblt/auxio/home/tabs/AdaptiveTabStrategy.kt index 36aed93bf..73170ef4c 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/tabs/AdaptiveTabStrategy.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/tabs/AdaptiveTabStrategy.kt @@ -22,7 +22,7 @@ import android.content.Context import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import org.oxycblt.auxio.R -import org.oxycblt.auxio.music.MusicMode +import org.oxycblt.auxio.music.MusicType /** * A [TabLayoutMediator.TabConfigurationStrategy] that uses larger/smaller tab configurations @@ -32,7 +32,7 @@ import org.oxycblt.auxio.music.MusicMode * @param tabs Current tab configuration from settings * @author Alexander Capehart (OxygenCobalt) */ -class AdaptiveTabStrategy(context: Context, private val tabs: List) : +class AdaptiveTabStrategy(context: Context, private val tabs: List) : TabLayoutMediator.TabConfigurationStrategy { private val width = context.resources.configuration.smallestScreenWidthDp @@ -41,23 +41,23 @@ class AdaptiveTabStrategy(context: Context, private val tabs: List) : val string: Int when (tabs[position]) { - MusicMode.SONGS -> { + MusicType.SONGS -> { icon = R.drawable.ic_song_24 string = R.string.lbl_songs } - MusicMode.ALBUMS -> { + MusicType.ALBUMS -> { icon = R.drawable.ic_album_24 string = R.string.lbl_albums } - MusicMode.ARTISTS -> { + MusicType.ARTISTS -> { icon = R.drawable.ic_artist_24 string = R.string.lbl_artists } - MusicMode.GENRES -> { + MusicType.GENRES -> { icon = R.drawable.ic_genre_24 string = R.string.lbl_genres } - MusicMode.PLAYLISTS -> { + MusicType.PLAYLISTS -> { icon = R.drawable.ic_playlist_24 string = R.string.lbl_playlists } diff --git a/app/src/main/java/org/oxycblt/auxio/home/tabs/Tab.kt b/app/src/main/java/org/oxycblt/auxio/home/tabs/Tab.kt index 5cacd084b..aee964e45 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/tabs/Tab.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/tabs/Tab.kt @@ -18,30 +18,30 @@ package org.oxycblt.auxio.home.tabs -import org.oxycblt.auxio.music.MusicMode +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.util.logE import org.oxycblt.auxio.util.logW /** * A representation of a library tab suitable for configuration. * - * @param mode The type of list in the home view this instance corresponds to. + * @param type The type of list in the home view this instance corresponds to. * @author Alexander Capehart (OxygenCobalt) */ -sealed class Tab(open val mode: MusicMode) { +sealed class Tab(open val type: MusicType) { /** * A visible tab. This will be visible in the home and tab configuration views. * - * @param mode The type of list in the home view this instance corresponds to. + * @param type The type of list in the home view this instance corresponds to. */ - data class Visible(override val mode: MusicMode) : Tab(mode) + data class Visible(override val type: MusicType) : Tab(type) /** * A visible tab. This will be visible in the tab configuration view, but not in the home view. * - * @param mode The type of list in the home view this instance corresponds to. + * @param type The type of list in the home view this instance corresponds to. */ - data class Invisible(override val mode: MusicMode) : Tab(mode) + data class Invisible(override val type: MusicType) : Tab(type) companion object { // Like other IO-bound datatypes in Auxio, tabs are stored in a binary format. However, tabs @@ -67,14 +67,14 @@ sealed class Tab(open val mode: MusicMode) { */ const val SEQUENCE_DEFAULT = 0b1000_1001_1010_1011_1100 - /** Maps between the integer code in the tab sequence and it's [MusicMode]. */ + /** Maps between the integer code in the tab sequence and it's [MusicType]. */ private val MODE_TABLE = arrayOf( - MusicMode.SONGS, - MusicMode.ALBUMS, - MusicMode.ARTISTS, - MusicMode.GENRES, - MusicMode.PLAYLISTS) + MusicType.SONGS, + MusicType.ALBUMS, + MusicType.ARTISTS, + MusicType.GENRES, + MusicType.PLAYLISTS) /** * Convert an array of [Tab]s into it's integer representation. @@ -84,7 +84,7 @@ sealed class Tab(open val mode: MusicMode) { */ fun toIntCode(tabs: Array): Int { // Like when deserializing, make sure there are no duplicate tabs for whatever reason. - val distinct = tabs.distinctBy { it.mode } + val distinct = tabs.distinctBy { it.type } if (tabs.size != distinct.size) { logW( "Tab sequences should not have duplicates [old: ${tabs.size} new: ${distinct.size}]") @@ -95,8 +95,8 @@ sealed class Tab(open val mode: MusicMode) { for (tab in distinct) { val bin = when (tab) { - is Visible -> 1.shl(3) or MODE_TABLE.indexOf(tab.mode) - is Invisible -> MODE_TABLE.indexOf(tab.mode) + is Visible -> 1.shl(3) or MODE_TABLE.indexOf(tab.type) + is Invisible -> MODE_TABLE.indexOf(tab.type) } sequence = sequence or bin.shl(shift) @@ -131,7 +131,7 @@ sealed class Tab(open val mode: MusicMode) { } // Make sure there are no duplicate tabs - val distinct = tabs.distinctBy { it.mode } + val distinct = tabs.distinctBy { it.type } if (tabs.size != distinct.size) { logW( "Tab sequences should not have duplicates [old: ${tabs.size} new: ${distinct.size}]") diff --git a/app/src/main/java/org/oxycblt/auxio/home/tabs/TabAdapter.kt b/app/src/main/java/org/oxycblt/auxio/home/tabs/TabAdapter.kt index 277c0c39b..aa71b89f1 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/tabs/TabAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/tabs/TabAdapter.kt @@ -26,7 +26,7 @@ import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.ItemTabBinding import org.oxycblt.auxio.list.EditClickListListener import org.oxycblt.auxio.list.recycler.DialogRecyclerView -import org.oxycblt.auxio.music.MusicMode +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.logD @@ -107,14 +107,14 @@ class TabViewHolder private constructor(private val binding: ItemTabBinding) : fun bind(tab: Tab, listener: EditClickListListener) { listener.bind(tab, this, dragHandle = binding.tabDragHandle) binding.tabCheckBox.apply { - // Update the CheckBox name to align with the mode + // Update the CheckBox name to align with the type setText( - when (tab.mode) { - MusicMode.SONGS -> R.string.lbl_songs - MusicMode.ALBUMS -> R.string.lbl_albums - MusicMode.ARTISTS -> R.string.lbl_artists - MusicMode.GENRES -> R.string.lbl_genres - MusicMode.PLAYLISTS -> R.string.lbl_playlists + when (tab.type) { + MusicType.SONGS -> R.string.lbl_songs + MusicType.ALBUMS -> R.string.lbl_albums + MusicType.ARTISTS -> R.string.lbl_artists + MusicType.GENRES -> R.string.lbl_genres + MusicType.PLAYLISTS -> R.string.lbl_playlists }) // Unlike in other adapters, we update the checked state alongside diff --git a/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt b/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt index fd6b36ae7..57bc73c15 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt @@ -91,13 +91,13 @@ class TabCustomizeDialog : override fun onClick(item: Tab, viewHolder: RecyclerView.ViewHolder) { // We will need the exact index of the tab to update on in order to // notify the adapter of the change. - val index = tabAdapter.tabs.indexOfFirst { it.mode == item.mode } + val index = tabAdapter.tabs.indexOfFirst { it.type == item.type } val old = tabAdapter.tabs[index] val new = when (old) { // Invert the visibility of the tab - is Tab.Visible -> Tab.Invisible(old.mode) - is Tab.Invisible -> Tab.Visible(old.mode) + is Tab.Visible -> Tab.Invisible(old.type) + is Tab.Invisible -> Tab.Visible(old.type) } logD("Flipping tab visibility [from: $old to: $new]") tabAdapter.setTab(index, new) 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 fc8a51390..766ea462c 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/Music.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Music.kt @@ -80,23 +80,23 @@ sealed interface Music : Item { class UID private constructor( private val format: Format, - private val mode: MusicMode, + private val type: MusicType, private val uuid: UUID ) : Parcelable { // Cache the hashCode for HashMap efficiency. @IgnoredOnParcel private var hashCode = format.hashCode() init { - hashCode = 31 * hashCode + mode.hashCode() + hashCode = 31 * hashCode + type.hashCode() hashCode = 31 * hashCode + uuid.hashCode() } override fun hashCode() = hashCode override fun equals(other: Any?) = - other is UID && format == other.format && mode == other.mode && uuid == other.uuid + other is UID && format == other.format && type == other.type && uuid == other.uuid - override fun toString() = "${format.namespace}:${mode.intCode.toString(16)}-$uuid" + override fun toString() = "${format.namespace}:${type.intCode.toString(16)}-$uuid" /** * Internal marker of [Music.UID] format type. @@ -124,23 +124,23 @@ sealed interface Music : Item { * Creates an Auxio-style [UID] of random composition. Used if there is no * non-subjective, unlikely-to-change metadata of the music. * - * @param mode The analogous [MusicMode] of the item that created this [UID]. + * @param type The analogous [MusicType] of the item that created this [UID]. */ - fun auxio(mode: MusicMode): UID { - return UID(Format.AUXIO, mode, UUID.randomUUID()) + fun auxio(type: MusicType): UID { + return UID(Format.AUXIO, type, UUID.randomUUID()) } /** * Creates an Auxio-style [UID] with a [UUID] composed of a hash of the non-subjective, * unlikely-to-change metadata of the music. * - * @param mode The analogous [MusicMode] of the item that created this [UID]. + * @param type The analogous [MusicType] of the item that created this [UID]. * @param updates Block to update the [MessageDigest] hash with the metadata of the * item. Make sure the metadata hashed semantically aligns with the format * specification. * @return A new auxio-style [UID]. */ - fun auxio(mode: MusicMode, updates: MessageDigest.() -> Unit): UID { + fun auxio(type: MusicType, updates: MessageDigest.() -> Unit): UID { val digest = MessageDigest.getInstance("SHA-256").run { updates() @@ -170,19 +170,19 @@ sealed interface Music : Item { .or(digest[13].toLong().and(0xFF).shl(16)) .or(digest[14].toLong().and(0xFF).shl(8)) .or(digest[15].toLong().and(0xFF))) - return UID(Format.AUXIO, mode, uuid) + return UID(Format.AUXIO, type, uuid) } /** * Creates a MusicBrainz-style [UID] with a [UUID] derived from the MusicBrainz ID * extracted from a file. * - * @param mode The analogous [MusicMode] of the item that created this [UID]. + * @param type The analogous [MusicType] of the item that created this [UID]. * @param mbid The analogous MusicBrainz ID for this item that was extracted from a * file. * @return A new MusicBrainz-style [UID]. */ - fun musicBrainz(mode: MusicMode, mbid: UUID) = UID(Format.MUSICBRAINZ, mode, mbid) + fun musicBrainz(type: MusicType, mbid: UUID) = UID(Format.MUSICBRAINZ, type, mbid) /** * Convert a [UID]'s string representation back into a concrete [UID] instance. @@ -210,10 +210,10 @@ sealed interface Music : Item { return null } - val mode = - MusicMode.fromIntCode(ids[0].toIntOrNull(16) ?: return null) ?: return null + val type = + MusicType.fromIntCode(ids[0].toIntOrNull(16) ?: return null) ?: return null val uuid = ids[1].toUuidOrNull() ?: return null - return UID(format, mode, uuid) + return UID(format, type, uuid) } } } diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicMode.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicType.kt similarity index 73% rename from app/src/main/java/org/oxycblt/auxio/music/MusicMode.kt rename to app/src/main/java/org/oxycblt/auxio/music/MusicType.kt index 03ec48dae..19f535af1 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicType.kt @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 Auxio Project - * MusicMode.kt is part of Auxio. + * MusicType.kt is part of Auxio. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,20 +21,20 @@ package org.oxycblt.auxio.music import org.oxycblt.auxio.IntegerTable /** - * Represents a data configuration corresponding to a specific type of [Music], + * General configuration enum to control what kind of music is being worked with. * * @author Alexander Capehart (OxygenCobalt) */ -enum class MusicMode { - /** Configure with respect to [Song] instances. */ +enum class MusicType { + /** @see Song */ SONGS, - /** Configure with respect to [Album] instances. */ + /** @see Album */ ALBUMS, - /** Configure with respect to [Artist] instances. */ + /** @see Artist */ ARTISTS, - /** Configure with respect to [Genre] instances. */ + /** @see Genre */ GENRES, - /** Configure with respect to [Playlist] instances. */ + /** @see Playlist */ PLAYLISTS; /** @@ -54,11 +54,11 @@ enum class MusicMode { companion object { /** - * Convert a [MusicMode] integer representation into an instance. + * Convert a [MusicType] integer representation into an instance. * - * @param intCode An integer representation of a [MusicMode] - * @return The corresponding [MusicMode], or null if the [MusicMode] is invalid. - * @see MusicMode.intCode + * @param intCode An integer representation of a [MusicType] + * @return The corresponding [MusicType], or null if the [MusicType] is invalid. + * @see MusicType.intCode */ fun fromIntCode(intCode: Int) = when (intCode) { diff --git a/app/src/main/java/org/oxycblt/auxio/music/device/DeviceMusicImpl.kt b/app/src/main/java/org/oxycblt/auxio/music/device/DeviceMusicImpl.kt index 2f12b7290..e568b8f16 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/device/DeviceMusicImpl.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/device/DeviceMusicImpl.kt @@ -25,8 +25,8 @@ import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicSettings +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.fs.MimeType import org.oxycblt.auxio.music.fs.Path @@ -54,8 +54,8 @@ import org.oxycblt.auxio.util.update class SongImpl(private val rawSong: RawSong, musicSettings: MusicSettings) : Song { override val uid = // Attempt to use a MusicBrainz ID first before falling back to a hashed UID. - rawSong.musicBrainzId?.toUuidOrNull()?.let { Music.UID.musicBrainz(MusicMode.SONGS, it) } - ?: Music.UID.auxio(MusicMode.SONGS) { + rawSong.musicBrainzId?.toUuidOrNull()?.let { Music.UID.musicBrainz(MusicType.SONGS, it) } + ?: Music.UID.auxio(MusicType.SONGS) { // Song UIDs are based on the raw data without parsing so that they remain // consistent across music setting changes. Parents are not held up to the // same standard since grouping is already inherently linked to settings. @@ -251,8 +251,8 @@ class AlbumImpl( override val uid = // Attempt to use a MusicBrainz ID first before falling back to a hashed UID. - rawAlbum.musicBrainzId?.let { Music.UID.musicBrainz(MusicMode.ALBUMS, it) } - ?: Music.UID.auxio(MusicMode.ALBUMS) { + rawAlbum.musicBrainzId?.let { Music.UID.musicBrainz(MusicType.ALBUMS, it) } + ?: Music.UID.auxio(MusicType.ALBUMS) { // Hash based on only names despite the presence of a date to increase stability. // I don't know if there is any situation where an artist will have two albums with // the exact same name, but if there is, I would love to know. @@ -366,8 +366,8 @@ class ArtistImpl(grouping: Grouping, musicSettings: MusicSetti override val uid = // Attempt to use a MusicBrainz ID first before falling back to a hashed UID. - rawArtist.musicBrainzId?.let { Music.UID.musicBrainz(MusicMode.ARTISTS, it) } - ?: Music.UID.auxio(MusicMode.ARTISTS) { update(rawArtist.name) } + rawArtist.musicBrainzId?.let { Music.UID.musicBrainz(MusicType.ARTISTS, it) } + ?: Music.UID.auxio(MusicType.ARTISTS) { update(rawArtist.name) } override val name = rawArtist.name?.let { Name.Known.from(it, rawArtist.sortName, musicSettings) } ?: Name.Unknown(R.string.def_artist) @@ -461,7 +461,7 @@ class ArtistImpl(grouping: Grouping, musicSettings: MusicSetti class GenreImpl(grouping: Grouping, musicSettings: MusicSettings) : Genre { private val rawGenre = grouping.raw.inner - override val uid = Music.UID.auxio(MusicMode.GENRES) { update(rawGenre.name) } + override val uid = Music.UID.auxio(MusicType.GENRES) { update(rawGenre.name) } override val name = rawGenre.name?.let { Name.Known.from(it, rawGenre.name, musicSettings) } ?: Name.Unknown(R.string.def_genre) diff --git a/app/src/main/java/org/oxycblt/auxio/music/user/PlaylistImpl.kt b/app/src/main/java/org/oxycblt/auxio/music/user/PlaylistImpl.kt index 9ad14f411..19cf12401 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/user/PlaylistImpl.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/user/PlaylistImpl.kt @@ -19,8 +19,8 @@ package org.oxycblt.auxio.music.user import org.oxycblt.auxio.music.Music -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicSettings +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.Playlist import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.device.DeviceLibrary @@ -78,7 +78,7 @@ private constructor( */ fun from(name: String, songs: List, musicSettings: MusicSettings) = PlaylistImpl( - Music.UID.auxio(MusicMode.PLAYLISTS), + Music.UID.auxio(MusicType.PLAYLISTS), Name.Known.from(name, null, musicSettings), songs) diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchSettings.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchSettings.kt index 16edab48b..71fd94583 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchSettings.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchSettings.kt @@ -23,7 +23,7 @@ import androidx.core.content.edit import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import org.oxycblt.auxio.R -import org.oxycblt.auxio.music.MusicMode +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.settings.Settings /** @@ -32,19 +32,21 @@ import org.oxycblt.auxio.settings.Settings * @author Alexander Capehart (OxygenCobalt) */ interface SearchSettings : Settings { - /** The type of Music the search view is currently filtering to. */ - var searchFilterMode: MusicMode? + /** The type of Music the search view is should filter to. */ + var filterTo: MusicType? } class SearchSettingsImpl @Inject constructor(@ApplicationContext context: Context) : Settings.Impl(context), SearchSettings { - override var searchFilterMode: MusicMode? + override var filterTo: MusicType? get() = - MusicMode.fromIntCode( - sharedPreferences.getInt(getString(R.string.set_key_search_filter), Int.MIN_VALUE)) + MusicType.fromIntCode( + sharedPreferences.getInt( + getString(R.string.set_key_search_filter_to), Int.MIN_VALUE)) set(value) { sharedPreferences.edit { - putInt(getString(R.string.set_key_search_filter), value?.intCode ?: Int.MIN_VALUE) + putInt( + getString(R.string.set_key_search_filter_to), value?.intCode ?: Int.MIN_VALUE) apply() } } diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt index 9bf784010..3b8c9d004 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt @@ -33,8 +33,8 @@ import org.oxycblt.auxio.list.BasicHeader import org.oxycblt.auxio.list.Divider import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Sort -import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicRepository +import org.oxycblt.auxio.music.MusicType import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.device.DeviceLibrary import org.oxycblt.auxio.music.user.UserLibrary @@ -117,12 +117,12 @@ constructor( userLibrary: UserLibrary, query: String ): List { - val filterMode = searchSettings.searchFilterMode + val filter = searchSettings.filterTo val items = - if (filterMode == null) { - // A nulled filter mode means to not filter anything. - logD("No filter mode specified, using entire library") + if (filter == null) { + // A nulled filter type means to not filter anything. + logD("No filter specified, using entire library") SearchEngine.Items( deviceLibrary.songs, deviceLibrary.albums, @@ -130,14 +130,13 @@ constructor( deviceLibrary.genres, userLibrary.playlists) } else { - logD("Filter mode specified, filtering library") + logD("Filter specified, reducing library") SearchEngine.Items( - songs = if (filterMode == MusicMode.SONGS) deviceLibrary.songs else null, - albums = if (filterMode == MusicMode.ALBUMS) deviceLibrary.albums else null, - artists = if (filterMode == MusicMode.ARTISTS) deviceLibrary.artists else null, - genres = if (filterMode == MusicMode.GENRES) deviceLibrary.genres else null, - playlists = - if (filterMode == MusicMode.PLAYLISTS) userLibrary.playlists else null) + songs = if (filter == MusicType.SONGS) deviceLibrary.songs else null, + albums = if (filter == MusicType.ALBUMS) deviceLibrary.albums else null, + artists = if (filter == MusicType.ARTISTS) deviceLibrary.artists else null, + genres = if (filter == MusicType.GENRES) deviceLibrary.genres else null, + playlists = if (filter == MusicType.PLAYLISTS) userLibrary.playlists else null) } val results = searchEngine.search(items, query) @@ -199,35 +198,35 @@ constructor( */ @IdRes fun getFilterOptionId() = - when (searchSettings.searchFilterMode) { - MusicMode.SONGS -> R.id.option_filter_songs - MusicMode.ALBUMS -> R.id.option_filter_albums - MusicMode.ARTISTS -> R.id.option_filter_artists - MusicMode.GENRES -> R.id.option_filter_genres - MusicMode.PLAYLISTS -> R.id.option_filter_playlists + when (searchSettings.filterTo) { + MusicType.SONGS -> R.id.option_filter_songs + MusicType.ALBUMS -> R.id.option_filter_albums + MusicType.ARTISTS -> R.id.option_filter_artists + MusicType.GENRES -> R.id.option_filter_genres + MusicType.PLAYLISTS -> R.id.option_filter_playlists // Null maps to filtering nothing. null -> R.id.option_filter_all } /** - * Update the filter mode with the newly-selected filter option. + * Update the filter type with the newly-selected filter option. * * @return A menu item ID of the new filtering option selected. */ fun setFilterOptionId(@IdRes id: Int) { - val newFilterMode = + val newFilter = when (id) { - R.id.option_filter_songs -> MusicMode.SONGS - R.id.option_filter_albums -> MusicMode.ALBUMS - R.id.option_filter_artists -> MusicMode.ARTISTS - R.id.option_filter_genres -> MusicMode.GENRES - R.id.option_filter_playlists -> MusicMode.PLAYLISTS + R.id.option_filter_songs -> MusicType.SONGS + R.id.option_filter_albums -> MusicType.ALBUMS + R.id.option_filter_artists -> MusicType.ARTISTS + R.id.option_filter_genres -> MusicType.GENRES + R.id.option_filter_playlists -> MusicType.PLAYLISTS // Null maps to filtering nothing. R.id.option_filter_all -> null else -> error("Invalid option ID provided") } - logD("Updating filter mode to $newFilterMode") - searchSettings.searchFilterMode = newFilterMode + logD("Updating filter type to $newFilter") + searchSettings.filterTo = newFilter search(lastQuery) } diff --git a/app/src/main/res/values/settings.xml b/app/src/main/res/values/settings.xml index 87004a171..dbc493109 100644 --- a/app/src/main/res/values/settings.xml +++ b/app/src/main/res/values/settings.xml @@ -42,7 +42,7 @@ auxio_bar_action auxio_notif_action - KEY_SEARCH_FILTER + KEY_SEARCH_FILTER auxio_songs_sort auxio_albums_sort diff --git a/app/src/test/java/org/oxycblt/auxio/music/MusicModeTest.kt b/app/src/test/java/org/oxycblt/auxio/music/MusicModeTest.kt index 1cd68bb51..c11985970 100644 --- a/app/src/test/java/org/oxycblt/auxio/music/MusicModeTest.kt +++ b/app/src/test/java/org/oxycblt/auxio/music/MusicModeTest.kt @@ -24,9 +24,9 @@ import org.junit.Test class MusicModeTest { @Test fun intCode() { - assertEquals(MusicMode.SONGS, MusicMode.fromIntCode(MusicMode.SONGS.intCode)) - assertEquals(MusicMode.ALBUMS, MusicMode.fromIntCode(MusicMode.ALBUMS.intCode)) - assertEquals(MusicMode.ARTISTS, MusicMode.fromIntCode(MusicMode.ARTISTS.intCode)) - assertEquals(MusicMode.GENRES, MusicMode.fromIntCode(MusicMode.GENRES.intCode)) + assertEquals(MusicType.SONGS, MusicType.fromIntCode(MusicType.SONGS.intCode)) + assertEquals(MusicType.ALBUMS, MusicType.fromIntCode(MusicType.ALBUMS.intCode)) + assertEquals(MusicType.ARTISTS, MusicType.fromIntCode(MusicType.ARTISTS.intCode)) + assertEquals(MusicType.GENRES, MusicType.fromIntCode(MusicType.GENRES.intCode)) } }