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

View file

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

View file

@ -40,7 +40,7 @@ import java.util.Collections
abstract class AbsTagEditorActivity : AbsBaseActivity() {
protected var id: Int = 0
protected var id: Long = 0
private set
private var paletteColorPrimary: Int = 0
private var isInNoImageMode: Boolean = false
@ -187,22 +187,16 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
}
setUpViews()
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
}
private fun setUpViews() {
setUpScrollView()
setUpFab()
setUpImageView()
}
private fun setUpScrollView() {
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
}
private lateinit var items: List<String>
private fun setUpImageView() {
@ -261,7 +255,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
private fun getIntentExtras() {
val intentExtras = intent.extras
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 {
@ -415,5 +409,4 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
private val TAG = AbsTagEditorActivity::class.java.simpleName
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.MaterialUtil
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.glide.palette.BitmapPaletteTranscoder
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.util.ImageUtil
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.albumText
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.genreTitle
import kotlinx.android.synthetic.main.activity_album_tag_editor.imageContainer
@ -56,7 +58,9 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
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)
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
@ -113,15 +117,18 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
MaterialUtil.setTint(genreContainer, false)
MaterialUtil.setTint(albumTitleContainer, false)
MaterialUtil.setTint(albumArtistContainer, false)
MaterialUtil.setTint(artistContainer, false)
albumText.appHandleColor().addTextChangedListener(this)
albumArtistText.appHandleColor().addTextChangedListener(this)
genreTitle.appHandleColor().addTextChangedListener(this)
yearTitle.appHandleColor().addTextChangedListener(this)
albumText.addTextChangedListener(this)
artistText.addTextChangedListener(this)
albumArtistText.addTextChangedListener(this)
genreTitle.addTextChangedListener(this)
yearTitle.addTextChangedListener(this)
}
private fun fillViewsWithFileTags() {
albumText.setText(albumTitle)
artistText.setText(artistName)
albumArtistText.setText(albumArtistName)
genreTitle.setText(genreName)
yearTitle.setText(songYear)
@ -139,10 +146,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
deleteAlbumArt = false
}
override fun onPause() {
super.onPause()
}
private fun toastLoadingFailed() {
Toast.makeText(
this@AlbumTagEditorActivity,
@ -168,26 +171,28 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
//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.GENRE] = genreTitle.text.toString()
fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString()
writeValuesToFiles(
fieldKeyValueMap,
if (deleteAlbumArt) ArtworkInfo(id, null)
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
when {
deleteAlbumArt -> ArtworkInfo(id, null)
albumArtBitmap == null -> null
else -> ArtworkInfo(id, albumArtBitmap!!)
}
)
}
override fun getSongPaths(): List<String> {
//val songs = AlbumLoader.getAlbum(this, id).songs
//val paths = ArrayList<String>(songs!!.size)
//for (song in songs) {
// paths.add(song.data)
//}
//return paths
return emptyList()
val songs = AlbumLoader.getSongsForAlbum(this, id)
val paths = ArrayList<String>(songs.size)
for (song in songs) {
paths.add(song.data)
}
return paths
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
@ -206,7 +211,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
}
companion object {
val TAG: String = AlbumTagEditorActivity::class.java.simpleName
}
}

View file

@ -6,7 +6,6 @@ import android.text.Editable
import android.text.TextWatcher
import code.name.monkey.appthemehelper.util.MaterialUtil
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.loaders.SongLoader
import kotlinx.android.synthetic.main.activity_song_tag_editor.albumArtistContainer
@ -43,7 +42,6 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
setNoImageMode()
setUpViews()
applyToolbar(toolbar)
}
private fun setUpViews() {
@ -58,15 +56,15 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
MaterialUtil.setTint(trackNumberContainer, false)
MaterialUtil.setTint(lyricsContainer, false)
songText.appHandleColor().addTextChangedListener(this)
albumText.appHandleColor().addTextChangedListener(this)
albumArtistText.appHandleColor().addTextChangedListener(this)
artistText.appHandleColor().addTextChangedListener(this)
genreText.appHandleColor().addTextChangedListener(this)
yearText.appHandleColor().addTextChangedListener(this)
trackNumberText.appHandleColor().addTextChangedListener(this)
lyricsText.appHandleColor().addTextChangedListener(this)
songComposerText.appHandleColor().addTextChangedListener(this)
songText.addTextChangedListener(this)
albumText.addTextChangedListener(this)
albumArtistText.addTextChangedListener(this)
artistText.addTextChangedListener(this)
genreText.addTextChangedListener(this)
yearText.addTextChangedListener(this)
trackNumberText.addTextChangedListener(this)
lyricsText.addTextChangedListener(this)
songComposerText.addTextChangedListener(this)
}
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.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song
import java.util.ArrayList
abstract class AbsOffsetSongAdapter(
activity: AppCompatActivity,
dataSet: ArrayList<Song>,
dataSet: MutableList<Song>,
@LayoutRes itemLayoutRes: Int,
cabHolder: 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.model.Song
import com.google.android.material.button.MaterialButton
import java.util.ArrayList
class ShuffleButtonSongAdapter(
activity: AppCompatActivity,
dataSet: ArrayList<Song>,
dataSet: MutableList<Song>,
itemLayoutRes: Int,
cabHolder: 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.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import java.util.ArrayList
class SimpleSongAdapter(
context: AppCompatActivity,
songs: ArrayList<Song>,
songs: MutableList<Song>,
layoutRes: Int,
cabHolder: CabHolder?
) : SongAdapter(context, songs, layoutRes, cabHolder) {
override fun swapDataSet(dataSet: ArrayList<Song>) {
this.dataSet.clear()
this.dataSet = dataSet
override fun swapDataSet(dataSet: List<Song>) {
this.dataSet = dataSet.toMutableList()
notifyDataSetChanged()
}

View file

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

View file

@ -27,7 +27,6 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.list.listItems
class AddToPlaylistDialog : DialogFragment() {
override fun onCreateDialog(
@ -47,7 +46,9 @@ class AddToPlaylistDialog : DialogFragment() {
val songs = arguments!!.getParcelableArrayList<Song>("songs") ?: return@listItems
if (index == 0) {
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 {
dialog.dismiss()
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlists[index - 1].id, true)
@ -64,10 +65,10 @@ class AddToPlaylistDialog : DialogFragment() {
return create(list)
}
fun create(songs: ArrayList<Song>): AddToPlaylistDialog {
fun create(songs: List<Song>): AddToPlaylistDialog {
val dialog = AddToPlaylistDialog()
val args = Bundle()
args.putParcelableArrayList("songs", songs)
args.putParcelableArrayList("songs", ArrayList(songs))
dialog.arguments = args
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.layout
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.util.PlaylistsUtil
import code.name.monkey.retromusic.util.PreferenceUtil
@ -35,7 +34,6 @@ import com.afollestad.materialdialogs.customview.getCustomView
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
class CreatePlaylistDialog : DialogFragment() {
private lateinit var playlistView: TextInputEditText
@ -73,7 +71,10 @@ class CreatePlaylistDialog : DialogFragment() {
MaterialUtil.setTint(actionNewPlaylistContainer, false)
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
}

View file

@ -104,10 +104,10 @@ class DeleteSongsDialog : DialogFragment() {
return create(list)
}
fun create(songs: ArrayList<Song>): DeleteSongsDialog {
fun create(songs: List<Song>): DeleteSongsDialog {
val dialog = DeleteSongsDialog()
val args = Bundle()
args.putParcelableArrayList("songs", songs)
args.putParcelableArrayList("songs", ArrayList(songs))
dialog.arguments = args
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.layout
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.PreferenceUtil
import com.afollestad.materialdialogs.LayoutMode
@ -60,7 +59,7 @@ class RenamePlaylistDialog : DialogFragment() {
MaterialUtil.setTint(actionNewPlaylistContainer, false)
val playlistId = arguments!!.getLong(PLAYLIST_ID)
playlistView.appHandleColor()
playlistView
.setText(PlaylistsUtil.getNameForPlaylist(context!!, playlistId), TextView.BufferType.EDITABLE)
return materialDialog
}

View file

@ -17,11 +17,7 @@ package code.name.monkey.retromusic.extensions
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.annotation.LayoutRes
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper
@Suppress("UNCHECKED_CAST")
fun <T : View> ViewGroup.inflate(@LayoutRes layout: Int): T {
@ -41,8 +37,3 @@ fun View.hidden() {
}
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;
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.ActivityOptions;
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.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
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.MainActivityFragmentCallbacks;
import code.name.monkey.retromusic.util.NavigationUtil;
@ -301,49 +304,52 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
if (fragment instanceof AlbumsFragment) {
switch (item.getItemId()) {
case R.id.action_album_sort_order_asc:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z;
sortOrder = AlbumSortOrder.ALBUM_A_Z;
break;
case R.id.action_album_sort_order_desc:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A;
sortOrder = AlbumSortOrder.ALBUM_Z_A;
break;
case R.id.action_album_sort_order_artist:
sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST;
sortOrder = AlbumSortOrder.ALBUM_ARTIST;
break;
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;
}
} else if (fragment instanceof ArtistsFragment) {
switch (item.getItemId()) {
case R.id.action_artist_sort_order_asc:
sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z;
sortOrder = ArtistSortOrder.ARTIST_A_Z;
break;
case R.id.action_artist_sort_order_desc:
sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A;
sortOrder = ArtistSortOrder.ARTIST_Z_A;
break;
}
} else if (fragment instanceof SongsFragment) {
switch (item.getItemId()) {
case R.id.action_song_sort_order_asc:
sortOrder = SortOrder.SongSortOrder.SONG_A_Z;
sortOrder = SongSortOrder.SONG_A_Z;
break;
case R.id.action_song_sort_order_desc:
sortOrder = SortOrder.SongSortOrder.SONG_Z_A;
sortOrder = SongSortOrder.SONG_Z_A;
break;
case R.id.action_song_sort_order_artist:
sortOrder = SortOrder.SongSortOrder.SONG_ARTIST;
sortOrder = SongSortOrder.SONG_ARTIST;
break;
case R.id.action_song_sort_order_album:
sortOrder = SortOrder.SongSortOrder.SONG_ALBUM;
sortOrder = SongSortOrder.SONG_ALBUM;
break;
case R.id.action_song_sort_order_year:
sortOrder = SortOrder.SongSortOrder.SONG_YEAR;
sortOrder = SongSortOrder.SONG_YEAR;
break;
case R.id.action_song_sort_order_date:
sortOrder = SortOrder.SongSortOrder.SONG_DATE;
sortOrder = SongSortOrder.SONG_DATE;
break;
case R.id.action_song_sort_order_composer:
sortOrder = SortOrder.SongSortOrder.COMPOSER;
sortOrder = SongSortOrder.COMPOSER;
break;
}
@ -452,33 +458,35 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
if (fragment instanceof AlbumsFragment) {
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)
.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)
.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)
.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) {
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)
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_Z_A));
.setChecked(currentSortOrder.equals(ArtistSortOrder.ARTIST_Z_A));
} else if (fragment instanceof SongsFragment) {
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)
.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)
.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)
.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)
.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)
.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)
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.COMPOSER));
.setChecked(currentSortOrder.equals(SongSortOrder.COMPOSER));
}
sortOrderMenu.setGroupCheckable(0, true, true);

View file

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

View file

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

View file

@ -21,6 +21,7 @@ class SortOrder {
* Artist sort order entries.
*/
interface ArtistSortOrder {
companion object {
/* Artist sort order A-Z */
@ -41,6 +42,7 @@ class SortOrder {
* Album sort order entries.
*/
interface AlbumSortOrder {
companion object {
/* Album sort order A-Z */
@ -57,7 +59,7 @@ class SortOrder {
+ ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER)
/* 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.
*/
interface SongSortOrder {
companion object {
/* Song sort order A-Z */
@ -97,6 +100,7 @@ class SortOrder {
* Album song sort order entries.
*/
interface AlbumSongSortOrder {
companion object {
/* Album song sort order A-Z */
@ -118,6 +122,7 @@ class SortOrder {
* Artist song sort order entries.
*/
interface ArtistSongSortOrder {
companion object {
/* Artist song sort order A-Z */
@ -144,6 +149,7 @@ class SortOrder {
* Artist album sort order entries.
*/
interface ArtistAlbumSortOrder {
companion object {
/* Artist album sort order A-Z */
@ -164,6 +170,7 @@ class SortOrder {
* Genre sort order entries.
*/
interface GenreSortOrder {
companion object {
/* Genre sort order A-Z */
@ -173,5 +180,4 @@ class SortOrder {
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.provider.BaseColumns
import android.provider.MediaStore
import android.provider.MediaStore.Audio.Albums.*
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.Constants.baseProjection
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.Song
import code.name.monkey.retromusic.util.PreferenceUtil
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 {
fun getAllAlbums(context: Context): List<Album> {
return makeAlbumsCursor(context, null, null)
return makeAlbumCursor(context, null, null)
.mapList(true) {
Album.fromCursor(this)
}
}
fun getSongsForAlbum(context: Context, albumId: Long): ArrayList<Song> {
return SongLoader.getSongs(makeAlbumSongCursor(context, albumId))
fun getAlbum(context: Context, id: Long): Album {
return getAlbum(makeAlbumCursor(context, "_id=?", arrayOf(id.toString())))
}
fun getAlbum(context: Context, id: Long): Album {
return getAlbum(makeAlbumsCursor(context, "_id=?", arrayOf(id.toString())))
fun getSongsForAlbum(context: Context, albumId: Long): ArrayList<Song> {
return SongLoader.getSongs(makeAlbumSongCursor(context, albumId))
}
fun getAlbumsForArtist(context: Context, artistId: Long): List<Album> {
@ -60,15 +61,15 @@ object AlbumLoader {
return context.contentResolver.query(
MediaStore.Audio.Artists.Albums.getContentUri("external", artistId),
arrayOf(
if (VersionUtils.hasQ()) MediaStore.Audio.Artists.Albums.ALBUM_ID else BaseColumns._ID,
MediaStore.Audio.Artists.Albums.ALBUM,
MediaStore.Audio.Artists.Albums.ARTIST,
MediaStore.Audio.Artists.Albums.NUMBER_OF_SONGS,
MediaStore.Audio.Artists.Albums.FIRST_YEAR
getAlbumId(),
"album",
"artist",
"numsongs",
"minyear"
),
null,
null,
MediaStore.Audio.Albums.DEFAULT_SORT_ORDER
DEFAULT_SORT_ORDER
)
}
@ -82,27 +83,19 @@ object AlbumLoader {
} ?: Album()
}
private fun getAlbums(cursor: Cursor?): ArrayList<Album> {
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? {
private fun makeAlbumCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? {
return context.contentResolver.query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
arrayOf("_id", "album", "artist", "artist_id", "numsongs", "minyear"),
EXTERNAL_CONTENT_URI,
arrayOf(
getAlbumId(),
"album", "artist",
"artist_id",
"numsongs",
"minyear"
),
selection,
paramArrayOfString,
SortOrder.AlbumSortOrder.ALBUM_A_Z
PreferenceUtil.getInstance(context).albumSortOrder
)
}
@ -113,7 +106,40 @@ object AlbumLoader {
baseProjection,
selection,
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 code.name.monkey.retromusic.Constants.baseProjection
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.Song
import code.name.monkey.retromusic.util.PreferenceUtil
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> {
return getArtists(makeArtistCursor(context, null, null))
@ -113,14 +61,19 @@ object ArtistLoader {
private fun makeArtistCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? {
return context.contentResolver.query(
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,
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)
.mapList(true) { Song.fromCursor(this, artistId = artistId) }
}
@ -137,4 +90,25 @@ object ArtistLoader {
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

@ -39,14 +39,15 @@ object LastAddedSongsLoader {
context,
MediaStore.Audio.Media.DATE_ADDED + ">?",
arrayOf(cutoff.toString()),
MediaStore.Audio.Media.DATE_ADDED + " DESC")
MediaStore.Audio.Media.DATE_ADDED + " DESC"
)
}
fun getLastAddedAlbums(context: Context): ArrayList<Album> {
return ArrayList()
return AlbumLoader.splitIntoAlbums(getLastAddedSongs(context))
}
fun getLastAddedArtists(context: Context): ArrayList<Artist> {
return ArrayList()
return ArtistLoader.splitIntoArtists(getLastAddedAlbums(context))
}
}

View file

@ -75,32 +75,14 @@ object SongLoader {
}
@JvmStatic
fun getSong(context: Context, queryId: Int): Song {
fun getSong(context: Context, queryId: Long): Song {
val cursor = makeSongCursor(context, AudioColumns._ID + "=?", arrayOf(queryId.toString()))
return getSong(cursor)
}
private fun getSongFromCursorImpl(
cursor: Cursor
): Song {
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 ?: ""
)
}
): Song = Song.fromCursor(cursor)
@JvmOverloads
fun makeSongCursor(

View file

@ -139,10 +139,10 @@ object TopAndRecentlyPlayedTracksLoader {
context: Context
): ArrayList<Album> {
arrayListOf<Album>()
return ArrayList()//AlbumLoader.splitIntoAlbums(getTopTracks(context))
return AlbumLoader.splitIntoAlbums(getTopTracks(context))
}
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
import android.database.Cursor
import android.provider.MediaStore
import android.provider.MediaStore.Audio.Albums.ALBUM
import android.provider.MediaStore.Audio.Albums.ARTIST
import android.provider.MediaStore.Audio.Albums.FIRST_YEAR
import android.provider.MediaStore.Audio.Albums.NUMBER_OF_SONGS
import android.provider.MediaStore.Audio.Albums._ID
import android.provider.MediaStore.Audio.Artists.Albums.ALBUM_ID
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.loaders.getAlbumId
data class Album(
var id: Long = 0,
@ -35,14 +34,18 @@ data class Album(
companion object {
fun fromCursor(cursor: Cursor, artistId: Long = -1): Album {
return Album(
id = cursor.value(if (VersionUtils.hasQ()) ALBUM_ID else _ID),
id = cursor.value(getAlbumId()),
title = cursor.valueOrEmpty(ALBUM),
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),
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"
}
}

View file

@ -27,7 +27,7 @@ open class Song(
val duration: Long,
val data: String,
val dateModified: Long,
val albumId: Int,
val albumId: Long,
val albumName: String,
val artistId: Long,
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(
id = cursor.value(Media._ID),
albumId = cursor.value(Media.ALBUM_ID),
artistId = cursor.value(Media.ARTIST_ID),
albumId = cursor.valueOrDefault(Media.ALBUM_ID, albumId),
artistId = cursor.valueOrDefault(Media.ARTIST_ID, artistId),
albumName = cursor.valueOrEmpty(Media.ALBUM),
artistName = cursor.valueOrEmpty(Media.ARTIST),
composer = cursor.valueOrEmpty(Media.COMPOSER),
data = cursor.valueOrEmpty(Media.DATA),
dateModified = cursor.value(Media.DATE_ADDED),
dateModified = cursor.value(Media.DATE_MODIFIED),
duration = cursor.value(Media.DURATION),
title = cursor.valueOrEmpty(Media.TITLE),
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.Result
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.Artist
import code.name.monkey.retromusic.model.Song
@ -39,7 +40,7 @@ import kotlin.coroutines.CoroutineContext
*/
interface ArtistDetailsView : BaseView {
fun songs(songs: ArrayList<Song>)
fun songs(songs: List<Song>)
fun albums(albums: List<Album>)
@ -102,7 +103,7 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
override fun loadArtistSongs(artistId: Long) {
launch {
val songs = AlbumLoader.getSongsForAlbum(App.getContext(), artistId)
val songs = ArtistLoader.getSongsForArtist(App.getContext(), artistId)
withContext(Dispatchers.Main) {
view.songs(songs)
}

View file

@ -844,7 +844,7 @@ public class MusicService extends Service implements
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) {
if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue
.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();
Uri localUri = Uri.parse("content://media/external/audio/albumart");
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
@ -348,7 +348,7 @@ public class MusicUtil {
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();
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);
}
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.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId);
ActivityCompat.startActivity(activity, intent, null);

View file

@ -14,6 +14,12 @@
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.content.Context;
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.NowPlayingScreen;
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.AlbumSortOrder;
import code.name.monkey.retromusic.model.CategoryInfo;
import code.name.monkey.retromusic.transform.CascadingPageTransformer;
import code.name.monkey.retromusic.transform.DepthTransformation;
@ -365,6 +371,7 @@ public final class PreferenceUtil {
}
}
@NonNull
public String getAlbumDetailSongSortOrder() {
return mPreferences
.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);
}
@NonNull
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) {
@ -428,12 +436,12 @@ public final class PreferenceUtil {
}
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() {
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) {
@ -462,11 +470,12 @@ public final class PreferenceUtil {
}
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() {
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) {
@ -536,7 +545,7 @@ public final class PreferenceUtil {
}
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() {
@ -719,7 +728,7 @@ public final class PreferenceUtil {
}
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) {

View file

@ -2,9 +2,9 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/gradient_background"
android:background="?attr/colorSurface"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">
<LinearLayout
android:layout_width="match_parent"
@ -87,6 +87,24 @@
android:maxLines="1" />
</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
android:id="@+id/albumArtistContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"

View file

@ -85,6 +85,26 @@
android:maxLines="1" />
</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
android:id="@+id/albumArtistContainer"
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_artist" 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_desc" 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="drive_mode">Drive mode</string>
<string name="retro_music_player">Retro Music Player</string>
<string name="sort_num_songs">Number of songs</string>
</resources>

View file

@ -35,48 +35,6 @@ import java.lang.reflect.Field;
*/
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
@NonNull
public static Drawable createTintedDrawable(Context context,