Major refactor about artist and album

This commit is contained in:
h4h13 2020-02-06 10:47:43 +05:30
parent b922549dee
commit 6b959ec24a
36 changed files with 326 additions and 337 deletions

View file

@ -8,7 +8,6 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.SubMenu import android.view.SubMenu
import android.view.View import android.view.View
import android.widget.ImageView
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
@ -49,6 +48,7 @@ import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.activity_album.albumCoverContainer import kotlinx.android.synthetic.main.activity_album.albumCoverContainer
import kotlinx.android.synthetic.main.activity_album.albumText import kotlinx.android.synthetic.main.activity_album.albumText
import kotlinx.android.synthetic.main.activity_album.albumTitle import kotlinx.android.synthetic.main.activity_album.albumTitle
import kotlinx.android.synthetic.main.activity_album.artistImage
import kotlinx.android.synthetic.main.activity_album.image import kotlinx.android.synthetic.main.activity_album.image
import kotlinx.android.synthetic.main.activity_album.toolbar import kotlinx.android.synthetic.main.activity_album.toolbar
import kotlinx.android.synthetic.main.activity_album_content.aboutAlbumText import kotlinx.android.synthetic.main.activity_album_content.aboutAlbumText
@ -88,8 +88,9 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
private lateinit var simpleSongAdapter: SimpleSongAdapter private lateinit var simpleSongAdapter: SimpleSongAdapter
private lateinit var album: Album private lateinit var album: Album
private lateinit var artistImage: ImageView private lateinit var songs: ArrayList<Song>
private var cab: MaterialCab? = null private var cab: MaterialCab? = null
private val savedSortOrder: String private val savedSortOrder: String
get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder
@ -106,7 +107,6 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
slide.excludeTarget(R.id.status_bar, true) slide.excludeTarget(R.id.status_bar, true)
slide.excludeTarget(android.R.id.statusBarBackground, true) slide.excludeTarget(android.R.id.statusBarBackground, true)
slide.excludeTarget(android.R.id.navigationBarBackground, true) slide.excludeTarget(android.R.id.navigationBarBackground, true)
window.enterTransition = slide window.enterTransition = slide
} }
@ -135,12 +135,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
windowEnterTransition() windowEnterTransition()
ActivityCompat.postponeEnterTransition(this) ActivityCompat.postponeEnterTransition(this)
artistImage = findViewById(R.id.artistImage)
setupRecyclerView() setupRecyclerView()
artistImage.setOnClickListener { artistImage.setOnClickListener {
println("Click Artist $album")
val artistPairs = ActivityOptions.makeSceneTransitionAnimation( val artistPairs = ActivityOptions.makeSceneTransitionAnimation(
this, this,
UtilPair.create( UtilPair.create(
@ -151,10 +149,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs) NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs)
} }
playAction.apply { playAction.apply {
//setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) } setOnClickListener { MusicPlayerRemote.openQueue(songs, 0, true) }
} }
shuffleAction.apply { shuffleAction.apply {
//setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album.songs!!, true) } setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songs, true) }
} }
aboutAlbumText.setOnClickListener { aboutAlbumText.setOnClickListener {
@ -187,12 +185,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
override fun album(album: Album) { override fun album(album: Album) {
complete() complete()
/*if (album.songs!!.isEmpty()) {
finish()
return
}*/
this.album = album this.album = album
albumTitle.text = album.title albumTitle.text = album.title
if (MusicUtil.getYearString(album.year) == "-") { if (MusicUtil.getYearString(album.year) == "-") {
albumText.text = String.format("%s", album.artist) albumText.text = String.format("%s", album.artist)
@ -206,6 +199,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
} }
override fun songs(songs: ArrayList<Song>) { override fun songs(songs: ArrayList<Song>) {
this.songs = songs
simpleSongAdapter.swapDataSet(songs) simpleSongAdapter.swapDataSet(songs)
} }
@ -361,16 +355,18 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
private fun setUpSortOrderMenu(sortOrder: SubMenu) { private fun setUpSortOrderMenu(sortOrder: SubMenu) {
when (savedSortOrder) { when (savedSortOrder) {
AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked = true AlbumSongSortOrder.SONG_A_Z ->
AlbumSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true sortOrder.findItem(R.id.action_sort_order_title).isChecked = true
AlbumSongSortOrder.SONG_TRACK_LIST -> sortOrder.findItem(R.id.action_sort_order_track_list).isChecked = AlbumSongSortOrder.SONG_Z_A ->
true sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true
AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration) AlbumSongSortOrder.SONG_TRACK_LIST ->
.isChecked = true sortOrder.findItem(R.id.action_sort_order_track_list).isChecked = true
AlbumSongSortOrder.SONG_DURATION ->
sortOrder.findItem(R.id.action_sort_order_artist_song_duration).isChecked = true
} }
} }
private fun setSaveSortOrder(sortOrder: String?) { private fun setSaveSortOrder(sortOrder: String) {
PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder
reload() reload()
} }

View file

@ -189,7 +189,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
ActivityCompat.startPostponedEnterTransition(this) ActivityCompat.startPostponedEnterTransition(this)
} }
override fun songs(songs: ArrayList<Song>) { override fun songs(songs: List<Song>) {
songAdapter.swapDataSet(songs) songAdapter.swapDataSet(songs)
} }
@ -215,7 +215,6 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
) )
artistDetailsPresenter.loadArtistAlbums(artist.id) artistDetailsPresenter.loadArtistAlbums(artist.id)
artistDetailsPresenter.loadArtistSongs(artist.id) artistDetailsPresenter.loadArtistSongs(artist.id)
//albumAdapter.swapDataSet(artist.albums!!)
} }
private fun loadBiography( private fun loadBiography(

View file

@ -40,7 +40,7 @@ import java.util.Collections
abstract class AbsTagEditorActivity : AbsBaseActivity() { abstract class AbsTagEditorActivity : AbsBaseActivity() {
protected var id: Int = 0 protected var id: Long = 0
private set private set
private var paletteColorPrimary: Int = 0 private var paletteColorPrimary: Int = 0
private var isInNoImageMode: Boolean = false private var isInNoImageMode: Boolean = false
@ -187,22 +187,16 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
} }
setUpViews() setUpViews()
setStatusbarColorAuto() setStatusbarColorAuto()
setNavigationbarColorAuto() setNavigationbarColorAuto()
setTaskDescriptionColorAuto() setTaskDescriptionColorAuto()
} }
private fun setUpViews() { private fun setUpViews() {
setUpScrollView()
setUpFab() setUpFab()
setUpImageView() setUpImageView()
} }
private fun setUpScrollView() {
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
}
private lateinit var items: List<String> private lateinit var items: List<String>
private fun setUpImageView() { private fun setUpImageView() {
@ -261,7 +255,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
private fun getIntentExtras() { private fun getIntentExtras() {
val intentExtras = intent.extras val intentExtras = intent.extras
if (intentExtras != null) { if (intentExtras != null) {
id = intentExtras.getInt(EXTRA_ID) id = intentExtras.getLong(EXTRA_ID)
} }
} }
@ -406,7 +400,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
} }
} }
class ArtworkInfo constructor(val albumId: Int, val artwork: Bitmap?) class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)
companion object { companion object {
@ -415,5 +409,4 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
private val TAG = AbsTagEditorActivity::class.java.simpleName private val TAG = AbsTagEditorActivity::class.java.simpleName
private const val REQUEST_CODE_SELECT_IMAGE = 1000 private const val REQUEST_CODE_SELECT_IMAGE = 1000
} }
} }

View file

@ -15,10 +15,10 @@ import android.widget.Toast
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.extensions.applyToolbar import code.name.monkey.retromusic.extensions.applyToolbar
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.loaders.AlbumLoader
import code.name.monkey.retromusic.rest.LastFMRestClient import code.name.monkey.retromusic.rest.LastFMRestClient
import code.name.monkey.retromusic.util.ImageUtil import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
@ -31,6 +31,8 @@ import kotlinx.android.synthetic.main.activity_album_tag_editor.albumArtistConta
import kotlinx.android.synthetic.main.activity_album_tag_editor.albumArtistText import kotlinx.android.synthetic.main.activity_album_tag_editor.albumArtistText
import kotlinx.android.synthetic.main.activity_album_tag_editor.albumText import kotlinx.android.synthetic.main.activity_album_tag_editor.albumText
import kotlinx.android.synthetic.main.activity_album_tag_editor.albumTitleContainer import kotlinx.android.synthetic.main.activity_album_tag_editor.albumTitleContainer
import kotlinx.android.synthetic.main.activity_album_tag_editor.artistContainer
import kotlinx.android.synthetic.main.activity_album_tag_editor.artistText
import kotlinx.android.synthetic.main.activity_album_tag_editor.genreContainer import kotlinx.android.synthetic.main.activity_album_tag_editor.genreContainer
import kotlinx.android.synthetic.main.activity_album_tag_editor.genreTitle import kotlinx.android.synthetic.main.activity_album_tag_editor.genreTitle
import kotlinx.android.synthetic.main.activity_album_tag_editor.imageContainer import kotlinx.android.synthetic.main.activity_album_tag_editor.imageContainer
@ -56,7 +58,9 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override fun loadImageFromFile(selectedFileUri: Uri?) { override fun loadImageFromFile(selectedFileUri: Uri?) {
Glide.with(this@AlbumTagEditorActivity).load(selectedFileUri).asBitmap() Glide.with(this@AlbumTagEditorActivity)
.load(selectedFileUri)
.asBitmap()
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java) .transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true) .diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
.into(object : SimpleTarget<BitmapPaletteWrapper>() { .into(object : SimpleTarget<BitmapPaletteWrapper>() {
@ -113,15 +117,18 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
MaterialUtil.setTint(genreContainer, false) MaterialUtil.setTint(genreContainer, false)
MaterialUtil.setTint(albumTitleContainer, false) MaterialUtil.setTint(albumTitleContainer, false)
MaterialUtil.setTint(albumArtistContainer, false) MaterialUtil.setTint(albumArtistContainer, false)
MaterialUtil.setTint(artistContainer, false)
albumText.appHandleColor().addTextChangedListener(this) albumText.addTextChangedListener(this)
albumArtistText.appHandleColor().addTextChangedListener(this) artistText.addTextChangedListener(this)
genreTitle.appHandleColor().addTextChangedListener(this) albumArtistText.addTextChangedListener(this)
yearTitle.appHandleColor().addTextChangedListener(this) genreTitle.addTextChangedListener(this)
yearTitle.addTextChangedListener(this)
} }
private fun fillViewsWithFileTags() { private fun fillViewsWithFileTags() {
albumText.setText(albumTitle) albumText.setText(albumTitle)
artistText.setText(artistName)
albumArtistText.setText(albumArtistName) albumArtistText.setText(albumArtistName)
genreTitle.setText(genreName) genreTitle.setText(genreName)
yearTitle.setText(songYear) yearTitle.setText(songYear)
@ -139,10 +146,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
deleteAlbumArt = false deleteAlbumArt = false
} }
override fun onPause() {
super.onPause()
}
private fun toastLoadingFailed() { private fun toastLoadingFailed() {
Toast.makeText( Toast.makeText(
this@AlbumTagEditorActivity, this@AlbumTagEditorActivity,
@ -168,26 +171,28 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java) val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString() fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
//android seems not to recognize album_artist field so we additionally write the normal artist field //android seems not to recognize album_artist field so we additionally write the normal artist field
fieldKeyValueMap[FieldKey.ARTIST] = albumArtistText.text.toString() fieldKeyValueMap[FieldKey.ARTIST] = artistText.text.toString()
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString() fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString() fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString() fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString()
writeValuesToFiles( writeValuesToFiles(
fieldKeyValueMap, fieldKeyValueMap,
if (deleteAlbumArt) ArtworkInfo(id, null) when {
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!) deleteAlbumArt -> ArtworkInfo(id, null)
albumArtBitmap == null -> null
else -> ArtworkInfo(id, albumArtBitmap!!)
}
) )
} }
override fun getSongPaths(): List<String> { override fun getSongPaths(): List<String> {
//val songs = AlbumLoader.getAlbum(this, id).songs val songs = AlbumLoader.getSongsForAlbum(this, id)
//val paths = ArrayList<String>(songs!!.size) val paths = ArrayList<String>(songs.size)
//for (song in songs) { for (song in songs) {
// paths.add(song.data) paths.add(song.data)
//} }
//return paths return paths
return emptyList()
} }
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
@ -206,7 +211,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
} }
companion object { companion object {
val TAG: String = AlbumTagEditorActivity::class.java.simpleName val TAG: String = AlbumTagEditorActivity::class.java.simpleName
} }
} }

View file

@ -6,7 +6,6 @@ import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.extensions.applyToolbar import code.name.monkey.retromusic.extensions.applyToolbar
import code.name.monkey.retromusic.loaders.SongLoader import code.name.monkey.retromusic.loaders.SongLoader
import kotlinx.android.synthetic.main.activity_song_tag_editor.albumArtistContainer import kotlinx.android.synthetic.main.activity_song_tag_editor.albumArtistContainer
@ -43,7 +42,6 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
setNoImageMode() setNoImageMode()
setUpViews() setUpViews()
applyToolbar(toolbar) applyToolbar(toolbar)
} }
private fun setUpViews() { private fun setUpViews() {
@ -58,15 +56,15 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
MaterialUtil.setTint(trackNumberContainer, false) MaterialUtil.setTint(trackNumberContainer, false)
MaterialUtil.setTint(lyricsContainer, false) MaterialUtil.setTint(lyricsContainer, false)
songText.appHandleColor().addTextChangedListener(this) songText.addTextChangedListener(this)
albumText.appHandleColor().addTextChangedListener(this) albumText.addTextChangedListener(this)
albumArtistText.appHandleColor().addTextChangedListener(this) albumArtistText.addTextChangedListener(this)
artistText.appHandleColor().addTextChangedListener(this) artistText.addTextChangedListener(this)
genreText.appHandleColor().addTextChangedListener(this) genreText.addTextChangedListener(this)
yearText.appHandleColor().addTextChangedListener(this) yearText.addTextChangedListener(this)
trackNumberText.appHandleColor().addTextChangedListener(this) trackNumberText.addTextChangedListener(this)
lyricsText.appHandleColor().addTextChangedListener(this) lyricsText.addTextChangedListener(this)
songComposerText.appHandleColor().addTextChangedListener(this) songComposerText.addTextChangedListener(this)
} }
private fun fillViewsWithFileTags() { private fun fillViewsWithFileTags() {

View file

@ -9,11 +9,10 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import java.util.ArrayList
abstract class AbsOffsetSongAdapter( abstract class AbsOffsetSongAdapter(
activity: AppCompatActivity, activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: MutableList<Song>,
@LayoutRes itemLayoutRes: Int, @LayoutRes itemLayoutRes: Int,
cabHolder: CabHolder? cabHolder: CabHolder?
) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) { ) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {

View file

@ -7,11 +7,10 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import java.util.ArrayList
class ShuffleButtonSongAdapter( class ShuffleButtonSongAdapter(
activity: AppCompatActivity, activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: MutableList<Song>,
itemLayoutRes: Int, itemLayoutRes: Int,
cabHolder: CabHolder? cabHolder: CabHolder?
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) { ) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {

View file

@ -6,18 +6,16 @@ import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import java.util.ArrayList
class SimpleSongAdapter( class SimpleSongAdapter(
context: AppCompatActivity, context: AppCompatActivity,
songs: ArrayList<Song>, songs: MutableList<Song>,
layoutRes: Int, layoutRes: Int,
cabHolder: CabHolder? cabHolder: CabHolder?
) : SongAdapter(context, songs, layoutRes, cabHolder) { ) : SongAdapter(context, songs, layoutRes, cabHolder) {
override fun swapDataSet(dataSet: ArrayList<Song>) { override fun swapDataSet(dataSet: List<Song>) {
this.dataSet.clear() this.dataSet = dataSet.toMutableList()
this.dataSet = dataSet
notifyDataSetChanged() notifyDataSetChanged()
} }

View file

@ -34,7 +34,7 @@ import java.util.ArrayList
open class SongAdapter( open class SongAdapter(
protected val activity: AppCompatActivity, protected val activity: AppCompatActivity,
dataSet: ArrayList<Song>, dataSet: MutableList<Song>,
protected var itemLayoutRes: Int, protected var itemLayoutRes: Int,
cabHolder: CabHolder?, cabHolder: CabHolder?,
showSectionName: Boolean = true showSectionName: Boolean = true
@ -42,7 +42,7 @@ open class SongAdapter(
activity, cabHolder, R.menu.menu_media_selection activity, cabHolder, R.menu.menu_media_selection
), MaterialCab.Callback, PopupTextProvider { ), MaterialCab.Callback, PopupTextProvider {
var dataSet: ArrayList<Song> var dataSet: MutableList<Song>
private var showSectionName = true private var showSectionName = true
init { init {
@ -51,8 +51,8 @@ open class SongAdapter(
this.setHasStableIds(true) this.setHasStableIds(true)
} }
open fun swapDataSet(dataSet: ArrayList<Song>) { open fun swapDataSet(dataSet: List<Song>) {
this.dataSet = dataSet this.dataSet = dataSet.toMutableList()
notifyDataSetChanged() notifyDataSetChanged()
} }

View file

@ -27,11 +27,10 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.list.listItems import com.afollestad.materialdialogs.list.listItems
class AddToPlaylistDialog : DialogFragment() { class AddToPlaylistDialog : DialogFragment() {
override fun onCreateDialog( override fun onCreateDialog(
savedInstanceState: Bundle? savedInstanceState: Bundle?
): Dialog { ): Dialog {
val playlists = PlaylistLoader.getAllPlaylists(requireContext()) val playlists = PlaylistLoader.getAllPlaylists(requireContext())
val playlistNames: MutableList<String> = mutableListOf() val playlistNames: MutableList<String> = mutableListOf()
@ -47,7 +46,9 @@ class AddToPlaylistDialog : DialogFragment() {
val songs = arguments!!.getParcelableArrayList<Song>("songs") ?: return@listItems val songs = arguments!!.getParcelableArrayList<Song>("songs") ?: return@listItems
if (index == 0) { if (index == 0) {
dialog.dismiss() dialog.dismiss()
activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") } activity?.supportFragmentManager?.let {
CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST")
}
} else { } else {
dialog.dismiss() dialog.dismiss()
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlists[index - 1].id, true) PlaylistsUtil.addToPlaylist(requireContext(), songs, playlists[index - 1].id, true)
@ -64,10 +65,10 @@ class AddToPlaylistDialog : DialogFragment() {
return create(list) return create(list)
} }
fun create(songs: ArrayList<Song>): AddToPlaylistDialog { fun create(songs: List<Song>): AddToPlaylistDialog {
val dialog = AddToPlaylistDialog() val dialog = AddToPlaylistDialog()
val args = Bundle() val args = Bundle()
args.putParcelableArrayList("songs", songs) args.putParcelableArrayList("songs", ArrayList(songs))
dialog.arguments = args dialog.arguments = args
return dialog return dialog
} }

View file

@ -23,7 +23,6 @@ import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.R.layout import code.name.monkey.retromusic.R.layout
import code.name.monkey.retromusic.R.string import code.name.monkey.retromusic.R.string
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PlaylistsUtil import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
@ -35,36 +34,35 @@ import com.afollestad.materialdialogs.customview.getCustomView
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
class CreatePlaylistDialog : DialogFragment() { class CreatePlaylistDialog : DialogFragment() {
private lateinit var playlistView: TextInputEditText private lateinit var playlistView: TextInputEditText
private lateinit var actionNewPlaylistContainer: TextInputLayout private lateinit var actionNewPlaylistContainer: TextInputLayout
override fun onCreateDialog( override fun onCreateDialog(
savedInstanceState: Bundle? savedInstanceState: Bundle?
): Dialog { ): Dialog {
val materialDialog = MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)) val materialDialog = MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT))
.show { .show {
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
title(string.new_playlist_title) title(string.new_playlist_title)
customView(layout.dialog_playlist) customView(layout.dialog_playlist)
negativeButton(android.R.string.cancel) negativeButton(android.R.string.cancel)
positiveButton(string.create_action) { positiveButton(string.create_action) {
if (activity == null) { if (activity == null) {
return@positiveButton return@positiveButton
} }
val songs = arguments?.getParcelableArrayList<Song>("songs") val songs = arguments?.getParcelableArrayList<Song>("songs")
?: return@positiveButton ?: return@positiveButton
if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) { if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) {
val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString()) val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString())
if (playlistId != -1 && activity != null) { if (playlistId != -1 && activity != null) {
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true) PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true)
}
} }
} }
} }
}
val dialogView = materialDialog.getCustomView() val dialogView = materialDialog.getCustomView()
playlistView = dialogView.findViewById(R.id.actionNewPlaylist) playlistView = dialogView.findViewById(R.id.actionNewPlaylist)
@ -73,7 +71,10 @@ class CreatePlaylistDialog : DialogFragment() {
MaterialUtil.setTint(actionNewPlaylistContainer, false) MaterialUtil.setTint(actionNewPlaylistContainer, false)
val playlistId = arguments!!.getLong(MediaStore.Audio.Playlists.Members.PLAYLIST_ID) val playlistId = arguments!!.getLong(MediaStore.Audio.Playlists.Members.PLAYLIST_ID)
playlistView.appHandleColor().setText(PlaylistsUtil.getNameForPlaylist(requireContext(), playlistId), TextView.BufferType.EDITABLE) playlistView.setText(
PlaylistsUtil.getNameForPlaylist(requireContext(), playlistId),
TextView.BufferType.EDITABLE
)
return materialDialog return materialDialog
} }

View file

@ -104,10 +104,10 @@ class DeleteSongsDialog : DialogFragment() {
return create(list) return create(list)
} }
fun create(songs: ArrayList<Song>): DeleteSongsDialog { fun create(songs: List<Song>): DeleteSongsDialog {
val dialog = DeleteSongsDialog() val dialog = DeleteSongsDialog()
val args = Bundle() val args = Bundle()
args.putParcelableArrayList("songs", songs) args.putParcelableArrayList("songs", ArrayList(songs))
dialog.arguments = args dialog.arguments = args
return dialog return dialog
} }

View file

@ -23,7 +23,6 @@ import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.R.layout import code.name.monkey.retromusic.R.layout
import code.name.monkey.retromusic.R.string import code.name.monkey.retromusic.R.string
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.util.PlaylistsUtil import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.LayoutMode import com.afollestad.materialdialogs.LayoutMode
@ -60,7 +59,7 @@ class RenamePlaylistDialog : DialogFragment() {
MaterialUtil.setTint(actionNewPlaylistContainer, false) MaterialUtil.setTint(actionNewPlaylistContainer, false)
val playlistId = arguments!!.getLong(PLAYLIST_ID) val playlistId = arguments!!.getLong(PLAYLIST_ID)
playlistView.appHandleColor() playlistView
.setText(PlaylistsUtil.getNameForPlaylist(context!!, playlistId), TextView.BufferType.EDITABLE) .setText(PlaylistsUtil.getNameForPlaylist(context!!, playlistId), TextView.BufferType.EDITABLE)
return materialDialog return materialDialog
} }

View file

@ -17,11 +17,7 @@ package code.name.monkey.retromusic.extensions
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.EditText
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun <T : View> ViewGroup.inflate(@LayoutRes layout: Int): T { fun <T : View> ViewGroup.inflate(@LayoutRes layout: Int): T {
@ -40,9 +36,4 @@ fun View.hidden() {
visibility = View.INVISIBLE visibility = View.INVISIBLE
} }
fun View.showOrHide(show: Boolean) = if (show) show() else hide() fun View.showOrHide(show: Boolean) = if (show) show() else hide()
fun EditText.appHandleColor(): EditText {
TintHelper.colorHandles(this, ThemeStore.accentColor(context))
return this
}

View file

@ -1,5 +1,9 @@
package code.name.monkey.retromusic.fragments.mainactivity; package code.name.monkey.retromusic.fragments.mainactivity;
import static code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder;
import static code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder;
import static code.name.monkey.retromusic.helper.SortOrder.SongSortOrder;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
@ -27,7 +31,6 @@ import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog;
import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment; import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment;
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment; import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment; import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment;
import code.name.monkey.retromusic.helper.SortOrder;
import code.name.monkey.retromusic.interfaces.CabHolder; import code.name.monkey.retromusic.interfaces.CabHolder;
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks; import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
import code.name.monkey.retromusic.util.NavigationUtil; import code.name.monkey.retromusic.util.NavigationUtil;
@ -301,49 +304,52 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
if (fragment instanceof AlbumsFragment) { if (fragment instanceof AlbumsFragment) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_album_sort_order_asc: case R.id.action_album_sort_order_asc:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z; sortOrder = AlbumSortOrder.ALBUM_A_Z;
break; break;
case R.id.action_album_sort_order_desc: case R.id.action_album_sort_order_desc:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A; sortOrder = AlbumSortOrder.ALBUM_Z_A;
break; break;
case R.id.action_album_sort_order_artist: case R.id.action_album_sort_order_artist:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST; sortOrder = AlbumSortOrder.ALBUM_ARTIST;
break; break;
case R.id.action_album_sort_order_year: case R.id.action_album_sort_order_year:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR; sortOrder = AlbumSortOrder.ALBUM_YEAR;
break;
case R.id.action_album_sort_num_songs:
sortOrder = AlbumSortOrder.ALBUM_NUMBER_OF_SONGS;
break; break;
} }
} else if (fragment instanceof ArtistsFragment) { } else if (fragment instanceof ArtistsFragment) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_artist_sort_order_asc: case R.id.action_artist_sort_order_asc:
sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z; sortOrder = ArtistSortOrder.ARTIST_A_Z;
break; break;
case R.id.action_artist_sort_order_desc: case R.id.action_artist_sort_order_desc:
sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A; sortOrder = ArtistSortOrder.ARTIST_Z_A;
break; break;
} }
} else if (fragment instanceof SongsFragment) { } else if (fragment instanceof SongsFragment) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_song_sort_order_asc: case R.id.action_song_sort_order_asc:
sortOrder = SortOrder.SongSortOrder.SONG_A_Z; sortOrder = SongSortOrder.SONG_A_Z;
break; break;
case R.id.action_song_sort_order_desc: case R.id.action_song_sort_order_desc:
sortOrder = SortOrder.SongSortOrder.SONG_Z_A; sortOrder = SongSortOrder.SONG_Z_A;
break; break;
case R.id.action_song_sort_order_artist: case R.id.action_song_sort_order_artist:
sortOrder = SortOrder.SongSortOrder.SONG_ARTIST; sortOrder = SongSortOrder.SONG_ARTIST;
break; break;
case R.id.action_song_sort_order_album: case R.id.action_song_sort_order_album:
sortOrder = SortOrder.SongSortOrder.SONG_ALBUM; sortOrder = SongSortOrder.SONG_ALBUM;
break; break;
case R.id.action_song_sort_order_year: case R.id.action_song_sort_order_year:
sortOrder = SortOrder.SongSortOrder.SONG_YEAR; sortOrder = SongSortOrder.SONG_YEAR;
break; break;
case R.id.action_song_sort_order_date: case R.id.action_song_sort_order_date:
sortOrder = SortOrder.SongSortOrder.SONG_DATE; sortOrder = SongSortOrder.SONG_DATE;
break; break;
case R.id.action_song_sort_order_composer: case R.id.action_song_sort_order_composer:
sortOrder = SortOrder.SongSortOrder.COMPOSER; sortOrder = SongSortOrder.COMPOSER;
break; break;
} }
@ -452,33 +458,35 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
if (fragment instanceof AlbumsFragment) { if (fragment instanceof AlbumsFragment) {
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z) sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_A_Z)); .setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_A_Z));
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a) sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_Z_A)); .setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_Z_A));
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist) sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST)); .setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_ARTIST));
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year) sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year)
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_YEAR)); .setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_YEAR));
sortOrderMenu.add(0, R.id.action_album_sort_num_songs, 4, R.string.sort_num_songs)
.setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_NUMBER_OF_SONGS));
} else if (fragment instanceof ArtistsFragment) { } else if (fragment instanceof ArtistsFragment) {
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z) sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z)
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_A_Z)); .setChecked(currentSortOrder.equals(ArtistSortOrder.ARTIST_A_Z));
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a) sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a)
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_Z_A)); .setChecked(currentSortOrder.equals(ArtistSortOrder.ARTIST_Z_A));
} else if (fragment instanceof SongsFragment) { } else if (fragment instanceof SongsFragment) {
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z) sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_A_Z)); .setChecked(currentSortOrder.equals(SongSortOrder.SONG_A_Z));
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a) sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_Z_A)); .setChecked(currentSortOrder.equals(SongSortOrder.SONG_Z_A));
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist) sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ARTIST)); .setChecked(currentSortOrder.equals(SongSortOrder.SONG_ARTIST));
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album) sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ALBUM)); .setChecked(currentSortOrder.equals(SongSortOrder.SONG_ALBUM));
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year) sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_YEAR)); .setChecked(currentSortOrder.equals(SongSortOrder.SONG_YEAR));
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 5, R.string.sort_order_date) sortOrderMenu.add(0, R.id.action_song_sort_order_date, 5, R.string.sort_order_date)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_DATE)); .setChecked(currentSortOrder.equals(SongSortOrder.SONG_DATE));
sortOrderMenu.add(0, R.id.action_song_sort_order_composer, 6, R.string.sort_order_composer) sortOrderMenu.add(0, R.id.action_song_sort_order_composer, 6, R.string.sort_order_composer)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.COMPOSER)); .setChecked(currentSortOrder.equals(SongSortOrder.COMPOSER));
} }
sortOrderMenu.setGroupCheckable(0, true, true); sortOrderMenu.setGroupCheckable(0, true, true);

View file

@ -40,7 +40,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
} }
override fun createAdapter(): SongAdapter { override fun createAdapter(): SongAdapter {
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet val dataSet = if (adapter == null) mutableListOf() else adapter!!.dataSet
return ShuffleButtonSongAdapter( return ShuffleButtonSongAdapter(
libraryFragment.mainActivity, libraryFragment.mainActivity,
dataSet, dataSet,

View file

@ -29,7 +29,6 @@ import android.os.Environment
import android.os.IBinder import android.os.IBinder
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import code.name.monkey.retromusic.loaders.SongLoader import code.name.monkey.retromusic.loaders.SongLoader
@ -158,7 +157,7 @@ object MusicPlayerRemote {
return cursor.getString(columnIndex) return cursor.getString(columnIndex)
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, e.message) println(e.message)
} finally { } finally {
cursor?.close() cursor?.close()
} }
@ -222,7 +221,7 @@ object MusicPlayerRemote {
/** /**
* Async * Async
*/ */
fun openQueue(queue: ArrayList<Song>, startPosition: Int, startPlaying: Boolean) { fun openQueue(queue: List<Song>, startPosition: Int, startPlaying: Boolean) {
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) { if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
musicService!!.openQueue(queue, startPosition, startPlaying) musicService!!.openQueue(queue, startPosition, startPlaying)
if (PreferenceUtil.getInstance(musicService).isShuffleModeOn) if (PreferenceUtil.getInstance(musicService).isShuffleModeOn)
@ -233,7 +232,7 @@ object MusicPlayerRemote {
/** /**
* Async * Async
*/ */
fun openAndShuffleQueue(queue: ArrayList<Song>, startPlaying: Boolean) { fun openAndShuffleQueue(queue: List<Song>, startPlaying: Boolean) {
var startPosition = 0 var startPosition = 0
if (queue.isNotEmpty()) { if (queue.isNotEmpty()) {
startPosition = Random().nextInt(queue.size) startPosition = Random().nextInt(queue.size)
@ -246,7 +245,7 @@ object MusicPlayerRemote {
} }
private fun tryToHandleOpenPlayingQueue( private fun tryToHandleOpenPlayingQueue(
queue: ArrayList<Song>, queue: List<Song>,
startPosition: Int, startPosition: Int,
startPlaying: Boolean startPlaying: Boolean
): Boolean { ): Boolean {
@ -316,7 +315,7 @@ object MusicPlayerRemote {
return false return false
} }
fun playNext(songs: ArrayList<Song>): Boolean { fun playNext(songs: List<Song>): Boolean {
if (musicService != null) { if (musicService != null) {
if (playingQueue.size > 0) { if (playingQueue.size > 0) {
musicService!!.addSongs(position + 1, songs) musicService!!.addSongs(position + 1, songs)
@ -353,7 +352,7 @@ object MusicPlayerRemote {
return false return false
} }
fun enqueue(songs: ArrayList<Song>): Boolean { fun enqueue(songs: List<Song>): Boolean {
if (musicService != null) { if (musicService != null) {
if (playingQueue.size > 0) { if (playingQueue.size > 0) {
musicService!!.addSongs(songs) musicService!!.addSongs(songs)

View file

@ -21,6 +21,7 @@ class SortOrder {
* Artist sort order entries. * Artist sort order entries.
*/ */
interface ArtistSortOrder { interface ArtistSortOrder {
companion object { companion object {
/* Artist sort order A-Z */ /* Artist sort order A-Z */
@ -41,6 +42,7 @@ class SortOrder {
* Album sort order entries. * Album sort order entries.
*/ */
interface AlbumSortOrder { interface AlbumSortOrder {
companion object { companion object {
/* Album sort order A-Z */ /* Album sort order A-Z */
@ -57,7 +59,7 @@ class SortOrder {
+ ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER) + ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER)
/* Album sort order year */ /* Album sort order year */
const val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC" const val ALBUM_YEAR = MediaStore.Audio.Albums.FIRST_YEAR + " DESC"
} }
} }
@ -65,6 +67,7 @@ class SortOrder {
* Song sort order entries. * Song sort order entries.
*/ */
interface SongSortOrder { interface SongSortOrder {
companion object { companion object {
/* Song sort order A-Z */ /* Song sort order A-Z */
@ -97,6 +100,7 @@ class SortOrder {
* Album song sort order entries. * Album song sort order entries.
*/ */
interface AlbumSongSortOrder { interface AlbumSongSortOrder {
companion object { companion object {
/* Album song sort order A-Z */ /* Album song sort order A-Z */
@ -118,6 +122,7 @@ class SortOrder {
* Artist song sort order entries. * Artist song sort order entries.
*/ */
interface ArtistSongSortOrder { interface ArtistSongSortOrder {
companion object { companion object {
/* Artist song sort order A-Z */ /* Artist song sort order A-Z */
@ -144,6 +149,7 @@ class SortOrder {
* Artist album sort order entries. * Artist album sort order entries.
*/ */
interface ArtistAlbumSortOrder { interface ArtistAlbumSortOrder {
companion object { companion object {
/* Artist album sort order A-Z */ /* Artist album sort order A-Z */
@ -164,6 +170,7 @@ class SortOrder {
* Genre sort order entries. * Genre sort order entries.
*/ */
interface GenreSortOrder { interface GenreSortOrder {
companion object { companion object {
/* Genre sort order A-Z */ /* Genre sort order A-Z */
@ -173,5 +180,4 @@ class SortOrder {
const val ALBUM_Z_A = "$GENRE_A_Z DESC" const val ALBUM_Z_A = "$GENRE_A_Z DESC"
} }
} }
} }

View file

@ -18,12 +18,13 @@ import android.content.Context
import android.database.Cursor import android.database.Cursor
import android.provider.BaseColumns import android.provider.BaseColumns
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.MediaStore.Audio.Albums.*
import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.Constants.baseProjection import code.name.monkey.retromusic.Constants.baseProjection
import code.name.monkey.retromusic.extensions.mapList import code.name.monkey.retromusic.extensions.mapList
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
import android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI as SONGS_URI import android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI as SONGS_URI
/** /**
@ -33,18 +34,18 @@ import android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI as SONGS_URI
object AlbumLoader { object AlbumLoader {
fun getAllAlbums(context: Context): List<Album> { fun getAllAlbums(context: Context): List<Album> {
return makeAlbumsCursor(context, null, null) return makeAlbumCursor(context, null, null)
.mapList(true) { .mapList(true) {
Album.fromCursor(this) Album.fromCursor(this)
} }
} }
fun getSongsForAlbum(context: Context, albumId: Long): ArrayList<Song> { fun getAlbum(context: Context, id: Long): Album {
return SongLoader.getSongs(makeAlbumSongCursor(context, albumId)) return getAlbum(makeAlbumCursor(context, "_id=?", arrayOf(id.toString())))
} }
fun getAlbum(context: Context, id: Long): Album { fun getSongsForAlbum(context: Context, albumId: Long): ArrayList<Song> {
return getAlbum(makeAlbumsCursor(context, "_id=?", arrayOf(id.toString()))) return SongLoader.getSongs(makeAlbumSongCursor(context, albumId))
} }
fun getAlbumsForArtist(context: Context, artistId: Long): List<Album> { fun getAlbumsForArtist(context: Context, artistId: Long): List<Album> {
@ -60,15 +61,15 @@ object AlbumLoader {
return context.contentResolver.query( return context.contentResolver.query(
MediaStore.Audio.Artists.Albums.getContentUri("external", artistId), MediaStore.Audio.Artists.Albums.getContentUri("external", artistId),
arrayOf( arrayOf(
if (VersionUtils.hasQ()) MediaStore.Audio.Artists.Albums.ALBUM_ID else BaseColumns._ID, getAlbumId(),
MediaStore.Audio.Artists.Albums.ALBUM, "album",
MediaStore.Audio.Artists.Albums.ARTIST, "artist",
MediaStore.Audio.Artists.Albums.NUMBER_OF_SONGS, "numsongs",
MediaStore.Audio.Artists.Albums.FIRST_YEAR "minyear"
), ),
null, null,
null, null,
MediaStore.Audio.Albums.DEFAULT_SORT_ORDER DEFAULT_SORT_ORDER
) )
} }
@ -82,27 +83,19 @@ object AlbumLoader {
} ?: Album() } ?: Album()
} }
private fun getAlbums(cursor: Cursor?): ArrayList<Album> { private fun makeAlbumCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? {
val albums = ArrayList<Album>()
if (cursor != null && cursor.moveToFirst()) {
do {
albums.add(getAlbumFromCursorImpl(cursor))
} while (cursor.moveToNext())
}
return albums
}
private fun getAlbumFromCursorImpl(cursor: Cursor): Album {
return Album.fromCursor(cursor)
}
private fun makeAlbumsCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? {
return context.contentResolver.query( return context.contentResolver.query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, EXTERNAL_CONTENT_URI,
arrayOf("_id", "album", "artist", "artist_id", "numsongs", "minyear"), arrayOf(
getAlbumId(),
"album", "artist",
"artist_id",
"numsongs",
"minyear"
),
selection, selection,
paramArrayOfString, paramArrayOfString,
SortOrder.AlbumSortOrder.ALBUM_A_Z PreferenceUtil.getInstance(context).albumSortOrder
) )
} }
@ -113,7 +106,40 @@ object AlbumLoader {
baseProjection, baseProjection,
selection, selection,
null, null,
SortOrder.SongSortOrder.SONG_A_Z PreferenceUtil.getInstance(context).albumDetailSongSortOrder
) )
} }
fun splitIntoAlbums(
songs: ArrayList<Song>?
): ArrayList<Album> {
val albums = ArrayList<Album>()
if (songs != null) {
for (song in songs) {
getOrCreateAlbum(albums, song)
}
}
return albums
}
private fun getOrCreateAlbum(
albums: ArrayList<Album>,
song: Song
): Album {
for (album in albums) {
if (album.id == song.albumId) {
return album
}
}
val album = Album.fromSong(song)
albums.add(album)
return album
}
}
/*
* Android Q and more don't have `_id` for Albums and Artist albums so we have to use album_id
* */
fun getAlbumId(): String {
return if (VersionUtils.hasQ()) ALBUM_ID else BaseColumns._ID
} }

View file

@ -19,64 +19,12 @@ import android.database.Cursor
import android.provider.MediaStore import android.provider.MediaStore
import code.name.monkey.retromusic.Constants.baseProjection import code.name.monkey.retromusic.Constants.baseProjection
import code.name.monkey.retromusic.extensions.mapList import code.name.monkey.retromusic.extensions.mapList
import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
object ArtistLoader { object ArtistLoader {
/*private fun getSongLoaderSortOrder(context: Context): String {
return PreferenceUtil.getInstance(context).artistSortOrder + ", " + PreferenceUtil.getInstance(context).artistAlbumSortOrder + ", " + PreferenceUtil.getInstance(context).albumSongSortOrder
}
fun getAllArtists(context: Context): ArrayList<Artist> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
null, null,
getSongLoaderSortOrder(context))
)
return splitIntoArtists(null)
}
fun getArtists(context: Context, query: String): ArrayList<Artist> {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST + " LIKE ?",
arrayOf("%$query%"),
getSongLoaderSortOrder(context))
)
return splitIntoArtists(null)
}
fun splitIntoArtists(albums: ArrayList<Album>?): ArrayList<Artist> {
val artists = ArrayList<Artist>()
if (albums != null) {
for (album in albums) {
getOrCreateArtist(artists, album.artistId).albums!!.add(album)
}
}
return artists
}
private fun getOrCreateArtist(artists: ArrayList<Artist>, artistId: Int): Artist {
for (artist in artists) {
*//*if (artist.albums!!.isNotEmpty() && artist.albums[0].songs!!.isNotEmpty() && artist.albums[0].songs!![0].artistId == artistId) {
return artist
}*//*
}
val album = Artist()
artists.add(album)
return album
}
fun getArtist(context: Context, artistId: Int): Artist {
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST_ID + "=?",
arrayOf(artistId.toString()),
getSongLoaderSortOrder(context))
)
return Artist(ArrayList())
}*/
fun getAllArtists(context: Context): ArrayList<Artist> { fun getAllArtists(context: Context): ArrayList<Artist> {
return getArtists(makeArtistCursor(context, null, null)) return getArtists(makeArtistCursor(context, null, null))
@ -113,14 +61,19 @@ object ArtistLoader {
private fun makeArtistCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? { private fun makeArtistCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? {
return context.contentResolver.query( return context.contentResolver.query(
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
arrayOf("_id", "artist", "number_of_albums", "number_of_tracks"), arrayOf(
"_id",
"artist",
"number_of_albums",
"number_of_tracks"
),
selection, selection,
paramArrayOfString, paramArrayOfString,
SortOrder.ArtistSortOrder.ARTIST_A_Z PreferenceUtil.getInstance(context).artistSortOrder
) )
} }
fun getSongsForArtist(context: Context, artistId: Long): List<Any> { fun getSongsForArtist(context: Context, artistId: Long): List<Song> {
return makeArtistSongCursor(context, artistId) return makeArtistSongCursor(context, artistId)
.mapList(true) { Song.fromCursor(this, artistId = artistId) } .mapList(true) { Song.fromCursor(this, artistId = artistId) }
} }
@ -137,4 +90,25 @@ object ArtistLoader {
artistSongSortOrder artistSongSortOrder
) )
} }
fun splitIntoArtists(albums: ArrayList<Album>): ArrayList<Artist> {
val artists = ArrayList<Artist>()
if (albums.isNotEmpty()) {
for (album in albums) {
getOrCreateArtist(artists, album)
}
}
return artists
}
private fun getOrCreateArtist(artists: ArrayList<Artist>, album: Album): Artist {
for (artist in artists) {
if (artist.id == album.artistId) {
return artist
}
}
val a = Artist.fromAlbum(album)
artists.add(a)
return a
}
} }

View file

@ -36,17 +36,18 @@ object LastAddedSongsLoader {
val cutoff = PreferenceUtil.getInstance(context).lastAddedCutoff val cutoff = PreferenceUtil.getInstance(context).lastAddedCutoff
return SongLoader.makeSongCursor( return SongLoader.makeSongCursor(
context, context,
MediaStore.Audio.Media.DATE_ADDED + ">?", MediaStore.Audio.Media.DATE_ADDED + ">?",
arrayOf(cutoff.toString()), arrayOf(cutoff.toString()),
MediaStore.Audio.Media.DATE_ADDED + " DESC") MediaStore.Audio.Media.DATE_ADDED + " DESC"
)
} }
fun getLastAddedAlbums(context: Context): ArrayList<Album> { fun getLastAddedAlbums(context: Context): ArrayList<Album> {
return ArrayList() return AlbumLoader.splitIntoAlbums(getLastAddedSongs(context))
} }
fun getLastAddedArtists(context: Context): ArrayList<Artist> { fun getLastAddedArtists(context: Context): ArrayList<Artist> {
return ArrayList() return ArtistLoader.splitIntoArtists(getLastAddedAlbums(context))
} }
} }

View file

@ -75,32 +75,14 @@ object SongLoader {
} }
@JvmStatic @JvmStatic
fun getSong(context: Context, queryId: Int): Song { fun getSong(context: Context, queryId: Long): Song {
val cursor = makeSongCursor(context, AudioColumns._ID + "=?", arrayOf(queryId.toString())) val cursor = makeSongCursor(context, AudioColumns._ID + "=?", arrayOf(queryId.toString()))
return getSong(cursor) return getSong(cursor)
} }
private fun getSongFromCursorImpl( private fun getSongFromCursorImpl(
cursor: Cursor cursor: Cursor
): Song { ): Song = Song.fromCursor(cursor)
val id = cursor.getLong(0)
val title = cursor.getString(1)
val trackNumber = cursor.getInt(2)
val year = cursor.getInt(3)
val duration = cursor.getLong(4)
val data = cursor.getString(5)
val dateModified = cursor.getLong(6)
val albumId = cursor.getInt(7)
val albumName = cursor.getString(8)
val artistId = cursor.getLong(9)
val artistName = cursor.getString(10)
val composer = cursor.getString(11)
return Song(
id, title, trackNumber, year, duration, data, dateModified, albumId,
albumName ?: "", artistId, artistName, composer ?: ""
)
}
@JvmOverloads @JvmOverloads
fun makeSongCursor( fun makeSongCursor(

View file

@ -139,10 +139,10 @@ object TopAndRecentlyPlayedTracksLoader {
context: Context context: Context
): ArrayList<Album> { ): ArrayList<Album> {
arrayListOf<Album>() arrayListOf<Album>()
return ArrayList()//AlbumLoader.splitIntoAlbums(getTopTracks(context)) return AlbumLoader.splitIntoAlbums(getTopTracks(context))
} }
fun getTopArtists(context: Context): ArrayList<Artist> { fun getTopArtists(context: Context): ArrayList<Artist> {
return ArrayList()//ArtistLoader.splitIntoArtists(getTopAlbums(context)) return ArtistLoader.splitIntoArtists(getTopAlbums(context))
} }
} }

View file

@ -15,13 +15,12 @@
package code.name.monkey.retromusic.model package code.name.monkey.retromusic.model
import android.database.Cursor import android.database.Cursor
import android.provider.MediaStore
import android.provider.MediaStore.Audio.Albums.ALBUM import android.provider.MediaStore.Audio.Albums.ALBUM
import android.provider.MediaStore.Audio.Albums.ARTIST import android.provider.MediaStore.Audio.Albums.ARTIST
import android.provider.MediaStore.Audio.Albums.FIRST_YEAR import android.provider.MediaStore.Audio.Albums.FIRST_YEAR
import android.provider.MediaStore.Audio.Albums.NUMBER_OF_SONGS import android.provider.MediaStore.Audio.Albums.NUMBER_OF_SONGS
import android.provider.MediaStore.Audio.Albums._ID import code.name.monkey.retromusic.loaders.getAlbumId
import android.provider.MediaStore.Audio.Artists.Albums.ALBUM_ID
import code.name.monkey.appthemehelper.util.VersionUtils
data class Album( data class Album(
var id: Long = 0, var id: Long = 0,
@ -35,14 +34,18 @@ data class Album(
companion object { companion object {
fun fromCursor(cursor: Cursor, artistId: Long = -1): Album { fun fromCursor(cursor: Cursor, artistId: Long = -1): Album {
return Album( return Album(
id = cursor.value(if (VersionUtils.hasQ()) ALBUM_ID else _ID), id = cursor.value(getAlbumId()),
title = cursor.valueOrEmpty(ALBUM), title = cursor.valueOrEmpty(ALBUM),
artist = cursor.valueOrEmpty(ARTIST), artist = cursor.valueOrEmpty(ARTIST),
artistId = artistId, artistId = if (artistId == -1L) cursor.value(MediaStore.Audio.AudioColumns.ARTIST_ID) else artistId,
songCount = cursor.value(NUMBER_OF_SONGS), songCount = cursor.value(NUMBER_OF_SONGS),
year = cursor.value(FIRST_YEAR) year = cursor.value(FIRST_YEAR)
) )
} }
fun fromSong(song: Song): Album {
return Album(song.albumId, song.albumName, song.artistName, song.artistId, -1, song.year)
}
} }
} }

View file

@ -84,6 +84,10 @@ class Artist(
) )
} }
fun fromAlbum(album: Album): Artist {
return Artist(album.artistId, album.artist, -1, -1)
}
const val UNKNOWN_ARTIST_DISPLAY_NAME = "Unknown Artist" const val UNKNOWN_ARTIST_DISPLAY_NAME = "Unknown Artist"
} }
} }

View file

@ -27,7 +27,7 @@ open class Song(
val duration: Long, val duration: Long,
val data: String, val data: String,
val dateModified: Long, val dateModified: Long,
val albumId: Int, val albumId: Long,
val albumName: String, val albumName: String,
val artistId: Long, val artistId: Long,
val artistName: String, val artistName: String,
@ -52,16 +52,16 @@ open class Song(
"" ""
) )
fun fromCursor(cursor: Cursor, artistId: Long): Any { fun fromCursor(cursor: Cursor, albumId: Long = -1, artistId: Long = -1): Song {
return Song( return Song(
id = cursor.value(Media._ID), id = cursor.value(Media._ID),
albumId = cursor.value(Media.ALBUM_ID), albumId = cursor.valueOrDefault(Media.ALBUM_ID, albumId),
artistId = cursor.value(Media.ARTIST_ID), artistId = cursor.valueOrDefault(Media.ARTIST_ID, artistId),
albumName = cursor.valueOrEmpty(Media.ALBUM), albumName = cursor.valueOrEmpty(Media.ALBUM),
artistName = cursor.valueOrEmpty(Media.ARTIST), artistName = cursor.valueOrEmpty(Media.ARTIST),
composer = cursor.valueOrEmpty(Media.COMPOSER), composer = cursor.valueOrEmpty(Media.COMPOSER),
data = cursor.valueOrEmpty(Media.DATA), data = cursor.valueOrEmpty(Media.DATA),
dateModified = cursor.value(Media.DATE_ADDED), dateModified = cursor.value(Media.DATE_MODIFIED),
duration = cursor.value(Media.DURATION), duration = cursor.value(Media.DURATION),
title = cursor.valueOrEmpty(Media.TITLE), title = cursor.valueOrEmpty(Media.TITLE),
trackNumber = cursor.value(Media.TRACK), trackNumber = cursor.value(Media.TRACK),

View file

@ -17,6 +17,7 @@ package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.Result import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.loaders.AlbumLoader import code.name.monkey.retromusic.loaders.AlbumLoader
import code.name.monkey.retromusic.loaders.ArtistLoader
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
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
@ -39,7 +40,7 @@ import kotlin.coroutines.CoroutineContext
*/ */
interface ArtistDetailsView : BaseView { interface ArtistDetailsView : BaseView {
fun songs(songs: ArrayList<Song>) fun songs(songs: List<Song>)
fun albums(albums: List<Album>) fun albums(albums: List<Album>)
@ -102,7 +103,7 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
override fun loadArtistSongs(artistId: Long) { override fun loadArtistSongs(artistId: Long) {
launch { launch {
val songs = AlbumLoader.getSongsForAlbum(App.getContext(), artistId) val songs = ArtistLoader.getSongsForArtist(App.getContext(), artistId)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
view.songs(songs) view.songs(songs)
} }

View file

@ -844,7 +844,7 @@ public class MusicService extends Service implements
return true; return true;
} }
public void openQueue(@Nullable final ArrayList<Song> playingQueue, final int startPosition, public void openQueue(@Nullable final List<Song> playingQueue, final int startPosition,
final boolean startPlaying) { final boolean startPlaying) {
if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue
.size()) { .size()) {

View file

@ -99,7 +99,7 @@ public class MusicUtil {
} }
} }
public static void deleteAlbumArt(@NonNull Context context, int albumId) { public static void deleteAlbumArt(@NonNull Context context, long albumId) {
ContentResolver contentResolver = context.getContentResolver(); ContentResolver contentResolver = context.getContentResolver();
Uri localUri = Uri.parse("content://media/external/audio/albumart"); Uri localUri = Uri.parse("content://media/external/audio/albumart");
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null); contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
@ -348,7 +348,7 @@ public class MusicUtil {
return -1; return -1;
} }
public static void insertAlbumArt(@NonNull Context context, int albumId, String path) { public static void insertAlbumArt(@NonNull Context context, long albumId, String path) {
ContentResolver contentResolver = context.getContentResolver(); ContentResolver contentResolver = context.getContentResolver();
Uri artworkUri = Uri.parse("content://media/external/audio/albumart"); Uri artworkUri = Uri.parse("content://media/external/audio/albumart");

View file

@ -59,7 +59,7 @@ public class NavigationUtil {
ActivityCompat.startActivity(activity, new Intent(activity, AboutActivity.class), null); ActivityCompat.startActivity(activity, new Intent(activity, AboutActivity.class), null);
} }
public static void goToAlbum(@NonNull Activity activity, int albumId) { public static void goToAlbum(@NonNull Activity activity, long albumId) {
Intent intent = new Intent(activity, AlbumDetailsActivity.class); Intent intent = new Intent(activity, AlbumDetailsActivity.class);
intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId); intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId);
ActivityCompat.startActivity(activity, intent, null); ActivityCompat.startActivity(activity, intent, null);

View file

@ -14,6 +14,12 @@
package code.name.monkey.retromusic.util; package code.name.monkey.retromusic.util;
import static code.name.monkey.retromusic.helper.SortOrder.ArtistAlbumSortOrder;
import static code.name.monkey.retromusic.helper.SortOrder.ArtistSongSortOrder;
import static code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder;
import static code.name.monkey.retromusic.helper.SortOrder.GenreSortOrder;
import static code.name.monkey.retromusic.helper.SortOrder.SongSortOrder;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -33,8 +39,8 @@ import code.name.monkey.retromusic.activities.MainActivity;
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.fragments.mainactivity.folders.FoldersFragment; import code.name.monkey.retromusic.fragments.mainactivity.folders.FoldersFragment;
import code.name.monkey.retromusic.helper.SortOrder;
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder; import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder;
import code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder;
import code.name.monkey.retromusic.model.CategoryInfo; import code.name.monkey.retromusic.model.CategoryInfo;
import code.name.monkey.retromusic.transform.CascadingPageTransformer; import code.name.monkey.retromusic.transform.CascadingPageTransformer;
import code.name.monkey.retromusic.transform.DepthTransformation; import code.name.monkey.retromusic.transform.DepthTransformation;
@ -365,6 +371,7 @@ public final class PreferenceUtil {
} }
} }
@NonNull
public String getAlbumDetailSongSortOrder() { public String getAlbumDetailSongSortOrder() {
return mPreferences return mPreferences
.getString(ALBUM_DETAIL_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST); .getString(ALBUM_DETAIL_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST);
@ -417,8 +424,9 @@ public final class PreferenceUtil {
.getString(ALBUM_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST); .getString(ALBUM_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST);
} }
@NonNull
public final String getAlbumSortOrder() { public final String getAlbumSortOrder() {
return mPreferences.getString(ALBUM_SORT_ORDER, SortOrder.AlbumSortOrder.ALBUM_A_Z); return mPreferences.getString(ALBUM_SORT_ORDER, AlbumSortOrder.ALBUM_A_Z);
} }
public void setAlbumSortOrder(final String sortOrder) { public void setAlbumSortOrder(final String sortOrder) {
@ -428,12 +436,12 @@ public final class PreferenceUtil {
} }
public final String getArtistAlbumSortOrder() { public final String getArtistAlbumSortOrder() {
return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR); return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, ArtistAlbumSortOrder.ALBUM_YEAR);
} }
public String getArtistDetailSongSortOrder() { public String getArtistDetailSongSortOrder() {
return mPreferences return mPreferences
.getString(ARTIST_DETAIL_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z); .getString(ARTIST_DETAIL_SONG_SORT_ORDER, ArtistSongSortOrder.SONG_A_Z);
} }
public void setArtistDetailSongSortOrder(String sortOrder) { public void setArtistDetailSongSortOrder(String sortOrder) {
@ -462,11 +470,12 @@ public final class PreferenceUtil {
} }
public final String getArtistSongSortOrder() { public final String getArtistSongSortOrder() {
return mPreferences.getString(ARTIST_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z); return mPreferences.getString(ARTIST_SONG_SORT_ORDER, ArtistSongSortOrder.SONG_A_Z);
} }
@NonNull
public final String getArtistSortOrder() { public final String getArtistSortOrder() {
return mPreferences.getString(ARTIST_SORT_ORDER, SortOrder.ArtistSortOrder.ARTIST_A_Z); return mPreferences.getString(ARTIST_SORT_ORDER, ArtistSortOrder.ARTIST_A_Z);
} }
public void setArtistSortOrder(final String sortOrder) { public void setArtistSortOrder(final String sortOrder) {
@ -536,7 +545,7 @@ public final class PreferenceUtil {
} }
public final String getGenreSortOrder() { public final String getGenreSortOrder() {
return mPreferences.getString(GENRE_SORT_ORDER, SortOrder.GenreSortOrder.GENRE_A_Z); return mPreferences.getString(GENRE_SORT_ORDER, GenreSortOrder.GENRE_A_Z);
} }
public boolean getHeadsetPlugged() { public boolean getHeadsetPlugged() {
@ -719,7 +728,7 @@ public final class PreferenceUtil {
} }
public final String getSongSortOrder() { public final String getSongSortOrder() {
return mPreferences.getString(SONG_SORT_ORDER, SortOrder.SongSortOrder.SONG_A_Z); return mPreferences.getString(SONG_SORT_ORDER, SongSortOrder.SONG_A_Z);
} }
public void setSongSortOrder(final String sortOrder) { public void setSongSortOrder(final String sortOrder) {

View file

@ -2,9 +2,9 @@
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:id="@+id/gradient_background" android:id="@+id/gradient_background"
android:background="?attr/colorSurface"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="?attr/colorSurface">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -87,6 +87,24 @@
android:maxLines="1" /> android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/artistContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:hintEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/artistText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:hint="@string/artist"
android:inputType="text|textCapWords"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/albumArtistContainer" android:id="@+id/albumArtistContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"

View file

@ -85,6 +85,26 @@
android:maxLines="1" /> android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/artistContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
app:hintEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/artistText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:hint="@string/artist"
android:inputType="text|textCapWords"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/albumArtistContainer" android:id="@+id/albumArtistContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"

View file

@ -8,6 +8,7 @@
<item name="action_album_sort_order_desc" type="id" /> <item name="action_album_sort_order_desc" type="id" />
<item name="action_album_sort_order_artist" type="id" /> <item name="action_album_sort_order_artist" type="id" />
<item name="action_album_sort_order_year" type="id" /> <item name="action_album_sort_order_year" type="id" />
<item name="action_album_sort_num_songs" type="id" />
<item name="action_artist_sort_order_asc" type="id" /> <item name="action_artist_sort_order_asc" type="id" />
<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" />

View file

@ -825,4 +825,5 @@
<string name="share_to_stories">Share to Stories</string> <string name="share_to_stories">Share to Stories</string>
<string name="drive_mode">Drive mode</string> <string name="drive_mode">Drive mode</string>
<string name="retro_music_player">Retro Music Player</string> <string name="retro_music_player">Retro Music Player</string>
<string name="sort_num_songs">Number of songs</string>
</resources> </resources>

View file

@ -35,48 +35,6 @@ import java.lang.reflect.Field;
*/ */
public final class TintHelper { public final class TintHelper {
@SuppressWarnings("JavaReflectionMemberAccess")
public static void colorHandles(@NonNull TextView view, int color) {
try {
Field editorField = TextView.class.getDeclaredField("mEditor");
if (!editorField.isAccessible()) {
editorField.setAccessible(true);
}
Object editor = editorField.get(view);
Class<?> editorClass = editor.getClass();
String[] handleNames = {"mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"};
String[] resNames = {"mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"};
for (int i = 0; i < handleNames.length; i++) {
Field handleField = editorClass.getDeclaredField(handleNames[i]);
if (!handleField.isAccessible()) {
handleField.setAccessible(true);
}
Drawable handleDrawable = (Drawable) handleField.get(editor);
if (handleDrawable == null) {
Field resField = TextView.class.getDeclaredField(resNames[i]);
if (!resField.isAccessible()) {
resField.setAccessible(true);
}
int resId = resField.getInt(view);
handleDrawable = view.getResources().getDrawable(resId);
}
if (handleDrawable != null) {
Drawable drawable = handleDrawable.mutate();
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
handleField.set(editor, drawable);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@CheckResult @CheckResult
@NonNull @NonNull
public static Drawable createTintedDrawable(Context context, public static Drawable createTintedDrawable(Context context,