Compare commits
7 commits
Author | SHA1 | Date | |
---|---|---|---|
|
3a0e130e06 | ||
|
d8dc39d293 | ||
|
102d18cd6a | ||
|
393bd59a1c | ||
|
eee663f717 | ||
|
6b959ec24a | ||
|
b922549dee |
101 changed files with 1428 additions and 1599 deletions
|
@ -22,8 +22,8 @@ android {
|
|||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
applicationId "code.name.monkey.retromusic"
|
||||
versionCode 405
|
||||
versionName '3.4.900'
|
||||
versionCode 408
|
||||
versionName '3.5.000'
|
||||
|
||||
multiDexEnabled true
|
||||
|
||||
|
@ -129,8 +129,8 @@ dependencies {
|
|||
implementation 'androidx.preference:preference:1.1.0'
|
||||
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.core:core-ktx:1.1.0'
|
||||
implementation 'androidx.fragment:fragment:1.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.2.0'
|
||||
implementation 'androidx.fragment:fragment:1.2.1'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
|
||||
implementation 'com.google.android.material:material:1.2.0-alpha04'
|
||||
|
|
|
@ -1 +1 @@
|
|||
<html>
<head>
<style type="text/css">
* {
word-wrap: break-word;
}
{style-placeholder}
a {
color: {link-color};
}
a:active {
color: {link-color-active};
}
ol {
list-style-position: inside;
padding-left: 0;
padding-right: 0;
}
li {
padding-top: 8px;
}
</style>
</head>
<body>
<h4>v3.4.900</h4>
<ul>
<li>Added playlist search</li>
<li>Added Drive mode</li>
<li>Added Album and Artist layout change option in library</li>
<li>Added Show more album and artist information in details</li>
<li>Added Pixel style scroller bar</li>
<li>Added current now playing share</li>
<li>Fix font issues and colors in some places</li>
<li>Improved Full now playing theme</li>
</ul>
<h4>v3.4.850</h4>
<ul>
<li>Added new theme called circle</li>
<li>Added tiny color card style for home artists</li>
<li>Added extra track info details to now playing themes</li>
<li>Added scroll animation</li>
<li>Added smooth transition animations 🤔</li>
<li>Added current playing tab options for Bottom Navigation View</li>
<li>Added search in genre</li>
<li>Improved selecting feedback effect(ripple with corners)</li>
<li>Fix bugs & crashes</li>
<li>Fix crashing on lyrics</li>
<li>Fix genre details last song is under mini player</li>
<li>Fix colors mistakes and font sizes</li>
<li>Fix slider jumping while scrolling in now playing themes</li>
</ul>
<h4>v3.4.800</h4>
<ul>
<li>Improved dark theme colors and Follow system theme</li>
<li>Rounded rectangle ripple for BottomNavigationView</li>
<li>Follow sleep timer dialog checkbox color as accent</li>
<li>Added song list selection for Album and Artist details</li>
<li>Fixed Toolbar popup text color when selecting songs</li>
</ul>
<h4>v3.4.700</h4>
<ul>
<li>Added splash screen(for app loading time)</li>
<li>Updated dark theme colors</li>
<li>Added circular progress view</li>
<li>Hiding year if not showing</li>
</ul>
<h4>v3.4.600</h4>
<ul>
<li>Fix notification layout height</li>
<li>Fix folder list last item not showing</li>
<li>Added auto hide/ show controls according to first and last item</li>
</ul>
<h4>v3.4.500</h4>
<ul>
<li>Added peak theme</li>
<li>Added app rating dialog</li>
<li>Fix song name scrolling in now playing themes if it's long</li>
<li>Fix playing queue last item hiding FAB</li>
<li>Added desaturated color option for dark mode</li>
<li>Fix slow search loading</li>
<li>Fix last added slow loading</li>
<li>Fix home banner toolbar corner</li>
<li>Fix home crashing when switching between two tabs</li>
<li>Fix remaining time in playing queue</li>
<li>Fix font not applied for some components</li>
<li>Fix crashing on album details sorting</li>
<li>Fixed lot of internal bugs</li>
<li>Fix dialog expand</li>
<li>Fix list card color</li>
<li>Removed SlidingUpPanel to replace with BottomSheet</li>
<li>Removed color theme as per material design guidelines</li>
<li>Removed classic theme(We're bringing back)</li>
<li>Replace line switch to Material Switch in settings</li>
<li>Performance improved</li>
<li>Updated internal libraries</li>
<li>Updated translation</li>
<li>Limiting the use of Theme engine for making use of system colors</li>
<li>Change home icon from the user icon</li>
<li>Corrected all toolbar with elevation when scrolling</li>
</ul>
<p>If you see entire app white or dark or black select same theme in settings to fix </p>
<p style="line-height:150%"><a href="https://github.com/h4h13/RetroMusicPlayer/wiki/FAQ">FAQ's</a>
</p>
<p style="line-height:150%">*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again. </p>
</body>
|
||||
<html>
<head>
<style type="text/css">
* {
word-wrap: break-word;
}
{style-placeholder}
a {
color: {link-color};
}
a:active {
color: {link-color-active};
}
ol {
list-style-position: inside;
padding-left: 0;
padding-right: 0;
}
li {
padding-top: 8px;
}
</style>
</head>
<body>
<h4>v.3.5.000</h4>
<ul>
<li>Major code refactor for Album and Artist loading</li>
</ul>
<h4>v3.4.900</h4>
<ul>
<li>Added playlist search</li>
<li>Added Drive mode</li>
<li>Added Album and Artist layout change option in library</li>
<li>Added Show more album and artist information in details</li>
<li>Added Pixel style scroller bar</li>
<li>Added current now playing share</li>
<li>Fix font issues and colors in some places</li>
<li>Improved Full now playing theme</li>
</ul>
<h4>v3.4.850</h4>
<ul>
<li>Added new theme called circle</li>
<li>Added tiny color card style for home artists</li>
<li>Added extra track info details to now playing themes</li>
<li>Added scroll animation</li>
<li>Added smooth transition animations 🤔</li>
<li>Added current playing tab options for Bottom Navigation View</li>
<li>Added search in genre</li>
<li>Improved selecting feedback effect(ripple with corners)</li>
<li>Fix bugs & crashes</li>
<li>Fix crashing on lyrics</li>
<li>Fix genre details last song is under mini player</li>
<li>Fix colors mistakes and font sizes</li>
<li>Fix slider jumping while scrolling in now playing themes</li>
</ul>
<h4>v3.4.800</h4>
<ul>
<li>Improved dark theme colors and Follow system theme</li>
<li>Rounded rectangle ripple for BottomNavigationView</li>
<li>Follow sleep timer dialog checkbox color as accent</li>
<li>Added song list selection for Album and Artist details</li>
<li>Fixed Toolbar popup text color when selecting songs</li>
</ul>
<h4>v3.4.700</h4>
<ul>
<li>Added splash screen(for app loading time)</li>
<li>Updated dark theme colors</li>
<li>Added circular progress view</li>
<li>Hiding year if not showing</li>
</ul>
<h4>v3.4.600</h4>
<ul>
<li>Fix notification layout height</li>
<li>Fix folder list last item not showing</li>
<li>Added auto hide/ show controls according to first and last item</li>
</ul>
<h4>v3.4.500</h4>
<ul>
<li>Added peak theme</li>
<li>Added app rating dialog</li>
<li>Fix song name scrolling in now playing themes if it's long</li>
<li>Fix playing queue last item hiding FAB</li>
<li>Added desaturated color option for dark mode</li>
<li>Fix slow search loading</li>
<li>Fix last added slow loading</li>
<li>Fix home banner toolbar corner</li>
<li>Fix home crashing when switching between two tabs</li>
<li>Fix remaining time in playing queue</li>
<li>Fix font not applied for some components</li>
<li>Fix crashing on album details sorting</li>
<li>Fixed lot of internal bugs</li>
<li>Fix dialog expand</li>
<li>Fix list card color</li>
<li>Removed SlidingUpPanel to replace with BottomSheet</li>
<li>Removed color theme as per material design guidelines</li>
<li>Removed classic theme(We're bringing back)</li>
<li>Replace line switch to Material Switch in settings</li>
<li>Performance improved</li>
<li>Updated internal libraries</li>
<li>Updated translation</li>
<li>Limiting the use of Theme engine for making use of system colors</li>
<li>Change home icon from the user icon</li>
<li>Corrected all toolbar with elevation when scrolling</li>
</ul>
<p>If you see entire app white or dark or black select same theme in settings to fix </p>
<p style="line-height:150%"><a href="https://github.com/h4h13/RetroMusicPlayer/wiki/FAQ">FAQ's</a>
</p>
<p style="line-height:150%">*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again. </p>
</body>
|
|
@ -31,7 +31,7 @@ object Constants {
|
|||
const val FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md"
|
||||
const val PINTEREST = "https://in.pinterest.com/retromusicapp/"
|
||||
|
||||
const val BASE_SELECTION = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"
|
||||
const val baseSelection = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"
|
||||
|
||||
val baseProjection = arrayOf(BaseColumns._ID, // 0
|
||||
MediaStore.Audio.AudioColumns.TITLE, // 1
|
||||
|
|
|
@ -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
|
||||
|
@ -27,14 +26,15 @@ import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
|||
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
|
||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||
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.mvp.presenter.AlbumDetailsPresenter
|
||||
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView
|
||||
import code.name.monkey.retromusic.rest.model.LastFmAlbum
|
||||
|
@ -48,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
|
||||
|
@ -62,7 +63,6 @@ import kotlinx.android.synthetic.main.activity_album_content.scrobbles
|
|||
import kotlinx.android.synthetic.main.activity_album_content.scrobblesLabel
|
||||
import kotlinx.android.synthetic.main.activity_album_content.shuffleAction
|
||||
import kotlinx.android.synthetic.main.activity_album_content.songTitle
|
||||
import java.util.ArrayList
|
||||
import javax.inject.Inject
|
||||
import android.util.Pair as UtilPair
|
||||
|
||||
|
@ -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: List<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
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
|||
albumDetailsPresenter.attachView(this)
|
||||
|
||||
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
||||
intent.extras?.getInt(EXTRA_ALBUM_ID)?.let {
|
||||
intent.extras?.getLong(EXTRA_ALBUM_ID)?.let {
|
||||
albumDetailsPresenter.loadAlbum(it)
|
||||
albumCoverContainer?.transitionName = "${getString(R.string.transition_album_art)}_$it"
|
||||
}
|
||||
|
@ -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,39 +185,30 @@ 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 • %s",
|
||||
album.artistName,
|
||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
|
||||
)
|
||||
albumText.text = String.format("%s", album.artist)
|
||||
} else {
|
||||
albumText.text = String.format(
|
||||
"%s • %s • %s",
|
||||
album.artistName,
|
||||
MusicUtil.getYearString(album.year),
|
||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
|
||||
)
|
||||
albumText.text = String.format("%s • %s", album.artist, MusicUtil.getYearString(album.year))
|
||||
}
|
||||
loadAlbumCover()
|
||||
simpleSongAdapter.swapDataSet(album.songs)
|
||||
albumDetailsPresenter.albumSongs(album.id)
|
||||
albumDetailsPresenter.loadMore(album.artistId)
|
||||
albumDetailsPresenter.aboutAlbum(album.artistName!!, album.title!!)
|
||||
albumDetailsPresenter.aboutAlbum(album.artist, album.title)
|
||||
}
|
||||
|
||||
override fun moreAlbums(albums: ArrayList<Album>) {
|
||||
override fun songs(songs: List<Song>) {
|
||||
this.songs = songs
|
||||
simpleSongAdapter.swapDataSet(songs)
|
||||
}
|
||||
|
||||
override fun moreAlbums(albums: List<Album>) {
|
||||
moreTitle.show()
|
||||
moreRecyclerView.show()
|
||||
moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName)
|
||||
moreTitle.text = String.format(getString(R.string.label_more_from), album.artist)
|
||||
|
||||
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
|
||||
val albumAdapter = HorizontalAlbumAdapter(this, albums, null)
|
||||
moreRecyclerView.layoutManager = GridLayoutManager(
|
||||
this,
|
||||
1,
|
||||
|
@ -250,19 +239,23 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
|||
}
|
||||
|
||||
override fun loadArtistImage(artist: Artist) {
|
||||
ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build()
|
||||
.dontAnimate().dontTransform().into(object : RetroMusicColoredTarget(artistImage) {
|
||||
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
|
||||
.generatePalette(this)
|
||||
.build()
|
||||
.dontAnimate()
|
||||
.dontTransform()
|
||||
.into(object : RetroMusicColoredTarget(artistImage) {
|
||||
override fun onColorReady(color: Int) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun loadAlbumCover() {
|
||||
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(this)
|
||||
.ignoreMediaStore(PreferenceUtil.getInstance(this).ignoreMediaStoreArtwork())
|
||||
AlbumGlideRequest.Builder(Glide.with(this), album.id)
|
||||
.generatePalette(this)
|
||||
.build().dontAnimate().dontTransform()
|
||||
.build()
|
||||
.dontAnimate()
|
||||
.dontTransform()
|
||||
.into(object : RetroMusicColoredTarget(image) {
|
||||
override fun onColorReady(color: Int) {
|
||||
setColors(color)
|
||||
|
@ -362,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()
|
||||
}
|
||||
|
@ -383,7 +378,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
|||
|
||||
private fun reload() {
|
||||
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
||||
intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) }
|
||||
intent.extras?.getLong(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) }
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
|||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||
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.mvp.presenter.ArtistDetailsPresenter
|
||||
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
||||
|
@ -57,7 +59,6 @@ import kotlinx.android.synthetic.main.activity_artist_details.artistTitle
|
|||
import kotlinx.android.synthetic.main.activity_artist_details.image
|
||||
import kotlinx.android.synthetic.main.activity_artist_details.text
|
||||
import kotlinx.android.synthetic.main.activity_artist_details.toolbar
|
||||
import java.text.DecimalFormat
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -84,6 +85,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
private var cab: MaterialCab? = null
|
||||
private var biography: Spanned? = null
|
||||
private lateinit var artist: Artist
|
||||
private lateinit var songs: List<Song>
|
||||
private lateinit var songAdapter: SimpleSongAdapter
|
||||
private lateinit var albumAdapter: HorizontalAlbumAdapter
|
||||
private var forceDownload: Boolean = false
|
||||
|
@ -118,7 +120,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
artistDetailsPresenter.attachView(this)
|
||||
|
||||
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
||||
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let {
|
||||
intent.extras?.getLong(EXTRA_ARTIST_ID)?.let {
|
||||
artistDetailsPresenter.loadArtist(it)
|
||||
val name = "${getString(R.string.transition_artist_image)}_$it"
|
||||
artistCoverContainer?.transitionName = name
|
||||
|
@ -133,10 +135,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
setupRecyclerView()
|
||||
|
||||
playAction.apply {
|
||||
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
|
||||
setOnClickListener { MusicPlayerRemote.openQueue(songs, 0, true) }
|
||||
}
|
||||
shuffleAction.apply {
|
||||
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
|
||||
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songs, true) }
|
||||
}
|
||||
|
||||
biographyText.setOnClickListener {
|
||||
|
@ -154,7 +156,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
|
||||
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), null)
|
||||
albumRecyclerView.apply {
|
||||
itemAnimator = DefaultItemAnimator()
|
||||
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
||||
|
@ -189,6 +191,15 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
ActivityCompat.startPostponedEnterTransition(this)
|
||||
}
|
||||
|
||||
override fun songs(songs: List<Song>) {
|
||||
this.songs = songs
|
||||
songAdapter.swapDataSet(songs)
|
||||
}
|
||||
|
||||
override fun albums(albums: List<Album>) {
|
||||
albumAdapter.swapDataSet(ArrayList(albums))
|
||||
}
|
||||
|
||||
override fun artist(artist: Artist) {
|
||||
complete()
|
||||
if (artist.songCount <= 0) {
|
||||
|
@ -202,13 +213,11 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
}
|
||||
artistTitle.text = artist.name
|
||||
text.text = String.format(
|
||||
"%s • %s",
|
||||
MusicUtil.getArtistInfoString(this, artist),
|
||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs))
|
||||
"%s",
|
||||
MusicUtil.getArtistInfoString(this, artist)
|
||||
)
|
||||
|
||||
songAdapter.swapDataSet(artist.songs)
|
||||
albumAdapter.swapDataSet(artist.albums!!)
|
||||
artistDetailsPresenter.loadArtistAlbums(artist.id)
|
||||
artistDetailsPresenter.loadArtistSongs(artist.id)
|
||||
}
|
||||
|
||||
private fun loadBiography(
|
||||
|
@ -281,30 +290,17 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
||||
|
||||
val toolbarColor = ATHUtil.resolveColor(this, R.attr.colorSurface)
|
||||
//status_bar.setBackgroundColor(toolbarColor)
|
||||
|
||||
toolbar.setBackgroundColor(toolbarColor)
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.title = null
|
||||
}
|
||||
|
||||
private fun numberFormat(count: Float): String {
|
||||
val prefixes = arrayOf("", "K", "M", "B", "T", "P", "E")
|
||||
var index = 0
|
||||
var finalCount = count
|
||||
while (finalCount / 1000 >= 1) {
|
||||
finalCount /= 1000
|
||||
index++
|
||||
}
|
||||
val decimal = DecimalFormat("#.##")
|
||||
return String.format("%s %s", decimal.format(finalCount), prefixes[index])
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return handleSortOrderMenuItem(item)
|
||||
}
|
||||
|
||||
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
||||
val songs = artist.songs
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
super.onBackPressed()
|
||||
|
@ -354,7 +350,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
|||
|
||||
private fun reload() {
|
||||
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
||||
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) }
|
||||
intent.extras?.getLong(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) }
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDet
|
|||
})
|
||||
}
|
||||
|
||||
override fun songs(songs: ArrayList<Song>) {
|
||||
override fun songs(songs: List<Song>) {
|
||||
songAdapter.swapDataSet(songs)
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ import code.name.monkey.retromusic.fragments.mainactivity.home.BannerHomeFragmen
|
|||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.SearchQueryHelper
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
|
||||
import code.name.monkey.retromusic.loaders.AlbumLoader
|
||||
import code.name.monkey.retromusic.loaders.ArtistLoader
|
||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.util.AppRater
|
||||
|
@ -155,14 +153,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
|||
val id = parseIdFromIntent(intent, "albumId", "album").toInt()
|
||||
if (id >= 0) {
|
||||
val position = intent.getIntExtra("position", 0)
|
||||
MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).songs!!, position, true)
|
||||
//MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).songs!!, position, true)
|
||||
handled = true
|
||||
}
|
||||
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
|
||||
val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
|
||||
if (id >= 0) {
|
||||
val position = intent.getIntExtra("position", 0)
|
||||
MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).songs, position, true)
|
||||
//MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).songs, position, true)
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +218,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
|||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
if (key == PreferenceUtil.GENERAL_THEME || key == PreferenceUtil.BLACK_THEME || key == PreferenceUtil.ADAPTIVE_COLOR_APP || key == PreferenceUtil.DOMINANT_COLOR || key == PreferenceUtil.USER_NAME || key == PreferenceUtil.TOGGLE_FULL_SCREEN || key == PreferenceUtil.TOGGLE_VOLUME || key == PreferenceUtil.ROUND_CORNERS || key == PreferenceUtil.CAROUSEL_EFFECT || key == PreferenceUtil.NOW_PLAYING_SCREEN_ID || key == PreferenceUtil.TOGGLE_GENRE || key == PreferenceUtil.BANNER_IMAGE_PATH || key == PreferenceUtil.PROFILE_IMAGE_PATH || key == PreferenceUtil.CIRCULAR_ALBUM_ART || key == PreferenceUtil.KEEP_SCREEN_ON || key == PreferenceUtil.TOGGLE_SEPARATE_LINE || key == PreferenceUtil.ALBUM_GRID_STYLE || key == PreferenceUtil.ARTIST_GRID_STYLE || key == PreferenceUtil.TOGGLE_HOME_BANNER || key == PreferenceUtil.TOGGLE_ADD_CONTROLS || key == PreferenceUtil.ALBUM_COVER_STYLE || key == PreferenceUtil.HOME_ARTIST_GRID_STYLE || key == PreferenceUtil.ALBUM_COVER_TRANSFORM || key == PreferenceUtil.DESATURATED_COLOR || key == PreferenceUtil.TAB_TEXT_MODE || key == PreferenceUtil.LIBRARY_CATEGORIES
|
||||
if (key == PreferenceUtil.GENERAL_THEME || key == PreferenceUtil.BLACK_THEME || key == PreferenceUtil.ADAPTIVE_COLOR_APP || key == PreferenceUtil.DOMINANT_COLOR || key == PreferenceUtil.USER_NAME || key == PreferenceUtil.TOGGLE_FULL_SCREEN || key == PreferenceUtil.TOGGLE_VOLUME || key == PreferenceUtil.ROUND_CORNERS || key == PreferenceUtil.CAROUSEL_EFFECT || key == PreferenceUtil.NOW_PLAYING_SCREEN_ID || key == PreferenceUtil.TOGGLE_GENRE || key == PreferenceUtil.BANNER_IMAGE_PATH || key == PreferenceUtil.PROFILE_IMAGE_PATH || key == PreferenceUtil.CIRCULAR_ALBUM_ART || key == PreferenceUtil.KEEP_SCREEN_ON || key == PreferenceUtil.TOGGLE_SEPARATE_LINE || key == PreferenceUtil.TOGGLE_HOME_BANNER || key == PreferenceUtil.TOGGLE_ADD_CONTROLS || key == PreferenceUtil.ALBUM_COVER_STYLE || key == PreferenceUtil.HOME_ARTIST_GRID_STYLE || key == PreferenceUtil.ALBUM_COVER_TRANSFORM || key == PreferenceUtil.DESATURATED_COLOR || key == PreferenceUtil.TAB_TEXT_MODE || key == PreferenceUtil.LIBRARY_CATEGORIES
|
||||
) postRecreate()
|
||||
}
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
|||
emptyText.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
override fun songs(songs: ArrayList<Song>) {
|
||||
override fun songs(songs: List<Song>) {
|
||||
adapter.swapDataSet(songs)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ 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
|
||||
|
@ -32,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
|
||||
|
@ -39,7 +40,6 @@ import kotlinx.android.synthetic.main.activity_album_tag_editor.toolbar
|
|||
import kotlinx.android.synthetic.main.activity_album_tag_editor.yearContainer
|
||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.yearTitle
|
||||
import org.jaudiotagger.tag.FieldKey
|
||||
import java.util.ArrayList
|
||||
import java.util.EnumMap
|
||||
|
||||
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||
|
@ -58,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>() {
|
||||
|
@ -115,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)
|
||||
|
@ -141,10 +146,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
deleteAlbumArt = false
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
private fun toastLoadingFailed() {
|
||||
Toast.makeText(
|
||||
this@AlbumTagEditorActivity,
|
||||
|
@ -170,21 +171,24 @@ 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)
|
||||
val songs = AlbumLoader.getSongsForAlbum(this, id)
|
||||
val paths = ArrayList<String>(songs.size)
|
||||
for (song in songs) {
|
||||
paths.add(song.data)
|
||||
}
|
||||
|
@ -207,7 +211,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val TAG: String = AlbumTagEditorActivity::class.java.simpleName
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -9,7 +9,6 @@ import code.name.monkey.retromusic.R
|
|||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
|
@ -18,11 +17,11 @@ import java.util.Locale
|
|||
|
||||
class GenreAdapter(
|
||||
private val activity: Activity,
|
||||
dataSet: ArrayList<Genre>,
|
||||
dataSet: List<Genre>,
|
||||
private val mItemLayoutRes: Int
|
||||
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
||||
|
||||
var dataSet = ArrayList<Genre>()
|
||||
var dataSet = listOf<Genre>()
|
||||
private set
|
||||
|
||||
init {
|
||||
|
@ -48,7 +47,7 @@ class GenreAdapter(
|
|||
return dataSet.size
|
||||
}
|
||||
|
||||
fun swapDataSet(list: ArrayList<Genre>) {
|
||||
fun swapDataSet(list: List<Genre>) {
|
||||
dataSet = list
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ class HomeAdapter(
|
|||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
println("ViewType ${getItemViewType(position)}")
|
||||
when (getItemViewType(position)) {
|
||||
RECENT_ALBUMS -> {
|
||||
val viewHolder = holder as AlbumViewHolder
|
||||
|
@ -121,7 +120,6 @@ class HomeAdapter(
|
|||
activity,
|
||||
list,
|
||||
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity),
|
||||
false,
|
||||
null
|
||||
)
|
||||
adapter = artistAdapter
|
||||
|
|
|
@ -9,8 +9,9 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
||||
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
|
||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
||||
|
@ -60,9 +61,18 @@ class SearchAdapter(
|
|||
ALBUM -> {
|
||||
val album = dataSet?.get(position) as Album
|
||||
holder.title?.text = album.title
|
||||
holder.text?.text = album.artistName
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity).build().into(holder.image)
|
||||
holder.text?.text = album.artist
|
||||
holder.image?.let {
|
||||
AlbumGlideRequest.Builder(Glide.with(activity), album.id)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.dontAnimate()
|
||||
.dontTransform()
|
||||
.into(object : RetroMusicColoredTarget(it) {
|
||||
override fun onColorReady(color: Int) {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
ARTIST -> {
|
||||
val artist = dataSet?.get(position) as Artist
|
||||
|
@ -134,21 +144,24 @@ class SearchAdapter(
|
|||
val item = dataSet!![adapterPosition]
|
||||
when (itemViewType) {
|
||||
ALBUM -> {
|
||||
item as Album
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||
activity,
|
||||
UtilPair.create(image, activity.getString(R.string.transition_album_art))
|
||||
)
|
||||
NavigationUtil.goToAlbumOptions(activity, (item as Album).id, options)
|
||||
NavigationUtil.goToAlbumOptions(activity, item.id, options)
|
||||
}
|
||||
ARTIST -> {
|
||||
item as Artist
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||
activity,
|
||||
UtilPair.create(image, activity.getString(R.string.transition_artist_image))
|
||||
)
|
||||
NavigationUtil.goToArtistOptions(activity, (item as Artist).id, options)
|
||||
NavigationUtil.goToArtistOptions(activity, item.id, options)
|
||||
}
|
||||
GENRE -> {
|
||||
NavigationUtil.goToGenre(activity, item as Genre)
|
||||
item as Genre
|
||||
NavigationUtil.goToGenre(activity, item)
|
||||
}
|
||||
PLAYLIST -> {
|
||||
NavigationUtil.goToPlaylistNew(activity, item as Playlist)
|
||||
|
|
|
@ -2,7 +2,6 @@ package code.name.monkey.retromusic.adapter.album
|
|||
|
||||
import android.app.ActivityOptions
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
|
@ -13,9 +12,8 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
||||
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.SortOrder
|
||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||
|
@ -29,9 +27,8 @@ import me.zhanghai.android.fastscroll.PopupTextProvider
|
|||
|
||||
open class AlbumAdapter(
|
||||
protected val activity: AppCompatActivity,
|
||||
dataSet: ArrayList<Album>,
|
||||
protected var itemLayoutRes: Int,
|
||||
usePalette: Boolean,
|
||||
dataSet: List<Album>,
|
||||
var itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?
|
||||
) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(
|
||||
activity,
|
||||
|
@ -39,28 +36,15 @@ open class AlbumAdapter(
|
|||
R.menu.menu_media_selection
|
||||
), PopupTextProvider {
|
||||
|
||||
var dataSet: ArrayList<Album>
|
||||
var dataSet: List<Album>
|
||||
protected set
|
||||
|
||||
protected var usePalette = false
|
||||
|
||||
init {
|
||||
this.dataSet = dataSet
|
||||
this.usePalette = usePalette
|
||||
this.setHasStableIds(true)
|
||||
}
|
||||
|
||||
fun useItemLayout(itemLayoutRes: Int) {
|
||||
this.itemLayoutRes = itemLayoutRes
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun usePalette(usePalette: Boolean) {
|
||||
this.usePalette = usePalette
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun swapDataSet(dataSet: ArrayList<Album>) {
|
||||
fun swapDataSet(dataSet: List<Album>) {
|
||||
this.dataSet = dataSet
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
@ -79,7 +63,7 @@ open class AlbumAdapter(
|
|||
}
|
||||
|
||||
protected open fun getAlbumText(album: Album): String? {
|
||||
return album.artistName
|
||||
return album.artist
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
|
@ -88,15 +72,6 @@ open class AlbumAdapter(
|
|||
holder.itemView.isActivated = isChecked
|
||||
holder.title?.text = getAlbumTitle(album)
|
||||
holder.text?.text = getAlbumText(album)
|
||||
holder.playSongs?.setOnClickListener {
|
||||
album.songs?.let { songs ->
|
||||
MusicPlayerRemote.openQueue(
|
||||
songs,
|
||||
0,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
loadAlbumCover(album, holder)
|
||||
}
|
||||
|
||||
|
@ -123,15 +98,12 @@ open class AlbumAdapter(
|
|||
if (holder.image == null) {
|
||||
return
|
||||
}
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
||||
AlbumGlideRequest.Builder(Glide.with(activity), album.id)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.dontAnimate()
|
||||
.dontTransform()
|
||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
super.onLoadCleared(placeholder)
|
||||
setColors(defaultFooterColor, holder)
|
||||
}
|
||||
|
||||
override fun onColorReady(color: Int) {
|
||||
setColors(color, holder)
|
||||
}
|
||||
|
@ -143,7 +115,7 @@ open class AlbumAdapter(
|
|||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return dataSet[position].id.toLong()
|
||||
return dataSet[position].id
|
||||
}
|
||||
|
||||
override fun getIdentifier(position: Int): Album? {
|
||||
|
@ -163,7 +135,7 @@ open class AlbumAdapter(
|
|||
private fun getSongList(albums: List<Album>): ArrayList<Song> {
|
||||
val songs = ArrayList<Song>()
|
||||
for (album in albums) {
|
||||
songs.addAll(album.songs!!)
|
||||
//songs.addAll(album.songs!!)
|
||||
}
|
||||
return songs
|
||||
}
|
||||
|
@ -177,7 +149,7 @@ open class AlbumAdapter(
|
|||
when (PreferenceUtil.getInstance(activity).albumSortOrder) {
|
||||
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName =
|
||||
dataSet[position].title
|
||||
SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].artistName
|
||||
SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].artist
|
||||
SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString(
|
||||
dataSet[position].year
|
||||
)
|
||||
|
|
|
@ -22,9 +22,8 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.views.MetalRecyclerViewPager
|
||||
|
@ -46,15 +45,6 @@ class AlbumFullWidthAdapter(
|
|||
val album = dataSet[position]
|
||||
holder.title?.text = getAlbumTitle(album)
|
||||
holder.text?.text = getAlbumText(album)
|
||||
holder.playSongs?.setOnClickListener {
|
||||
album.songs?.let { songs ->
|
||||
MusicPlayerRemote.openQueue(
|
||||
songs,
|
||||
0,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
loadAlbumCover(album, holder)
|
||||
}
|
||||
|
||||
|
@ -63,21 +53,32 @@ class AlbumFullWidthAdapter(
|
|||
}
|
||||
|
||||
private fun getAlbumText(album: Album): String? {
|
||||
return album.artistName
|
||||
return album.artist
|
||||
}
|
||||
|
||||
private fun loadAlbumCover(album: Album, holder: FullMetalViewHolder) {
|
||||
if (holder.image == null) {
|
||||
return
|
||||
}
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
|
||||
AlbumGlideRequest.Builder(Glide.with(activity), album.id)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.dontAnimate()
|
||||
.dontTransform()
|
||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||
override fun onColorReady(color: Int) {
|
||||
|
||||
}
|
||||
})
|
||||
/*SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||
override fun onColorReady(color: Int) {
|
||||
}
|
||||
})
|
||||
})*/
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
package code.name.monkey.retromusic.adapter.album
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import java.util.ArrayList
|
||||
|
||||
class HorizontalAlbumAdapter(
|
||||
activity: AppCompatActivity,
|
||||
dataSet: ArrayList<Album>,
|
||||
usePalette: Boolean,
|
||||
dataSet: List<Album>,
|
||||
cabHolder: CabHolder?
|
||||
) : AlbumAdapter(
|
||||
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder
|
||||
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, cabHolder
|
||||
) {
|
||||
|
||||
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
||||
|
@ -36,17 +33,14 @@ class HorizontalAlbumAdapter(
|
|||
|
||||
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
||||
if (holder.image == null) return
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
||||
AlbumGlideRequest.Builder(Glide.with(activity), album.id)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.dontAnimate()
|
||||
.dontTransform()
|
||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
super.onLoadCleared(placeholder)
|
||||
setColors(albumArtistFooterColor, holder)
|
||||
}
|
||||
|
||||
override fun onColorReady(color: Int) {
|
||||
if (usePalette) setColors(color, holder)
|
||||
else setColors(albumArtistFooterColor, holder)
|
||||
//setColors(color, holder)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -28,26 +28,20 @@ import java.util.ArrayList
|
|||
|
||||
class ArtistAdapter(
|
||||
val activity: AppCompatActivity,
|
||||
var dataSet: ArrayList<Artist>,
|
||||
var dataSet: List<Artist>,
|
||||
var itemLayoutRes: Int,
|
||||
var usePalette: Boolean,
|
||||
cabHolder: CabHolder?
|
||||
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
|
||||
activity, cabHolder, R.menu.menu_media_selection
|
||||
), PopupTextProvider {
|
||||
|
||||
fun swapDataSet(dataSet: ArrayList<Artist>) {
|
||||
fun swapDataSet(dataSet: List<Artist>) {
|
||||
this.dataSet = dataSet
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun usePalette(usePalette: Boolean) {
|
||||
this.usePalette = usePalette
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemId(position: Int): Long {
|
||||
return dataSet[position].id.toLong()
|
||||
return dataSet[position].id
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
|
@ -121,7 +115,7 @@ class ArtistAdapter(
|
|||
private fun getSongList(artists: List<Artist>): ArrayList<Song> {
|
||||
val songs = ArrayList<Song>()
|
||||
for (artist in artists) {
|
||||
songs.addAll(artist.songs) // maybe async in future?
|
||||
//songs.addAll(artist.songs) // maybe async in future?
|
||||
}
|
||||
return songs
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package code.name.monkey.retromusic.adapter.base;
|
|||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -60,8 +59,6 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
|
|||
@Nullable
|
||||
public View paletteColorContainer;
|
||||
|
||||
@Nullable
|
||||
public ImageButton playSongs;
|
||||
|
||||
@Nullable
|
||||
public RecyclerView recyclerView;
|
||||
|
@ -93,7 +90,6 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
|
|||
paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
|
||||
recyclerView = itemView.findViewById(R.id.recycler_view);
|
||||
mask = itemView.findViewById(R.id.mask);
|
||||
playSongs = itemView.findViewById(R.id.playSongs);
|
||||
dummyContainer = itemView.findViewById(R.id.dummy_view);
|
||||
|
||||
if (imageContainerCard != null) {
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.ArrayList
|
|||
|
||||
class PlaylistAdapter(
|
||||
private val activity: AppCompatActivity,
|
||||
var dataSet: ArrayList<Playlist>,
|
||||
var dataSet: List<Playlist>,
|
||||
private var itemLayoutRes: Int,
|
||||
cabHolder: CabHolder?
|
||||
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(
|
||||
|
@ -49,7 +49,7 @@ class PlaylistAdapter(
|
|||
setHasStableIds(true)
|
||||
}
|
||||
|
||||
fun swapDataSet(dataSet: ArrayList<Playlist>) {
|
||||
fun swapDataSet(dataSet: List<Playlist>) {
|
||||
this.dataSet = dataSet
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -63,7 +63,7 @@ open class PlaylistSongAdapter(
|
|||
imageContainerCard ?: image,
|
||||
"${activity.getString(R.string.transition_album_art)}_${song.albumId}"
|
||||
)
|
||||
NavigationUtil.goToAlbumOptions(activity, song.albumId, activityOptions)
|
||||
NavigationUtil.goToAlbumOptions(activity, song.albumId.toLong(), activityOptions)
|
||||
return true
|
||||
}
|
||||
return super.onSongMenuItemClick(item)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ open class SongAdapter(
|
|||
imageContainerCard ?: image,
|
||||
"${activity.getString(R.string.transition_album_art)}_${song.albumId}"
|
||||
)
|
||||
NavigationUtil.goToAlbumOptions(activity, song.albumId, activityOptions)
|
||||
NavigationUtil.goToAlbumOptions(activity, song.albumId.toLong(), activityOptions)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,11 +27,10 @@ import com.afollestad.materialdialogs.MaterialDialog
|
|||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
|
||||
|
||||
class AddToPlaylistDialog : DialogFragment() {
|
||||
|
||||
override fun onCreateDialog(
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?
|
||||
): Dialog {
|
||||
val playlists = PlaylistLoader.getAllPlaylists(requireContext())
|
||||
val playlistNames: MutableList<String> = mutableListOf()
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ import com.afollestad.materialdialogs.MaterialDialog
|
|||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import java.util.Collections
|
||||
import java.util.Comparator
|
||||
|
||||
class BlacklistFolderChooserDialog : DialogFragment() {
|
||||
|
||||
|
@ -40,7 +40,6 @@ class BlacklistFolderChooserDialog : DialogFragment() {
|
|||
private var canGoUp = false
|
||||
private var callback: FolderCallback? = null
|
||||
|
||||
|
||||
private fun contentsArray(): List<String> {
|
||||
if (parentContents == null) {
|
||||
return if (canGoUp) {
|
||||
|
@ -81,7 +80,11 @@ class BlacklistFolderChooserDialog : DialogFragment() {
|
|||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
var savedInstanceStateFinal = savedInstanceState
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
||||
ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.checkSelfPermission(
|
||||
requireActivity(),
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
return MaterialDialog(requireActivity(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||
title(R.string.md_error_label)
|
||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||
|
|
|
@ -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,36 +34,35 @@ 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
|
||||
private lateinit var actionNewPlaylistContainer: TextInputLayout
|
||||
|
||||
override fun onCreateDialog(
|
||||
savedInstanceState: Bundle?
|
||||
savedInstanceState: Bundle?
|
||||
): Dialog {
|
||||
val materialDialog = MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT))
|
||||
.show {
|
||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||
title(string.new_playlist_title)
|
||||
customView(layout.dialog_playlist)
|
||||
negativeButton(android.R.string.cancel)
|
||||
positiveButton(string.create_action) {
|
||||
if (activity == null) {
|
||||
return@positiveButton
|
||||
}
|
||||
val songs = arguments?.getParcelableArrayList<Song>("songs")
|
||||
?: return@positiveButton
|
||||
.show {
|
||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||
title(string.new_playlist_title)
|
||||
customView(layout.dialog_playlist)
|
||||
negativeButton(android.R.string.cancel)
|
||||
positiveButton(string.create_action) {
|
||||
if (activity == null) {
|
||||
return@positiveButton
|
||||
}
|
||||
val songs = arguments?.getParcelableArrayList<Song>("songs")
|
||||
?: return@positiveButton
|
||||
|
||||
if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) {
|
||||
val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString())
|
||||
if (playlistId != -1 && activity != null) {
|
||||
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true)
|
||||
}
|
||||
if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) {
|
||||
val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString())
|
||||
if (playlistId != -1 && activity != null) {
|
||||
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dialogView = materialDialog.getCustomView()
|
||||
playlistView = dialogView.findViewById(R.id.actionNewPlaylist)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.extensions
|
||||
|
||||
import android.database.Cursor
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2020-02-05.
|
||||
*/
|
||||
|
||||
fun Cursor?.forEach(
|
||||
closeAfter: Boolean = false,
|
||||
each: Cursor.() -> Unit
|
||||
) {
|
||||
if (this == null) return
|
||||
if (moveToFirst()) {
|
||||
do {
|
||||
each(this)
|
||||
} while (moveToNext())
|
||||
}
|
||||
if (closeAfter) {
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Cursor?.mapList(
|
||||
closeAfter: Boolean = false,
|
||||
mapper: Cursor.() -> T
|
||||
): MutableList<T> {
|
||||
val result = mutableListOf<T>()
|
||||
forEach(closeAfter = closeAfter) {
|
||||
result.add(mapper(this))
|
||||
}
|
||||
return result
|
||||
}
|
|
@ -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 {
|
||||
|
@ -40,9 +36,4 @@ fun View.hidden() {
|
|||
visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
fun View.showOrHide(show: Boolean) = if (show) show() else hide()
|
||||
|
||||
fun EditText.appHandleColor(): EditText {
|
||||
TintHelper.colorHandles(this, ThemeStore.accentColor(context))
|
||||
return this
|
||||
}
|
||||
fun View.showOrHide(show: Boolean) = if (show) show() else hide()
|
|
@ -10,21 +10,19 @@ enum class NowPlayingScreen constructor(
|
|||
@param:DrawableRes @field:DrawableRes val drawableResId: Int,
|
||||
val id: Int
|
||||
) {
|
||||
|
||||
NORMAL(R.string.normal, R.drawable.np_normal, 0),
|
||||
FLAT(R.string.flat, R.drawable.np_flat, 1),
|
||||
FIT(R.string.fit, R.drawable.np_fit, 12),
|
||||
TINY(R.string.tiny, R.drawable.np_tiny, 7),
|
||||
PEAK(R.string.peak, R.drawable.np_peak, 14),
|
||||
|
||||
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
|
||||
BLUR(R.string.blur, R.drawable.np_blur, 4),
|
||||
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
|
||||
CARD(R.string.card, R.drawable.np_card, 6),
|
||||
COLOR(R.string.color, R.drawable.np_color, 5),
|
||||
CIRCLE(R.string.circle, R.drawable.np_minimalistic_circle, 15),
|
||||
FIT(R.string.fit, R.drawable.np_fit, 12),
|
||||
FLAT(R.string.flat, R.drawable.np_flat, 1),
|
||||
FULL(R.string.full, R.drawable.np_full, 2),
|
||||
MATERIAL(R.string.material, R.drawable.np_material, 11),
|
||||
NORMAL(R.string.normal, R.drawable.np_normal, 0),
|
||||
PEAK(R.string.peak, R.drawable.np_peak, 14),
|
||||
PLAIN(R.string.plain, R.drawable.np_plain, 3),
|
||||
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
|
||||
TINY(R.string.tiny, R.drawable.np_tiny, 7),
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
|
|||
fun setAndSaveLayoutRes(layoutRes: Int) {
|
||||
setLayoutRes(layoutRes)
|
||||
saveLayoutRes(layoutRes)
|
||||
invalidateAdapter()
|
||||
}
|
||||
|
||||
private val maxGridSizeForList: Int
|
||||
|
@ -118,12 +119,6 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
|
|||
|
||||
protected abstract fun saveGridSizeLand(gridColumns: Int)
|
||||
|
||||
protected abstract fun saveUsePalette(usePalette: Boolean)
|
||||
|
||||
protected abstract fun loadUsePalette(): Boolean
|
||||
|
||||
protected abstract fun setUsePalette(usePalette: Boolean)
|
||||
|
||||
protected abstract fun loadLayoutRes(): Int
|
||||
|
||||
protected abstract fun saveLayoutRes(layoutRes: Int)
|
||||
|
|
|
@ -111,7 +111,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
|||
return true
|
||||
}
|
||||
R.id.action_go_to_artist -> {
|
||||
NavigationUtil.goToArtist(requireActivity(), song.artistId)
|
||||
NavigationUtil.goToArtist(requireActivity(), song.artistId.toInt())
|
||||
return true
|
||||
}
|
||||
R.id.now_playing -> {
|
||||
|
|
|
@ -41,7 +41,7 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
|||
albumsPresenter.detachView()
|
||||
}
|
||||
|
||||
override fun albums(albums: java.util.ArrayList<Album>) {
|
||||
override fun albums(albums: List<Album>) {
|
||||
adapter?.swapDataSet(albums)
|
||||
}
|
||||
|
||||
|
@ -53,21 +53,13 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
|||
}
|
||||
|
||||
override fun createAdapter(): AlbumAdapter {
|
||||
/* var itemLayoutRes = itemLayoutRes
|
||||
notifyLayoutResChanged(itemLayoutRes)
|
||||
if (itemLayoutRes != R.layout.item_list) {
|
||||
itemLayoutRes = PreferenceUtil.getInstance(requireContext()).getAlbumGridStyle(requireContext())
|
||||
}*/
|
||||
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
|
||||
return AlbumAdapter(libraryFragment.mainActivity, dataSet, itemLayoutRes(), loadUsePalette(), libraryFragment)
|
||||
}
|
||||
|
||||
public override fun loadUsePalette(): Boolean {
|
||||
return PreferenceUtil.getInstance(requireContext()).albumColoredFooters()
|
||||
}
|
||||
|
||||
override fun setUsePalette(usePalette: Boolean) {
|
||||
adapter?.usePalette(usePalette)
|
||||
return AlbumAdapter(
|
||||
libraryFragment.mainActivity,
|
||||
dataSet,
|
||||
itemLayoutRes(),
|
||||
libraryFragment
|
||||
)
|
||||
}
|
||||
|
||||
override fun setGridSize(gridSize: Int) {
|
||||
|
@ -99,10 +91,6 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
|||
PreferenceUtil.getInstance(requireContext()).setAlbumGridSizeLand(gridColumns)
|
||||
}
|
||||
|
||||
override fun saveUsePalette(usePalette: Boolean) {
|
||||
PreferenceUtil.getInstance(requireContext()).setAlbumColoredFooters(usePalette)
|
||||
}
|
||||
|
||||
override fun onMediaStoreChanged() {
|
||||
albumsPresenter.loadAlbums()
|
||||
}
|
||||
|
@ -116,7 +104,6 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
|||
}
|
||||
|
||||
override fun setLayoutRes(layoutRes: Int) {
|
||||
//adapter?.itemCount?.let { adapter?.notifyItemRangeChanged(0, it) }
|
||||
}
|
||||
|
||||
override fun loadLayoutRes(): Int {
|
||||
|
|
|
@ -16,7 +16,7 @@ import javax.inject.Inject
|
|||
class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(),
|
||||
ArtistsView {
|
||||
|
||||
override fun artists(artists: ArrayList<Artist>) {
|
||||
override fun artists(artists: List<Artist>) {
|
||||
adapter?.swapDataSet(artists)
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,6 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
|
|||
libraryFragment.mainActivity,
|
||||
dataSet,
|
||||
itemLayoutRes(),
|
||||
loadUsePalette(),
|
||||
libraryFragment
|
||||
)
|
||||
}
|
||||
|
@ -87,18 +86,6 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
|
|||
PreferenceUtil.getInstance(requireContext()).setArtistGridSizeLand(gridColumns)
|
||||
}
|
||||
|
||||
override fun saveUsePalette(usePalette: Boolean) {
|
||||
PreferenceUtil.getInstance(requireContext()).setArtistColoredFooters(usePalette)
|
||||
}
|
||||
|
||||
public override fun loadUsePalette(): Boolean {
|
||||
return PreferenceUtil.getInstance(requireContext()).artistColoredFooters()
|
||||
}
|
||||
|
||||
override fun setUsePalette(usePalette: Boolean) {
|
||||
adapter?.usePalette(usePalette)
|
||||
}
|
||||
|
||||
override fun setGridSize(gridSize: Int) {
|
||||
layoutManager?.spanCount = gridSize
|
||||
adapter?.notifyDataSetChanged()
|
||||
|
@ -121,9 +108,7 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
|
|||
val TAG: String = ArtistsFragment::class.java.simpleName
|
||||
|
||||
fun newInstance(): ArtistsFragment {
|
||||
|
||||
val args = Bundle()
|
||||
|
||||
val fragment = ArtistsFragment()
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
|
|
|
@ -26,14 +26,12 @@ import code.name.monkey.retromusic.mvp.presenter.GenresPresenter
|
|||
import code.name.monkey.retromusic.mvp.presenter.GenresView
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(), GenresView {
|
||||
override fun genres(genres: ArrayList<Genre>) {
|
||||
override fun genres(genres: List<Genre>) {
|
||||
adapter?.swapDataSet(genres)
|
||||
}
|
||||
|
||||
override fun showEmptyView() {
|
||||
|
||||
}
|
||||
|
||||
override fun createLayoutManager(): LinearLayoutManager {
|
||||
|
@ -48,11 +46,9 @@ class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearL
|
|||
override val emptyMessage: Int
|
||||
get() = R.string.no_genres
|
||||
|
||||
|
||||
@Inject
|
||||
lateinit var genresPresenter: GenresPresenter
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
App.musicComponent.inject(this)
|
||||
|
@ -62,6 +58,7 @@ class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearL
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
genresPresenter.attachView(this)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (adapter!!.dataSet.isEmpty()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -63,7 +63,7 @@ class PlaylistsFragment : AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, L
|
|||
adapter?.swapDataSet(ArrayList())
|
||||
}
|
||||
|
||||
override fun playlists(playlists: ArrayList<Playlist>) {
|
||||
override fun playlists(playlists: List<Playlist>) {
|
||||
adapter?.swapDataSet(playlists)
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -49,7 +49,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
|
|||
)
|
||||
}
|
||||
|
||||
override fun songs(songs: ArrayList<Song>) {
|
||||
override fun songs(songs: List<Song>) {
|
||||
adapter?.swapDataSet(songs)
|
||||
}
|
||||
|
||||
|
@ -73,17 +73,6 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
|
|||
PreferenceUtil.getInstance(requireContext()).setSongGridSizeLand(gridColumns)
|
||||
}
|
||||
|
||||
public override fun saveUsePalette(usePalette: Boolean) {
|
||||
PreferenceUtil.getInstance(requireContext()).setSongColoredFooters(usePalette)
|
||||
}
|
||||
|
||||
public override fun loadUsePalette(): Boolean {
|
||||
return PreferenceUtil.getInstance(requireContext()).songColoredFooters()
|
||||
}
|
||||
|
||||
public override fun setUsePalette(usePalette: Boolean) {
|
||||
}
|
||||
|
||||
override fun setGridSize(gridSize: Int) {
|
||||
adapter?.notifyDataSetChanged()
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ class BlurPlayerFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPrefer
|
|||
private fun updateBlur() {
|
||||
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
|
||||
colorBackground!!.clearColorFilter()
|
||||
colorBackground?.clearColorFilter()
|
||||
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
||||
.checkIgnoreMediaStore(requireContext())
|
||||
.generatePalette(requireContext()).build()
|
||||
|
@ -109,7 +109,7 @@ class BlurPlayerFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPrefer
|
|||
.into(object : RetroMusicColoredTarget(colorBackground) {
|
||||
override fun onColorReady(color: Int) {
|
||||
if (color == defaultFooterColor) {
|
||||
colorBackground!!.setColorFilter(color)
|
||||
colorBackground?.setColorFilter(color)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -13,9 +13,9 @@ import code.name.monkey.retromusic.R
|
|||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
||||
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||
import code.name.monkey.retromusic.glide.BlurTransformation
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
|
@ -53,7 +53,7 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
|
|||
override fun onColorChanged(color: Int) {
|
||||
playbackControlsFragment.setDark(color)
|
||||
lastColor = color
|
||||
callbacks!!.onPaletteColorChanged()
|
||||
callbacks?.onPaletteColorChanged()
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||
|
||||
playerToolbar.setTitleTextColor(Color.WHITE)
|
||||
|
@ -127,10 +127,19 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
|
|||
}
|
||||
|
||||
private fun updateBlur() {
|
||||
colorBackground?.clearColorFilter()
|
||||
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
|
||||
colorBackground!!.clearColorFilter()
|
||||
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
||||
AlbumGlideRequest.Builder.from(Glide.with(requireContext()), MusicPlayerRemote.currentSong.albumId)
|
||||
.generatePalette(requireContext())
|
||||
.build()
|
||||
.transform(BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()).build())
|
||||
.into(object : RetroMusicColoredTarget(colorBackground) {
|
||||
override fun onColorReady(color: Int) {
|
||||
}
|
||||
})
|
||||
//colorBackground?.clearColorFilter()
|
||||
/*SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
||||
.checkIgnoreMediaStore(requireContext())
|
||||
.generatePalette(requireContext()).build()
|
||||
.transform(BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()).build())
|
||||
|
@ -138,11 +147,9 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
|
|||
//.override(320, 480)
|
||||
.into(object : RetroMusicColoredTarget(colorBackground) {
|
||||
override fun onColorReady(color: Int) {
|
||||
if (color == defaultFooterColor) {
|
||||
colorBackground!!.setColorFilter(color)
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
})*/
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
@ -18,8 +18,8 @@ import code.name.monkey.retromusic.model.Song
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import code.name.monkey.retromusic.views.DrawableGradient
|
||||
import kotlinx.android.synthetic.main.fragment_player.*
|
||||
|
||||
import kotlinx.android.synthetic.main.fragment_player.colorGradientBackground
|
||||
import kotlinx.android.synthetic.main.fragment_player.playerToolbar
|
||||
|
||||
class PlayerFragment : AbsPlayerFragment() {
|
||||
|
||||
|
@ -30,18 +30,21 @@ class PlayerFragment : AbsPlayerFragment() {
|
|||
private lateinit var playbackControlsFragment: PlayerPlaybackControlsFragment
|
||||
private var valueAnimator: ValueAnimator? = null
|
||||
|
||||
|
||||
private fun colorize(i: Int) {
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator?.cancel()
|
||||
}
|
||||
|
||||
valueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), ATHUtil.resolveColor(requireContext(), R.attr.colorSurface), i)
|
||||
valueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), lastColor, i)
|
||||
valueAnimator?.addUpdateListener { animation ->
|
||||
if (isAdded) {
|
||||
val drawable = DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
intArrayOf(animation.animatedValue as Int,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)), 0)
|
||||
val drawable = DrawableGradient(
|
||||
GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
intArrayOf(
|
||||
animation.animatedValue as Int,
|
||||
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)
|
||||
), 0
|
||||
)
|
||||
colorGradientBackground?.background = drawable
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +73,11 @@ class PlayerFragment : AbsPlayerFragment() {
|
|||
lastColor = color
|
||||
callbacks?.onPaletteColorChanged()
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.colorControlNormal), requireActivity())
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
ATHUtil.resolveColor(context, R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
|
||||
if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) {
|
||||
colorize(color)
|
||||
|
@ -88,9 +95,10 @@ class PlayerFragment : AbsPlayerFragment() {
|
|||
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
|
||||
return inflater.inflate(R.layout.fragment_player, container, false)
|
||||
}
|
||||
|
@ -101,19 +109,24 @@ class PlayerFragment : AbsPlayerFragment() {
|
|||
setUpPlayerToolbar()
|
||||
}
|
||||
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
|
||||
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playbackControlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
|
||||
val playerAlbumCoverFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playerAlbumCoverFragment.setCallbacks(this)
|
||||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener {requireActivity().onBackPressed() }
|
||||
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.colorControlNormal), requireActivity())
|
||||
ToolbarContentTintHelper.colorizeToolbar(
|
||||
playerToolbar,
|
||||
ATHUtil.resolveColor(context, R.attr.colorControlNormal),
|
||||
requireActivity()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.glide
|
||||
|
||||
import android.R.anim
|
||||
import android.content.Context
|
||||
import code.name.monkey.retromusic.R.drawable
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import com.bumptech.glide.BitmapRequestBuilder
|
||||
import com.bumptech.glide.DrawableTypeRequest
|
||||
import com.bumptech.glide.RequestManager
|
||||
import com.bumptech.glide.load.Key
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy.NONE
|
||||
import com.bumptech.glide.signature.MediaStoreSignature
|
||||
|
||||
/**
|
||||
* Created by hemanths on 2020-02-05.
|
||||
*/
|
||||
|
||||
class AlbumGlideRequest {
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_DISK_CACHE_STRATEGY = NONE
|
||||
private const val DEFAULT_ERROR_IMAGE = drawable.default_album_art
|
||||
private const val DEFAULT_ANIMATION = anim.fade_in
|
||||
|
||||
private fun createBaseRequest(
|
||||
requestManager: RequestManager,
|
||||
albumId: Long
|
||||
): DrawableTypeRequest<*> =
|
||||
requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(albumId))
|
||||
|
||||
private fun createSignature(albumId: Long): Key? {
|
||||
return MediaStoreSignature("", albumId, 0)
|
||||
}
|
||||
}
|
||||
|
||||
class Builder(val requestManager: RequestManager, val albumId: Long) {
|
||||
companion object {
|
||||
fun from(requestManager: RequestManager, albumId: Long): Builder {
|
||||
return Builder(requestManager, albumId)
|
||||
}
|
||||
}
|
||||
|
||||
fun generatePalette(context: Context): PaletteBuilder {
|
||||
return PaletteBuilder(this, context)
|
||||
}
|
||||
}
|
||||
|
||||
class PaletteBuilder(private val builder: Builder, private val context: Context) {
|
||||
|
||||
fun build(): BitmapRequestBuilder<out Any, BitmapPaletteWrapper> =
|
||||
createBaseRequest(builder.requestManager, builder.albumId)
|
||||
.asBitmap()
|
||||
.transcode(BitmapPaletteTranscoder(context), BitmapPaletteWrapper::class.java)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(builder.albumId))
|
||||
}
|
||||
}
|
|
@ -20,11 +20,9 @@ import code.name.monkey.appthemehelper.util.ATHUtil
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
import com.bumptech.glide.request.animation.GlideAnimation
|
||||
|
||||
|
||||
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
|
||||
|
||||
protected val defaultFooterColor: Int
|
||||
|
@ -40,15 +38,17 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
|
|||
onColorReady(defaultFooterColor)
|
||||
}
|
||||
|
||||
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
|
||||
override fun onResourceReady(
|
||||
resource: BitmapPaletteWrapper?,
|
||||
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?
|
||||
) {
|
||||
super.onResourceReady(resource, glideAnimation)
|
||||
val defaultColor = defaultFooterColor
|
||||
|
||||
resource?.let {
|
||||
onColorReady(if (PreferenceUtil.getInstance(getView().context).isDominantColor)
|
||||
RetroColorUtil.getDominantColor(it.bitmap, defaultColor)
|
||||
else
|
||||
RetroColorUtil.getColor(it.palette, defaultColor))
|
||||
onColorReady(
|
||||
RetroColorUtil.getColor(it.palette, defaultColor)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@ import android.graphics.Bitmap;
|
|||
import androidx.palette.graphics.Palette;
|
||||
|
||||
public class BitmapPaletteWrapper {
|
||||
|
||||
private final Bitmap mBitmap;
|
||||
|
||||
private final Palette mPalette;
|
||||
|
||||
public BitmapPaletteWrapper(Bitmap bitmap, Palette palette) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -91,7 +91,7 @@ object SongMenuHelper {
|
|||
return true
|
||||
}
|
||||
R.id.action_go_to_artist -> {
|
||||
NavigationUtil.goToArtist(activity, song.artistId)
|
||||
NavigationUtil.goToArtist(activity, song.artistId.toInt())
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,89 +15,136 @@
|
|||
package code.name.monkey.retromusic.loaders
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.MediaStore.Audio.AudioColumns
|
||||
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.model.Album
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
import android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI as SONGS_URI
|
||||
|
||||
/**
|
||||
* Created by hemanths on 11/08/17.
|
||||
*/
|
||||
|
||||
object AlbumLoader {
|
||||
object AlbumLoader {
|
||||
|
||||
fun getAlbums(
|
||||
context: Context,
|
||||
query: String
|
||||
): ArrayList<Album> {
|
||||
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
|
||||
context,
|
||||
AudioColumns.ALBUM + " LIKE ?",
|
||||
arrayOf("%$query%"),
|
||||
getSongLoaderSortOrder(context))
|
||||
fun getAllAlbums(context: Context): List<Album> {
|
||||
return makeAlbumCursor(context, null, null)
|
||||
.mapList(true) {
|
||||
Album.fromCursor(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAlbum(context: Context, id: Long): Album {
|
||||
return getAlbum(makeAlbumCursor(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> {
|
||||
return makeAlbumForArtistCursor(context, artistId).mapList(true) {
|
||||
Album.fromCursor(this, artistId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeAlbumForArtistCursor(context: Context, artistId: Long): Cursor? {
|
||||
if (artistId == -1L) {
|
||||
return null
|
||||
}
|
||||
return context.contentResolver.query(
|
||||
MediaStore.Audio.Artists.Albums.getContentUri("external", artistId),
|
||||
arrayOf(
|
||||
getAlbumId(),
|
||||
"album",
|
||||
"artist",
|
||||
"numsongs",
|
||||
"minyear"
|
||||
),
|
||||
null,
|
||||
null,
|
||||
DEFAULT_SORT_ORDER
|
||||
)
|
||||
return splitIntoAlbums(songs)
|
||||
}
|
||||
|
||||
fun getAlbum(
|
||||
context: Context,
|
||||
albumId: Int
|
||||
): Album {
|
||||
val songs = SongLoader.getSongs(
|
||||
SongLoader.makeSongCursor(
|
||||
context,
|
||||
AudioColumns.ALBUM_ID + "=?",
|
||||
arrayOf(albumId.toString()),
|
||||
getSongLoaderSortOrder(context)))
|
||||
val album = Album(songs)
|
||||
sortSongsByTrackNumber(album)
|
||||
return album
|
||||
private fun getAlbum(cursor: Cursor?): Album {
|
||||
return cursor?.use {
|
||||
if (cursor.moveToFirst()) {
|
||||
Album.fromCursor(cursor)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} ?: Album()
|
||||
}
|
||||
|
||||
fun getAllAlbums(
|
||||
context: Context
|
||||
): ArrayList<Album> {
|
||||
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, null, null, getSongLoaderSortOrder(context)))
|
||||
return splitIntoAlbums(songs)
|
||||
private fun makeAlbumCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? {
|
||||
return context.contentResolver.query(
|
||||
EXTERNAL_CONTENT_URI,
|
||||
arrayOf(
|
||||
getAlbumId(),
|
||||
"album", "artist",
|
||||
"artist_id",
|
||||
"numsongs",
|
||||
"minyear"
|
||||
),
|
||||
selection,
|
||||
paramArrayOfString,
|
||||
PreferenceUtil.getInstance(context).albumSortOrder
|
||||
)
|
||||
}
|
||||
|
||||
private fun makeAlbumSongCursor(context: Context, albumID: Long): Cursor? {
|
||||
val selection = "is_music=1 AND title != '' AND album_id=$albumID"
|
||||
return context.contentResolver.query(
|
||||
SONGS_URI,
|
||||
baseProjection,
|
||||
selection,
|
||||
null,
|
||||
PreferenceUtil.getInstance(context).albumDetailSongSortOrder
|
||||
)
|
||||
}
|
||||
|
||||
fun splitIntoAlbums(
|
||||
songs: ArrayList<Song>?
|
||||
songs: ArrayList<Song>?
|
||||
): ArrayList<Album> {
|
||||
val albums = ArrayList<Album>()
|
||||
if (songs != null) {
|
||||
for (song in songs) {
|
||||
getOrCreateAlbum(albums, song.albumId).songs?.add(song)
|
||||
getOrCreateAlbum(albums, song)
|
||||
}
|
||||
}
|
||||
for (album in albums) {
|
||||
sortSongsByTrackNumber(album)
|
||||
}
|
||||
return albums
|
||||
}
|
||||
|
||||
private fun getOrCreateAlbum(
|
||||
albums: ArrayList<Album>,
|
||||
albumId: Int
|
||||
albums: ArrayList<Album>,
|
||||
song: Song
|
||||
): Album {
|
||||
for (album in albums) {
|
||||
if (album.songs!!.isNotEmpty() && album.songs[0].albumId == albumId) {
|
||||
if (album.id == song.albumId) {
|
||||
return album
|
||||
}
|
||||
}
|
||||
val album = Album()
|
||||
val album = Album.fromSong(song)
|
||||
albums.add(album)
|
||||
return album
|
||||
}
|
||||
|
||||
private fun sortSongsByTrackNumber(album: Album) {
|
||||
album.songs?.sortWith(Comparator { o1, o2 -> o1.trackNumber.compareTo(o2.trackNumber) })
|
||||
}
|
||||
|
||||
private fun getSongLoaderSortOrder(context: Context): String {
|
||||
return PreferenceUtil.getInstance(context).albumSortOrder + ", " + PreferenceUtil.getInstance(context).albumSongSortOrder
|
||||
fun getAlbums(context: Context, paramString: String): List<Album> {
|
||||
return makeAlbumCursor(context, "album LIKE ?", arrayOf("$paramString%"))
|
||||
.mapList(true) { Album.fromCursor(this) }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
}
|
|
@ -15,64 +15,107 @@
|
|||
package code.name.monkey.retromusic.loaders
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.MediaStore.Audio.AudioColumns
|
||||
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.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(AlbumLoader.splitIntoAlbums(songs))
|
||||
return getArtists(makeArtistCursor(context, null, 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(AlbumLoader.splitIntoAlbums(songs))
|
||||
fun getArtist(context: Context, artistId: Long): Artist {
|
||||
return getArtist(makeArtistCursor(context, "_id=?", arrayOf(artistId.toString())))
|
||||
}
|
||||
|
||||
fun splitIntoArtists(albums: ArrayList<Album>?): ArrayList<Artist> {
|
||||
private fun getArtist(cursor: Cursor?): Artist {
|
||||
return cursor?.use {
|
||||
if (cursor.moveToFirst()) {
|
||||
Artist.fromCursor(cursor)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} ?: Artist()
|
||||
}
|
||||
|
||||
fun getArtists(context: Context, paramString: String): List<Artist> {
|
||||
return makeArtistCursor(context, "artist LIKE ?", arrayOf("$paramString%"))
|
||||
.mapList(true) {
|
||||
Artist.fromCursor(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getArtists(cursor: Cursor?): ArrayList<Artist> {
|
||||
val artists = ArrayList<Artist>()
|
||||
if (albums != null) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
do {
|
||||
artists.add(getArtistFromCursor(cursor))
|
||||
} while (cursor.moveToNext())
|
||||
}
|
||||
return artists
|
||||
}
|
||||
|
||||
private fun getArtistFromCursor(cursor: Cursor): Artist {
|
||||
return Artist.fromCursor(cursor)
|
||||
}
|
||||
|
||||
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"
|
||||
),
|
||||
selection,
|
||||
paramArrayOfString,
|
||||
PreferenceUtil.getInstance(context).artistSortOrder
|
||||
)
|
||||
}
|
||||
|
||||
fun getSongsForArtist(context: Context, artistId: Long): List<Song> {
|
||||
return makeArtistSongCursor(context, artistId)
|
||||
.mapList(true) { Song.fromCursor(this, artistId = artistId) }
|
||||
}
|
||||
|
||||
private fun makeArtistSongCursor(context: Context, artistId: Long): Cursor? {
|
||||
val artistSongSortOrder = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
|
||||
val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
||||
val selection = "is_music=1 AND title != '' AND artist_id=$artistId"
|
||||
return context.contentResolver.query(
|
||||
uri,
|
||||
baseProjection,
|
||||
selection,
|
||||
null,
|
||||
artistSongSortOrder
|
||||
)
|
||||
}
|
||||
|
||||
fun splitIntoArtists(albums: ArrayList<Album>): ArrayList<Artist> {
|
||||
val artists = ArrayList<Artist>()
|
||||
if (albums.isNotEmpty()) {
|
||||
for (album in albums) {
|
||||
getOrCreateArtist(artists, album.artistId).albums!!.add(album)
|
||||
getOrCreateArtist(artists, album)
|
||||
}
|
||||
}
|
||||
return artists
|
||||
}
|
||||
|
||||
private fun getOrCreateArtist(artists: ArrayList<Artist>, artistId: Int): Artist {
|
||||
private fun getOrCreateArtist(artists: ArrayList<Artist>, album: Album): Artist {
|
||||
for (artist in artists) {
|
||||
if (artist.albums!!.isNotEmpty() && artist.albums[0].songs!!.isNotEmpty() && artist.albums[0].songs!![0].artistId == artistId) {
|
||||
if (artist.id == album.artistId) {
|
||||
return artist
|
||||
}
|
||||
}
|
||||
val album = Artist()
|
||||
artists.add(album)
|
||||
return album
|
||||
val a = Artist.fromAlbum(album)
|
||||
artists.add(a)
|
||||
return a
|
||||
}
|
||||
|
||||
fun getArtist(context: Context, artistId: Int): Artist {
|
||||
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
|
||||
context,
|
||||
AudioColumns.ARTIST_ID + "=?",
|
||||
arrayOf(artistId.toString()),
|
||||
getSongLoaderSortOrder(context))
|
||||
)
|
||||
return Artist(AlbumLoader.splitIntoAlbums(songs))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ import android.database.Cursor
|
|||
import android.net.Uri
|
||||
import android.provider.BaseColumns
|
||||
import android.provider.MediaStore.Audio.Genres
|
||||
import code.name.monkey.retromusic.Constants.BASE_SELECTION
|
||||
import code.name.monkey.retromusic.Constants.baseSelection
|
||||
import code.name.monkey.retromusic.Constants.baseProjection
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
|
@ -94,7 +94,7 @@ object GenreLoader {
|
|||
try {
|
||||
return context.contentResolver.query(
|
||||
Genres.Members.getContentUri("external", genreId.toLong()),
|
||||
baseProjection, BASE_SELECTION, null, PreferenceUtil.getInstance(context).songSortOrder)
|
||||
baseProjection, baseSelection, null, PreferenceUtil.getInstance(context).songSortOrder)
|
||||
} catch (e: SecurityException) {
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -36,10 +36,11 @@ object LastAddedSongsLoader {
|
|||
val cutoff = PreferenceUtil.getInstance(context).lastAddedCutoff
|
||||
|
||||
return SongLoader.makeSongCursor(
|
||||
context,
|
||||
MediaStore.Audio.Media.DATE_ADDED + ">?",
|
||||
arrayOf(cutoff.toString()),
|
||||
MediaStore.Audio.Media.DATE_ADDED + " DESC")
|
||||
context,
|
||||
MediaStore.Audio.Media.DATE_ADDED + ">?",
|
||||
arrayOf(cutoff.toString()),
|
||||
MediaStore.Audio.Media.DATE_ADDED + " DESC"
|
||||
)
|
||||
}
|
||||
|
||||
fun getLastAddedAlbums(context: Context): ArrayList<Album> {
|
||||
|
|
|
@ -18,7 +18,7 @@ import android.content.Context
|
|||
import android.database.Cursor
|
||||
import android.provider.MediaStore
|
||||
import android.provider.MediaStore.Audio.AudioColumns
|
||||
import code.name.monkey.retromusic.Constants.BASE_SELECTION
|
||||
import code.name.monkey.retromusic.Constants.baseSelection
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.PlaylistSong
|
||||
|
@ -104,7 +104,7 @@ object PlaylistSongsLoader {
|
|||
MediaStore.Audio.Playlists.Members._ID,//11
|
||||
AudioColumns.COMPOSER
|
||||
)// 12
|
||||
, BASE_SELECTION, null,
|
||||
, baseSelection, null,
|
||||
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER
|
||||
)
|
||||
} catch (e: SecurityException) {
|
||||
|
|
|
@ -18,10 +18,9 @@ import android.content.Context
|
|||
import android.database.Cursor
|
||||
import android.provider.MediaStore
|
||||
import android.provider.MediaStore.Audio.AudioColumns
|
||||
import code.name.monkey.retromusic.Constants.BASE_SELECTION
|
||||
import code.name.monkey.retromusic.Constants.baseProjection
|
||||
import code.name.monkey.retromusic.Constants.baseSelection
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.providers.BlacklistStore
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import java.util.ArrayList
|
||||
|
||||
|
@ -61,7 +60,7 @@ object SongLoader {
|
|||
return getSongs(cursor)
|
||||
}
|
||||
|
||||
fun getSong(
|
||||
private fun getSong(
|
||||
cursor: Cursor?
|
||||
): Song {
|
||||
val song: Song
|
||||
|
@ -75,98 +74,79 @@ 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.getInt(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.getInt(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)
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun makeSongCursor(
|
||||
context: Context,
|
||||
selection: String?,
|
||||
selectionValues: Array<String>?,
|
||||
selectionString: String?,
|
||||
selectionValuesArray: Array<String>?,
|
||||
sortOrder: String = PreferenceUtil.getInstance(context).songSortOrder
|
||||
): Cursor? {
|
||||
var selectionFinal = selection
|
||||
var selectionValuesFinal = selectionValues
|
||||
selectionFinal = if (selection != null && selection.trim { it <= ' ' } != "") {
|
||||
"$BASE_SELECTION AND $selectionFinal"
|
||||
): Cursor {
|
||||
var selectionValues: Array<String>? = arrayOf()
|
||||
var selection = if (selectionString != null && selectionString.trim() != "") {
|
||||
"$baseSelection AND $selectionString"
|
||||
} else {
|
||||
BASE_SELECTION
|
||||
baseSelection
|
||||
}
|
||||
|
||||
// Blacklist
|
||||
val paths = BlacklistStore.getInstance(context).paths
|
||||
/*val paths = BlacklistStore.getInstance(context).paths
|
||||
if (paths.isNotEmpty()) {
|
||||
selectionFinal = generateBlacklistSelection(selectionFinal, paths.size)
|
||||
selectionValuesFinal = addBlacklistSelectionValues(selectionValuesFinal, paths)
|
||||
selection = generateBlacklistSelection(selection, paths.size)
|
||||
selectionValues = addBlacklistSelectionValues(selectionValuesArray, paths)
|
||||
}*/
|
||||
if (PreferenceUtil.getInstance(context).filterLength != 0) {
|
||||
selection =
|
||||
"$selection AND ${MediaStore.Audio.Media.DURATION} >= ${PreferenceUtil.getInstance(context).filterLength * 1000}"
|
||||
}
|
||||
|
||||
try {
|
||||
return context.contentResolver.query(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
baseProjection,
|
||||
selectionFinal + " AND " + MediaStore.Audio.Media.DURATION + ">= " + (PreferenceUtil.getInstance(
|
||||
context
|
||||
).filterLength * 1000),
|
||||
selectionValuesFinal,
|
||||
sortOrder
|
||||
)
|
||||
} catch (e: SecurityException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateBlacklistSelection(
|
||||
selection: String?,
|
||||
pathCount: Int
|
||||
): String {
|
||||
val newSelection = StringBuilder(
|
||||
if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "")
|
||||
newSelection.append(AudioColumns.DATA + " NOT LIKE ?")
|
||||
for (i in 0 until pathCount - 1) {
|
||||
newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?")
|
||||
}
|
||||
return newSelection.toString()
|
||||
}
|
||||
|
||||
private fun addBlacklistSelectionValues(
|
||||
selectionValues: Array<String>?,
|
||||
paths: ArrayList<String>
|
||||
): Array<String>? {
|
||||
var selectionValuesFinal = selectionValues
|
||||
if (selectionValuesFinal == null) {
|
||||
selectionValuesFinal = emptyArray()
|
||||
}
|
||||
val newSelectionValues = Array(selectionValuesFinal.size + paths.size) {
|
||||
"n = $it"
|
||||
}
|
||||
System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size)
|
||||
for (i in selectionValuesFinal.size until newSelectionValues.size) {
|
||||
newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%"
|
||||
}
|
||||
return newSelectionValues
|
||||
return context.contentResolver.query(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||
baseProjection,
|
||||
selection,
|
||||
selectionValuesArray,
|
||||
sortOrder
|
||||
)
|
||||
?: throw IllegalStateException("Unable to query ${MediaStore.Audio.Media.EXTERNAL_CONTENT_URI}, system returned null.")
|
||||
}
|
||||
}
|
||||
|
||||
fun generateBlacklistSelection(
|
||||
selection: String?,
|
||||
pathCount: Int
|
||||
): String {
|
||||
val newSelection = StringBuilder(
|
||||
if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "")
|
||||
newSelection.append(AudioColumns.DATA + " NOT LIKE ?")
|
||||
for (i in 0 until pathCount - 1) {
|
||||
newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?")
|
||||
}
|
||||
return newSelection.toString()
|
||||
}
|
||||
|
||||
fun addBlacklistSelectionValues(
|
||||
selectionValues: Array<String>?,
|
||||
paths: ArrayList<String>
|
||||
): Array<String>? {
|
||||
var selectionValuesFinal = selectionValues
|
||||
if (selectionValuesFinal == null) {
|
||||
selectionValuesFinal = emptyArray()
|
||||
}
|
||||
val newSelectionValues = Array(selectionValuesFinal.size + paths.size) {
|
||||
"n = $it"
|
||||
}
|
||||
System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size)
|
||||
for (i in selectionValuesFinal.size until newSelectionValues.size) {
|
||||
newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%"
|
||||
}
|
||||
return newSelectionValues
|
||||
}
|
|
@ -143,6 +143,6 @@ object TopAndRecentlyPlayedTracksLoader {
|
|||
}
|
||||
|
||||
fun getTopArtists(context: Context): ArrayList<Artist> {
|
||||
return ArtistLoader.splitIntoArtists(getTopAlbums(context))
|
||||
return ArtistLoader.splitIntoArtists(getTopAlbums(context))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.misc
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.loaders.AlbumLoader
|
||||
import code.name.monkey.retromusic.loaders.ArtistLoader
|
||||
import code.name.monkey.retromusic.loaders.SongLoader
|
||||
import java.util.*
|
||||
|
||||
internal class AsyncSearchResultLoader(context: Context, private val query: String) : WrappedAsyncTaskLoader<List<Any>>(context) {
|
||||
|
||||
override fun loadInBackground(): List<Any>? {
|
||||
val results = ArrayList<Any>()
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
val songs = SongLoader.getSongs(context, query.trim { it <= ' ' })
|
||||
if (!songs.isEmpty()) {
|
||||
results.add(context.resources.getString(R.string.songs))
|
||||
results.addAll(songs)
|
||||
}
|
||||
|
||||
val artists = ArtistLoader.getArtists(context, query.trim { it <= ' ' })
|
||||
if (!artists.isEmpty()) {
|
||||
results.add(context.resources.getString(R.string.artists))
|
||||
results.addAll(artists)
|
||||
}
|
||||
|
||||
val albums = AlbumLoader.getAlbums(context, query.trim { it <= ' ' })
|
||||
if (!albums.isEmpty()) {
|
||||
results.add(context.resources.getString(R.string.albums))
|
||||
results.addAll(albums)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
}
|
|
@ -14,41 +14,72 @@
|
|||
|
||||
package code.name.monkey.retromusic.model
|
||||
|
||||
import java.util.ArrayList
|
||||
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 code.name.monkey.retromusic.loaders.getAlbumId
|
||||
|
||||
class Album {
|
||||
val songs: ArrayList<Song>?
|
||||
data class Album(
|
||||
var id: Long = 0,
|
||||
var title: String = "",
|
||||
var artist: String = "",
|
||||
var artistId: Long = 0,
|
||||
var songCount: Int = 0,
|
||||
var year: Int = 0
|
||||
) {
|
||||
|
||||
val id: Int
|
||||
get() = safeGetFirstSong().albumId
|
||||
companion object {
|
||||
fun fromCursor(cursor: Cursor, artistId: Long = -1): Album {
|
||||
return Album(
|
||||
id = cursor.value(getAlbumId()),
|
||||
title = cursor.valueOrEmpty(ALBUM),
|
||||
artist = cursor.valueOrEmpty(ARTIST),
|
||||
artistId = if (artistId == -1L) cursor.value(MediaStore.Audio.AudioColumns.ARTIST_ID) else artistId,
|
||||
songCount = cursor.value(NUMBER_OF_SONGS),
|
||||
year = cursor.value(FIRST_YEAR)
|
||||
)
|
||||
}
|
||||
|
||||
val title: String?
|
||||
get() = safeGetFirstSong().albumName
|
||||
|
||||
val artistId: Int
|
||||
get() = safeGetFirstSong().artistId
|
||||
|
||||
val artistName: String?
|
||||
get() = safeGetFirstSong().artistName
|
||||
|
||||
val year: Int
|
||||
get() = safeGetFirstSong().year
|
||||
|
||||
val dateModified: Long
|
||||
get() = safeGetFirstSong().dateModified
|
||||
|
||||
val songCount: Int
|
||||
get() = songs!!.size
|
||||
|
||||
constructor(songs: ArrayList<Song>) {
|
||||
this.songs = songs
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.songs = ArrayList()
|
||||
}
|
||||
|
||||
fun safeGetFirstSong(): Song {
|
||||
return if (songs!!.isEmpty()) Song.emptySong else songs[0]
|
||||
fun fromSong(song: Song): Album {
|
||||
return Album(song.albumId, song.albumName, song.artistName, song.artistId, -1, song.year)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Cursor.valueOrEmpty(name: String): String = valueOrDefault(name, "")
|
||||
|
||||
inline fun <reified T> Cursor.value(name: String): T {
|
||||
val index = getColumnIndexOrThrow(name)
|
||||
return when (T::class) {
|
||||
Short::class -> getShort(index) as T
|
||||
Int::class -> getInt(index) as T
|
||||
Long::class -> getLong(index) as T
|
||||
Boolean::class -> (getInt(index) == 1) as T
|
||||
String::class -> getString(index) as T
|
||||
Float::class -> getFloat(index) as T
|
||||
Double::class -> getDouble(index) as T
|
||||
ByteArray::class -> getBlob(index) as T
|
||||
else -> throw IllegalStateException("What do I do with ${T::class.java.simpleName}?")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> Cursor.valueOrDefault(name: String, defaultValue: T): T {
|
||||
val index = getColumnIndex(name)
|
||||
if (index == -1) {
|
||||
return defaultValue
|
||||
}
|
||||
return when (T::class) {
|
||||
Short::class -> getShort(index) as? T ?: defaultValue
|
||||
Int::class -> getInt(index) as? T ?: defaultValue
|
||||
Long::class -> getLong(index) as? T ?: defaultValue
|
||||
Boolean::class -> (getInt(index) == 1) as T
|
||||
String::class -> getString(index) as? T ?: defaultValue
|
||||
Float::class -> getFloat(index) as? T ?: defaultValue
|
||||
Double::class -> getDouble(index) as? T ?: defaultValue
|
||||
ByteArray::class -> getBlob(index) as? T ?: defaultValue
|
||||
else -> throw IllegalStateException("What do I do with ${T::class.java.simpleName}?")
|
||||
}
|
||||
}
|
|
@ -14,57 +14,34 @@
|
|||
|
||||
package code.name.monkey.retromusic.model
|
||||
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import java.util.ArrayList
|
||||
import android.database.Cursor
|
||||
import android.provider.MediaStore.Audio.Artists.ARTIST
|
||||
import android.provider.MediaStore.Audio.Artists.NUMBER_OF_ALBUMS
|
||||
import android.provider.MediaStore.Audio.Artists.NUMBER_OF_TRACKS
|
||||
import android.provider.MediaStore.Audio.Artists._ID
|
||||
|
||||
class Artist {
|
||||
val albums: ArrayList<Album>?
|
||||
|
||||
val id: Int
|
||||
get() = safeGetFirstAlbum().artistId
|
||||
|
||||
val name: String
|
||||
get() {
|
||||
val name = safeGetFirstAlbum().artistName
|
||||
return if (MusicUtil.isArtistNameUnknown(name)) {
|
||||
UNKNOWN_ARTIST_DISPLAY_NAME
|
||||
} else name!!
|
||||
}
|
||||
|
||||
val songCount: Int
|
||||
get() {
|
||||
var songCount = 0
|
||||
for (album in albums!!) {
|
||||
songCount += album.songCount
|
||||
}
|
||||
return songCount
|
||||
}
|
||||
|
||||
val albumCount: Int
|
||||
get() = albums!!.size
|
||||
|
||||
val songs: ArrayList<Song>
|
||||
get() {
|
||||
val songs = ArrayList<Song>()
|
||||
for (album in albums!!) {
|
||||
songs.addAll(album.songs!!)
|
||||
}
|
||||
return songs
|
||||
}
|
||||
|
||||
constructor(albums: ArrayList<Album>) {
|
||||
this.albums = albums
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.albums = ArrayList()
|
||||
}
|
||||
|
||||
fun safeGetFirstAlbum(): Album {
|
||||
return if (albums!!.isEmpty()) Album() else albums[0]
|
||||
}
|
||||
class Artist(
|
||||
var id: Long = 0,
|
||||
var name: String = "",
|
||||
var songCount: Int = 0,
|
||||
var albumCount: Int = 0
|
||||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
fun fromCursor(cursor: Cursor): Artist {
|
||||
return Artist(
|
||||
id = cursor.value(_ID),
|
||||
name = cursor.value(ARTIST),
|
||||
songCount = cursor.value(NUMBER_OF_TRACKS),
|
||||
albumCount = cursor.value(NUMBER_OF_ALBUMS)
|
||||
)
|
||||
}
|
||||
|
||||
fun fromAlbum(album: Album): Artist {
|
||||
return Artist(album.artistId, album.artist, -1, -1)
|
||||
}
|
||||
|
||||
const val UNKNOWN_ARTIST_DISPLAY_NAME = "Unknown Artist"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,21 +13,23 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.model
|
||||
|
||||
import android.database.Cursor
|
||||
import android.os.Parcelable
|
||||
import android.provider.MediaStore.Audio.Media
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
open class Song(
|
||||
val id: Int,
|
||||
val id: Long,
|
||||
val title: String,
|
||||
val trackNumber: Int,
|
||||
val year: Int,
|
||||
val duration: Long,
|
||||
val data: String,
|
||||
val dateModified: Long,
|
||||
val albumId: Int,
|
||||
val albumId: Long,
|
||||
val albumName: String,
|
||||
val artistId: Int,
|
||||
val artistId: Long,
|
||||
val artistName: String,
|
||||
val composer: String?
|
||||
) : Parcelable {
|
||||
|
@ -49,5 +51,22 @@ open class Song(
|
|||
"",
|
||||
""
|
||||
)
|
||||
|
||||
fun fromCursor(cursor: Cursor, albumId: Long = -1, artistId: Long = -1): Song {
|
||||
return Song(
|
||||
id = cursor.value(Media._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_MODIFIED),
|
||||
duration = cursor.value(Media.DURATION),
|
||||
title = cursor.valueOrEmpty(Media.TITLE),
|
||||
trackNumber = cursor.value(Media.TRACK),
|
||||
year = cursor.value(Media.YEAR)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ package code.name.monkey.retromusic.mvp.presenter
|
|||
import code.name.monkey.retromusic.Result.Success
|
||||
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.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
|
@ -36,21 +37,24 @@ interface AlbumDetailsView {
|
|||
|
||||
fun album(album: Album)
|
||||
|
||||
fun songs(songs: List<Song>)
|
||||
|
||||
fun complete()
|
||||
|
||||
fun loadArtistImage(artist: Artist)
|
||||
|
||||
fun moreAlbums(
|
||||
albums: ArrayList<Album>
|
||||
)
|
||||
fun moreAlbums(albums: List<Album>)
|
||||
|
||||
fun aboutAlbum(lastFmAlbum: LastFmAlbum)
|
||||
}
|
||||
|
||||
interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
|
||||
fun loadAlbum(albumId: Int)
|
||||
fun loadAlbum(albumId: Long)
|
||||
|
||||
fun albumSongs(albumId: Long)
|
||||
|
||||
fun loadMore(artistId: Long)
|
||||
|
||||
fun loadMore(artistId: Int)
|
||||
fun aboutAlbum(artist: String, album: String)
|
||||
|
||||
class AlbumDetailsPresenterImpl @Inject constructor(
|
||||
|
@ -60,7 +64,7 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
|
|||
private val job = Job()
|
||||
private lateinit var album: Album
|
||||
|
||||
override fun loadMore(artistId: Int) {
|
||||
override fun loadMore(artistId: Long) {
|
||||
launch {
|
||||
when (val result = repository.artistById(artistId)) {
|
||||
is Success -> withContext(Dispatchers.Main) { showArtistImage(result.data) }
|
||||
|
@ -80,13 +84,9 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
|
|||
|
||||
private fun showArtistImage(artist: Artist) {
|
||||
view?.loadArtistImage(artist)
|
||||
|
||||
artist.albums?.filter { it.id != album.id }?.let {
|
||||
if (it.isNotEmpty()) view?.moreAlbums(ArrayList(it))
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadAlbum(albumId: Int) {
|
||||
override fun loadAlbum(albumId: Long) {
|
||||
launch {
|
||||
when (val result = repository.albumById(albumId)) {
|
||||
is Success -> withContext(Dispatchers.Main) {
|
||||
|
@ -98,6 +98,15 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
|
|||
}
|
||||
}
|
||||
|
||||
override fun albumSongs(albumId: Long) {
|
||||
launch {
|
||||
when (val result = repository.albumSongsById(albumId)) {
|
||||
is Success -> withContext(Dispatchers.Main) { view.songs(result.data) }
|
||||
is Error -> withContext(Dispatchers.Main) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun detachView() {
|
||||
super.detachView()
|
||||
job.cancel()
|
||||
|
|
|
@ -25,7 +25,6 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.ArrayList
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
|
@ -33,35 +32,37 @@ import kotlin.coroutines.CoroutineContext
|
|||
* Created by hemanths on 12/08/17.
|
||||
*/
|
||||
interface AlbumsView : BaseView {
|
||||
fun albums(albums: ArrayList<Album>)
|
||||
|
||||
fun albums(albums: List<Album>)
|
||||
}
|
||||
|
||||
interface AlbumsPresenter : Presenter<AlbumsView> {
|
||||
|
||||
fun loadAlbums()
|
||||
fun loadAlbums()
|
||||
|
||||
class AlbumsPresenterImpl @Inject constructor(
|
||||
class AlbumsPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<AlbumsView>(), AlbumsPresenter, CoroutineScope {
|
||||
private val job = Job()
|
||||
) : PresenterImpl<AlbumsView>(), AlbumsPresenter, CoroutineScope {
|
||||
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = Dispatchers.IO + job
|
||||
private val job = Job()
|
||||
|
||||
override fun detachView() {
|
||||
super.detachView()
|
||||
job.cancel()
|
||||
}
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = Dispatchers.IO + job
|
||||
|
||||
override fun loadAlbums() {
|
||||
launch {
|
||||
when (val result = repository.allAlbums()) {
|
||||
is Result.Success -> withContext(Dispatchers.Main) {
|
||||
view?.albums(result.data)
|
||||
}
|
||||
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun detachView() {
|
||||
super.detachView()
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
override fun loadAlbums() {
|
||||
launch {
|
||||
when (val result = repository.allAlbums()) {
|
||||
is Result.Success -> withContext(Dispatchers.Main) {
|
||||
view?.albums(result.data)
|
||||
}
|
||||
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,8 +14,10 @@
|
|||
|
||||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.Result
|
||||
import code.name.monkey.retromusic.Result.Success
|
||||
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.mvp.BaseView
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
|
@ -35,14 +37,24 @@ import kotlin.coroutines.CoroutineContext
|
|||
*/
|
||||
interface ArtistDetailsView : BaseView {
|
||||
|
||||
fun songs(songs: List<Song>)
|
||||
|
||||
fun albums(albums: List<Album>)
|
||||
|
||||
fun artist(artist: Artist)
|
||||
|
||||
fun artistInfo(lastFmArtist: LastFmArtist?)
|
||||
|
||||
fun complete()
|
||||
}
|
||||
|
||||
interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
|
||||
|
||||
fun loadArtist(artistId: Int)
|
||||
fun loadArtist(artistId: Long)
|
||||
|
||||
fun loadArtistSongs(artistId: Long)
|
||||
|
||||
fun loadArtistAlbums(artistId: Long)
|
||||
|
||||
fun loadBiography(
|
||||
name: String,
|
||||
|
@ -62,26 +74,35 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
|
|||
override fun loadBiography(name: String, lang: String?, cache: String?) {
|
||||
launch {
|
||||
when (val result = repository.artistInfo(name, lang, cache)) {
|
||||
is Result.Success -> withContext(Dispatchers.Main) {
|
||||
view?.artistInfo(result.data)
|
||||
}
|
||||
is Result.Error -> withContext(Dispatchers.Main) {
|
||||
|
||||
}
|
||||
is Success -> withContext(Dispatchers.Main) { view?.artistInfo(result.data) }
|
||||
is Error -> withContext(Dispatchers.Main) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadArtist(artistId: Int) {
|
||||
override fun loadArtist(artistId: Long) {
|
||||
launch {
|
||||
when (val result = repository.artistById(artistId)) {
|
||||
is Result.Success -> withContext(Dispatchers.Main) {
|
||||
view?.artist(result.data)
|
||||
is Success -> withContext(Dispatchers.Main) { view?.artist(result.data) }
|
||||
is Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is Result.Error -> withContext(Dispatchers.Main) {
|
||||
view?.showEmptyView()
|
||||
}
|
||||
override fun loadArtistSongs(artistId: Long) {
|
||||
launch {
|
||||
when (val result = repository.artistSongsById(artistId)) {
|
||||
is Success -> withContext(Dispatchers.Main) { view.songs(result.data) }
|
||||
is Error -> withContext(Dispatchers.Main) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadArtistAlbums(artistId: Long) {
|
||||
launch {
|
||||
when (val result = repository.artistAlbumsById(artistId)) {
|
||||
is Success -> withContext(Dispatchers.Main) { view.albums(result.data) }
|
||||
is Error -> withContext(Dispatchers.Main) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,16 @@ import code.name.monkey.retromusic.mvp.BaseView
|
|||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
interface ArtistsView : BaseView {
|
||||
fun artists(artists: ArrayList<Artist>)
|
||||
fun artists(artists: List<Artist>)
|
||||
}
|
||||
|
||||
interface ArtistsPresenter : Presenter<ArtistsView> {
|
||||
|
@ -33,8 +37,9 @@ interface ArtistsPresenter : Presenter<ArtistsView> {
|
|||
fun loadArtists()
|
||||
|
||||
class ArtistsPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<ArtistsView>(), ArtistsPresenter, CoroutineScope {
|
||||
|
||||
private val job = Job()
|
||||
|
||||
override val coroutineContext: CoroutineContext
|
||||
|
|
|
@ -20,26 +20,30 @@ import code.name.monkey.retromusic.mvp.BaseView
|
|||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
interface GenreDetailsView : BaseView {
|
||||
fun songs(songs: ArrayList<Song>)
|
||||
|
||||
fun songs(songs: List<Song>)
|
||||
}
|
||||
|
||||
interface GenreDetailsPresenter : Presenter<GenreDetailsView> {
|
||||
fun loadGenreSongs(genreId: Int)
|
||||
|
||||
class GenreDetailsPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<GenreDetailsView>(), GenreDetailsPresenter, CoroutineScope {
|
||||
|
||||
private val job = Job()
|
||||
|
||||
override val coroutineContext: CoroutineContext
|
||||
|
@ -50,7 +54,6 @@ interface GenreDetailsPresenter : Presenter<GenreDetailsView> {
|
|||
job.cancel()
|
||||
}
|
||||
|
||||
|
||||
override fun loadGenreSongs(genreId: Int) {
|
||||
launch {
|
||||
when (val result = repository.getGenre(genreId)) {
|
||||
|
|
|
@ -20,8 +20,11 @@ import code.name.monkey.retromusic.mvp.BaseView
|
|||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
|
@ -29,15 +32,17 @@ import kotlin.coroutines.CoroutineContext
|
|||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
interface GenresView : BaseView {
|
||||
fun genres(genres: ArrayList<Genre>)
|
||||
|
||||
fun genres(genres: List<Genre>)
|
||||
}
|
||||
|
||||
interface GenresPresenter : Presenter<GenresView> {
|
||||
fun loadGenres()
|
||||
|
||||
class GenresPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<GenresView>(), GenresPresenter, CoroutineScope {
|
||||
|
||||
private val job = Job()
|
||||
|
||||
override val coroutineContext: CoroutineContext
|
||||
|
|
|
@ -16,19 +16,25 @@ package code.name.monkey.retromusic.mvp.presenter
|
|||
|
||||
import code.name.monkey.retromusic.Result
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.mvp.*
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 19/08/17.
|
||||
*/
|
||||
|
||||
interface PlaylistView : BaseView {
|
||||
fun playlists(playlists: ArrayList<Playlist>)
|
||||
|
||||
fun playlists(playlists: List<Playlist>)
|
||||
}
|
||||
|
||||
interface PlaylistsPresenter : Presenter<PlaylistView> {
|
||||
|
@ -36,7 +42,7 @@ interface PlaylistsPresenter : Presenter<PlaylistView> {
|
|||
fun playlists()
|
||||
|
||||
class PlaylistsPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter, CoroutineScope {
|
||||
|
||||
private val job = Job()
|
||||
|
|
|
@ -15,10 +15,17 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.Result
|
||||
import code.name.monkey.retromusic.model.*
|
||||
import code.name.monkey.retromusic.mvp.*
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
|
@ -26,14 +33,15 @@ import kotlin.coroutines.CoroutineContext
|
|||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
interface PlaylistSongsView : BaseView {
|
||||
fun songs(songs: ArrayList<Song>)
|
||||
|
||||
fun songs(songs: List<Song>)
|
||||
}
|
||||
|
||||
interface PlaylistSongsPresenter : Presenter<PlaylistSongsView> {
|
||||
fun loadPlaylistSongs(playlist: Playlist)
|
||||
|
||||
class PlaylistSongsPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<PlaylistSongsView>(), PlaylistSongsPresenter, CoroutineScope {
|
||||
|
||||
private var job: Job = Job()
|
||||
|
|
|
@ -16,10 +16,14 @@ package code.name.monkey.retromusic.mvp.presenter
|
|||
|
||||
import code.name.monkey.retromusic.Result
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.*
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
|
@ -27,36 +31,37 @@ import kotlin.coroutines.CoroutineContext
|
|||
* Created by hemanths on 10/08/17.
|
||||
*/
|
||||
interface SongView {
|
||||
fun songs(songs: ArrayList<Song>)
|
||||
|
||||
fun showEmptyView()
|
||||
fun songs(songs: List<Song>)
|
||||
|
||||
fun showEmptyView()
|
||||
}
|
||||
|
||||
interface SongPresenter : Presenter<SongView> {
|
||||
fun loadSongs()
|
||||
class SongPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
|
||||
fun loadSongs()
|
||||
class SongPresenterImpl @Inject constructor(
|
||||
private val repository: Repository
|
||||
) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
|
||||
|
||||
private var job: Job = Job()
|
||||
private var job: Job = Job()
|
||||
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = Dispatchers.IO + job
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = Dispatchers.IO + job
|
||||
|
||||
override fun loadSongs() {
|
||||
launch {
|
||||
when (val songs = repository.allSongs()) {
|
||||
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
|
||||
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun loadSongs() {
|
||||
launch {
|
||||
when (val songs = repository.allSongs()) {
|
||||
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
|
||||
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun detachView() {
|
||||
super.detachView()
|
||||
job.cancel();
|
||||
}
|
||||
}
|
||||
override fun detachView() {
|
||||
super.detachView()
|
||||
job.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,7 +41,12 @@ class BlacklistPreference : ATEDialogPreference {
|
|||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr,
|
||||
defStyleRes
|
||||
)
|
||||
|
||||
init {
|
||||
icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN)
|
||||
|
@ -55,23 +60,23 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val blacklistFolderChooserDialog = childFragmentManager.findFragmentByTag("FOLDER_CHOOSER") as BlacklistFolderChooserDialog?
|
||||
val blacklistFolderChooserDialog =
|
||||
childFragmentManager.findFragmentByTag("FOLDER_CHOOSER") as BlacklistFolderChooserDialog?
|
||||
blacklistFolderChooserDialog?.setCallback(this)
|
||||
refreshBlacklistData()
|
||||
return MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||
title(code.name.monkey.retromusic.R.string.blacklist)
|
||||
title(R.string.blacklist)
|
||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||
positiveButton(android.R.string.ok) {
|
||||
dismiss()
|
||||
}
|
||||
neutralButton(text = getString(R.string.clear_action)) {
|
||||
MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||
title(code.name.monkey.retromusic.R.string.clear_blacklist)
|
||||
message(code.name.monkey.retromusic.R.string.do_you_want_to_clear_the_blacklist)
|
||||
title(R.string.clear_blacklist)
|
||||
message(R.string.do_you_want_to_clear_the_blacklist)
|
||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||
positiveButton(code.name.monkey.retromusic.R.string.clear_action) {
|
||||
positiveButton(R.string.clear_action) {
|
||||
BlacklistStore.getInstance(context).clear()
|
||||
refreshBlacklistData()
|
||||
}
|
||||
|
@ -81,13 +86,20 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
|
|||
negativeButton(R.string.add_action) {
|
||||
val dialog = BlacklistFolderChooserDialog.create()
|
||||
dialog.setCallback(this@BlacklistPreferenceDialog)
|
||||
dialog.show(childFragmentManager, "FOLDER_CHOOSER");
|
||||
dialog.show(childFragmentManager, "FOLDER_CHOOSER")
|
||||
}
|
||||
listItems(items = paths, waitForPositiveButton = false) { _, _, text ->
|
||||
MaterialDialog(context, BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||
MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||
title(code.name.monkey.retromusic.R.string.remove_from_blacklist)
|
||||
message(text = Html.fromHtml(getString(code.name.monkey.retromusic.R.string.do_you_want_to_remove_from_the_blacklist, text)))
|
||||
title(R.string.remove_from_blacklist)
|
||||
message(
|
||||
text = Html.fromHtml(
|
||||
getString(
|
||||
R.string.do_you_want_to_remove_from_the_blacklist,
|
||||
text
|
||||
)
|
||||
)
|
||||
)
|
||||
positiveButton(code.name.monkey.retromusic.R.string.remove_action) {
|
||||
BlacklistStore.getInstance(context).removePath(File(text.toString()))
|
||||
refreshBlacklistData()
|
||||
|
@ -108,7 +120,7 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
|
|||
}
|
||||
|
||||
override fun onFolderSelection(dialog: BlacklistFolderChooserDialog, folder: File) {
|
||||
BlacklistStore.getInstance(context!!).addPath(folder);
|
||||
refreshBlacklistData();
|
||||
BlacklistStore.getInstance(context!!).addPath(folder)
|
||||
refreshBlacklistData()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package code.name.monkey.retromusic.preferences
|
|||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.PorterDuff
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
|
@ -30,8 +31,12 @@ import androidx.viewpager.widget.PagerAdapter
|
|||
import androidx.viewpager.widget.ViewPager
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
|
@ -42,18 +47,23 @@ import com.bumptech.glide.Glide
|
|||
|
||||
class NowPlayingScreenPreference : ATEDialogPreference {
|
||||
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr,
|
||||
defStyleRes
|
||||
)
|
||||
|
||||
private val mLayoutRes = R.layout.preference_dialog_now_playing_screen
|
||||
|
||||
override fun getDialogLayoutResource(): Int {
|
||||
return mLayoutRes;
|
||||
return mLayoutRes
|
||||
}
|
||||
|
||||
init {
|
||||
|
@ -66,11 +76,9 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
|
|||
private var viewPagerPosition: Int = 0
|
||||
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
|
@ -78,13 +86,12 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
|
|||
}
|
||||
|
||||
override fun onDialogClosed(positiveResult: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val view = LayoutInflater.from(activity).inflate(R.layout.preference_dialog_now_playing_screen, null)
|
||||
val viewPager = view.findViewById<ViewPager>(R.id.now_playing_screen_view_pager)
|
||||
?: throw IllegalStateException("Dialog view must contain a ViewPager with id 'now_playing_screen_view_pager'")
|
||||
?: throw IllegalStateException("Dialog view must contain a ViewPager with id 'now_playing_screen_view_pager'")
|
||||
viewPager.adapter = NowPlayingScreenAdapter(activity!!)
|
||||
viewPager.addOnPageChangeListener(this)
|
||||
viewPager.pageMargin = ViewUtil.convertDpToPixel(32f, resources).toInt()
|
||||
|
@ -109,24 +116,6 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
|
|||
}
|
||||
}
|
||||
|
||||
private fun isNowPlayingThemes(nowPlayingScreen: NowPlayingScreen): Boolean {
|
||||
if (nowPlayingScreen == NowPlayingScreen.BLUR_CARD) {
|
||||
PreferenceUtil.getInstance(requireContext()).resetCarouselEffect()
|
||||
PreferenceUtil.getInstance(requireContext()).resetCircularAlbumArt()
|
||||
}
|
||||
|
||||
return (nowPlayingScreen == NowPlayingScreen.FULL ||
|
||||
nowPlayingScreen == NowPlayingScreen.CARD ||
|
||||
nowPlayingScreen == NowPlayingScreen.PLAIN ||
|
||||
nowPlayingScreen == NowPlayingScreen.BLUR ||
|
||||
nowPlayingScreen == NowPlayingScreen.COLOR ||
|
||||
nowPlayingScreen == NowPlayingScreen.SIMPLE ||
|
||||
nowPlayingScreen == NowPlayingScreen.BLUR_CARD ||
|
||||
nowPlayingScreen == NowPlayingScreen.CIRCLE ||
|
||||
nowPlayingScreen == NowPlayingScreen.ADAPTIVE)
|
||||
&& !App.isProVersion()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(key: String): NowPlayingScreenPreferenceDialog {
|
||||
val bundle = Bundle()
|
||||
|
@ -138,7 +127,7 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
|
|||
}
|
||||
}
|
||||
|
||||
private class NowPlayingScreenAdapter internal constructor(private val context: Context) : PagerAdapter() {
|
||||
private class NowPlayingScreenAdapter(private val context: Context) : PagerAdapter() {
|
||||
|
||||
override fun instantiateItem(collection: ViewGroup, position: Int): Any {
|
||||
val nowPlayingScreen = NowPlayingScreen.values()[position]
|
||||
|
@ -148,16 +137,26 @@ private class NowPlayingScreenAdapter internal constructor(private val context:
|
|||
collection.addView(layout)
|
||||
|
||||
val image = layout.findViewById<ImageView>(R.id.image)
|
||||
val proText = layout.findViewById<TextView>(R.id.proText)
|
||||
val title = layout.findViewById<TextView>(R.id.title)
|
||||
Glide.with(context).load(nowPlayingScreen.drawableResId).into(image)
|
||||
title.setText(nowPlayingScreen.titleRes)
|
||||
|
||||
if (isNowPlayingThemes(nowPlayingScreen)) {
|
||||
proText.show()
|
||||
} else {
|
||||
proText.hide()
|
||||
}
|
||||
val color = ThemeStore.accentColor(context)
|
||||
proText.backgroundTintList = ColorStateList.valueOf(color)
|
||||
proText.setTextColor(MaterialValueHelper.getPrimaryTextColor(context,ColorUtil.isColorLight(color)))
|
||||
return layout
|
||||
}
|
||||
|
||||
override fun destroyItem(collection: ViewGroup,
|
||||
position: Int,
|
||||
view: Any) {
|
||||
override fun destroyItem(
|
||||
collection: ViewGroup,
|
||||
position: Int,
|
||||
view: Any
|
||||
) {
|
||||
collection.removeView(view as View)
|
||||
}
|
||||
|
||||
|
@ -172,4 +171,19 @@ private class NowPlayingScreenAdapter internal constructor(private val context:
|
|||
override fun getPageTitle(position: Int): CharSequence? {
|
||||
return context.getString(NowPlayingScreen.values()[position].titleRes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isNowPlayingThemes(nowPlayingScreen: NowPlayingScreen): Boolean {
|
||||
return (nowPlayingScreen == NowPlayingScreen.FULL ||
|
||||
nowPlayingScreen == NowPlayingScreen.CARD ||
|
||||
nowPlayingScreen == NowPlayingScreen.PLAIN ||
|
||||
nowPlayingScreen == NowPlayingScreen.BLUR ||
|
||||
nowPlayingScreen == NowPlayingScreen.COLOR ||
|
||||
nowPlayingScreen == NowPlayingScreen.SIMPLE ||
|
||||
nowPlayingScreen == NowPlayingScreen.BLUR_CARD ||
|
||||
nowPlayingScreen == NowPlayingScreen.CIRCLE ||
|
||||
nowPlayingScreen == NowPlayingScreen.ADAPTIVE ||
|
||||
nowPlayingScreen == NowPlayingScreen.MATERIAL ||
|
||||
nowPlayingScreen == NowPlayingScreen.PEAK)
|
||||
&& !App.isProVersion()
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ import javax.inject.Inject
|
|||
|
||||
class RepositoryImpl @Inject constructor(private val context: Context) : Repository {
|
||||
|
||||
override suspend fun allAlbums(): Result<ArrayList<Album>> {
|
||||
override suspend fun allAlbums(): Result<List<Album>> {
|
||||
return try {
|
||||
val albums = AlbumLoader.getAllAlbums(context)
|
||||
if (albums.isNotEmpty()) {
|
||||
|
@ -58,14 +58,37 @@ class RepositoryImpl @Inject constructor(private val context: Context) : Reposit
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun albumById(albumId: Int): Result<Album> {
|
||||
override suspend fun albumById(albumId: Long): Result<Album> {
|
||||
return try {
|
||||
val album = AlbumLoader.getAlbum(context, albumId)
|
||||
if (album != null) {
|
||||
Success(album)
|
||||
} else {
|
||||
Error(Throwable("No album"))
|
||||
}
|
||||
Success(album)
|
||||
} catch (e: Exception) {
|
||||
Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun albumSongsById(albumId: Long): Result<List<Song>> {
|
||||
return try {
|
||||
val songs = AlbumLoader.getSongsForAlbum(context, albumId)
|
||||
Success(songs)
|
||||
} catch (e: Exception) {
|
||||
Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun artistSongsById(artistId: Long): Result<List<Song>> {
|
||||
return try {
|
||||
val songs = ArtistLoader.getSongsForArtist(context, artistId)
|
||||
Success(songs)
|
||||
} catch (e: Exception) {
|
||||
Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun artistAlbumsById(artistId: Long): Result<List<Album>> {
|
||||
return try {
|
||||
val albums = AlbumLoader.getAlbumsForArtist(context, artistId)
|
||||
Success(albums)
|
||||
} catch (e: Exception) {
|
||||
Error(e)
|
||||
}
|
||||
|
@ -289,7 +312,7 @@ class RepositoryImpl @Inject constructor(private val context: Context) : Reposit
|
|||
errorMessage = "Error"
|
||||
)
|
||||
|
||||
override suspend fun artistById(artistId: Int): Result<Artist> {
|
||||
override suspend fun artistById(artistId: Long): Result<Artist> {
|
||||
return try {
|
||||
val artist = ArtistLoader.getArtist(context, artistId)
|
||||
return Success(artist)
|
||||
|
|
|
@ -30,23 +30,29 @@ import code.name.monkey.retromusic.rest.model.LastFmArtist
|
|||
|
||||
interface Repository {
|
||||
|
||||
suspend fun allAlbums(): Result<ArrayList<Album>>
|
||||
suspend fun allAlbums(): Result<List<Album>>
|
||||
|
||||
suspend fun albumById(albumId: Int): Result<Album>
|
||||
suspend fun albumById(albumId: Long): Result<Album>
|
||||
|
||||
suspend fun allSongs(): Result<ArrayList<Song>>
|
||||
suspend fun albumSongsById(albumId: Long): Result<List<Song>>
|
||||
|
||||
suspend fun allArtists(): Result<ArrayList<Artist>>
|
||||
suspend fun artistSongsById(artistId: Long): Result<List<Song>>
|
||||
|
||||
suspend fun allPlaylists(): Result<ArrayList<Playlist>>
|
||||
suspend fun artistAlbumsById(artistId: Long): Result<List<Album>>
|
||||
|
||||
suspend fun allGenres(): Result<ArrayList<Genre>>
|
||||
suspend fun allSongs(): Result<List<Song>>
|
||||
|
||||
suspend fun allArtists(): Result<List<Artist>>
|
||||
|
||||
suspend fun allPlaylists(): Result<List<Playlist>>
|
||||
|
||||
suspend fun allGenres(): Result<List<Genre>>
|
||||
|
||||
suspend fun search(query: String?): Result<MutableList<Any>>
|
||||
|
||||
suspend fun getPlaylistSongs(playlist: Playlist): Result<ArrayList<Song>>
|
||||
suspend fun getPlaylistSongs(playlist: Playlist): Result<List<Song>>
|
||||
|
||||
suspend fun getGenre(genreId: Int): Result<ArrayList<Song>>
|
||||
suspend fun getGenre(genreId: Int): Result<List<Song>>
|
||||
|
||||
suspend fun recentArtists(): Result<Home>
|
||||
|
||||
|
@ -62,5 +68,5 @@ interface Repository {
|
|||
|
||||
suspend fun albumInfo(artist: String, album: String): Result<LastFmAlbum>
|
||||
|
||||
suspend fun artistById(artistId: Int): Result<Artist>
|
||||
suspend fun artistById(artistId: Long): Result<Artist>
|
||||
}
|
|
@ -642,7 +642,7 @@ public class MusicService extends Service implements
|
|||
break;
|
||||
case SHUFFLE_MODE_NONE:
|
||||
this.shuffleMode = shuffleMode;
|
||||
int currentSongId = Objects.requireNonNull(getCurrentSong()).getId();
|
||||
long currentSongId = Objects.requireNonNull(getCurrentSong()).getId();
|
||||
playingQueue = new ArrayList<>(originalPlayingQueue);
|
||||
int newPosition = 0;
|
||||
if (getPlayingQueue() != null) {
|
||||
|
@ -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()) {
|
||||
|
|
|
@ -1,370 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
package code.name.monkey.retromusic.service;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.MediaDescription;
|
||||
import android.media.browse.MediaBrowser;
|
||||
import android.media.session.MediaSession;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.service.media.MediaBrowserService;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.loaders.AlbumLoader;
|
||||
import code.name.monkey.retromusic.loaders.ArtistLoader;
|
||||
import code.name.monkey.retromusic.loaders.PlaylistLoader;
|
||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
@TargetApi(21)
|
||||
public class WearBrowserService extends MediaBrowserService {
|
||||
|
||||
public static final String MEDIA_ID_ROOT = "__ROOT__";
|
||||
public static final int TYPE_ARTIST = 0;
|
||||
public static final int TYPE_ALBUM = 1;
|
||||
public static final int TYPE_SONG = 2;
|
||||
public static final int TYPE_PLAYLIST = 3;
|
||||
public static final int TYPE_ARTIST_SONG_ALBUMS = 4;
|
||||
public static final int TYPE_ALBUM_SONGS = 5;
|
||||
public static final int TYPE_ARTIST_ALL_SONGS = 6;
|
||||
public static final int TYPE_PLAYLIST_ALL_SONGS = 7;
|
||||
|
||||
public static WearBrowserService sInstance;
|
||||
private MediaSession mSession;
|
||||
private Context mContext;
|
||||
private boolean mServiceStarted;
|
||||
|
||||
public static WearBrowserService getInstance() {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
sInstance = this;
|
||||
mContext = this;
|
||||
mSession = new MediaSession(this, "WearBrowserService");
|
||||
setSessionToken(mSession.getSessionToken());
|
||||
mSession.setCallback(new MediaSessionCallback());
|
||||
mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent startIntent, int flags, int startId) {
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
mServiceStarted = false;
|
||||
mSession.release();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BrowserRoot onGetRoot(@NonNull String s, int i, @Nullable Bundle bundle) {
|
||||
return new BrowserRoot(MEDIA_ID_ROOT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowser.MediaItem>> result) {
|
||||
result.detach();
|
||||
loadChildren(parentId, result);
|
||||
}
|
||||
|
||||
private void setSessionActive() {
|
||||
if (!mServiceStarted) {
|
||||
startService(new Intent(getApplicationContext(), WearBrowserService.class));
|
||||
mServiceStarted = true;
|
||||
}
|
||||
|
||||
if (!mSession.isActive()) {
|
||||
mSession.setActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSessionInactive() {
|
||||
if (mServiceStarted) {
|
||||
stopSelf();
|
||||
mServiceStarted = false;
|
||||
}
|
||||
|
||||
if (mSession.isActive()) {
|
||||
mSession.setActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillMediaItems(List<MediaBrowser.MediaItem> mediaItems,
|
||||
String mediaId,
|
||||
String title,
|
||||
String subTitle,
|
||||
Uri icon,
|
||||
int playableOrBrowsable) {
|
||||
mediaItems.add(new MediaBrowser.MediaItem(
|
||||
new MediaDescription.Builder()
|
||||
.setMediaId(mediaId)
|
||||
.setTitle(title)
|
||||
.setIconUri(icon)
|
||||
.setSubtitle(subTitle)
|
||||
.build(), playableOrBrowsable
|
||||
));
|
||||
}
|
||||
|
||||
private void addMediaRoots(List<MediaBrowser.MediaItem> mMediaRoot) {
|
||||
mMediaRoot.add(new MediaBrowser.MediaItem(
|
||||
new MediaDescription.Builder()
|
||||
.setMediaId(Integer.toString(TYPE_ARTIST))
|
||||
.setTitle(getString(R.string.artists))
|
||||
.setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_artist_art), 1f))
|
||||
.setSubtitle(getString(R.string.artists))
|
||||
.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
|
||||
));
|
||||
|
||||
mMediaRoot.add(new MediaBrowser.MediaItem(
|
||||
new MediaDescription.Builder()
|
||||
.setMediaId(Integer.toString(TYPE_ALBUM))
|
||||
.setTitle(getString(R.string.albums))
|
||||
.setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_album_art), 1f))
|
||||
.setSubtitle(getString(R.string.albums))
|
||||
.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
|
||||
));
|
||||
|
||||
mMediaRoot.add(new MediaBrowser.MediaItem(
|
||||
new MediaDescription.Builder()
|
||||
.setMediaId(Integer.toString(TYPE_SONG))
|
||||
.setTitle(getString(R.string.songs))
|
||||
.setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_album_art), 1f))
|
||||
.setSubtitle(getString(R.string.songs))
|
||||
.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
|
||||
));
|
||||
|
||||
|
||||
mMediaRoot.add(new MediaBrowser.MediaItem(
|
||||
new MediaDescription.Builder()
|
||||
.setMediaId(Integer.toString(TYPE_PLAYLIST))
|
||||
.setTitle(getString(R.string.playlists))
|
||||
.setIconUri(Uri.parse("android.resource://code.name.monkey.retromusic/drawable/ic_queue_music_white_24dp"))
|
||||
.setSubtitle(getString(R.string.playlists))
|
||||
.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
private void loadChildren(final String parentId, final Result<List<MediaBrowser.MediaItem>> result) {
|
||||
|
||||
final List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
|
||||
|
||||
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(final Void... unused) {
|
||||
|
||||
if (parentId.equals(MEDIA_ID_ROOT)) {
|
||||
addMediaRoots(mediaItems);
|
||||
} else {
|
||||
switch (Integer.parseInt(Character.toString(parentId.charAt(0)))) {
|
||||
case TYPE_ARTIST:
|
||||
List<Artist> artistList = ArtistLoader.INSTANCE.getAllArtists(mContext) ;
|
||||
for (Artist artist : artistList) {
|
||||
String albumNmber = String.format("%d %s", artist.getAlbums().size(), artist.getAlbums().size() > 1 ? "Albums" : "Album");
|
||||
String songCount = String.format("%d %s", artist.getSongs().size(), artist.getSongs().size() > 1 ? "Songs" : "Song");
|
||||
fillMediaItems(mediaItems,
|
||||
Integer.toString(TYPE_ARTIST_SONG_ALBUMS) + Long.toString(artist.getId()),
|
||||
artist.getName(),
|
||||
albumNmber + " • " + songCount,
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"),
|
||||
MediaBrowser.MediaItem.FLAG_BROWSABLE);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_ARTIST_SONG_ALBUMS:
|
||||
fillMediaItems(mediaItems,
|
||||
Integer.toString(TYPE_ARTIST_ALL_SONGS) + Long.parseLong(parentId.substring(1)),
|
||||
"All songs",
|
||||
"All songs by artist",
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"),
|
||||
MediaBrowser.MediaItem.FLAG_BROWSABLE);
|
||||
|
||||
List<Album> artistAlbums = ArtistLoader.INSTANCE.getArtist(mContext, Integer.parseInt(parentId.substring(1))).getAlbums(); //ArtistAlbumLoader.getAlbumsForArtist(mContext, Long.parseLong(parentId.substring(1)));
|
||||
for (Album album : artistAlbums) {
|
||||
String songCount = String.format("%d %s", album.getSongs().size(), album.getSongs().size() > 1 ? "Songs" : "Song");
|
||||
fillMediaItems(mediaItems,
|
||||
Integer.toString(TYPE_ALBUM_SONGS) + Long.toString(album.getId()),
|
||||
album.getTitle(),
|
||||
songCount,
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"),
|
||||
MediaBrowser.MediaItem.FLAG_BROWSABLE);
|
||||
}
|
||||
break;
|
||||
case TYPE_ALBUM:
|
||||
List<Album> albumList = AlbumLoader.INSTANCE.getAllAlbums(mContext);
|
||||
for (Album album : albumList) {
|
||||
fillMediaItems(mediaItems,
|
||||
Integer.toString(TYPE_ALBUM_SONGS) + Long.toString(album.getId()),
|
||||
album.getTitle(),
|
||||
album.getArtistName(),
|
||||
MusicUtil.getMediaStoreAlbumCoverUri(album.getId()),
|
||||
MediaBrowser.MediaItem.FLAG_BROWSABLE);
|
||||
}
|
||||
break;
|
||||
case TYPE_SONG:
|
||||
List<Song> songList = SongLoader.INSTANCE.getAllSongs(mContext);
|
||||
for (Song song : songList) {
|
||||
fillMediaItems(mediaItems,
|
||||
String.valueOf(song.getId()),
|
||||
song.getTitle(),
|
||||
song.getAlbumName(),
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
|
||||
MediaBrowser.MediaItem.FLAG_PLAYABLE);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_ALBUM_SONGS:
|
||||
List<Song> albumSongList = AlbumLoader.INSTANCE.getAlbum(mContext, Integer.parseInt(parentId.substring(1))).getSongs();
|
||||
for (Song song : albumSongList) {
|
||||
fillMediaItems(mediaItems,
|
||||
String.valueOf(song.getId()),
|
||||
song.getTitle(),
|
||||
song.getAlbumName(),
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
|
||||
MediaBrowser.MediaItem.FLAG_PLAYABLE);
|
||||
}
|
||||
break;
|
||||
case TYPE_ARTIST_ALL_SONGS:
|
||||
List<Song> artistSongs = ArtistLoader.INSTANCE.getArtist(mContext, Integer.parseInt(parentId.substring(1))).getSongs();
|
||||
for (Song song : artistSongs) {
|
||||
fillMediaItems(mediaItems,
|
||||
String.valueOf(song.getId()),
|
||||
song.getTitle(),
|
||||
song.getAlbumName(),
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
|
||||
MediaBrowser.MediaItem.FLAG_PLAYABLE);
|
||||
}
|
||||
break;
|
||||
case TYPE_PLAYLIST:
|
||||
List<Playlist> playlistList = PlaylistLoader.INSTANCE.getAllPlaylists(mContext);
|
||||
for (Playlist playlist : playlistList) {
|
||||
int size = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(mContext, playlist).size();
|
||||
String songCount = String.format("%d %s", size, size > 1 ? "Songs" : "Song");
|
||||
fillMediaItems(mediaItems,
|
||||
Integer.toString(TYPE_PLAYLIST_ALL_SONGS) + Long.toString(playlist.id),
|
||||
playlist.name,
|
||||
songCount,
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/ic_queue_music_white_24dp"),
|
||||
MediaBrowser.MediaItem.FLAG_BROWSABLE);
|
||||
}
|
||||
break;
|
||||
case TYPE_PLAYLIST_ALL_SONGS:
|
||||
List<Song> playlistSongs = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(mContext, Integer.parseInt(parentId.substring(1)));
|
||||
for (Song song : playlistSongs) {
|
||||
fillMediaItems(mediaItems,
|
||||
String.valueOf(song.getId()),
|
||||
song.getTitle(),
|
||||
song.getAlbumName(),
|
||||
Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
|
||||
MediaBrowser.MediaItem.FLAG_PLAYABLE);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
result.sendResult(mediaItems);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
}
|
||||
|
||||
private final class MediaSessionCallback extends MediaSession.Callback {
|
||||
|
||||
@Override
|
||||
public void onPlay() {
|
||||
setSessionActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSeekTo(long position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayFromMediaId(final String mediaId, Bundle extras) {
|
||||
long songId = Long.parseLong(mediaId);
|
||||
setSessionActive();
|
||||
ArrayList<Song> songs = new ArrayList<>();
|
||||
songs.add(SongLoader.INSTANCE.getSong(mContext, Integer.parseInt(mediaId)));
|
||||
MusicPlayerRemote.INSTANCE.openQueue(songs, 0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
setSessionInactive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSkipToNext() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSkipToPrevious() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFastForward() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRewind() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCustomAction(@NonNull String action, Bundle extras) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,10 +19,11 @@ import android.database.Cursor;
|
|||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.loaders.SortedCursor;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
|
@ -37,137 +38,9 @@ import java.util.Collections;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.loaders.SortedCursor;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
|
||||
|
||||
public final class FileUtil {
|
||||
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
public static byte[] readBytes(InputStream stream) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int count;
|
||||
while ((count = stream.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, count);
|
||||
}
|
||||
stream.close();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Song> matchFilesWithMediaStore(@NonNull Context context,
|
||||
@Nullable List<File> files) {
|
||||
return SongLoader.INSTANCE.getSongs(makeSongCursor(context, files));
|
||||
}
|
||||
|
||||
public static String safeGetCanonicalPath(File file) {
|
||||
try {
|
||||
return file.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SortedCursor makeSongCursor(@NonNull final Context context,
|
||||
@Nullable final List<File> files) {
|
||||
String selection = null;
|
||||
String[] paths = null;
|
||||
|
||||
if (files != null) {
|
||||
paths = toPathArray(files);
|
||||
|
||||
if (files.size() > 0
|
||||
&& files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle.
|
||||
selection =
|
||||
MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
Cursor songCursor = SongLoader.INSTANCE.makeSongCursor(context, selection, selection == null ? null : paths);
|
||||
|
||||
return songCursor == null ? null
|
||||
: new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);
|
||||
}
|
||||
|
||||
private static String makePlaceholders(int len) {
|
||||
StringBuilder sb = new StringBuilder(len * 2 - 1);
|
||||
sb.append("?");
|
||||
for (int i = 1; i < len; i++) {
|
||||
sb.append(",?");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String[] toPathArray(@Nullable List<File> files) {
|
||||
if (files != null) {
|
||||
String[] paths = new String[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
/*try {
|
||||
paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
paths[i] = files.get(i).getPath();
|
||||
}*/
|
||||
paths[i] = safeGetCanonicalPath(files.get(i));
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> fileList = new LinkedList<>();
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
if (found != null) {
|
||||
Collections.addAll(fileList, found);
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> files = new LinkedList<>();
|
||||
internalListFilesDeep(files, directory, fileFilter);
|
||||
return files;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull Collection<File> files,
|
||||
@Nullable FileFilter fileFilter) {
|
||||
List<File> resFiles = new LinkedList<>();
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(resFiles, file, fileFilter);
|
||||
} else if (fileFilter == null || fileFilter.accept(file)) {
|
||||
resFiles.add(file);
|
||||
}
|
||||
}
|
||||
return resFiles;
|
||||
}
|
||||
|
||||
private static void internalListFilesDeep(@NonNull Collection<File> files,
|
||||
@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
|
||||
if (found != null) {
|
||||
for (File file : found) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(files, file, fileFilter);
|
||||
} else {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean fileIsMimeType(File file, String mimeType, MimeTypeMap mimeTypeMap) {
|
||||
if (mimeType == null || mimeType.equals("*/*")) {
|
||||
return true;
|
||||
|
@ -209,15 +82,95 @@ public final class FileUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String stripExtension(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
public static boolean isExternalMemoryAvailable() {
|
||||
Boolean isSDPresent = Environment.getExternalStorageState()
|
||||
.equals(android.os.Environment.MEDIA_MOUNTED);
|
||||
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();
|
||||
|
||||
if (isSDSupportedDevice && isSDPresent) {
|
||||
// yes SD-card is present
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
// Sorry
|
||||
}
|
||||
int pos = str.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return str;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> fileList = new LinkedList<>();
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
if (found != null) {
|
||||
Collections.addAll(fileList, found);
|
||||
}
|
||||
return str.substring(0, pos);
|
||||
return fileList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
List<File> files = new LinkedList<>();
|
||||
internalListFilesDeep(files, directory, fileFilter);
|
||||
return files;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<File> listFilesDeep(@NonNull Collection<File> files,
|
||||
@Nullable FileFilter fileFilter) {
|
||||
List<File> resFiles = new LinkedList<>();
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(resFiles, file, fileFilter);
|
||||
} else if (fileFilter == null || fileFilter.accept(file)) {
|
||||
resFiles.add(file);
|
||||
}
|
||||
}
|
||||
return resFiles;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SortedCursor makeSongCursor(@NonNull final Context context,
|
||||
@Nullable final List<File> files) {
|
||||
String selection = null;
|
||||
String[] paths = null;
|
||||
|
||||
if (files != null) {
|
||||
paths = toPathArray(files);
|
||||
|
||||
if (files.size() > 0
|
||||
&& files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle.
|
||||
selection =
|
||||
MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
Cursor songCursor = SongLoader.makeSongCursor(context, selection, selection == null ? null : paths);
|
||||
|
||||
return songCursor == null ? null
|
||||
: new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ArrayList<Song> matchFilesWithMediaStore(@NonNull Context context,
|
||||
@Nullable List<File> files) {
|
||||
return SongLoader.INSTANCE.getSongs(makeSongCursor(context, files));
|
||||
}
|
||||
|
||||
public static String read(File file) throws Exception {
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
String ret = readFromStream(fin);
|
||||
fin.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] readBytes(InputStream stream) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int count;
|
||||
while ((count = stream.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, count);
|
||||
}
|
||||
stream.close();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static String readFromStream(InputStream is) throws Exception {
|
||||
|
@ -234,27 +187,6 @@ public final class FileUtil {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String read(File file) throws Exception {
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
String ret = readFromStream(fin);
|
||||
fin.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isExternalMemoryAvailable() {
|
||||
Boolean isSDPresent = Environment.getExternalStorageState()
|
||||
.equals(android.os.Environment.MEDIA_MOUNTED);
|
||||
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();
|
||||
|
||||
if (isSDSupportedDevice && isSDPresent) {
|
||||
// yes SD-card is present
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
// Sorry
|
||||
}
|
||||
}
|
||||
|
||||
public static File safeGetCanonicalFile(File file) {
|
||||
try {
|
||||
return file.getCanonicalFile();
|
||||
|
@ -264,5 +196,70 @@ public final class FileUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String safeGetCanonicalPath(File file) {
|
||||
try {
|
||||
return file.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
public static String stripExtension(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
int pos = str.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, pos);
|
||||
}
|
||||
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
private static void internalListFilesDeep(@NonNull Collection<File> files,
|
||||
@NonNull File directory, @Nullable FileFilter fileFilter) {
|
||||
File[] found = directory.listFiles(fileFilter);
|
||||
|
||||
if (found != null) {
|
||||
for (File file : found) {
|
||||
if (file.isDirectory()) {
|
||||
internalListFilesDeep(files, file, fileFilter);
|
||||
} else {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String makePlaceholders(int len) {
|
||||
StringBuilder sb = new StringBuilder(len * 2 - 1);
|
||||
sb.append("?");
|
||||
for (int i = 1; i < len; i++) {
|
||||
sb.append(",?");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String[] toPathArray(@Nullable List<File> files) {
|
||||
if (files != null) {
|
||||
String[] paths = new String[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
/*try {
|
||||
paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
paths[i] = files.get(i).getPath();
|
||||
}*/
|
||||
paths[i] = safeGetCanonicalPath(files.get(i));
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -262,7 +262,7 @@ public class MusicUtil {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public static Uri getMediaStoreAlbumCoverUri(int albumId) {
|
||||
public static Uri getMediaStoreAlbumCoverUri(long albumId) {
|
||||
final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
|
||||
return ContentUris.withAppendedId(sArtworkUri, albumId);
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ public class MusicUtil {
|
|||
return songCount + " " + songString;
|
||||
}
|
||||
|
||||
public static Uri getSongFileUri(int songId) {
|
||||
public static Uri getSongFileUri(long songId) {
|
||||
return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
|
|
@ -59,14 +59,14 @@ 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);
|
||||
}
|
||||
|
||||
public static void goToAlbumOptions(@NonNull Activity activity,
|
||||
int albumId,
|
||||
long albumId,
|
||||
@NonNull ActivityOptions options) {
|
||||
Intent intent = new Intent(activity, AlbumDetailsActivity.class);
|
||||
intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId);
|
||||
|
@ -80,7 +80,7 @@ public class NavigationUtil {
|
|||
}
|
||||
|
||||
public static void goToArtistOptions(@NotNull Activity activity,
|
||||
int artistId,
|
||||
long artistId,
|
||||
@NonNull ActivityOptions options) {
|
||||
|
||||
Intent intent = new Intent(activity, ArtistDetailActivity.class);
|
||||
|
|
|
@ -130,7 +130,7 @@ public class PlaylistsUtil {
|
|||
}
|
||||
|
||||
static boolean doPlaylistContains(@NonNull final Context context, final long playlistId,
|
||||
final int songId) {
|
||||
final long songId) {
|
||||
if (playlistId != -1) {
|
||||
try {
|
||||
Cursor c = context.getContentResolver().query(
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<corners android:radius="35dp"/>
|
||||
<stroke
|
||||
android:color="@color/md_white_1000"
|
||||
android:width="2dp"/>
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2020 Hemanth Savarala.
|
||||
~
|
||||
~ Licensed under the GNU General Public License v3
|
||||
~
|
||||
~ This is free software: you can redistribute it and/or modify it under
|
||||
~ the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
~
|
||||
~ This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
~ See the GNU General Public License for more details.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="4dp" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="?attr/colorAccent" />
|
||||
|
||||
</shape>
|
|
@ -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"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
android:id="@+id/imageContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="156dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardUseCompatPadding="true">
|
||||
android:layout_margin="8dp"
|
||||
app:cardCornerRadius="16dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/image"
|
||||
|
@ -21,17 +21,6 @@
|
|||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/playSongs"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="12dp"
|
||||
android:background="@drawable/color_circle_gradient"
|
||||
android:backgroundTint="@color/eighty_percent_black_overlay"
|
||||
android:padding="8dp"
|
||||
app:srcCompat="@drawable/ic_play_arrow_white_32dp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
android:id="@+id/imageContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="256dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardUseCompatPadding="true">
|
||||
android:layout_margin="8dp"
|
||||
app:cardCornerRadius="16dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/image"
|
||||
|
@ -21,17 +21,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/playSongs"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="12dp"
|
||||
android:background="@drawable/color_circle_gradient"
|
||||
android:backgroundTint="@color/eighty_percent_black_overlay"
|
||||
android:padding="8dp"
|
||||
app:srcCompat="@drawable/ic_play_arrow_white_32dp" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
android:id="@+id/imageContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="196dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardUseCompatPadding="true">
|
||||
android:layout_margin="8dp"
|
||||
app:cardCornerRadius="16dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/image"
|
||||
|
@ -22,16 +22,6 @@
|
|||
android:scaleType="centerCrop"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/playSongs"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="12dp"
|
||||
android:background="@drawable/color_circle_gradient"
|
||||
android:backgroundTint="@color/eighty_percent_black_overlay"
|
||||
android:padding="8dp"
|
||||
app:srcCompat="@drawable/ic_play_arrow_white_32dp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:text="@string/songs"
|
||||
android:textAppearance="@style/TextViewHeadline5"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:text="@string/albums"
|
||||
android:textAppearance="@style/TextViewHeadline5"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
android:textStyle="bold"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
@ -69,7 +69,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:text="@string/songs"
|
||||
android:textAppearance="@style/TextViewHeadline5"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
android:textStyle="bold"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
@ -83,8 +83,7 @@
|
|||
android:nestedScrollingEnabled="false"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/songTitle"
|
||||
tools:listitem="@layout/item_song"
|
||||
tools:visibility="gone" />
|
||||
tools:listitem="@layout/item_song" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/biographyTitle"
|
||||
|
@ -92,7 +91,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:text="@string/biography"
|
||||
android:textAppearance="@style/TextViewHeadline5"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
app:layout_constrainedWidth="true"
|
||||
|
@ -104,13 +103,13 @@
|
|||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/biographyText"
|
||||
style="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lineSpacingExtra="5dp"
|
||||
android:maxLines="4"
|
||||
android:padding="16dp"
|
||||
android:textAppearance="@style/TextViewBody1"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/colorSurface"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
|
@ -18,10 +19,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/shadow_up_full_theme" />
|
||||
|
||||
<View
|
||||
android:id="@+id/mask"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -5,20 +5,16 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
android:background="?attr/colorSurface"
|
||||
android:focusable="true">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/colorBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/colorSurface"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<View
|
||||
android:id="@+id/mask"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#20000000" />
|
||||
|
||||
<include layout="@layout/shadow_statusbar_toolbar" />
|
||||
|
||||
|
||||
|
@ -86,5 +82,4 @@
|
|||
tools:layout="@layout/fragment_card_blur_player_playback_controls" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -12,58 +12,63 @@
|
|||
android:id="@+id/playerMenu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="?attr/roundSelector"
|
||||
android:padding="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/text"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/titleContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_more_vert_white_24dp" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="315dp"
|
||||
<LinearLayout
|
||||
android:id="@+id/titleContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
android:textColor="@color/md_white_1000"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/text"
|
||||
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
|
||||
app:layout_constraintStart_toEndOf="@+id/songFavourite"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="315dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.75"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="8dp"
|
||||
android:textColor="@color/md_white_1000"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toTopOf="@+id/progressSlider"
|
||||
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
|
||||
app:layout_constraintStart_toEndOf="@+id/songFavourite"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||
tools:layout_editor_absoluteX="48dp"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextViewHeadline6"
|
||||
android:textColor="@color/md_white_1000"
|
||||
android:textStyle="bold"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.75"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="8dp"
|
||||
android:textColor="@color/md_white_1000"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/songFavourite"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:background="?attr/roundSelector"
|
||||
android:padding="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/text"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/titleContainer"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/title"
|
||||
app:layout_constraintTop_toTopOf="@+id/titleContainer"
|
||||
app:srcCompat="@drawable/ic_favorite_border_white_24dp" />
|
||||
|
||||
|
||||
|
@ -95,7 +100,7 @@
|
|||
android:splitTrack="false"
|
||||
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
||||
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
||||
app:layout_constraintTop_toBottomOf="@id/text"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleContainer"
|
||||
tools:ignore="RtlHardcoded,UnusedAttribute"
|
||||
tools:progress="20" />
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:scaleType="centerCrop"
|
||||
tools:srcCompat="@tools:sample/backgrounds/scenic[16]" />
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/imageText"
|
||||
|
@ -58,8 +58,7 @@
|
|||
android:minHeight="40dp"
|
||||
android:textAppearance="@style/TextViewSubtitle2"
|
||||
android:visibility="gone"
|
||||
tools:text="100"
|
||||
tools:visibility="visible" />
|
||||
tools:text="100" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</FrameLayout>
|
||||
|
||||
|
|
|
@ -22,16 +22,6 @@
|
|||
android:scaleType="centerCrop"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/playSongs"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="12dp"
|
||||
android:background="@drawable/color_circle_gradient"
|
||||
android:backgroundTint="@color/eighty_percent_black_overlay"
|
||||
android:padding="8dp"
|
||||
app:srcCompat="@drawable/ic_play_arrow_white_32dp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
|
|
|
@ -25,10 +25,25 @@
|
|||
android:id="@+id/image"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/proText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/proText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/line_button"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:text="@string/pro"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -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" />
|
||||
|
|
|
@ -825,4 +825,6 @@
|
|||
<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>
|
||||
<string name="pro">Pro</string>
|
||||
</resources>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
<code.name.monkey.retromusic.preferences.BlacklistPreference
|
||||
android:key="blacklist"
|
||||
app:enabled="false"
|
||||
android:layout="@layout/list_item_view"
|
||||
android:summary="@string/pref_summary_blacklist"
|
||||
android:title="@string/pref_title_blacklist"
|
||||
|
|
|
@ -53,13 +53,6 @@
|
|||
android:layout="@layout/list_item_view_switch"
|
||||
android:summary="@string/pref_summary_colored_app_shortcuts"
|
||||
android:title="@string/pref_title_app_shortcuts" />
|
||||
|
||||
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="dominant_color"
|
||||
android:layout="@layout/list_item_view_switch"
|
||||
android:summary="@string/pref_summary_dominant_color"
|
||||
android:title="@string/pref_title_toggle_dominant_color" />
|
||||
|
||||
|
||||
</code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -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,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue