Playlist refresh
Bottom navigation shows when coming from notification
Removed animation for lyrics page
Added playlist reorder
Added refresh for album & artist details when update
Fix when scan to update library
Added sort for playlist
Fix album art not showing in lockscreen
This commit is contained in:
Hemanth S 2020-10-09 23:14:02 +05:30
parent e5f6e83dd4
commit 33f4f31066
55 changed files with 2532 additions and 2199 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -108,6 +108,7 @@ const val INITIALIZED_BLACKLIST = "initialized_blacklist"
const val ARTIST_SORT_ORDER = "artist_sort_order" const val ARTIST_SORT_ORDER = "artist_sort_order"
const val ARTIST_ALBUM_SORT_ORDER = "artist_album_sort_order" const val ARTIST_ALBUM_SORT_ORDER = "artist_album_sort_order"
const val ALBUM_SORT_ORDER = "album_sort_order" const val ALBUM_SORT_ORDER = "album_sort_order"
const val PLAYLIST_SORT_ORDER = "playlist_sort_order"
const val ALBUM_SONG_SORT_ORDER = "album_song_sort_order" const val ALBUM_SONG_SORT_ORDER = "album_song_sort_order"
const val ARTIST_SONG_SORT_ORDER = "artist_song_sort_order" const val ARTIST_SONG_SORT_ORDER = "artist_song_sort_order"
const val ALBUM_GRID_SIZE = "album_grid_size" const val ALBUM_GRID_SIZE = "album_grid_size"

View file

@ -17,8 +17,8 @@ package code.name.monkey.retromusic.activities
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import android.view.WindowManager import android.view.WindowManager
import androidx.core.view.ViewCompat
import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
@ -54,22 +54,17 @@ class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.
private fun buildContainerTransform(): MaterialContainerTransform { private fun buildContainerTransform(): MaterialContainerTransform {
val transform = MaterialContainerTransform() val transform = MaterialContainerTransform()
transform.setAllContainerColors( transform.setAllContainerColors(
MaterialColors.getColor(findViewById(android.R.id.content), R.attr.colorSurface) MaterialColors.getColor(findViewById(R.id.container), R.attr.colorSurface)
) )
transform.addTarget(android.R.id.content) transform.addTarget(R.id.container)
transform.duration = 300 transform.duration = 300
transform.interpolator = FastOutSlowInInterpolator()
transform.pathMotion = MaterialArcMotion()
return transform return transform
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
findViewById<View>(android.R.id.content).transitionName = "lyrics"
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementEnterTransition = buildContainerTransform()
window.sharedElementReturnTransition = buildContainerTransform()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lyrics) setContentView(R.layout.activity_lyrics)
ViewCompat.setTransitionName(container, "lyrics")
setStatusbarColorAuto() setStatusbarColorAuto()
setTaskDescriptionColorAuto() setTaskDescriptionColorAuto()
setNavigationbarColorAuto() setNavigationbarColorAuto()

View file

@ -23,7 +23,32 @@ import android.provider.MediaStore
import android.view.View import android.view.View
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.ui.NavigationUI import androidx.navigation.ui.NavigationUI
import code.name.monkey.retromusic.* import code.name.monkey.retromusic.ADAPTIVE_COLOR_APP
import code.name.monkey.retromusic.ALBUM_COVER_STYLE
import code.name.monkey.retromusic.ALBUM_COVER_TRANSFORM
import code.name.monkey.retromusic.BANNER_IMAGE_PATH
import code.name.monkey.retromusic.BLACK_THEME
import code.name.monkey.retromusic.CAROUSEL_EFFECT
import code.name.monkey.retromusic.CIRCULAR_ALBUM_ART
import code.name.monkey.retromusic.DESATURATED_COLOR
import code.name.monkey.retromusic.EXTRA_SONG_INFO
import code.name.monkey.retromusic.GENERAL_THEME
import code.name.monkey.retromusic.HOME_ARTIST_GRID_STYLE
import code.name.monkey.retromusic.KEEP_SCREEN_ON
import code.name.monkey.retromusic.LANGUAGE_NAME
import code.name.monkey.retromusic.LIBRARY_CATEGORIES
import code.name.monkey.retromusic.NOW_PLAYING_SCREEN_ID
import code.name.monkey.retromusic.PROFILE_IMAGE_PATH
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ROUND_CORNERS
import code.name.monkey.retromusic.TAB_TEXT_MODE
import code.name.monkey.retromusic.TOGGLE_ADD_CONTROLS
import code.name.monkey.retromusic.TOGGLE_FULL_SCREEN
import code.name.monkey.retromusic.TOGGLE_GENRE
import code.name.monkey.retromusic.TOGGLE_HOME_BANNER
import code.name.monkey.retromusic.TOGGLE_SEPARATE_LINE
import code.name.monkey.retromusic.TOGGLE_VOLUME
import code.name.monkey.retromusic.USER_NAME
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.extensions.findNavController import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -32,6 +57,7 @@ import code.name.monkey.retromusic.model.CategoryInfo
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.PlaylistSongsLoader import code.name.monkey.retromusic.repository.PlaylistSongsLoader
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.state.NowPlayingPanelState
import code.name.monkey.retromusic.util.AppRater import code.name.monkey.retromusic.util.AppRater
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
@ -94,7 +120,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
intent.getBooleanExtra(EXPAND_PANEL, false) && intent.getBooleanExtra(EXPAND_PANEL, false) &&
PreferenceUtil.isExpandPanel PreferenceUtil.isExpandPanel
) { ) {
expandPanel() libraryViewModel.setPanelState(NowPlayingPanelState.EXPAND)
intent.removeExtra(EXPAND_PANEL) intent.removeExtra(EXPAND_PANEL)
} }
} }

View file

@ -29,7 +29,11 @@ import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroBottomSheetBehavior import code.name.monkey.retromusic.RetroBottomSheetBehavior
import code.name.monkey.retromusic.extensions.* import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.peekHeightAnimate
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.translateXAnimate
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.MiniPlayerFragment import code.name.monkey.retromusic.fragments.MiniPlayerFragment
import code.name.monkey.retromusic.fragments.NowPlayingScreen import code.name.monkey.retromusic.fragments.NowPlayingScreen
@ -118,6 +122,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
val themeColor = ATHUtil.resolveColor(this, android.R.attr.windowBackground, Color.GRAY) val themeColor = ATHUtil.resolveColor(this, android.R.attr.windowBackground, Color.GRAY)
dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f)) dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
dimBackground.setOnClickListener { dimBackground.setOnClickListener {
println("dimBackground")
libraryViewModel.setPanelState(COLLAPSED_WITH) libraryViewModel.setPanelState(COLLAPSED_WITH)
} }
} }
@ -209,6 +214,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
ViewTreeObserver.OnGlobalLayoutListener { ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() { override fun onGlobalLayout() {
slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this) slidingPanel.viewTreeObserver.removeOnGlobalLayoutListener(this)
println("onServiceConnected")
if (bottomNavigationView.isVisible) { if (bottomNavigationView.isVisible) {
libraryViewModel.setPanelState(COLLAPSED_WITH) libraryViewModel.setPanelState(COLLAPSED_WITH)
} else { } else {
@ -225,6 +231,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
libraryViewModel.setPanelState(HIDE) libraryViewModel.setPanelState(HIDE)
} else { } else {
if (bottomNavigationView.isVisible) { if (bottomNavigationView.isVisible) {
println("onQueueChanged")
libraryViewModel.setPanelState(COLLAPSED_WITH) libraryViewModel.setPanelState(COLLAPSED_WITH)
} else { } else {
libraryViewModel.setPanelState(COLLAPSED_WITHOUT) libraryViewModel.setPanelState(COLLAPSED_WITHOUT)
@ -339,6 +346,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
EXPAND -> { EXPAND -> {
println("EXPAND") println("EXPAND")
expandPanel() expandPanel()
bottomNavigationView.translateXAnimate(150f)
} }
HIDE -> { HIDE -> {
println("HIDE") println("HIDE")

View file

@ -14,18 +14,16 @@
*/ */
package code.name.monkey.retromusic.adapter.album package code.name.monkey.retromusic.adapter.album
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.core.app.ActivityOptionsCompat import androidx.core.view.ViewCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.LyricsActivity
import code.name.monkey.retromusic.fragments.AlbumCoverStyle import code.name.monkey.retromusic.fragments.AlbumCoverStyle
import code.name.monkey.retromusic.fragments.NowPlayingScreen.* import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
@ -105,15 +103,10 @@ class AlbumCoverPagerAdapter(
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false) val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
ViewCompat.setTransitionName(view, "lyrics")
albumCover = view.findViewById(R.id.player_image) albumCover = view.findViewById(R.id.player_image)
albumCover.setOnClickListener { view.setOnClickListener {
val intent = Intent(requireContext(), LyricsActivity::class.java) showLyricsDialog()
val activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
requireActivity(),
it,
"lyrics"
)
startActivity(intent, activityOptions.toBundle())
} }
return view return view
} }

View file

@ -24,12 +24,10 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.os.bundleOf import androidx.core.view.ViewCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
@ -42,6 +40,7 @@ import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.ICabHolder import code.name.monkey.retromusic.interfaces.ICabHolder
import code.name.monkey.retromusic.interfaces.IPlaylistClickListener
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.PlaylistSongsLoader import code.name.monkey.retromusic.repository.PlaylistSongsLoader
@ -53,7 +52,8 @@ class PlaylistAdapter(
private val activity: FragmentActivity, private val activity: FragmentActivity,
var dataSet: List<PlaylistWithSongs>, var dataSet: List<PlaylistWithSongs>,
private var itemLayoutRes: Int, private var itemLayoutRes: Int,
ICabHolder: ICabHolder? ICabHolder: ICabHolder?,
private val listener: IPlaylistClickListener
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, PlaylistWithSongs>( ) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, PlaylistWithSongs>(
activity, activity,
ICabHolder, ICabHolder,
@ -172,10 +172,8 @@ class PlaylistAdapter(
if (isInQuickSelectMode) { if (isInQuickSelectMode) {
toggleChecked(layoutPosition) toggleChecked(layoutPosition)
} else { } else {
activity.findNavController(R.id.fragment_container).navigate( ViewCompat.setTransitionName(itemView, "playlist")
R.id.playlistDetailsFragment, listener.onPlaylistClick(dataSet[layoutPosition], itemView)
bundleOf(EXTRA_PLAYLIST to dataSet[layoutPosition])
)
} }
} }

View file

@ -26,7 +26,6 @@ import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType.Playlists
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class RemoveSongFromPlaylistDialog : DialogFragment() { class RemoveSongFromPlaylistDialog : DialogFragment() {
@ -74,7 +73,6 @@ class RemoveSongFromPlaylistDialog : DialogFragment() {
.setMessage(pair.second) .setMessage(pair.second)
.setPositiveButton(R.string.remove_action) { _, _ -> .setPositiveButton(R.string.remove_action) { _, _ ->
libraryViewModel.deleteSongsInPlaylist(songs) libraryViewModel.deleteSongsInPlaylist(songs)
libraryViewModel.forceReload(Playlists)
} }
.setNegativeButton(android.R.string.cancel, null) .setNegativeButton(android.R.string.cancel, null)
.create() .create()

View file

@ -222,8 +222,11 @@ class LibraryViewModel(
repository.renameRoomPlaylist(playListId, name) repository.renameRoomPlaylist(playListId, name)
} }
fun deleteSongsInPlaylist(songs: List<SongEntity>) = viewModelScope.launch(IO) { fun deleteSongsInPlaylist(songs: List<SongEntity>) {
repository.deleteSongsInPlaylist(songs) viewModelScope.launch(IO) {
repository.deleteSongsInPlaylist(songs)
forceReload(Playlists)
}
} }
fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>) = viewModelScope.launch(IO) { fun deleteSongsFromPlaylist(playlists: List<PlaylistEntity>) = viewModelScope.launch(IO) {

View file

@ -15,8 +15,10 @@
package code.name.monkey.retromusic.fragments.albums package code.name.monkey.retromusic.fragments.albums
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
@ -24,16 +26,26 @@ import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmAlbum import code.name.monkey.retromusic.network.model.LastFmAlbum
import code.name.monkey.retromusic.repository.RealRepository import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
class AlbumDetailsViewModel( class AlbumDetailsViewModel(
private val repository: RealRepository, private val repository: RealRepository,
private val albumId: Long private val albumId: Long
) : ViewModel(), IMusicServiceEventListener { ) : ViewModel(), IMusicServiceEventListener {
private val albumDetails = MutableLiveData<Album>()
fun getAlbum(): LiveData<Album> = liveData(IO) { init {
emit(repository.albumByIdAsync(albumId)) fetchAlbum()
} }
private fun fetchAlbum() {
viewModelScope.launch(IO) {
albumDetails.postValue(repository.albumByIdAsync(albumId))
}
}
fun getAlbum(): LiveData<Album> = albumDetails
fun getArtist(artistId: Long): LiveData<Artist> = liveData(IO) { fun getArtist(artistId: Long): LiveData<Artist> = liveData(IO) {
val artist = repository.artistById(artistId) val artist = repository.artistById(artistId)
emit(artist) emit(artist)
@ -51,6 +63,7 @@ class AlbumDetailsViewModel(
} }
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {
fetchAlbum()
} }
override fun onServiceConnected() {} override fun onServiceConnected() {}

View file

@ -94,16 +94,14 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true) setHasOptionsMenu(true)
libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITHOUT)
mainActivity.setSupportActionBar(toolbar) mainActivity.setSupportActionBar(toolbar)
libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITHOUT)
toolbar.title = null toolbar.title = null
setupRecyclerView() setupRecyclerView()
ViewCompat.setTransitionName(container, "artist") ViewCompat.setTransitionName(container, "artist")
postponeEnterTransition() postponeEnterTransition()
detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer { detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer {
startPostponedEnterTransition() startPostponedEnterTransition()

View file

@ -15,25 +15,36 @@
package code.name.monkey.retromusic.fragments.artists package code.name.monkey.retromusic.fragments.artists
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.network.Result import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmArtist import code.name.monkey.retromusic.network.model.LastFmArtist
import code.name.monkey.retromusic.repository.RealRepository import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
class ArtistDetailsViewModel( class ArtistDetailsViewModel(
private val realRepository: RealRepository, private val realRepository: RealRepository,
private val artistId: Long private val artistId: Long
) : ViewModel(), IMusicServiceEventListener { ) : ViewModel(), IMusicServiceEventListener {
private val artistDetails = MutableLiveData<Artist>()
fun getArtist(): LiveData<Artist> = liveData(IO) { init {
val artist = realRepository.artistById(artistId) fetchArtist()
emit(artist)
} }
private fun fetchArtist() {
viewModelScope.launch(IO) {
artistDetails.postValue(realRepository.artistById(artistId))
}
}
fun getArtist(): LiveData<Artist> = artistDetails
fun getArtistInfo( fun getArtistInfo(
name: String, name: String,
lang: String?, lang: String?,
@ -45,7 +56,7 @@ class ArtistDetailsViewModel(
} }
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {
getArtist() fetchArtist()
} }
override fun onServiceConnected() {} override fun onServiceConnected() {}

View file

@ -73,6 +73,7 @@ abstract class AbsRecyclerViewCustomGridSizeFragment<A : RecyclerView.Adapter<*>
fun setAndSaveSortOrder(sortOrder: String) { fun setAndSaveSortOrder(sortOrder: String) {
this.sortOrder = sortOrder this.sortOrder = sortOrder
println(sortOrder)
saveSortOrder(sortOrder) saveSortOrder(sortOrder)
setSortOrder(sortOrder) setSortOrder(sortOrder)
} }

View file

@ -61,6 +61,7 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
println("AbsRecyclerViewFragment")
libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITH) libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITH)
mainActivity.setSupportActionBar(toolbar) mainActivity.setSupportActionBar(toolbar)
mainActivity.supportActionBar?.title = null mainActivity.supportActionBar?.title = null

View file

@ -52,6 +52,7 @@ class HomeFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
println("AbsMainActivityFragment")
libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITH) libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITH)
mainActivity.setSupportActionBar(toolbar) mainActivity.setSupportActionBar(toolbar)
mainActivity.supportActionBar?.title = null mainActivity.supportActionBar?.title = null

View file

@ -5,10 +5,12 @@ import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.PlaylistSongAdapter import code.name.monkey.retromusic.adapter.song.PlaylistSongAdapter
import code.name.monkey.retromusic.db.PlaylistWithSongs import code.name.monkey.retromusic.db.PlaylistWithSongs
@ -18,6 +20,7 @@ import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.state.NowPlayingPanelState import code.name.monkey.retromusic.state.NowPlayingPanelState
import com.google.android.material.transition.MaterialContainerTransform
import kotlinx.android.synthetic.main.fragment_playlist_detail.* import kotlinx.android.synthetic.main.fragment_playlist_detail.*
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf import org.koin.core.parameter.parametersOf
@ -31,18 +34,29 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
private lateinit var playlist: PlaylistWithSongs private lateinit var playlist: PlaylistWithSongs
private lateinit var playlistSongAdapter: PlaylistSongAdapter private lateinit var playlistSongAdapter: PlaylistSongAdapter
override fun onActivityCreated(savedInstanceState: Bundle?) { private fun setUpTransitions() {
super.onActivityCreated(savedInstanceState) val transform = MaterialContainerTransform()
transform.setAllContainerColors(ATHUtil.resolveColor(requireContext(), R.attr.colorSurface))
sharedElementEnterTransition = transform
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setUpTransitions()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setHasOptionsMenu(true) setHasOptionsMenu(true)
libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITHOUT) libraryViewModel.setPanelState(NowPlayingPanelState.COLLAPSED_WITHOUT)
mainActivity.addMusicServiceEventListener(viewModel) mainActivity.addMusicServiceEventListener(viewModel)
mainActivity.setSupportActionBar(toolbar) mainActivity.setSupportActionBar(toolbar)
ViewCompat.setTransitionName(container, "playlist")
playlist = arguments.extraPlaylist playlist = arguments.extraPlaylist
toolbar.title = playlist.playlistEntity.playlistName toolbar.title = playlist.playlistEntity.playlistName
setUpRecyclerView() setUpRecyclerView()
viewModel.getSongs().observe(viewLifecycleOwner, { viewModel.getSongs().observe(viewLifecycleOwner, {
songs(it.toSongs()) songs(it.toSongs())
}) })

View file

@ -33,26 +33,7 @@ class PlaylistDetailsViewModel(
fun getSongs(): LiveData<List<SongEntity>> = fun getSongs(): LiveData<List<SongEntity>> =
realRepository.playlistSongs(playlist.playlistEntity.playListId) realRepository.playlistSongs(playlist.playlistEntity.playListId)
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {}
/*if (playlist !is AbsCustomPlaylist) {
// Playlist deleted
if (!PlaylistsUtil.doesPlaylistExist(App.getContext(), playlist.id)) {
//TODO Finish the page
return
}
// Playlist renamed
val playlistName =
PlaylistsUtil.getNameForPlaylist(App.getContext(), playlist.id.toLong())
if (playlistName != playlist.name) {
viewModelScope.launch {
playlist = realRepository.playlist(playlist.id)
_playlist.postValue(playlist)
}
}
}
loadPlaylistSongs(playlist)*/
}
override fun onServiceConnected() {} override fun onServiceConnected() {}
override fun onServiceDisconnected() {} override fun onServiceDisconnected() {}
override fun onQueueChanged() {} override fun onQueueChanged() {}

View file

@ -18,19 +18,31 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.SubMenu
import android.view.View import android.view.View
import androidx.lifecycle.Observer import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager import androidx.core.view.MenuCompat
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder
import code.name.monkey.retromusic.interfaces.IPlaylistClickListener
import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_library.* import kotlinx.android.synthetic.main.fragment_library.*
class PlaylistsFragment : AbsRecyclerViewFragment<PlaylistAdapter, LinearLayoutManager>() { class PlaylistsFragment :
AbsRecyclerViewCustomGridSizeFragment<PlaylistAdapter, GridLayoutManager>(),
IPlaylistClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
libraryViewModel.getPlaylists().observe(viewLifecycleOwner, Observer { libraryViewModel.getPlaylists().observe(viewLifecycleOwner, {
if (it.isNotEmpty()) if (it.isNotEmpty())
adapter?.swapDataSet(it) adapter?.swapDataSet(it)
else else
@ -41,8 +53,8 @@ class PlaylistsFragment : AbsRecyclerViewFragment<PlaylistAdapter, LinearLayoutM
override val emptyMessage: Int override val emptyMessage: Int
get() = R.string.no_playlists get() = R.string.no_playlists
override fun createLayoutManager(): LinearLayoutManager { override fun createLayoutManager(): GridLayoutManager {
return LinearLayoutManager(requireContext()) return GridLayoutManager(requireContext(), getGridSize())
} }
override fun createAdapter(): PlaylistAdapter { override fun createAdapter(): PlaylistAdapter {
@ -50,7 +62,8 @@ class PlaylistsFragment : AbsRecyclerViewFragment<PlaylistAdapter, LinearLayoutM
requireActivity(), requireActivity(),
ArrayList(), ArrayList(),
R.layout.item_list, R.layout.item_list,
null null,
this
) )
} }
@ -63,9 +76,118 @@ class PlaylistsFragment : AbsRecyclerViewFragment<PlaylistAdapter, LinearLayoutM
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
menu.removeItem(R.id.action_grid_size) menu.removeItem(R.id.action_grid_size)
menu.removeItem(R.id.action_layout_type) menu.removeItem(R.id.action_layout_type)
menu.removeItem(R.id.action_sort_order)
menu.add(0, R.id.action_add_to_playlist, 0, R.string.new_playlist_title) menu.add(0, R.id.action_add_to_playlist, 0, R.string.new_playlist_title)
menu.add(0, R.id.action_import_playlist, 0, R.string.import_playlist) menu.add(0, R.id.action_import_playlist, 0, R.string.import_playlist)
menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
MenuCompat.setGroupDividerEnabled(menu, true);
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (handleSortOrderMenuItem(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
private fun setUpSortOrderMenu(subMenu: SubMenu) {
val order: String? = getSortOrder()
subMenu.clear()
createId(
subMenu,
R.id.action_song_sort_order_asc,
R.string.sort_order_a_z,
order == PlaylistSortOrder.PLAYLIST_A_Z
)
createId(
subMenu,
R.id.action_song_sort_order_desc,
R.string.sort_order_z_a,
order == PlaylistSortOrder.PLAYLIST_Z_A
)
createId(
subMenu,
R.id.action_playlist_sort_order,
R.string.sort_order_num_songs,
order == PlaylistSortOrder.PLAYLIST_SONG_COUNT
)
createId(
subMenu,
R.id.action_playlist_sort_order_desc,
R.string.sort_order_num_songs_desc,
order == PlaylistSortOrder.PLAYLIST_SONG_COUNT_DESC
)
subMenu.setGroupCheckable(0, true, true)
}
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
val sortOrder: String = when (item.itemId) {
R.id.action_song_sort_order_asc -> PlaylistSortOrder.PLAYLIST_A_Z
R.id.action_song_sort_order_desc -> PlaylistSortOrder.PLAYLIST_Z_A
R.id.action_playlist_sort_order -> PlaylistSortOrder.PLAYLIST_SONG_COUNT
R.id.action_playlist_sort_order_desc -> PlaylistSortOrder.PLAYLIST_SONG_COUNT_DESC
else -> PreferenceUtil.playlistSortOrder
}
if (sortOrder != PreferenceUtil.playlistSortOrder) {
item.isChecked = true
setAndSaveSortOrder(sortOrder)
return true
}
return false
}
private fun createId(menu: SubMenu, id: Int, title: Int, checked: Boolean) {
menu.add(0, id, 0, title).isChecked = checked
}
override fun setGridSize(gridSize: Int) {
TODO("Not yet implemented")
}
override fun setSortOrder(sortOrder: String) {
libraryViewModel.forceReload(ReloadType.Playlists)
}
override fun loadSortOrder(): String {
return PreferenceUtil.playlistSortOrder
}
override fun saveSortOrder(sortOrder: String) {
PreferenceUtil.playlistSortOrder = sortOrder
}
override fun loadGridSize(): Int {
return 1
}
override fun saveGridSize(gridColumns: Int) {
//Add grid save
}
override fun loadGridSizeLand(): Int {
return 2
}
override fun saveGridSizeLand(gridColumns: Int) {
//Add land grid save
}
override fun loadLayoutRes(): Int {
return R.layout.item_list
}
override fun saveLayoutRes(layoutRes: Int) {
//Save layout
}
override fun onPlaylistClick(playlistWithSongs: PlaylistWithSongs, view: View) {
findNavController().navigate(
R.id.playlistDetailsFragment,
bundleOf(EXTRA_PLAYLIST to playlistWithSongs),
null,
FragmentNavigatorExtras(view to "playlist")
)
} }
} }

View file

@ -184,4 +184,25 @@ class SortOrder {
const val ALBUM_Z_A = "$GENRE_A_Z DESC" const val ALBUM_Z_A = "$GENRE_A_Z DESC"
} }
} }
/**
* Playlist sort order entries.
*/
interface PlaylistSortOrder {
companion object {
/* Playlist sort order A-Z */
const val PLAYLIST_A_Z = MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER
/* Playlist sort order Z-A */
const val PLAYLIST_Z_A = "$PLAYLIST_A_Z DESC"
/* Playlist sort order number of songs */
const val PLAYLIST_SONG_COUNT = "playlist_song_count"
/* Playlist sort order number of songs */
const val PLAYLIST_SONG_COUNT_DESC = "$PLAYLIST_SONG_COUNT DESC"
}
}
} }

View file

@ -0,0 +1,8 @@
package code.name.monkey.retromusic.interfaces
import android.view.View
import code.name.monkey.retromusic.db.PlaylistWithSongs
interface IPlaylistClickListener {
fun onPlaylistClick(playlistWithSongs: PlaylistWithSongs, view: View)
}

View file

@ -95,13 +95,17 @@ class RealGenreRepository(
} }
private fun makeGenreSongCursor(genreId: Long): Cursor? { private fun makeGenreSongCursor(genreId: Long): Cursor? {
return contentResolver.query( return try {
Genres.Members.getContentUri("external", genreId), contentResolver.query(
baseProjection, Genres.Members.getContentUri("external", genreId),
IS_MUSIC, baseProjection,
null, IS_MUSIC,
PreferenceUtil.songSortOrder null,
) PreferenceUtil.songSortOrder
)
} catch (e: SecurityException) {
return null
}
} }
private fun getGenresFromCursor(cursor: Cursor?): ArrayList<Genre> { private fun getGenresFromCursor(cursor: Cursor?): ArrayList<Genre> {
@ -143,17 +147,18 @@ class RealGenreRepository(
return genres return genres
} }
private fun makeGenreCursor(): Cursor? { private fun makeGenreCursor(): Cursor? {
val projection = arrayOf(Genres._ID, Genres.NAME) val projection = arrayOf(Genres._ID, Genres.NAME)
return contentResolver.query( return try {
Genres.EXTERNAL_CONTENT_URI, contentResolver.query(
projection, Genres.EXTERNAL_CONTENT_URI,
null, projection,
null, null,
PreferenceUtil.genreSortOrder null,
) PreferenceUtil.genreSortOrder
)
} catch (e: SecurityException) {
return null
}
} }
} }

View file

@ -2,8 +2,24 @@ package code.name.monkey.retromusic.repository
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import code.name.monkey.retromusic.db.* import code.name.monkey.retromusic.db.BlackListStoreDao
import code.name.monkey.retromusic.db.BlackListStoreEntity
import code.name.monkey.retromusic.db.HistoryDao
import code.name.monkey.retromusic.db.HistoryEntity
import code.name.monkey.retromusic.db.LyricsDao
import code.name.monkey.retromusic.db.PlayCountDao
import code.name.monkey.retromusic.db.PlayCountEntity
import code.name.monkey.retromusic.db.PlaylistDao
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.db.toHistoryEntity
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_A_Z
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_SONG_COUNT
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_SONG_COUNT_DESC
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder.Companion.PLAYLIST_Z_A
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
interface RoomRepository { interface RoomRepository {
@ -61,7 +77,22 @@ class RealRoomRepository(
@WorkerThread @WorkerThread
override suspend fun playlistWithSongs(): List<PlaylistWithSongs> = override suspend fun playlistWithSongs(): List<PlaylistWithSongs> =
playlistDao.playlistsWithSongs() when (PreferenceUtil.playlistSortOrder) {
PLAYLIST_A_Z ->
playlistDao.playlistsWithSongs().sortedBy {
it.playlistEntity.playlistName
}
PLAYLIST_Z_A -> playlistDao.playlistsWithSongs()
.sortedByDescending {
it.playlistEntity.playlistName
}
PLAYLIST_SONG_COUNT -> playlistDao.playlistsWithSongs().sortedBy { it.songs.size }
PLAYLIST_SONG_COUNT_DESC -> playlistDao.playlistsWithSongs()
.sortedByDescending { it.songs.size }
else -> playlistDao.playlistsWithSongs().sortedBy {
it.playlistEntity.playlistName
}
}
@WorkerThread @WorkerThread
override suspend fun insertSongs(songs: List<SongEntity>) { override suspend fun insertSongs(songs: List<SongEntity>) {

View file

@ -8,7 +8,75 @@ import androidx.core.content.ContextCompat
import androidx.core.content.edit import androidx.core.content.edit
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import code.name.monkey.retromusic.* import code.name.monkey.retromusic.ADAPTIVE_COLOR_APP
import code.name.monkey.retromusic.ALBUM_ARTISTS_ONLY
import code.name.monkey.retromusic.ALBUM_ART_ON_LOCK_SCREEN
import code.name.monkey.retromusic.ALBUM_COVER_STYLE
import code.name.monkey.retromusic.ALBUM_COVER_TRANSFORM
import code.name.monkey.retromusic.ALBUM_DETAIL_SONG_SORT_ORDER
import code.name.monkey.retromusic.ALBUM_GRID_SIZE
import code.name.monkey.retromusic.ALBUM_GRID_SIZE_LAND
import code.name.monkey.retromusic.ALBUM_GRID_STYLE
import code.name.monkey.retromusic.ALBUM_SONG_SORT_ORDER
import code.name.monkey.retromusic.ALBUM_SORT_ORDER
import code.name.monkey.retromusic.ARTIST_ALBUM_SORT_ORDER
import code.name.monkey.retromusic.ARTIST_GRID_SIZE
import code.name.monkey.retromusic.ARTIST_GRID_SIZE_LAND
import code.name.monkey.retromusic.ARTIST_GRID_STYLE
import code.name.monkey.retromusic.ARTIST_SONG_SORT_ORDER
import code.name.monkey.retromusic.ARTIST_SORT_ORDER
import code.name.monkey.retromusic.AUDIO_DUCKING
import code.name.monkey.retromusic.AUTO_DOWNLOAD_IMAGES_POLICY
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.BLACK_THEME
import code.name.monkey.retromusic.BLUETOOTH_PLAYBACK
import code.name.monkey.retromusic.BLURRED_ALBUM_ART
import code.name.monkey.retromusic.CAROUSEL_EFFECT
import code.name.monkey.retromusic.CHOOSE_EQUALIZER
import code.name.monkey.retromusic.CLASSIC_NOTIFICATION
import code.name.monkey.retromusic.COLORED_APP_SHORTCUTS
import code.name.monkey.retromusic.COLORED_NOTIFICATION
import code.name.monkey.retromusic.DESATURATED_COLOR
import code.name.monkey.retromusic.EXPAND_NOW_PLAYING_PANEL
import code.name.monkey.retromusic.EXTRA_SONG_INFO
import code.name.monkey.retromusic.FILTER_SONG
import code.name.monkey.retromusic.GAP_LESS_PLAYBACK
import code.name.monkey.retromusic.GENERAL_THEME
import code.name.monkey.retromusic.GENRE_SORT_ORDER
import code.name.monkey.retromusic.HOME_ALBUM_GRID_STYLE
import code.name.monkey.retromusic.HOME_ARTIST_GRID_STYLE
import code.name.monkey.retromusic.IGNORE_MEDIA_STORE_ARTWORK
import code.name.monkey.retromusic.INITIALIZED_BLACKLIST
import code.name.monkey.retromusic.KEEP_SCREEN_ON
import code.name.monkey.retromusic.LANGUAGE_NAME
import code.name.monkey.retromusic.LAST_ADDED_CUTOFF
import code.name.monkey.retromusic.LAST_CHANGELOG_VERSION
import code.name.monkey.retromusic.LAST_PAGE
import code.name.monkey.retromusic.LAST_SLEEP_TIMER_VALUE
import code.name.monkey.retromusic.LIBRARY_CATEGORIES
import code.name.monkey.retromusic.LOCK_SCREEN
import code.name.monkey.retromusic.LYRICS_OPTIONS
import code.name.monkey.retromusic.NEXT_SLEEP_TIMER_ELAPSED_REALTIME
import code.name.monkey.retromusic.NOW_PLAYING_SCREEN_ID
import code.name.monkey.retromusic.PAUSE_ON_ZERO_VOLUME
import code.name.monkey.retromusic.PLAYLIST_SORT_ORDER
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RECENTLY_PLAYED_CUTOFF
import code.name.monkey.retromusic.SAF_SDCARD_URI
import code.name.monkey.retromusic.SLEEP_TIMER_FINISH_SONG
import code.name.monkey.retromusic.SONG_GRID_SIZE
import code.name.monkey.retromusic.SONG_GRID_SIZE_LAND
import code.name.monkey.retromusic.SONG_GRID_STYLE
import code.name.monkey.retromusic.SONG_SORT_ORDER
import code.name.monkey.retromusic.START_DIRECTORY
import code.name.monkey.retromusic.TAB_TEXT_MODE
import code.name.monkey.retromusic.TOGGLE_ADD_CONTROLS
import code.name.monkey.retromusic.TOGGLE_FULL_SCREEN
import code.name.monkey.retromusic.TOGGLE_HEADSET
import code.name.monkey.retromusic.TOGGLE_HOME_BANNER
import code.name.monkey.retromusic.TOGGLE_SHUFFLE
import code.name.monkey.retromusic.TOGGLE_VOLUME
import code.name.monkey.retromusic.USER_NAME
import code.name.monkey.retromusic.extensions.getIntRes import code.name.monkey.retromusic.extensions.getIntRes
import code.name.monkey.retromusic.extensions.getStringOrDefault import code.name.monkey.retromusic.extensions.getStringOrDefault
import code.name.monkey.retromusic.fragments.AlbumCoverStyle import code.name.monkey.retromusic.fragments.AlbumCoverStyle
@ -16,7 +84,13 @@ import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.fragments.folder.FoldersFragment import code.name.monkey.retromusic.fragments.folder.FoldersFragment
import code.name.monkey.retromusic.helper.SortOrder.* import code.name.monkey.retromusic.helper.SortOrder.*
import code.name.monkey.retromusic.model.CategoryInfo import code.name.monkey.retromusic.model.CategoryInfo
import code.name.monkey.retromusic.transform.* import code.name.monkey.retromusic.transform.CascadingPageTransformer
import code.name.monkey.retromusic.transform.DepthTransformation
import code.name.monkey.retromusic.transform.HingeTransformation
import code.name.monkey.retromusic.transform.HorizontalFlipTransformation
import code.name.monkey.retromusic.transform.NormalPageTransformer
import code.name.monkey.retromusic.transform.VerticalFlipTransformation
import code.name.monkey.retromusic.transform.VerticalStackTransformer
import code.name.monkey.retromusic.util.theme.ThemeMode import code.name.monkey.retromusic.util.theme.ThemeMode
import com.google.android.material.bottomnavigation.LabelVisibilityMode import com.google.android.material.bottomnavigation.LabelVisibilityMode
import com.google.gson.Gson import com.google.gson.Gson
@ -154,6 +228,7 @@ object PreferenceUtil {
putString(ALBUM_SORT_ORDER, value) putString(ALBUM_SORT_ORDER, value)
} }
var artistSortOrder var artistSortOrder
get() = sharedPreferences.getStringOrDefault( get() = sharedPreferences.getStringOrDefault(
ARTIST_SORT_ORDER, ARTIST_SORT_ORDER,
@ -181,6 +256,15 @@ object PreferenceUtil {
ArtistAlbumSortOrder.ALBUM_A_Z ArtistAlbumSortOrder.ALBUM_A_Z
) )
var playlistSortOrder
get() = sharedPreferences.getStringOrDefault(
PLAYLIST_SORT_ORDER,
PlaylistSortOrder.PLAYLIST_A_Z
)
set(value) = sharedPreferences.edit {
putString(PLAYLIST_SORT_ORDER, value)
}
val genreSortOrder val genreSortOrder
get() = sharedPreferences.getStringOrDefault( get() = sharedPreferences.getStringOrDefault(
GENRE_SORT_ORDER, GENRE_SORT_ORDER,
@ -413,7 +497,7 @@ object PreferenceUtil {
val homeAlbumGridStyle: Int val homeAlbumGridStyle: Int
get() { get() {
val position = sharedPreferences.getStringOrDefault(HOME_ALBUM_GRID_STYLE, "0").toInt() val position = sharedPreferences.getStringOrDefault(HOME_ALBUM_GRID_STYLE, "4").toInt()
val typedArray = val typedArray =
App.getContext().resources.obtainTypedArray(R.array.pref_home_grid_style_layout) App.getContext().resources.obtainTypedArray(R.array.pref_home_grid_style_layout)
val layoutRes = typedArray.getResourceId(position, 0) val layoutRes = typedArray.getResourceId(position, 0)

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="@color/dark_color"
android:pathData="M0,0h108v108h-108z" />
</vector>

View file

@ -2,70 +2,71 @@
xmlns:aapt="http://schemas.android.com/aapt" xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp" android:width="108dp"
android:height="108dp" android:height="108dp"
android:viewportWidth="921.0526" android:viewportWidth="108"
android:viewportHeight="921.0526"> android:viewportHeight="108">
<group <group android:scaleX="0.12342857"
android:translateX="322.5263" android:scaleY="0.12342857"
android:translateY="285.5263"> android:translateX="36.966858"
<path android:translateY="32.4">
android:pathData="M10.256,0L265.4,0C268.967,0 270.26,0.371 271.563,1.069C272.867,1.766 273.89,2.789 274.587,4.093C275.285,5.396 275.656,6.689 275.656,10.256L275.656,177.191C275.656,180.757 275.285,182.05 274.587,183.353C273.89,184.657 272.867,185.68 271.563,186.378C270.26,187.075 268.967,187.446 265.4,187.446L10.256,187.446C6.689,187.446 5.396,187.075 4.093,186.378C2.789,185.68 1.766,184.657 1.069,183.353C0.371,182.05 0,180.757 -0,177.191L0,10.256C-0,6.689 0.371,5.396 1.069,4.093C1.766,2.789 2.789,1.766 4.093,1.069C5.396,0.371 6.689,0 10.256,0Z" <path
android:strokeWidth="1" android:pathData="M10.256,0L265.4,0C268.967,0 270.26,0.371 271.563,1.069C272.867,1.766 273.89,2.789 274.587,4.093C275.285,5.396 275.656,6.689 275.656,10.256L275.656,177.191C275.656,180.757 275.285,182.05 274.587,183.353C273.89,184.657 272.867,185.68 271.563,186.378C270.26,187.075 268.967,187.446 265.4,187.446L10.256,187.446C6.689,187.446 5.396,187.075 4.093,186.378C2.789,185.68 1.766,184.657 1.069,183.353C0.371,182.05 0,180.757 -0,177.191L0,10.256C-0,6.689 0.371,5.396 1.069,4.093C1.766,2.789 2.789,1.766 4.093,1.069C5.396,0.371 6.689,0 10.256,0Z"
android:fillType="evenOdd" android:strokeWidth="1"
android:strokeColor="#00000000"> android:fillType="evenOdd"
<aapt:attr name="android:fillColor"> android:strokeColor="#00000000">
<gradient <aapt:attr name="android:fillColor">
android:gradientRadius="236.10738" <gradient
android:centerX="0" android:gradientRadius="236.10738"
android:centerY="0" android:centerX="0"
android:type="radial"> android:centerY="0"
<item android:type="radial">
android:offset="0" <item
android:color="#FF3D5AFE" /> android:offset="0"
<item android:color="#FF3D5AFE" />
android:offset="1" <item
android:color="#FF651FFF" /> android:offset="1"
</gradient> android:color="#FF651FFF" />
</aapt:attr> </gradient>
</path> </aapt:attr>
<path </path>
android:pathData="M262.814,336.03L0.163,75.53L0.006,183.375C0.002,185.781 0.962,188.088 2.67,189.781L161.703,347.393C163.201,348.877 165.225,349.711 167.334,349.711L257.18,349.711C261.598,349.711 265.18,346.129 265.18,341.711C265.18,339.577 264.328,337.533 262.814,336.03Z" <path
android:strokeWidth="1" android:pathData="M262.814,336.03L0.163,75.53L0.006,183.375C0.002,185.781 0.962,188.088 2.67,189.781L161.703,347.393C163.201,348.877 165.225,349.711 167.334,349.711L257.18,349.711C261.598,349.711 265.18,346.129 265.18,341.711C265.18,339.577 264.328,337.533 262.814,336.03Z"
android:fillType="evenOdd" android:strokeWidth="1"
android:strokeColor="#00000000"> android:fillType="evenOdd"
<aapt:attr name="android:fillColor"> android:strokeColor="#00000000">
<gradient <aapt:attr name="android:fillColor">
android:gradientRadius="250.9684" <gradient
android:centerX="-32.788143" android:gradientRadius="250.9684"
android:centerY="67.34283" android:centerX="-32.788143"
android:type="radial"> android:centerY="67.34283"
<item android:type="radial">
android:offset="0" <item
android:color="#FF3D5AFE" /> android:offset="0"
<item android:color="#FF3D5AFE" />
android:offset="1" <item
android:color="#FF651FFF" /> android:offset="1"
</gradient> android:color="#FF651FFF" />
</aapt:attr> </gradient>
</path> </aapt:attr>
<path </path>
android:pathData="M8.035,349.71L59.204,349.71C63.623,349.71 67.204,346.128 67.204,341.71C67.204,339.608 66.377,337.59 64.901,336.093L13.732,284.191C10.63,281.045 5.565,281.009 2.418,284.111C0.894,285.614 0.035,287.666 0.035,289.808L0.035,341.71C0.035,346.128 3.617,349.71 8.035,349.71Z" <path
android:strokeWidth="1" android:pathData="M8.035,349.71L59.204,349.71C63.623,349.71 67.204,346.128 67.204,341.71C67.204,339.608 66.377,337.59 64.901,336.093L13.732,284.191C10.63,281.045 5.565,281.009 2.418,284.111C0.894,285.614 0.035,287.666 0.035,289.808L0.035,341.71C0.035,346.128 3.617,349.71 8.035,349.71Z"
android:fillType="evenOdd" android:strokeWidth="1"
android:strokeColor="#00000000"> android:fillType="evenOdd"
<aapt:attr name="android:fillColor"> android:strokeColor="#00000000">
<gradient <aapt:attr name="android:fillColor">
android:gradientRadius="95.39285" <gradient
android:centerX="-268.79202" android:gradientRadius="95.39285"
android:centerY="57.347355" android:centerX="-268.79202"
android:type="radial"> android:centerY="57.347355"
<item android:type="radial">
android:offset="0" <item
android:color="#FF3D5AFE" /> android:offset="0"
<item android:color="#FF3D5AFE" />
android:offset="1" <item
android:color="#FF651FFF" /> android:offset="1"
</gradient> android:color="#FF651FFF" />
</aapt:attr> </gradient>
</path> </aapt:attr>
</group> </path>
</group>
</vector> </vector>

View file

@ -5,6 +5,6 @@
android:viewportWidth="108" android:viewportWidth="108"
android:viewportHeight="108"> android:viewportHeight="108">
<path <path
android:fillColor="@color/md_white_1000" android:fillColor="@color/window_color"
android:pathData="M0,0h108v108h-108z" /> android:pathData="M0,0h108v108h-108z" />
</vector> </vector>

View file

@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/container"
android:layout_height="match_parent" android:layout_height="match_parent"
android:transitionName="@string/transition_lyrics"> android:transitionName="@string/transition_lyrics">

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon> </adaptive-icon>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon> </adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="ic_launcher_background">#FFFFFF</color> <color name="ic_launcher_background">#1C1C1C</color>
</resources> </resources>

View file

@ -16,6 +16,9 @@
<item name="action_artist_sort_order_desc" type="id" /> <item name="action_artist_sort_order_desc" type="id" />
<item name="action_song_sort_order_asc" type="id" /> <item name="action_song_sort_order_asc" type="id" />
<item name="action_song_sort_order_desc" type="id" /> <item name="action_song_sort_order_desc" type="id" />
<item name="action_playlist_sort_order_desc" type="id" />
<item name="action_playlist_sort_order" type="id" />
<item name="action_sort_order" type="id" />
<item name="action_song_sort_order_artist" type="id" /> <item name="action_song_sort_order_artist" type="id" />
<item name="action_song_sort_order_album" type="id" /> <item name="action_song_sort_order_album" type="id" />
<item name="action_song_sort_order_year" type="id" /> <item name="action_song_sort_order_year" type="id" />

View file

@ -891,4 +891,7 @@
<string name="import_playlist">Import playlist</string> <string name="import_playlist">Import playlist</string>
<string name="import_playlist_message">It imports all playlists listed in the Android Media Store with songs, if the playlists already exists, the songs will get merged.</string> <string name="import_playlist_message">It imports all playlists listed in the Android Media Store with songs, if the playlists already exists, the songs will get merged.</string>
<string name="import_label">Import</string> <string name="import_label">Import</string>
<string name="sort_order_num_songs">Song count</string>
<string name="sort_order_asc">Ascending</string>
<string name="sort_order_num_songs_desc">Song count desc</string>
</resources> </resources>

View file

@ -84,14 +84,14 @@
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference <code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="album_art_on_lockscreen" android:key="album_art_on_lock_screen"
android:layout="@layout/list_item_view_switch" android:layout="@layout/list_item_view_switch"
android:summary="@string/pref_summary_album_art_on_lockscreen" android:summary="@string/pref_summary_album_art_on_lockscreen"
android:title="@string/pref_title_album_art_on_lockscreen" /> android:title="@string/pref_title_album_art_on_lockscreen" />
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference <code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
android:defaultValue="false" android:defaultValue="false"
android:dependency="album_art_on_lockscreen" android:dependency="album_art_on_lock_screen"
android:key="blurred_album_art" android:key="blurred_album_art"
android:layout="@layout/list_item_view_switch" android:layout="@layout/list_item_view_switch"
android:summary="@string/pref_summary_blurred_album_art" android:summary="@string/pref_summary_blurred_album_art"