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
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|
||||||
applicationId "code.name.monkey.retromusic"
|
applicationId "code.name.monkey.retromusic"
|
||||||
versionCode 405
|
versionCode 408
|
||||||
versionName '3.4.900'
|
versionName '3.5.000'
|
||||||
|
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
|
||||||
|
@ -129,8 +129,8 @@ dependencies {
|
||||||
implementation 'androidx.preference:preference:1.1.0'
|
implementation 'androidx.preference:preference:1.1.0'
|
||||||
|
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
implementation 'androidx.core:core-ktx:1.1.0'
|
implementation 'androidx.core:core-ktx:1.2.0'
|
||||||
implementation 'androidx.fragment:fragment:1.2.0'
|
implementation 'androidx.fragment:fragment:1.2.1'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.2.0-alpha04'
|
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 FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md"
|
||||||
const val PINTEREST = "https://in.pinterest.com/retromusicapp/"
|
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
|
val baseProjection = arrayOf(BaseColumns._ID, // 0
|
||||||
MediaStore.Audio.AudioColumns.TITLE, // 1
|
MediaStore.Audio.AudioColumns.TITLE, // 1
|
||||||
|
|
|
@ -8,7 +8,6 @@ import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.SubMenu
|
import android.view.SubMenu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
@ -27,14 +26,15 @@ import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
||||||
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
|
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
|
||||||
import code.name.monkey.retromusic.extensions.ripAlpha
|
import code.name.monkey.retromusic.extensions.ripAlpha
|
||||||
import code.name.monkey.retromusic.extensions.show
|
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.ArtistGlideRequest
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
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.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
|
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter
|
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter
|
||||||
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView
|
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView
|
||||||
import code.name.monkey.retromusic.rest.model.LastFmAlbum
|
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.albumCoverContainer
|
||||||
import kotlinx.android.synthetic.main.activity_album.albumText
|
import kotlinx.android.synthetic.main.activity_album.albumText
|
||||||
import kotlinx.android.synthetic.main.activity_album.albumTitle
|
import kotlinx.android.synthetic.main.activity_album.albumTitle
|
||||||
|
import kotlinx.android.synthetic.main.activity_album.artistImage
|
||||||
import kotlinx.android.synthetic.main.activity_album.image
|
import kotlinx.android.synthetic.main.activity_album.image
|
||||||
import kotlinx.android.synthetic.main.activity_album.toolbar
|
import kotlinx.android.synthetic.main.activity_album.toolbar
|
||||||
import kotlinx.android.synthetic.main.activity_album_content.aboutAlbumText
|
import kotlinx.android.synthetic.main.activity_album_content.aboutAlbumText
|
||||||
|
@ -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.scrobblesLabel
|
||||||
import kotlinx.android.synthetic.main.activity_album_content.shuffleAction
|
import kotlinx.android.synthetic.main.activity_album_content.shuffleAction
|
||||||
import kotlinx.android.synthetic.main.activity_album_content.songTitle
|
import kotlinx.android.synthetic.main.activity_album_content.songTitle
|
||||||
import java.util.ArrayList
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import android.util.Pair as UtilPair
|
import android.util.Pair as UtilPair
|
||||||
|
|
||||||
|
@ -88,8 +88,9 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
|
|
||||||
private lateinit var simpleSongAdapter: SimpleSongAdapter
|
private lateinit var simpleSongAdapter: SimpleSongAdapter
|
||||||
private lateinit var album: Album
|
private lateinit var album: Album
|
||||||
private lateinit var artistImage: ImageView
|
private lateinit var songs: List<Song>
|
||||||
private var cab: MaterialCab? = null
|
private var cab: MaterialCab? = null
|
||||||
|
|
||||||
private val savedSortOrder: String
|
private val savedSortOrder: String
|
||||||
get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder
|
get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder
|
||||||
|
|
||||||
|
@ -106,7 +107,6 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
slide.excludeTarget(R.id.status_bar, true)
|
slide.excludeTarget(R.id.status_bar, true)
|
||||||
slide.excludeTarget(android.R.id.statusBarBackground, true)
|
slide.excludeTarget(android.R.id.statusBarBackground, true)
|
||||||
slide.excludeTarget(android.R.id.navigationBarBackground, true)
|
slide.excludeTarget(android.R.id.navigationBarBackground, true)
|
||||||
|
|
||||||
window.enterTransition = slide
|
window.enterTransition = slide
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
albumDetailsPresenter.attachView(this)
|
albumDetailsPresenter.attachView(this)
|
||||||
|
|
||||||
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
||||||
intent.extras?.getInt(EXTRA_ALBUM_ID)?.let {
|
intent.extras?.getLong(EXTRA_ALBUM_ID)?.let {
|
||||||
albumDetailsPresenter.loadAlbum(it)
|
albumDetailsPresenter.loadAlbum(it)
|
||||||
albumCoverContainer?.transitionName = "${getString(R.string.transition_album_art)}_$it"
|
albumCoverContainer?.transitionName = "${getString(R.string.transition_album_art)}_$it"
|
||||||
}
|
}
|
||||||
|
@ -135,12 +135,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
windowEnterTransition()
|
windowEnterTransition()
|
||||||
ActivityCompat.postponeEnterTransition(this)
|
ActivityCompat.postponeEnterTransition(this)
|
||||||
|
|
||||||
|
|
||||||
artistImage = findViewById(R.id.artistImage)
|
|
||||||
|
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
|
|
||||||
artistImage.setOnClickListener {
|
artistImage.setOnClickListener {
|
||||||
|
println("Click Artist $album")
|
||||||
val artistPairs = ActivityOptions.makeSceneTransitionAnimation(
|
val artistPairs = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
this,
|
this,
|
||||||
UtilPair.create(
|
UtilPair.create(
|
||||||
|
@ -151,10 +149,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs)
|
NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs)
|
||||||
}
|
}
|
||||||
playAction.apply {
|
playAction.apply {
|
||||||
setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
|
setOnClickListener { MusicPlayerRemote.openQueue(songs, 0, true) }
|
||||||
}
|
}
|
||||||
shuffleAction.apply {
|
shuffleAction.apply {
|
||||||
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album.songs!!, true) }
|
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songs, true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutAlbumText.setOnClickListener {
|
aboutAlbumText.setOnClickListener {
|
||||||
|
@ -187,39 +185,30 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
|
|
||||||
override fun album(album: Album) {
|
override fun album(album: Album) {
|
||||||
complete()
|
complete()
|
||||||
if (album.songs!!.isEmpty()) {
|
|
||||||
finish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.album = album
|
this.album = album
|
||||||
|
|
||||||
albumTitle.text = album.title
|
albumTitle.text = album.title
|
||||||
if (MusicUtil.getYearString(album.year) == "-") {
|
if (MusicUtil.getYearString(album.year) == "-") {
|
||||||
albumText.text = String.format(
|
albumText.text = String.format("%s", album.artist)
|
||||||
"%s • %s",
|
|
||||||
album.artistName,
|
|
||||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
albumText.text = String.format(
|
albumText.text = String.format("%s • %s", album.artist, MusicUtil.getYearString(album.year))
|
||||||
"%s • %s • %s",
|
|
||||||
album.artistName,
|
|
||||||
MusicUtil.getYearString(album.year),
|
|
||||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
loadAlbumCover()
|
loadAlbumCover()
|
||||||
simpleSongAdapter.swapDataSet(album.songs)
|
albumDetailsPresenter.albumSongs(album.id)
|
||||||
albumDetailsPresenter.loadMore(album.artistId)
|
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()
|
moreTitle.show()
|
||||||
moreRecyclerView.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(
|
moreRecyclerView.layoutManager = GridLayoutManager(
|
||||||
this,
|
this,
|
||||||
1,
|
1,
|
||||||
|
@ -250,19 +239,23 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadArtistImage(artist: Artist) {
|
override fun loadArtistImage(artist: Artist) {
|
||||||
ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build()
|
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
|
||||||
.dontAnimate().dontTransform().into(object : RetroMusicColoredTarget(artistImage) {
|
.generatePalette(this)
|
||||||
|
.build()
|
||||||
|
.dontAnimate()
|
||||||
|
.dontTransform()
|
||||||
|
.into(object : RetroMusicColoredTarget(artistImage) {
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAlbumCover() {
|
private fun loadAlbumCover() {
|
||||||
SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
|
AlbumGlideRequest.Builder(Glide.with(this), album.id)
|
||||||
.checkIgnoreMediaStore(this)
|
|
||||||
.ignoreMediaStore(PreferenceUtil.getInstance(this).ignoreMediaStoreArtwork())
|
|
||||||
.generatePalette(this)
|
.generatePalette(this)
|
||||||
.build().dontAnimate().dontTransform()
|
.build()
|
||||||
|
.dontAnimate()
|
||||||
|
.dontTransform()
|
||||||
.into(object : RetroMusicColoredTarget(image) {
|
.into(object : RetroMusicColoredTarget(image) {
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
setColors(color)
|
setColors(color)
|
||||||
|
@ -362,16 +355,18 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
|
|
||||||
private fun setUpSortOrderMenu(sortOrder: SubMenu) {
|
private fun setUpSortOrderMenu(sortOrder: SubMenu) {
|
||||||
when (savedSortOrder) {
|
when (savedSortOrder) {
|
||||||
AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked = true
|
AlbumSongSortOrder.SONG_A_Z ->
|
||||||
AlbumSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true
|
sortOrder.findItem(R.id.action_sort_order_title).isChecked = true
|
||||||
AlbumSongSortOrder.SONG_TRACK_LIST -> sortOrder.findItem(R.id.action_sort_order_track_list).isChecked =
|
AlbumSongSortOrder.SONG_Z_A ->
|
||||||
true
|
sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true
|
||||||
AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration)
|
AlbumSongSortOrder.SONG_TRACK_LIST ->
|
||||||
.isChecked = true
|
sortOrder.findItem(R.id.action_sort_order_track_list).isChecked = true
|
||||||
|
AlbumSongSortOrder.SONG_DURATION ->
|
||||||
|
sortOrder.findItem(R.id.action_sort_order_artist_song_duration).isChecked = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setSaveSortOrder(sortOrder: String?) {
|
private fun setSaveSortOrder(sortOrder: String) {
|
||||||
PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder
|
PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder
|
||||||
reload()
|
reload()
|
||||||
}
|
}
|
||||||
|
@ -383,7 +378,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C
|
||||||
|
|
||||||
private fun reload() {
|
private fun reload() {
|
||||||
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
|
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 {
|
} else {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,9 @@ import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter
|
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter
|
||||||
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView
|
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView
|
||||||
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
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.image
|
||||||
import kotlinx.android.synthetic.main.activity_artist_details.text
|
import kotlinx.android.synthetic.main.activity_artist_details.text
|
||||||
import kotlinx.android.synthetic.main.activity_artist_details.toolbar
|
import kotlinx.android.synthetic.main.activity_artist_details.toolbar
|
||||||
import java.text.DecimalFormat
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
private var cab: MaterialCab? = null
|
private var cab: MaterialCab? = null
|
||||||
private var biography: Spanned? = null
|
private var biography: Spanned? = null
|
||||||
private lateinit var artist: Artist
|
private lateinit var artist: Artist
|
||||||
|
private lateinit var songs: List<Song>
|
||||||
private lateinit var songAdapter: SimpleSongAdapter
|
private lateinit var songAdapter: SimpleSongAdapter
|
||||||
private lateinit var albumAdapter: HorizontalAlbumAdapter
|
private lateinit var albumAdapter: HorizontalAlbumAdapter
|
||||||
private var forceDownload: Boolean = false
|
private var forceDownload: Boolean = false
|
||||||
|
@ -118,7 +120,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
artistDetailsPresenter.attachView(this)
|
artistDetailsPresenter.attachView(this)
|
||||||
|
|
||||||
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
||||||
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let {
|
intent.extras?.getLong(EXTRA_ARTIST_ID)?.let {
|
||||||
artistDetailsPresenter.loadArtist(it)
|
artistDetailsPresenter.loadArtist(it)
|
||||||
val name = "${getString(R.string.transition_artist_image)}_$it"
|
val name = "${getString(R.string.transition_artist_image)}_$it"
|
||||||
artistCoverContainer?.transitionName = name
|
artistCoverContainer?.transitionName = name
|
||||||
|
@ -133,10 +135,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
setupRecyclerView()
|
setupRecyclerView()
|
||||||
|
|
||||||
playAction.apply {
|
playAction.apply {
|
||||||
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
|
setOnClickListener { MusicPlayerRemote.openQueue(songs, 0, true) }
|
||||||
}
|
}
|
||||||
shuffleAction.apply {
|
shuffleAction.apply {
|
||||||
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
|
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songs, true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
biographyText.setOnClickListener {
|
biographyText.setOnClickListener {
|
||||||
|
@ -154,7 +156,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
|
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), null)
|
||||||
albumRecyclerView.apply {
|
albumRecyclerView.apply {
|
||||||
itemAnimator = DefaultItemAnimator()
|
itemAnimator = DefaultItemAnimator()
|
||||||
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
||||||
|
@ -189,6 +191,15 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
ActivityCompat.startPostponedEnterTransition(this)
|
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) {
|
override fun artist(artist: Artist) {
|
||||||
complete()
|
complete()
|
||||||
if (artist.songCount <= 0) {
|
if (artist.songCount <= 0) {
|
||||||
|
@ -202,13 +213,11 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
}
|
}
|
||||||
artistTitle.text = artist.name
|
artistTitle.text = artist.name
|
||||||
text.text = String.format(
|
text.text = String.format(
|
||||||
"%s • %s",
|
"%s",
|
||||||
MusicUtil.getArtistInfoString(this, artist),
|
MusicUtil.getArtistInfoString(this, artist)
|
||||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs))
|
|
||||||
)
|
)
|
||||||
|
artistDetailsPresenter.loadArtistAlbums(artist.id)
|
||||||
songAdapter.swapDataSet(artist.songs)
|
artistDetailsPresenter.loadArtistSongs(artist.id)
|
||||||
albumAdapter.swapDataSet(artist.albums!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadBiography(
|
private fun loadBiography(
|
||||||
|
@ -281,30 +290,17 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
||||||
|
|
||||||
val toolbarColor = ATHUtil.resolveColor(this, R.attr.colorSurface)
|
val toolbarColor = ATHUtil.resolveColor(this, R.attr.colorSurface)
|
||||||
//status_bar.setBackgroundColor(toolbarColor)
|
|
||||||
toolbar.setBackgroundColor(toolbarColor)
|
toolbar.setBackgroundColor(toolbarColor)
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
supportActionBar?.title = null
|
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 {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
return handleSortOrderMenuItem(item)
|
return handleSortOrderMenuItem(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
||||||
val songs = artist.songs
|
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
android.R.id.home -> {
|
android.R.id.home -> {
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
|
@ -354,7 +350,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView,
|
||||||
|
|
||||||
private fun reload() {
|
private fun reload() {
|
||||||
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
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 {
|
} else {
|
||||||
finish()
|
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)
|
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.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.SearchQueryHelper
|
import code.name.monkey.retromusic.helper.SearchQueryHelper
|
||||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
|
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.loaders.PlaylistSongsLoader
|
||||||
import code.name.monkey.retromusic.service.MusicService
|
import code.name.monkey.retromusic.service.MusicService
|
||||||
import code.name.monkey.retromusic.util.AppRater
|
import code.name.monkey.retromusic.util.AppRater
|
||||||
|
@ -155,14 +153,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
||||||
val id = parseIdFromIntent(intent, "albumId", "album").toInt()
|
val id = parseIdFromIntent(intent, "albumId", "album").toInt()
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
val position = intent.getIntExtra("position", 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
|
handled = true
|
||||||
}
|
}
|
||||||
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
|
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
|
||||||
val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
|
val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
val position = intent.getIntExtra("position", 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
|
handled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +218,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
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()
|
) postRecreate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -238,7 +238,7 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
||||||
emptyText.visibility = View.VISIBLE
|
emptyText.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun songs(songs: ArrayList<Song>) {
|
override fun songs(songs: List<Song>) {
|
||||||
adapter.swapDataSet(songs)
|
adapter.swapDataSet(songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import java.util.Collections
|
||||||
|
|
||||||
abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
|
|
||||||
protected var id: Int = 0
|
protected var id: Long = 0
|
||||||
private set
|
private set
|
||||||
private var paletteColorPrimary: Int = 0
|
private var paletteColorPrimary: Int = 0
|
||||||
private var isInNoImageMode: Boolean = false
|
private var isInNoImageMode: Boolean = false
|
||||||
|
@ -187,22 +187,16 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
setUpViews()
|
setUpViews()
|
||||||
|
|
||||||
setStatusbarColorAuto()
|
setStatusbarColorAuto()
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
setTaskDescriptionColorAuto()
|
setTaskDescriptionColorAuto()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpViews() {
|
private fun setUpViews() {
|
||||||
setUpScrollView()
|
|
||||||
setUpFab()
|
setUpFab()
|
||||||
setUpImageView()
|
setUpImageView()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpScrollView() {
|
|
||||||
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var items: List<String>
|
private lateinit var items: List<String>
|
||||||
|
|
||||||
private fun setUpImageView() {
|
private fun setUpImageView() {
|
||||||
|
@ -261,7 +255,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
private fun getIntentExtras() {
|
private fun getIntentExtras() {
|
||||||
val intentExtras = intent.extras
|
val intentExtras = intent.extras
|
||||||
if (intentExtras != null) {
|
if (intentExtras != null) {
|
||||||
id = intentExtras.getInt(EXTRA_ID)
|
id = intentExtras.getLong(EXTRA_ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +400,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArtworkInfo constructor(val albumId: Int, val artwork: Bitmap?)
|
class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -415,5 +409,4 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
|
||||||
private val TAG = AbsTagEditorActivity::class.java.simpleName
|
private val TAG = AbsTagEditorActivity::class.java.simpleName
|
||||||
private const val REQUEST_CODE_SELECT_IMAGE = 1000
|
private const val REQUEST_CODE_SELECT_IMAGE = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import android.widget.Toast
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||||
|
@ -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.albumArtistText
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.albumText
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.albumText
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.albumTitleContainer
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.albumTitleContainer
|
||||||
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.artistContainer
|
||||||
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.artistText
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.genreContainer
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.genreContainer
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.genreTitle
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.genreTitle
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.imageContainer
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.imageContainer
|
||||||
|
@ -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.yearContainer
|
||||||
import kotlinx.android.synthetic.main.activity_album_tag_editor.yearTitle
|
import kotlinx.android.synthetic.main.activity_album_tag_editor.yearTitle
|
||||||
import org.jaudiotagger.tag.FieldKey
|
import org.jaudiotagger.tag.FieldKey
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.EnumMap
|
import java.util.EnumMap
|
||||||
|
|
||||||
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
|
@ -58,7 +58,9 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
|
|
||||||
override fun loadImageFromFile(selectedFileUri: Uri?) {
|
override fun loadImageFromFile(selectedFileUri: Uri?) {
|
||||||
|
|
||||||
Glide.with(this@AlbumTagEditorActivity).load(selectedFileUri).asBitmap()
|
Glide.with(this@AlbumTagEditorActivity)
|
||||||
|
.load(selectedFileUri)
|
||||||
|
.asBitmap()
|
||||||
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
|
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
|
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
|
||||||
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
|
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
|
||||||
|
@ -115,15 +117,18 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
MaterialUtil.setTint(genreContainer, false)
|
MaterialUtil.setTint(genreContainer, false)
|
||||||
MaterialUtil.setTint(albumTitleContainer, false)
|
MaterialUtil.setTint(albumTitleContainer, false)
|
||||||
MaterialUtil.setTint(albumArtistContainer, false)
|
MaterialUtil.setTint(albumArtistContainer, false)
|
||||||
|
MaterialUtil.setTint(artistContainer, false)
|
||||||
|
|
||||||
albumText.appHandleColor().addTextChangedListener(this)
|
albumText.addTextChangedListener(this)
|
||||||
albumArtistText.appHandleColor().addTextChangedListener(this)
|
artistText.addTextChangedListener(this)
|
||||||
genreTitle.appHandleColor().addTextChangedListener(this)
|
albumArtistText.addTextChangedListener(this)
|
||||||
yearTitle.appHandleColor().addTextChangedListener(this)
|
genreTitle.addTextChangedListener(this)
|
||||||
|
yearTitle.addTextChangedListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillViewsWithFileTags() {
|
private fun fillViewsWithFileTags() {
|
||||||
albumText.setText(albumTitle)
|
albumText.setText(albumTitle)
|
||||||
|
artistText.setText(artistName)
|
||||||
albumArtistText.setText(albumArtistName)
|
albumArtistText.setText(albumArtistName)
|
||||||
genreTitle.setText(genreName)
|
genreTitle.setText(genreName)
|
||||||
yearTitle.setText(songYear)
|
yearTitle.setText(songYear)
|
||||||
|
@ -141,10 +146,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
deleteAlbumArt = false
|
deleteAlbumArt = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
|
||||||
super.onPause()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toastLoadingFailed() {
|
private fun toastLoadingFailed() {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@AlbumTagEditorActivity,
|
this@AlbumTagEditorActivity,
|
||||||
|
@ -170,21 +171,24 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
|
||||||
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
|
||||||
//android seems not to recognize album_artist field so we additionally write the normal artist field
|
//android seems not to recognize album_artist field so we additionally write the normal artist field
|
||||||
fieldKeyValueMap[FieldKey.ARTIST] = albumArtistText.text.toString()
|
fieldKeyValueMap[FieldKey.ARTIST] = artistText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
|
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
|
||||||
fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString()
|
fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString()
|
||||||
|
|
||||||
writeValuesToFiles(
|
writeValuesToFiles(
|
||||||
fieldKeyValueMap,
|
fieldKeyValueMap,
|
||||||
if (deleteAlbumArt) ArtworkInfo(id, null)
|
when {
|
||||||
else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!)
|
deleteAlbumArt -> ArtworkInfo(id, null)
|
||||||
|
albumArtBitmap == null -> null
|
||||||
|
else -> ArtworkInfo(id, albumArtBitmap!!)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSongPaths(): List<String> {
|
override fun getSongPaths(): List<String> {
|
||||||
val songs = AlbumLoader.getAlbum(this, id).songs
|
val songs = AlbumLoader.getSongsForAlbum(this, id)
|
||||||
val paths = ArrayList<String>(songs!!.size)
|
val paths = ArrayList<String>(songs.size)
|
||||||
for (song in songs) {
|
for (song in songs) {
|
||||||
paths.add(song.data)
|
paths.add(song.data)
|
||||||
}
|
}
|
||||||
|
@ -207,7 +211,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val TAG: String = AlbumTagEditorActivity::class.java.simpleName
|
val TAG: String = AlbumTagEditorActivity::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
|
||||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||||
import code.name.monkey.retromusic.loaders.SongLoader
|
import code.name.monkey.retromusic.loaders.SongLoader
|
||||||
import kotlinx.android.synthetic.main.activity_song_tag_editor.albumArtistContainer
|
import kotlinx.android.synthetic.main.activity_song_tag_editor.albumArtistContainer
|
||||||
|
@ -43,7 +42,6 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
setNoImageMode()
|
setNoImageMode()
|
||||||
setUpViews()
|
setUpViews()
|
||||||
applyToolbar(toolbar)
|
applyToolbar(toolbar)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpViews() {
|
private fun setUpViews() {
|
||||||
|
@ -58,15 +56,15 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
|
||||||
MaterialUtil.setTint(trackNumberContainer, false)
|
MaterialUtil.setTint(trackNumberContainer, false)
|
||||||
MaterialUtil.setTint(lyricsContainer, false)
|
MaterialUtil.setTint(lyricsContainer, false)
|
||||||
|
|
||||||
songText.appHandleColor().addTextChangedListener(this)
|
songText.addTextChangedListener(this)
|
||||||
albumText.appHandleColor().addTextChangedListener(this)
|
albumText.addTextChangedListener(this)
|
||||||
albumArtistText.appHandleColor().addTextChangedListener(this)
|
albumArtistText.addTextChangedListener(this)
|
||||||
artistText.appHandleColor().addTextChangedListener(this)
|
artistText.addTextChangedListener(this)
|
||||||
genreText.appHandleColor().addTextChangedListener(this)
|
genreText.addTextChangedListener(this)
|
||||||
yearText.appHandleColor().addTextChangedListener(this)
|
yearText.addTextChangedListener(this)
|
||||||
trackNumberText.appHandleColor().addTextChangedListener(this)
|
trackNumberText.addTextChangedListener(this)
|
||||||
lyricsText.appHandleColor().addTextChangedListener(this)
|
lyricsText.addTextChangedListener(this)
|
||||||
songComposerText.appHandleColor().addTextChangedListener(this)
|
songComposerText.addTextChangedListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillViewsWithFileTags() {
|
private fun fillViewsWithFileTags() {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
||||||
import code.name.monkey.retromusic.model.Genre
|
import code.name.monkey.retromusic.model.Genre
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.NavigationUtil
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,11 +17,11 @@ import java.util.Locale
|
||||||
|
|
||||||
class GenreAdapter(
|
class GenreAdapter(
|
||||||
private val activity: Activity,
|
private val activity: Activity,
|
||||||
dataSet: ArrayList<Genre>,
|
dataSet: List<Genre>,
|
||||||
private val mItemLayoutRes: Int
|
private val mItemLayoutRes: Int
|
||||||
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<GenreAdapter.ViewHolder>() {
|
||||||
|
|
||||||
var dataSet = ArrayList<Genre>()
|
var dataSet = listOf<Genre>()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -48,7 +47,7 @@ class GenreAdapter(
|
||||||
return dataSet.size
|
return dataSet.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapDataSet(list: ArrayList<Genre>) {
|
fun swapDataSet(list: List<Genre>) {
|
||||||
dataSet = list
|
dataSet = list
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ class HomeAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
println("ViewType ${getItemViewType(position)}")
|
|
||||||
when (getItemViewType(position)) {
|
when (getItemViewType(position)) {
|
||||||
RECENT_ALBUMS -> {
|
RECENT_ALBUMS -> {
|
||||||
val viewHolder = holder as AlbumViewHolder
|
val viewHolder = holder as AlbumViewHolder
|
||||||
|
@ -121,7 +120,6 @@ class HomeAdapter(
|
||||||
activity,
|
activity,
|
||||||
list,
|
list,
|
||||||
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity),
|
PreferenceUtil.getInstance(activity).getHomeGridStyle(activity),
|
||||||
false,
|
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
adapter = artistAdapter
|
adapter = artistAdapter
|
||||||
|
|
|
@ -9,8 +9,9 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
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.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.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
|
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
|
||||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
||||||
|
@ -60,9 +61,18 @@ class SearchAdapter(
|
||||||
ALBUM -> {
|
ALBUM -> {
|
||||||
val album = dataSet?.get(position) as Album
|
val album = dataSet?.get(position) as Album
|
||||||
holder.title?.text = album.title
|
holder.title?.text = album.title
|
||||||
holder.text?.text = album.artistName
|
holder.text?.text = album.artist
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
holder.image?.let {
|
||||||
.checkIgnoreMediaStore(activity).build().into(holder.image)
|
AlbumGlideRequest.Builder(Glide.with(activity), album.id)
|
||||||
|
.generatePalette(activity)
|
||||||
|
.build()
|
||||||
|
.dontAnimate()
|
||||||
|
.dontTransform()
|
||||||
|
.into(object : RetroMusicColoredTarget(it) {
|
||||||
|
override fun onColorReady(color: Int) {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ARTIST -> {
|
ARTIST -> {
|
||||||
val artist = dataSet?.get(position) as Artist
|
val artist = dataSet?.get(position) as Artist
|
||||||
|
@ -134,21 +144,24 @@ class SearchAdapter(
|
||||||
val item = dataSet!![adapterPosition]
|
val item = dataSet!![adapterPosition]
|
||||||
when (itemViewType) {
|
when (itemViewType) {
|
||||||
ALBUM -> {
|
ALBUM -> {
|
||||||
|
item as Album
|
||||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
activity,
|
activity,
|
||||||
UtilPair.create(image, activity.getString(R.string.transition_album_art))
|
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 -> {
|
ARTIST -> {
|
||||||
|
item as Artist
|
||||||
val options = ActivityOptions.makeSceneTransitionAnimation(
|
val options = ActivityOptions.makeSceneTransitionAnimation(
|
||||||
activity,
|
activity,
|
||||||
UtilPair.create(image, activity.getString(R.string.transition_artist_image))
|
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 -> {
|
GENRE -> {
|
||||||
NavigationUtil.goToGenre(activity, item as Genre)
|
item as Genre
|
||||||
|
NavigationUtil.goToGenre(activity, item)
|
||||||
}
|
}
|
||||||
PLAYLIST -> {
|
PLAYLIST -> {
|
||||||
NavigationUtil.goToPlaylistNew(activity, item as Playlist)
|
NavigationUtil.goToPlaylistNew(activity, item as Playlist)
|
||||||
|
|
|
@ -2,7 +2,6 @@ package code.name.monkey.retromusic.adapter.album
|
||||||
|
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
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.R
|
||||||
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
|
||||||
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
|
||||||
|
import code.name.monkey.retromusic.glide.AlbumGlideRequest
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
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.SortOrder
|
||||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
|
@ -29,9 +27,8 @@ import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||||
|
|
||||||
open class AlbumAdapter(
|
open class AlbumAdapter(
|
||||||
protected val activity: AppCompatActivity,
|
protected val activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Album>,
|
dataSet: List<Album>,
|
||||||
protected var itemLayoutRes: Int,
|
var itemLayoutRes: Int,
|
||||||
usePalette: Boolean,
|
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(
|
) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(
|
||||||
activity,
|
activity,
|
||||||
|
@ -39,28 +36,15 @@ open class AlbumAdapter(
|
||||||
R.menu.menu_media_selection
|
R.menu.menu_media_selection
|
||||||
), PopupTextProvider {
|
), PopupTextProvider {
|
||||||
|
|
||||||
var dataSet: ArrayList<Album>
|
var dataSet: List<Album>
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
protected var usePalette = false
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
this.usePalette = usePalette
|
|
||||||
this.setHasStableIds(true)
|
this.setHasStableIds(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun useItemLayout(itemLayoutRes: Int) {
|
fun swapDataSet(dataSet: List<Album>) {
|
||||||
this.itemLayoutRes = itemLayoutRes
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun usePalette(usePalette: Boolean) {
|
|
||||||
this.usePalette = usePalette
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun swapDataSet(dataSet: ArrayList<Album>) {
|
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
@ -79,7 +63,7 @@ open class AlbumAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun getAlbumText(album: Album): String? {
|
protected open fun getAlbumText(album: Album): String? {
|
||||||
return album.artistName
|
return album.artist
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
@ -88,15 +72,6 @@ open class AlbumAdapter(
|
||||||
holder.itemView.isActivated = isChecked
|
holder.itemView.isActivated = isChecked
|
||||||
holder.title?.text = getAlbumTitle(album)
|
holder.title?.text = getAlbumTitle(album)
|
||||||
holder.text?.text = getAlbumText(album)
|
holder.text?.text = getAlbumText(album)
|
||||||
holder.playSongs?.setOnClickListener {
|
|
||||||
album.songs?.let { songs ->
|
|
||||||
MusicPlayerRemote.openQueue(
|
|
||||||
songs,
|
|
||||||
0,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadAlbumCover(album, holder)
|
loadAlbumCover(album, holder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,15 +98,12 @@ open class AlbumAdapter(
|
||||||
if (holder.image == null) {
|
if (holder.image == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
AlbumGlideRequest.Builder(Glide.with(activity), album.id)
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
.generatePalette(activity)
|
||||||
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
.build()
|
||||||
|
.dontAnimate()
|
||||||
|
.dontTransform()
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
override fun onLoadCleared(placeholder: Drawable?) {
|
|
||||||
super.onLoadCleared(placeholder)
|
|
||||||
setColors(defaultFooterColor, holder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
setColors(color, holder)
|
setColors(color, holder)
|
||||||
}
|
}
|
||||||
|
@ -143,7 +115,7 @@ open class AlbumAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
return dataSet[position].id.toLong()
|
return dataSet[position].id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIdentifier(position: Int): Album? {
|
override fun getIdentifier(position: Int): Album? {
|
||||||
|
@ -163,7 +135,7 @@ open class AlbumAdapter(
|
||||||
private fun getSongList(albums: List<Album>): ArrayList<Song> {
|
private fun getSongList(albums: List<Album>): ArrayList<Song> {
|
||||||
val songs = ArrayList<Song>()
|
val songs = ArrayList<Song>()
|
||||||
for (album in albums) {
|
for (album in albums) {
|
||||||
songs.addAll(album.songs!!)
|
//songs.addAll(album.songs!!)
|
||||||
}
|
}
|
||||||
return songs
|
return songs
|
||||||
}
|
}
|
||||||
|
@ -177,7 +149,7 @@ open class AlbumAdapter(
|
||||||
when (PreferenceUtil.getInstance(activity).albumSortOrder) {
|
when (PreferenceUtil.getInstance(activity).albumSortOrder) {
|
||||||
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName =
|
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName =
|
||||||
dataSet[position].title
|
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(
|
SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString(
|
||||||
dataSet[position].year
|
dataSet[position].year
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,9 +22,8 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import code.name.monkey.retromusic.R
|
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.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.model.Album
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.NavigationUtil
|
||||||
import code.name.monkey.retromusic.views.MetalRecyclerViewPager
|
import code.name.monkey.retromusic.views.MetalRecyclerViewPager
|
||||||
|
@ -46,15 +45,6 @@ class AlbumFullWidthAdapter(
|
||||||
val album = dataSet[position]
|
val album = dataSet[position]
|
||||||
holder.title?.text = getAlbumTitle(album)
|
holder.title?.text = getAlbumTitle(album)
|
||||||
holder.text?.text = getAlbumText(album)
|
holder.text?.text = getAlbumText(album)
|
||||||
holder.playSongs?.setOnClickListener {
|
|
||||||
album.songs?.let { songs ->
|
|
||||||
MusicPlayerRemote.openQueue(
|
|
||||||
songs,
|
|
||||||
0,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadAlbumCover(album, holder)
|
loadAlbumCover(album, holder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,21 +53,32 @@ class AlbumFullWidthAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlbumText(album: Album): String? {
|
private fun getAlbumText(album: Album): String? {
|
||||||
return album.artistName
|
return album.artist
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAlbumCover(album: Album, holder: FullMetalViewHolder) {
|
private fun loadAlbumCover(album: Album, holder: FullMetalViewHolder) {
|
||||||
if (holder.image == null) {
|
if (holder.image == null) {
|
||||||
return
|
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)
|
.checkIgnoreMediaStore(activity)
|
||||||
.generatePalette(activity)
|
.generatePalette(activity)
|
||||||
.build()
|
.build()
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
}
|
}
|
||||||
})
|
})*/
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
|
|
|
@ -1,26 +1,23 @@
|
||||||
package code.name.monkey.retromusic.adapter.album
|
package code.name.monkey.retromusic.adapter.album
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
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.RetroMusicColoredTarget
|
||||||
import code.name.monkey.retromusic.glide.SongGlideRequest
|
|
||||||
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
|
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
class HorizontalAlbumAdapter(
|
class HorizontalAlbumAdapter(
|
||||||
activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Album>,
|
dataSet: List<Album>,
|
||||||
usePalette: Boolean,
|
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : AlbumAdapter(
|
) : AlbumAdapter(
|
||||||
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder
|
activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, cabHolder
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
override fun createViewHolder(view: View, viewType: Int): ViewHolder {
|
||||||
|
@ -36,17 +33,14 @@ class HorizontalAlbumAdapter(
|
||||||
|
|
||||||
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
|
||||||
if (holder.image == null) return
|
if (holder.image == null) return
|
||||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
AlbumGlideRequest.Builder(Glide.with(activity), album.id)
|
||||||
.checkIgnoreMediaStore(activity).generatePalette(activity).build()
|
.generatePalette(activity)
|
||||||
|
.build()
|
||||||
|
.dontAnimate()
|
||||||
|
.dontTransform()
|
||||||
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
.into(object : RetroMusicColoredTarget(holder.image!!) {
|
||||||
override fun onLoadCleared(placeholder: Drawable?) {
|
|
||||||
super.onLoadCleared(placeholder)
|
|
||||||
setColors(albumArtistFooterColor, holder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
if (usePalette) setColors(color, holder)
|
//setColors(color, holder)
|
||||||
else setColors(albumArtistFooterColor, holder)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,26 +28,20 @@ import java.util.ArrayList
|
||||||
|
|
||||||
class ArtistAdapter(
|
class ArtistAdapter(
|
||||||
val activity: AppCompatActivity,
|
val activity: AppCompatActivity,
|
||||||
var dataSet: ArrayList<Artist>,
|
var dataSet: List<Artist>,
|
||||||
var itemLayoutRes: Int,
|
var itemLayoutRes: Int,
|
||||||
var usePalette: Boolean,
|
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
|
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(
|
||||||
activity, cabHolder, R.menu.menu_media_selection
|
activity, cabHolder, R.menu.menu_media_selection
|
||||||
), PopupTextProvider {
|
), PopupTextProvider {
|
||||||
|
|
||||||
fun swapDataSet(dataSet: ArrayList<Artist>) {
|
fun swapDataSet(dataSet: List<Artist>) {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun usePalette(usePalette: Boolean) {
|
|
||||||
this.usePalette = usePalette
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
override fun getItemId(position: Int): Long {
|
||||||
return dataSet[position].id.toLong()
|
return dataSet[position].id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
@ -121,7 +115,7 @@ class ArtistAdapter(
|
||||||
private fun getSongList(artists: List<Artist>): ArrayList<Song> {
|
private fun getSongList(artists: List<Artist>): ArrayList<Song> {
|
||||||
val songs = ArrayList<Song>()
|
val songs = ArrayList<Song>()
|
||||||
for (artist in artists) {
|
for (artist in artists) {
|
||||||
songs.addAll(artist.songs) // maybe async in future?
|
//songs.addAll(artist.songs) // maybe async in future?
|
||||||
}
|
}
|
||||||
return songs
|
return songs
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package code.name.monkey.retromusic.adapter.base;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -60,8 +59,6 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
|
||||||
@Nullable
|
@Nullable
|
||||||
public View paletteColorContainer;
|
public View paletteColorContainer;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public ImageButton playSongs;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public RecyclerView recyclerView;
|
public RecyclerView recyclerView;
|
||||||
|
@ -93,7 +90,6 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold
|
||||||
paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
|
paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer);
|
||||||
recyclerView = itemView.findViewById(R.id.recycler_view);
|
recyclerView = itemView.findViewById(R.id.recycler_view);
|
||||||
mask = itemView.findViewById(R.id.mask);
|
mask = itemView.findViewById(R.id.mask);
|
||||||
playSongs = itemView.findViewById(R.id.playSongs);
|
|
||||||
dummyContainer = itemView.findViewById(R.id.dummy_view);
|
dummyContainer = itemView.findViewById(R.id.dummy_view);
|
||||||
|
|
||||||
if (imageContainerCard != null) {
|
if (imageContainerCard != null) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ import java.util.ArrayList
|
||||||
|
|
||||||
class PlaylistAdapter(
|
class PlaylistAdapter(
|
||||||
private val activity: AppCompatActivity,
|
private val activity: AppCompatActivity,
|
||||||
var dataSet: ArrayList<Playlist>,
|
var dataSet: List<Playlist>,
|
||||||
private var itemLayoutRes: Int,
|
private var itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(
|
) : AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist>(
|
||||||
|
@ -49,7 +49,7 @@ class PlaylistAdapter(
|
||||||
setHasStableIds(true)
|
setHasStableIds(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun swapDataSet(dataSet: ArrayList<Playlist>) {
|
fun swapDataSet(dataSet: List<Playlist>) {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,10 @@ import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
abstract class AbsOffsetSongAdapter(
|
abstract class AbsOffsetSongAdapter(
|
||||||
activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Song>,
|
dataSet: MutableList<Song>,
|
||||||
@LayoutRes itemLayoutRes: Int,
|
@LayoutRes itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
||||||
|
|
|
@ -63,7 +63,7 @@ open class PlaylistSongAdapter(
|
||||||
imageContainerCard ?: image,
|
imageContainerCard ?: image,
|
||||||
"${activity.getString(R.string.transition_album_art)}_${song.albumId}"
|
"${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 true
|
||||||
}
|
}
|
||||||
return super.onSongMenuItemClick(item)
|
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.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
class ShuffleButtonSongAdapter(
|
class ShuffleButtonSongAdapter(
|
||||||
activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Song>,
|
dataSet: MutableList<Song>,
|
||||||
itemLayoutRes: Int,
|
itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) {
|
||||||
|
|
|
@ -6,18 +6,16 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
class SimpleSongAdapter(
|
class SimpleSongAdapter(
|
||||||
context: AppCompatActivity,
|
context: AppCompatActivity,
|
||||||
songs: ArrayList<Song>,
|
songs: MutableList<Song>,
|
||||||
layoutRes: Int,
|
layoutRes: Int,
|
||||||
cabHolder: CabHolder?
|
cabHolder: CabHolder?
|
||||||
) : SongAdapter(context, songs, layoutRes, cabHolder) {
|
) : SongAdapter(context, songs, layoutRes, cabHolder) {
|
||||||
|
|
||||||
override fun swapDataSet(dataSet: ArrayList<Song>) {
|
override fun swapDataSet(dataSet: List<Song>) {
|
||||||
this.dataSet.clear()
|
this.dataSet = dataSet.toMutableList()
|
||||||
this.dataSet = dataSet
|
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import java.util.ArrayList
|
||||||
|
|
||||||
open class SongAdapter(
|
open class SongAdapter(
|
||||||
protected val activity: AppCompatActivity,
|
protected val activity: AppCompatActivity,
|
||||||
dataSet: ArrayList<Song>,
|
dataSet: MutableList<Song>,
|
||||||
protected var itemLayoutRes: Int,
|
protected var itemLayoutRes: Int,
|
||||||
cabHolder: CabHolder?,
|
cabHolder: CabHolder?,
|
||||||
showSectionName: Boolean = true
|
showSectionName: Boolean = true
|
||||||
|
@ -42,7 +42,7 @@ open class SongAdapter(
|
||||||
activity, cabHolder, R.menu.menu_media_selection
|
activity, cabHolder, R.menu.menu_media_selection
|
||||||
), MaterialCab.Callback, PopupTextProvider {
|
), MaterialCab.Callback, PopupTextProvider {
|
||||||
|
|
||||||
var dataSet: ArrayList<Song>
|
var dataSet: MutableList<Song>
|
||||||
private var showSectionName = true
|
private var showSectionName = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -51,8 +51,8 @@ open class SongAdapter(
|
||||||
this.setHasStableIds(true)
|
this.setHasStableIds(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun swapDataSet(dataSet: ArrayList<Song>) {
|
open fun swapDataSet(dataSet: List<Song>) {
|
||||||
this.dataSet = dataSet
|
this.dataSet = dataSet.toMutableList()
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ open class SongAdapter(
|
||||||
imageContainerCard ?: image,
|
imageContainerCard ?: image,
|
||||||
"${activity.getString(R.string.transition_album_art)}_${song.albumId}"
|
"${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 true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,10 @@ import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||||
import com.afollestad.materialdialogs.list.listItems
|
import com.afollestad.materialdialogs.list.listItems
|
||||||
|
|
||||||
|
|
||||||
class AddToPlaylistDialog : DialogFragment() {
|
class AddToPlaylistDialog : DialogFragment() {
|
||||||
|
|
||||||
override fun onCreateDialog(
|
override fun onCreateDialog(
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): Dialog {
|
): Dialog {
|
||||||
val playlists = PlaylistLoader.getAllPlaylists(requireContext())
|
val playlists = PlaylistLoader.getAllPlaylists(requireContext())
|
||||||
val playlistNames: MutableList<String> = mutableListOf()
|
val playlistNames: MutableList<String> = mutableListOf()
|
||||||
|
@ -47,7 +46,9 @@ class AddToPlaylistDialog : DialogFragment() {
|
||||||
val songs = arguments!!.getParcelableArrayList<Song>("songs") ?: return@listItems
|
val songs = arguments!!.getParcelableArrayList<Song>("songs") ?: return@listItems
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") }
|
activity?.supportFragmentManager?.let {
|
||||||
|
CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlists[index - 1].id, true)
|
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlists[index - 1].id, true)
|
||||||
|
@ -64,10 +65,10 @@ class AddToPlaylistDialog : DialogFragment() {
|
||||||
return create(list)
|
return create(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(songs: ArrayList<Song>): AddToPlaylistDialog {
|
fun create(songs: List<Song>): AddToPlaylistDialog {
|
||||||
val dialog = AddToPlaylistDialog()
|
val dialog = AddToPlaylistDialog()
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putParcelableArrayList("songs", songs)
|
args.putParcelableArrayList("songs", ArrayList(songs))
|
||||||
dialog.arguments = args
|
dialog.arguments = args
|
||||||
return dialog
|
return dialog
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||||
import com.afollestad.materialdialogs.list.listItems
|
import com.afollestad.materialdialogs.list.listItems
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.Collections
|
||||||
import kotlin.collections.ArrayList
|
import java.util.Comparator
|
||||||
|
|
||||||
class BlacklistFolderChooserDialog : DialogFragment() {
|
class BlacklistFolderChooserDialog : DialogFragment() {
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ class BlacklistFolderChooserDialog : DialogFragment() {
|
||||||
private var canGoUp = false
|
private var canGoUp = false
|
||||||
private var callback: FolderCallback? = null
|
private var callback: FolderCallback? = null
|
||||||
|
|
||||||
|
|
||||||
private fun contentsArray(): List<String> {
|
private fun contentsArray(): List<String> {
|
||||||
if (parentContents == null) {
|
if (parentContents == null) {
|
||||||
return if (canGoUp) {
|
return if (canGoUp) {
|
||||||
|
@ -81,7 +80,11 @@ class BlacklistFolderChooserDialog : DialogFragment() {
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
var savedInstanceStateFinal = savedInstanceState
|
var savedInstanceStateFinal = savedInstanceState
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
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 {
|
return MaterialDialog(requireActivity(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||||
title(R.string.md_error_label)
|
title(R.string.md_error_label)
|
||||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
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
|
||||||
import code.name.monkey.retromusic.R.layout
|
import code.name.monkey.retromusic.R.layout
|
||||||
import code.name.monkey.retromusic.R.string
|
import code.name.monkey.retromusic.R.string
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.PlaylistsUtil
|
import code.name.monkey.retromusic.util.PlaylistsUtil
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
|
@ -35,36 +34,35 @@ import com.afollestad.materialdialogs.customview.getCustomView
|
||||||
import com.google.android.material.textfield.TextInputEditText
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
|
|
||||||
|
|
||||||
class CreatePlaylistDialog : DialogFragment() {
|
class CreatePlaylistDialog : DialogFragment() {
|
||||||
|
|
||||||
private lateinit var playlistView: TextInputEditText
|
private lateinit var playlistView: TextInputEditText
|
||||||
private lateinit var actionNewPlaylistContainer: TextInputLayout
|
private lateinit var actionNewPlaylistContainer: TextInputLayout
|
||||||
|
|
||||||
override fun onCreateDialog(
|
override fun onCreateDialog(
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): Dialog {
|
): Dialog {
|
||||||
val materialDialog = MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT))
|
val materialDialog = MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT))
|
||||||
.show {
|
.show {
|
||||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||||
title(string.new_playlist_title)
|
title(string.new_playlist_title)
|
||||||
customView(layout.dialog_playlist)
|
customView(layout.dialog_playlist)
|
||||||
negativeButton(android.R.string.cancel)
|
negativeButton(android.R.string.cancel)
|
||||||
positiveButton(string.create_action) {
|
positiveButton(string.create_action) {
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
return@positiveButton
|
return@positiveButton
|
||||||
}
|
}
|
||||||
val songs = arguments?.getParcelableArrayList<Song>("songs")
|
val songs = arguments?.getParcelableArrayList<Song>("songs")
|
||||||
?: return@positiveButton
|
?: return@positiveButton
|
||||||
|
|
||||||
if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) {
|
if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) {
|
||||||
val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString())
|
val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString())
|
||||||
if (playlistId != -1 && activity != null) {
|
if (playlistId != -1 && activity != null) {
|
||||||
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true)
|
PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val dialogView = materialDialog.getCustomView()
|
val dialogView = materialDialog.getCustomView()
|
||||||
playlistView = dialogView.findViewById(R.id.actionNewPlaylist)
|
playlistView = dialogView.findViewById(R.id.actionNewPlaylist)
|
||||||
|
@ -73,7 +71,10 @@ class CreatePlaylistDialog : DialogFragment() {
|
||||||
MaterialUtil.setTint(actionNewPlaylistContainer, false)
|
MaterialUtil.setTint(actionNewPlaylistContainer, false)
|
||||||
|
|
||||||
val playlistId = arguments!!.getLong(MediaStore.Audio.Playlists.Members.PLAYLIST_ID)
|
val playlistId = arguments!!.getLong(MediaStore.Audio.Playlists.Members.PLAYLIST_ID)
|
||||||
playlistView.appHandleColor().setText(PlaylistsUtil.getNameForPlaylist(requireContext(), playlistId), TextView.BufferType.EDITABLE)
|
playlistView.setText(
|
||||||
|
PlaylistsUtil.getNameForPlaylist(requireContext(), playlistId),
|
||||||
|
TextView.BufferType.EDITABLE
|
||||||
|
)
|
||||||
return materialDialog
|
return materialDialog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,10 +104,10 @@ class DeleteSongsDialog : DialogFragment() {
|
||||||
return create(list)
|
return create(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(songs: ArrayList<Song>): DeleteSongsDialog {
|
fun create(songs: List<Song>): DeleteSongsDialog {
|
||||||
val dialog = DeleteSongsDialog()
|
val dialog = DeleteSongsDialog()
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putParcelableArrayList("songs", songs)
|
args.putParcelableArrayList("songs", ArrayList(songs))
|
||||||
dialog.arguments = args
|
dialog.arguments = args
|
||||||
return dialog
|
return dialog
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.R.layout
|
import code.name.monkey.retromusic.R.layout
|
||||||
import code.name.monkey.retromusic.R.string
|
import code.name.monkey.retromusic.R.string
|
||||||
import code.name.monkey.retromusic.extensions.appHandleColor
|
|
||||||
import code.name.monkey.retromusic.util.PlaylistsUtil
|
import code.name.monkey.retromusic.util.PlaylistsUtil
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import com.afollestad.materialdialogs.LayoutMode
|
import com.afollestad.materialdialogs.LayoutMode
|
||||||
|
@ -60,7 +59,7 @@ class RenamePlaylistDialog : DialogFragment() {
|
||||||
MaterialUtil.setTint(actionNewPlaylistContainer, false)
|
MaterialUtil.setTint(actionNewPlaylistContainer, false)
|
||||||
|
|
||||||
val playlistId = arguments!!.getLong(PLAYLIST_ID)
|
val playlistId = arguments!!.getLong(PLAYLIST_ID)
|
||||||
playlistView.appHandleColor()
|
playlistView
|
||||||
.setText(PlaylistsUtil.getNameForPlaylist(context!!, playlistId), TextView.BufferType.EDITABLE)
|
.setText(PlaylistsUtil.getNameForPlaylist(context!!, playlistId), TextView.BufferType.EDITABLE)
|
||||||
return materialDialog
|
return materialDialog
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.EditText
|
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
|
||||||
import code.name.monkey.appthemehelper.util.TintHelper
|
|
||||||
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T : View> ViewGroup.inflate(@LayoutRes layout: Int): T {
|
fun <T : View> ViewGroup.inflate(@LayoutRes layout: Int): T {
|
||||||
|
@ -41,8 +37,3 @@ fun View.hidden() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun View.showOrHide(show: Boolean) = if (show) show() else hide()
|
fun View.showOrHide(show: Boolean) = if (show) show() else hide()
|
||||||
|
|
||||||
fun EditText.appHandleColor(): EditText {
|
|
||||||
TintHelper.colorHandles(this, ThemeStore.accentColor(context))
|
|
||||||
return this
|
|
||||||
}
|
|
|
@ -10,21 +10,19 @@ enum class NowPlayingScreen constructor(
|
||||||
@param:DrawableRes @field:DrawableRes val drawableResId: Int,
|
@param:DrawableRes @field:DrawableRes val drawableResId: Int,
|
||||||
val id: 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),
|
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
|
||||||
BLUR(R.string.blur, R.drawable.np_blur, 4),
|
BLUR(R.string.blur, R.drawable.np_blur, 4),
|
||||||
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
|
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
|
||||||
CARD(R.string.card, R.drawable.np_card, 6),
|
CARD(R.string.card, R.drawable.np_card, 6),
|
||||||
COLOR(R.string.color, R.drawable.np_color, 5),
|
COLOR(R.string.color, R.drawable.np_color, 5),
|
||||||
CIRCLE(R.string.circle, R.drawable.np_minimalistic_circle, 15),
|
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),
|
FULL(R.string.full, R.drawable.np_full, 2),
|
||||||
MATERIAL(R.string.material, R.drawable.np_material, 11),
|
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),
|
PLAIN(R.string.plain, R.drawable.np_plain, 3),
|
||||||
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
|
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) {
|
fun setAndSaveLayoutRes(layoutRes: Int) {
|
||||||
setLayoutRes(layoutRes)
|
setLayoutRes(layoutRes)
|
||||||
saveLayoutRes(layoutRes)
|
saveLayoutRes(layoutRes)
|
||||||
|
invalidateAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val maxGridSizeForList: Int
|
private val maxGridSizeForList: Int
|
||||||
|
@ -118,12 +119,6 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A : RecyclerVie
|
||||||
|
|
||||||
protected abstract fun saveGridSizeLand(gridColumns: Int)
|
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 loadLayoutRes(): Int
|
||||||
|
|
||||||
protected abstract fun saveLayoutRes(layoutRes: Int)
|
protected abstract fun saveLayoutRes(layoutRes: Int)
|
||||||
|
|
|
@ -111,7 +111,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.action_go_to_artist -> {
|
R.id.action_go_to_artist -> {
|
||||||
NavigationUtil.goToArtist(requireActivity(), song.artistId)
|
NavigationUtil.goToArtist(requireActivity(), song.artistId.toInt())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.now_playing -> {
|
R.id.now_playing -> {
|
||||||
|
|
|
@ -41,7 +41,7 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
||||||
albumsPresenter.detachView()
|
albumsPresenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun albums(albums: java.util.ArrayList<Album>) {
|
override fun albums(albums: List<Album>) {
|
||||||
adapter?.swapDataSet(albums)
|
adapter?.swapDataSet(albums)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,21 +53,13 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createAdapter(): AlbumAdapter {
|
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
|
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
|
||||||
return AlbumAdapter(libraryFragment.mainActivity, dataSet, itemLayoutRes(), loadUsePalette(), libraryFragment)
|
return AlbumAdapter(
|
||||||
}
|
libraryFragment.mainActivity,
|
||||||
|
dataSet,
|
||||||
public override fun loadUsePalette(): Boolean {
|
itemLayoutRes(),
|
||||||
return PreferenceUtil.getInstance(requireContext()).albumColoredFooters()
|
libraryFragment
|
||||||
}
|
)
|
||||||
|
|
||||||
override fun setUsePalette(usePalette: Boolean) {
|
|
||||||
adapter?.usePalette(usePalette)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setGridSize(gridSize: Int) {
|
override fun setGridSize(gridSize: Int) {
|
||||||
|
@ -99,10 +91,6 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
||||||
PreferenceUtil.getInstance(requireContext()).setAlbumGridSizeLand(gridColumns)
|
PreferenceUtil.getInstance(requireContext()).setAlbumGridSizeLand(gridColumns)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveUsePalette(usePalette: Boolean) {
|
|
||||||
PreferenceUtil.getInstance(requireContext()).setAlbumColoredFooters(usePalette)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
override fun onMediaStoreChanged() {
|
||||||
albumsPresenter.loadAlbums()
|
albumsPresenter.loadAlbums()
|
||||||
}
|
}
|
||||||
|
@ -116,7 +104,6 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLayoutRes(layoutRes: Int) {
|
override fun setLayoutRes(layoutRes: Int) {
|
||||||
//adapter?.itemCount?.let { adapter?.notifyItemRangeChanged(0, it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadLayoutRes(): Int {
|
override fun loadLayoutRes(): Int {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import javax.inject.Inject
|
||||||
class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(),
|
class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(),
|
||||||
ArtistsView {
|
ArtistsView {
|
||||||
|
|
||||||
override fun artists(artists: ArrayList<Artist>) {
|
override fun artists(artists: List<Artist>) {
|
||||||
adapter?.swapDataSet(artists)
|
adapter?.swapDataSet(artists)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,6 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
|
||||||
libraryFragment.mainActivity,
|
libraryFragment.mainActivity,
|
||||||
dataSet,
|
dataSet,
|
||||||
itemLayoutRes(),
|
itemLayoutRes(),
|
||||||
loadUsePalette(),
|
|
||||||
libraryFragment
|
libraryFragment
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -87,18 +86,6 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
|
||||||
PreferenceUtil.getInstance(requireContext()).setArtistGridSizeLand(gridColumns)
|
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) {
|
override fun setGridSize(gridSize: Int) {
|
||||||
layoutManager?.spanCount = gridSize
|
layoutManager?.spanCount = gridSize
|
||||||
adapter?.notifyDataSetChanged()
|
adapter?.notifyDataSetChanged()
|
||||||
|
@ -121,9 +108,7 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
|
||||||
val TAG: String = ArtistsFragment::class.java.simpleName
|
val TAG: String = ArtistsFragment::class.java.simpleName
|
||||||
|
|
||||||
fun newInstance(): ArtistsFragment {
|
fun newInstance(): ArtistsFragment {
|
||||||
|
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
|
|
||||||
val fragment = ArtistsFragment()
|
val fragment = ArtistsFragment()
|
||||||
fragment.arguments = args
|
fragment.arguments = args
|
||||||
return fragment
|
return fragment
|
||||||
|
|
|
@ -26,14 +26,12 @@ import code.name.monkey.retromusic.mvp.presenter.GenresPresenter
|
||||||
import code.name.monkey.retromusic.mvp.presenter.GenresView
|
import code.name.monkey.retromusic.mvp.presenter.GenresView
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(), GenresView {
|
class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(), GenresView {
|
||||||
override fun genres(genres: ArrayList<Genre>) {
|
override fun genres(genres: List<Genre>) {
|
||||||
adapter?.swapDataSet(genres)
|
adapter?.swapDataSet(genres)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showEmptyView() {
|
override fun showEmptyView() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createLayoutManager(): LinearLayoutManager {
|
override fun createLayoutManager(): LinearLayoutManager {
|
||||||
|
@ -48,11 +46,9 @@ class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearL
|
||||||
override val emptyMessage: Int
|
override val emptyMessage: Int
|
||||||
get() = R.string.no_genres
|
get() = R.string.no_genres
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var genresPresenter: GenresPresenter
|
lateinit var genresPresenter: GenresPresenter
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
App.musicComponent.inject(this)
|
App.musicComponent.inject(this)
|
||||||
|
@ -62,6 +58,7 @@ class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearL
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
genresPresenter.attachView(this)
|
genresPresenter.attachView(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if (adapter!!.dataSet.isEmpty()) {
|
if (adapter!!.dataSet.isEmpty()) {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package code.name.monkey.retromusic.fragments.mainactivity;
|
package code.name.monkey.retromusic.fragments.mainactivity;
|
||||||
|
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder;
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder;
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.SongSortOrder;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
|
@ -27,7 +31,6 @@ import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog;
|
||||||
import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment;
|
import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment;
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment;
|
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment;
|
||||||
import code.name.monkey.retromusic.helper.SortOrder;
|
|
||||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||||
|
@ -301,49 +304,52 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
||||||
if (fragment instanceof AlbumsFragment) {
|
if (fragment instanceof AlbumsFragment) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_album_sort_order_asc:
|
case R.id.action_album_sort_order_asc:
|
||||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z;
|
sortOrder = AlbumSortOrder.ALBUM_A_Z;
|
||||||
break;
|
break;
|
||||||
case R.id.action_album_sort_order_desc:
|
case R.id.action_album_sort_order_desc:
|
||||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A;
|
sortOrder = AlbumSortOrder.ALBUM_Z_A;
|
||||||
break;
|
break;
|
||||||
case R.id.action_album_sort_order_artist:
|
case R.id.action_album_sort_order_artist:
|
||||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST;
|
sortOrder = AlbumSortOrder.ALBUM_ARTIST;
|
||||||
break;
|
break;
|
||||||
case R.id.action_album_sort_order_year:
|
case R.id.action_album_sort_order_year:
|
||||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR;
|
sortOrder = AlbumSortOrder.ALBUM_YEAR;
|
||||||
|
break;
|
||||||
|
case R.id.action_album_sort_num_songs:
|
||||||
|
sortOrder = AlbumSortOrder.ALBUM_NUMBER_OF_SONGS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (fragment instanceof ArtistsFragment) {
|
} else if (fragment instanceof ArtistsFragment) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_artist_sort_order_asc:
|
case R.id.action_artist_sort_order_asc:
|
||||||
sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z;
|
sortOrder = ArtistSortOrder.ARTIST_A_Z;
|
||||||
break;
|
break;
|
||||||
case R.id.action_artist_sort_order_desc:
|
case R.id.action_artist_sort_order_desc:
|
||||||
sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A;
|
sortOrder = ArtistSortOrder.ARTIST_Z_A;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (fragment instanceof SongsFragment) {
|
} else if (fragment instanceof SongsFragment) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_song_sort_order_asc:
|
case R.id.action_song_sort_order_asc:
|
||||||
sortOrder = SortOrder.SongSortOrder.SONG_A_Z;
|
sortOrder = SongSortOrder.SONG_A_Z;
|
||||||
break;
|
break;
|
||||||
case R.id.action_song_sort_order_desc:
|
case R.id.action_song_sort_order_desc:
|
||||||
sortOrder = SortOrder.SongSortOrder.SONG_Z_A;
|
sortOrder = SongSortOrder.SONG_Z_A;
|
||||||
break;
|
break;
|
||||||
case R.id.action_song_sort_order_artist:
|
case R.id.action_song_sort_order_artist:
|
||||||
sortOrder = SortOrder.SongSortOrder.SONG_ARTIST;
|
sortOrder = SongSortOrder.SONG_ARTIST;
|
||||||
break;
|
break;
|
||||||
case R.id.action_song_sort_order_album:
|
case R.id.action_song_sort_order_album:
|
||||||
sortOrder = SortOrder.SongSortOrder.SONG_ALBUM;
|
sortOrder = SongSortOrder.SONG_ALBUM;
|
||||||
break;
|
break;
|
||||||
case R.id.action_song_sort_order_year:
|
case R.id.action_song_sort_order_year:
|
||||||
sortOrder = SortOrder.SongSortOrder.SONG_YEAR;
|
sortOrder = SongSortOrder.SONG_YEAR;
|
||||||
break;
|
break;
|
||||||
case R.id.action_song_sort_order_date:
|
case R.id.action_song_sort_order_date:
|
||||||
sortOrder = SortOrder.SongSortOrder.SONG_DATE;
|
sortOrder = SongSortOrder.SONG_DATE;
|
||||||
break;
|
break;
|
||||||
case R.id.action_song_sort_order_composer:
|
case R.id.action_song_sort_order_composer:
|
||||||
sortOrder = SortOrder.SongSortOrder.COMPOSER;
|
sortOrder = SongSortOrder.COMPOSER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -452,33 +458,35 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
||||||
|
|
||||||
if (fragment instanceof AlbumsFragment) {
|
if (fragment instanceof AlbumsFragment) {
|
||||||
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z)
|
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_A_Z));
|
.setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_A_Z));
|
||||||
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a)
|
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_Z_A));
|
.setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_Z_A));
|
||||||
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist)
|
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST));
|
.setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_ARTIST));
|
||||||
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year)
|
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_YEAR));
|
.setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_YEAR));
|
||||||
|
sortOrderMenu.add(0, R.id.action_album_sort_num_songs, 4, R.string.sort_num_songs)
|
||||||
|
.setChecked(currentSortOrder.equals(AlbumSortOrder.ALBUM_NUMBER_OF_SONGS));
|
||||||
} else if (fragment instanceof ArtistsFragment) {
|
} else if (fragment instanceof ArtistsFragment) {
|
||||||
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z)
|
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_A_Z));
|
.setChecked(currentSortOrder.equals(ArtistSortOrder.ARTIST_A_Z));
|
||||||
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a)
|
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_Z_A));
|
.setChecked(currentSortOrder.equals(ArtistSortOrder.ARTIST_Z_A));
|
||||||
} else if (fragment instanceof SongsFragment) {
|
} else if (fragment instanceof SongsFragment) {
|
||||||
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z)
|
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_A_Z));
|
.setChecked(currentSortOrder.equals(SongSortOrder.SONG_A_Z));
|
||||||
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a)
|
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_Z_A));
|
.setChecked(currentSortOrder.equals(SongSortOrder.SONG_Z_A));
|
||||||
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist)
|
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ARTIST));
|
.setChecked(currentSortOrder.equals(SongSortOrder.SONG_ARTIST));
|
||||||
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album)
|
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ALBUM));
|
.setChecked(currentSortOrder.equals(SongSortOrder.SONG_ALBUM));
|
||||||
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year)
|
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_YEAR));
|
.setChecked(currentSortOrder.equals(SongSortOrder.SONG_YEAR));
|
||||||
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 5, R.string.sort_order_date)
|
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 5, R.string.sort_order_date)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_DATE));
|
.setChecked(currentSortOrder.equals(SongSortOrder.SONG_DATE));
|
||||||
sortOrderMenu.add(0, R.id.action_song_sort_order_composer, 6, R.string.sort_order_composer)
|
sortOrderMenu.add(0, R.id.action_song_sort_order_composer, 6, R.string.sort_order_composer)
|
||||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.COMPOSER));
|
.setChecked(currentSortOrder.equals(SongSortOrder.COMPOSER));
|
||||||
}
|
}
|
||||||
|
|
||||||
sortOrderMenu.setGroupCheckable(0, true, true);
|
sortOrderMenu.setGroupCheckable(0, true, true);
|
||||||
|
|
|
@ -63,7 +63,7 @@ class PlaylistsFragment : AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, L
|
||||||
adapter?.swapDataSet(ArrayList())
|
adapter?.swapDataSet(ArrayList())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun playlists(playlists: ArrayList<Playlist>) {
|
override fun playlists(playlists: List<Playlist>) {
|
||||||
adapter?.swapDataSet(playlists)
|
adapter?.swapDataSet(playlists)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createAdapter(): SongAdapter {
|
override fun createAdapter(): SongAdapter {
|
||||||
val dataSet = if (adapter == null) ArrayList() else adapter!!.dataSet
|
val dataSet = if (adapter == null) mutableListOf() else adapter!!.dataSet
|
||||||
return ShuffleButtonSongAdapter(
|
return ShuffleButtonSongAdapter(
|
||||||
libraryFragment.mainActivity,
|
libraryFragment.mainActivity,
|
||||||
dataSet,
|
dataSet,
|
||||||
|
@ -49,7 +49,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun songs(songs: ArrayList<Song>) {
|
override fun songs(songs: List<Song>) {
|
||||||
adapter?.swapDataSet(songs)
|
adapter?.swapDataSet(songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,17 +73,6 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
|
||||||
PreferenceUtil.getInstance(requireContext()).setSongGridSizeLand(gridColumns)
|
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) {
|
override fun setGridSize(gridSize: Int) {
|
||||||
adapter?.notifyDataSetChanged()
|
adapter?.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ class BlurPlayerFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPrefer
|
||||||
private fun updateBlur() {
|
private fun updateBlur() {
|
||||||
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
|
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
|
||||||
colorBackground!!.clearColorFilter()
|
colorBackground?.clearColorFilter()
|
||||||
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
||||||
.checkIgnoreMediaStore(requireContext())
|
.checkIgnoreMediaStore(requireContext())
|
||||||
.generatePalette(requireContext()).build()
|
.generatePalette(requireContext()).build()
|
||||||
|
@ -109,7 +109,7 @@ class BlurPlayerFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPrefer
|
||||||
.into(object : RetroMusicColoredTarget(colorBackground) {
|
.into(object : RetroMusicColoredTarget(colorBackground) {
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
if (color == defaultFooterColor) {
|
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.base.AbsPlayerFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||||
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
|
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.BlurTransformation
|
||||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
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.MusicPlayerRemote
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
|
@ -53,7 +53,7 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
|
||||||
override fun onColorChanged(color: Int) {
|
override fun onColorChanged(color: Int) {
|
||||||
playbackControlsFragment.setDark(color)
|
playbackControlsFragment.setDark(color)
|
||||||
lastColor = color
|
lastColor = color
|
||||||
callbacks!!.onPaletteColorChanged()
|
callbacks?.onPaletteColorChanged()
|
||||||
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
|
||||||
|
|
||||||
playerToolbar.setTitleTextColor(Color.WHITE)
|
playerToolbar.setTitleTextColor(Color.WHITE)
|
||||||
|
@ -127,10 +127,19 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateBlur() {
|
private fun updateBlur() {
|
||||||
|
colorBackground?.clearColorFilter()
|
||||||
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
|
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
|
||||||
colorBackground!!.clearColorFilter()
|
AlbumGlideRequest.Builder.from(Glide.with(requireContext()), MusicPlayerRemote.currentSong.albumId)
|
||||||
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
|
.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())
|
.checkIgnoreMediaStore(requireContext())
|
||||||
.generatePalette(requireContext()).build()
|
.generatePalette(requireContext()).build()
|
||||||
.transform(BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()).build())
|
.transform(BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()).build())
|
||||||
|
@ -138,11 +147,9 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
|
||||||
//.override(320, 480)
|
//.override(320, 480)
|
||||||
.into(object : RetroMusicColoredTarget(colorBackground) {
|
.into(object : RetroMusicColoredTarget(colorBackground) {
|
||||||
override fun onColorReady(color: Int) {
|
override fun onColorReady(color: Int) {
|
||||||
if (color == defaultFooterColor) {
|
|
||||||
colorBackground!!.setColorFilter(color)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})*/
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
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.PreferenceUtil
|
||||||
import code.name.monkey.retromusic.util.ViewUtil
|
import code.name.monkey.retromusic.util.ViewUtil
|
||||||
import code.name.monkey.retromusic.views.DrawableGradient
|
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() {
|
class PlayerFragment : AbsPlayerFragment() {
|
||||||
|
|
||||||
|
@ -30,18 +30,21 @@ class PlayerFragment : AbsPlayerFragment() {
|
||||||
private lateinit var playbackControlsFragment: PlayerPlaybackControlsFragment
|
private lateinit var playbackControlsFragment: PlayerPlaybackControlsFragment
|
||||||
private var valueAnimator: ValueAnimator? = null
|
private var valueAnimator: ValueAnimator? = null
|
||||||
|
|
||||||
|
|
||||||
private fun colorize(i: Int) {
|
private fun colorize(i: Int) {
|
||||||
if (valueAnimator != null) {
|
if (valueAnimator != null) {
|
||||||
valueAnimator?.cancel()
|
valueAnimator?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
valueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), ATHUtil.resolveColor(requireContext(), R.attr.colorSurface), i)
|
valueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), lastColor, i)
|
||||||
valueAnimator?.addUpdateListener { animation ->
|
valueAnimator?.addUpdateListener { animation ->
|
||||||
if (isAdded) {
|
if (isAdded) {
|
||||||
val drawable = DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM,
|
val drawable = DrawableGradient(
|
||||||
intArrayOf(animation.animatedValue as Int,
|
GradientDrawable.Orientation.TOP_BOTTOM,
|
||||||
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)), 0)
|
intArrayOf(
|
||||||
|
animation.animatedValue as Int,
|
||||||
|
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)
|
||||||
|
), 0
|
||||||
|
)
|
||||||
colorGradientBackground?.background = drawable
|
colorGradientBackground?.background = drawable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +73,11 @@ class PlayerFragment : AbsPlayerFragment() {
|
||||||
lastColor = color
|
lastColor = color
|
||||||
callbacks?.onPaletteColorChanged()
|
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) {
|
if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) {
|
||||||
colorize(color)
|
colorize(color)
|
||||||
|
@ -88,9 +95,10 @@ class PlayerFragment : AbsPlayerFragment() {
|
||||||
toggleFavorite(MusicPlayerRemote.currentSong)
|
toggleFavorite(MusicPlayerRemote.currentSong)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?): View? {
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
|
||||||
return inflater.inflate(R.layout.fragment_player, container, false)
|
return inflater.inflate(R.layout.fragment_player, container, false)
|
||||||
}
|
}
|
||||||
|
@ -101,19 +109,24 @@ class PlayerFragment : AbsPlayerFragment() {
|
||||||
setUpPlayerToolbar()
|
setUpPlayerToolbar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun setUpSubFragments() {
|
private fun setUpSubFragments() {
|
||||||
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
|
playbackControlsFragment =
|
||||||
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
|
||||||
|
val playerAlbumCoverFragment =
|
||||||
|
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||||
playerAlbumCoverFragment.setCallbacks(this)
|
playerAlbumCoverFragment.setCallbacks(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpPlayerToolbar() {
|
private fun setUpPlayerToolbar() {
|
||||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||||
playerToolbar.setNavigationOnClickListener {requireActivity().onBackPressed() }
|
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||||
playerToolbar.setOnMenuItemClickListener(this)
|
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() {
|
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.R
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||||
import com.bumptech.glide.request.animation.GlideAnimation
|
import com.bumptech.glide.request.animation.GlideAnimation
|
||||||
|
|
||||||
|
|
||||||
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
|
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
|
||||||
|
|
||||||
protected val defaultFooterColor: Int
|
protected val defaultFooterColor: Int
|
||||||
|
@ -40,15 +38,17 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
|
||||||
onColorReady(defaultFooterColor)
|
onColorReady(defaultFooterColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
|
override fun onResourceReady(
|
||||||
|
resource: BitmapPaletteWrapper?,
|
||||||
|
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?
|
||||||
|
) {
|
||||||
super.onResourceReady(resource, glideAnimation)
|
super.onResourceReady(resource, glideAnimation)
|
||||||
val defaultColor = defaultFooterColor
|
val defaultColor = defaultFooterColor
|
||||||
|
|
||||||
resource?.let {
|
resource?.let {
|
||||||
onColorReady(if (PreferenceUtil.getInstance(getView().context).isDominantColor)
|
onColorReady(
|
||||||
RetroColorUtil.getDominantColor(it.bitmap, defaultColor)
|
RetroColorUtil.getColor(it.palette, defaultColor)
|
||||||
else
|
)
|
||||||
RetroColorUtil.getColor(it.palette, defaultColor))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,9 @@ import android.graphics.Bitmap;
|
||||||
import androidx.palette.graphics.Palette;
|
import androidx.palette.graphics.Palette;
|
||||||
|
|
||||||
public class BitmapPaletteWrapper {
|
public class BitmapPaletteWrapper {
|
||||||
|
|
||||||
private final Bitmap mBitmap;
|
private final Bitmap mBitmap;
|
||||||
|
|
||||||
private final Palette mPalette;
|
private final Palette mPalette;
|
||||||
|
|
||||||
public BitmapPaletteWrapper(Bitmap bitmap, Palette palette) {
|
public BitmapPaletteWrapper(Bitmap bitmap, Palette palette) {
|
||||||
|
|
|
@ -29,7 +29,6 @@ import android.os.Environment
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.util.Log
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import code.name.monkey.retromusic.loaders.SongLoader
|
import code.name.monkey.retromusic.loaders.SongLoader
|
||||||
|
@ -158,7 +157,7 @@ object MusicPlayerRemote {
|
||||||
return cursor.getString(columnIndex)
|
return cursor.getString(columnIndex)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, e.message)
|
println(e.message)
|
||||||
} finally {
|
} finally {
|
||||||
cursor?.close()
|
cursor?.close()
|
||||||
}
|
}
|
||||||
|
@ -222,7 +221,7 @@ object MusicPlayerRemote {
|
||||||
/**
|
/**
|
||||||
* Async
|
* Async
|
||||||
*/
|
*/
|
||||||
fun openQueue(queue: ArrayList<Song>, startPosition: Int, startPlaying: Boolean) {
|
fun openQueue(queue: List<Song>, startPosition: Int, startPlaying: Boolean) {
|
||||||
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
|
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
|
||||||
musicService!!.openQueue(queue, startPosition, startPlaying)
|
musicService!!.openQueue(queue, startPosition, startPlaying)
|
||||||
if (PreferenceUtil.getInstance(musicService).isShuffleModeOn)
|
if (PreferenceUtil.getInstance(musicService).isShuffleModeOn)
|
||||||
|
@ -233,7 +232,7 @@ object MusicPlayerRemote {
|
||||||
/**
|
/**
|
||||||
* Async
|
* Async
|
||||||
*/
|
*/
|
||||||
fun openAndShuffleQueue(queue: ArrayList<Song>, startPlaying: Boolean) {
|
fun openAndShuffleQueue(queue: List<Song>, startPlaying: Boolean) {
|
||||||
var startPosition = 0
|
var startPosition = 0
|
||||||
if (queue.isNotEmpty()) {
|
if (queue.isNotEmpty()) {
|
||||||
startPosition = Random().nextInt(queue.size)
|
startPosition = Random().nextInt(queue.size)
|
||||||
|
@ -246,7 +245,7 @@ object MusicPlayerRemote {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryToHandleOpenPlayingQueue(
|
private fun tryToHandleOpenPlayingQueue(
|
||||||
queue: ArrayList<Song>,
|
queue: List<Song>,
|
||||||
startPosition: Int,
|
startPosition: Int,
|
||||||
startPlaying: Boolean
|
startPlaying: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
@ -316,7 +315,7 @@ object MusicPlayerRemote {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun playNext(songs: ArrayList<Song>): Boolean {
|
fun playNext(songs: List<Song>): Boolean {
|
||||||
if (musicService != null) {
|
if (musicService != null) {
|
||||||
if (playingQueue.size > 0) {
|
if (playingQueue.size > 0) {
|
||||||
musicService!!.addSongs(position + 1, songs)
|
musicService!!.addSongs(position + 1, songs)
|
||||||
|
@ -353,7 +352,7 @@ object MusicPlayerRemote {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enqueue(songs: ArrayList<Song>): Boolean {
|
fun enqueue(songs: List<Song>): Boolean {
|
||||||
if (musicService != null) {
|
if (musicService != null) {
|
||||||
if (playingQueue.size > 0) {
|
if (playingQueue.size > 0) {
|
||||||
musicService!!.addSongs(songs)
|
musicService!!.addSongs(songs)
|
||||||
|
|
|
@ -21,6 +21,7 @@ class SortOrder {
|
||||||
* Artist sort order entries.
|
* Artist sort order entries.
|
||||||
*/
|
*/
|
||||||
interface ArtistSortOrder {
|
interface ArtistSortOrder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/* Artist sort order A-Z */
|
/* Artist sort order A-Z */
|
||||||
|
@ -41,6 +42,7 @@ class SortOrder {
|
||||||
* Album sort order entries.
|
* Album sort order entries.
|
||||||
*/
|
*/
|
||||||
interface AlbumSortOrder {
|
interface AlbumSortOrder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/* Album sort order A-Z */
|
/* Album sort order A-Z */
|
||||||
|
@ -57,7 +59,7 @@ class SortOrder {
|
||||||
+ ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER)
|
+ ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER)
|
||||||
|
|
||||||
/* Album sort order year */
|
/* Album sort order year */
|
||||||
const val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
|
const val ALBUM_YEAR = MediaStore.Audio.Albums.FIRST_YEAR + " DESC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +67,7 @@ class SortOrder {
|
||||||
* Song sort order entries.
|
* Song sort order entries.
|
||||||
*/
|
*/
|
||||||
interface SongSortOrder {
|
interface SongSortOrder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/* Song sort order A-Z */
|
/* Song sort order A-Z */
|
||||||
|
@ -97,6 +100,7 @@ class SortOrder {
|
||||||
* Album song sort order entries.
|
* Album song sort order entries.
|
||||||
*/
|
*/
|
||||||
interface AlbumSongSortOrder {
|
interface AlbumSongSortOrder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/* Album song sort order A-Z */
|
/* Album song sort order A-Z */
|
||||||
|
@ -118,6 +122,7 @@ class SortOrder {
|
||||||
* Artist song sort order entries.
|
* Artist song sort order entries.
|
||||||
*/
|
*/
|
||||||
interface ArtistSongSortOrder {
|
interface ArtistSongSortOrder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/* Artist song sort order A-Z */
|
/* Artist song sort order A-Z */
|
||||||
|
@ -144,6 +149,7 @@ class SortOrder {
|
||||||
* Artist album sort order entries.
|
* Artist album sort order entries.
|
||||||
*/
|
*/
|
||||||
interface ArtistAlbumSortOrder {
|
interface ArtistAlbumSortOrder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/* Artist album sort order A-Z */
|
/* Artist album sort order A-Z */
|
||||||
|
@ -164,6 +170,7 @@ class SortOrder {
|
||||||
* Genre sort order entries.
|
* Genre sort order entries.
|
||||||
*/
|
*/
|
||||||
interface GenreSortOrder {
|
interface GenreSortOrder {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/* Genre sort order A-Z */
|
/* Genre sort order A-Z */
|
||||||
|
@ -173,5 +180,4 @@ class SortOrder {
|
||||||
const val ALBUM_Z_A = "$GENRE_A_Z DESC"
|
const val ALBUM_Z_A = "$GENRE_A_Z DESC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -91,7 +91,7 @@ object SongMenuHelper {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.action_go_to_artist -> {
|
R.id.action_go_to_artist -> {
|
||||||
NavigationUtil.goToArtist(activity, song.artistId)
|
NavigationUtil.goToArtist(activity, song.artistId.toInt())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,89 +15,136 @@
|
||||||
package code.name.monkey.retromusic.loaders
|
package code.name.monkey.retromusic.loaders
|
||||||
|
|
||||||
import android.content.Context
|
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.Album
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import java.util.*
|
import android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI as SONGS_URI
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 11/08/17.
|
* Created by hemanths on 11/08/17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
object AlbumLoader {
|
object AlbumLoader {
|
||||||
|
|
||||||
fun getAlbums(
|
fun getAllAlbums(context: Context): List<Album> {
|
||||||
context: Context,
|
return makeAlbumCursor(context, null, null)
|
||||||
query: String
|
.mapList(true) {
|
||||||
): ArrayList<Album> {
|
Album.fromCursor(this)
|
||||||
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
|
}
|
||||||
context,
|
}
|
||||||
AudioColumns.ALBUM + " LIKE ?",
|
|
||||||
arrayOf("%$query%"),
|
fun getAlbum(context: Context, id: Long): Album {
|
||||||
getSongLoaderSortOrder(context))
|
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(
|
private fun getAlbum(cursor: Cursor?): Album {
|
||||||
context: Context,
|
return cursor?.use {
|
||||||
albumId: Int
|
if (cursor.moveToFirst()) {
|
||||||
): Album {
|
Album.fromCursor(cursor)
|
||||||
val songs = SongLoader.getSongs(
|
} else {
|
||||||
SongLoader.makeSongCursor(
|
null
|
||||||
context,
|
}
|
||||||
AudioColumns.ALBUM_ID + "=?",
|
} ?: Album()
|
||||||
arrayOf(albumId.toString()),
|
|
||||||
getSongLoaderSortOrder(context)))
|
|
||||||
val album = Album(songs)
|
|
||||||
sortSongsByTrackNumber(album)
|
|
||||||
return album
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAllAlbums(
|
private fun makeAlbumCursor(context: Context, selection: String?, paramArrayOfString: Array<String>?): Cursor? {
|
||||||
context: Context
|
return context.contentResolver.query(
|
||||||
): ArrayList<Album> {
|
EXTERNAL_CONTENT_URI,
|
||||||
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, null, null, getSongLoaderSortOrder(context)))
|
arrayOf(
|
||||||
return splitIntoAlbums(songs)
|
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(
|
fun splitIntoAlbums(
|
||||||
songs: ArrayList<Song>?
|
songs: ArrayList<Song>?
|
||||||
): ArrayList<Album> {
|
): ArrayList<Album> {
|
||||||
val albums = ArrayList<Album>()
|
val albums = ArrayList<Album>()
|
||||||
if (songs != null) {
|
if (songs != null) {
|
||||||
for (song in songs) {
|
for (song in songs) {
|
||||||
getOrCreateAlbum(albums, song.albumId).songs?.add(song)
|
getOrCreateAlbum(albums, song)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (album in albums) {
|
|
||||||
sortSongsByTrackNumber(album)
|
|
||||||
}
|
|
||||||
return albums
|
return albums
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOrCreateAlbum(
|
private fun getOrCreateAlbum(
|
||||||
albums: ArrayList<Album>,
|
albums: ArrayList<Album>,
|
||||||
albumId: Int
|
song: Song
|
||||||
): Album {
|
): Album {
|
||||||
for (album in albums) {
|
for (album in albums) {
|
||||||
if (album.songs!!.isNotEmpty() && album.songs[0].albumId == albumId) {
|
if (album.id == song.albumId) {
|
||||||
return album
|
return album
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val album = Album()
|
val album = Album.fromSong(song)
|
||||||
albums.add(album)
|
albums.add(album)
|
||||||
return album
|
return album
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sortSongsByTrackNumber(album: Album) {
|
fun getAlbums(context: Context, paramString: String): List<Album> {
|
||||||
album.songs?.sortWith(Comparator { o1, o2 -> o1.trackNumber.compareTo(o2.trackNumber) })
|
return makeAlbumCursor(context, "album LIKE ?", arrayOf("$paramString%"))
|
||||||
}
|
.mapList(true) { Album.fromCursor(this) }
|
||||||
|
|
||||||
private fun getSongLoaderSortOrder(context: Context): String {
|
|
||||||
return PreferenceUtil.getInstance(context).albumSortOrder + ", " + PreferenceUtil.getInstance(context).albumSongSortOrder
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
package code.name.monkey.retromusic.loaders
|
||||||
|
|
||||||
import android.content.Context
|
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.Album
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
|
|
||||||
|
|
||||||
object ArtistLoader {
|
object ArtistLoader {
|
||||||
private fun getSongLoaderSortOrder(context: Context): String {
|
|
||||||
return PreferenceUtil.getInstance(context).artistSortOrder + ", " + PreferenceUtil.getInstance(context).artistAlbumSortOrder + ", " + PreferenceUtil.getInstance(context).albumSongSortOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getAllArtists(context: Context): ArrayList<Artist> {
|
fun getAllArtists(context: Context): ArrayList<Artist> {
|
||||||
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
|
return getArtists(makeArtistCursor(context, null, null))
|
||||||
context,
|
|
||||||
null, null,
|
|
||||||
getSongLoaderSortOrder(context))
|
|
||||||
)
|
|
||||||
return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getArtists(context: Context, query: String): ArrayList<Artist> {
|
fun getArtist(context: Context, artistId: Long): Artist {
|
||||||
val songs = SongLoader.getSongs(SongLoader.makeSongCursor(
|
return getArtist(makeArtistCursor(context, "_id=?", arrayOf(artistId.toString())))
|
||||||
context,
|
|
||||||
AudioColumns.ARTIST + " LIKE ?",
|
|
||||||
arrayOf("%$query%"),
|
|
||||||
getSongLoaderSortOrder(context))
|
|
||||||
)
|
|
||||||
return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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>()
|
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) {
|
for (album in albums) {
|
||||||
getOrCreateArtist(artists, album.artistId).albums!!.add(album)
|
getOrCreateArtist(artists, album)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return artists
|
return artists
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOrCreateArtist(artists: ArrayList<Artist>, artistId: Int): Artist {
|
private fun getOrCreateArtist(artists: ArrayList<Artist>, album: Album): Artist {
|
||||||
for (artist in artists) {
|
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
|
return artist
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val album = Artist()
|
val a = Artist.fromAlbum(album)
|
||||||
artists.add(album)
|
artists.add(a)
|
||||||
return album
|
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.net.Uri
|
||||||
import android.provider.BaseColumns
|
import android.provider.BaseColumns
|
||||||
import android.provider.MediaStore.Audio.Genres
|
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.Constants.baseProjection
|
||||||
import code.name.monkey.retromusic.model.Genre
|
import code.name.monkey.retromusic.model.Genre
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
|
@ -94,7 +94,7 @@ object GenreLoader {
|
||||||
try {
|
try {
|
||||||
return context.contentResolver.query(
|
return context.contentResolver.query(
|
||||||
Genres.Members.getContentUri("external", genreId.toLong()),
|
Genres.Members.getContentUri("external", genreId.toLong()),
|
||||||
baseProjection, BASE_SELECTION, null, PreferenceUtil.getInstance(context).songSortOrder)
|
baseProjection, baseSelection, null, PreferenceUtil.getInstance(context).songSortOrder)
|
||||||
} catch (e: SecurityException) {
|
} catch (e: SecurityException) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,10 +36,11 @@ object LastAddedSongsLoader {
|
||||||
val cutoff = PreferenceUtil.getInstance(context).lastAddedCutoff
|
val cutoff = PreferenceUtil.getInstance(context).lastAddedCutoff
|
||||||
|
|
||||||
return SongLoader.makeSongCursor(
|
return SongLoader.makeSongCursor(
|
||||||
context,
|
context,
|
||||||
MediaStore.Audio.Media.DATE_ADDED + ">?",
|
MediaStore.Audio.Media.DATE_ADDED + ">?",
|
||||||
arrayOf(cutoff.toString()),
|
arrayOf(cutoff.toString()),
|
||||||
MediaStore.Audio.Media.DATE_ADDED + " DESC")
|
MediaStore.Audio.Media.DATE_ADDED + " DESC"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLastAddedAlbums(context: Context): ArrayList<Album> {
|
fun getLastAddedAlbums(context: Context): ArrayList<Album> {
|
||||||
|
|
|
@ -18,7 +18,7 @@ import android.content.Context
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.provider.MediaStore.Audio.AudioColumns
|
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.AbsCustomPlaylist
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
import code.name.monkey.retromusic.model.Playlist
|
||||||
import code.name.monkey.retromusic.model.PlaylistSong
|
import code.name.monkey.retromusic.model.PlaylistSong
|
||||||
|
@ -104,7 +104,7 @@ object PlaylistSongsLoader {
|
||||||
MediaStore.Audio.Playlists.Members._ID,//11
|
MediaStore.Audio.Playlists.Members._ID,//11
|
||||||
AudioColumns.COMPOSER
|
AudioColumns.COMPOSER
|
||||||
)// 12
|
)// 12
|
||||||
, BASE_SELECTION, null,
|
, baseSelection, null,
|
||||||
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER
|
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER
|
||||||
)
|
)
|
||||||
} catch (e: SecurityException) {
|
} catch (e: SecurityException) {
|
||||||
|
|
|
@ -18,10 +18,9 @@ import android.content.Context
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.provider.MediaStore.Audio.AudioColumns
|
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.baseProjection
|
||||||
|
import code.name.monkey.retromusic.Constants.baseSelection
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.providers.BlacklistStore
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
@ -61,7 +60,7 @@ object SongLoader {
|
||||||
return getSongs(cursor)
|
return getSongs(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSong(
|
private fun getSong(
|
||||||
cursor: Cursor?
|
cursor: Cursor?
|
||||||
): Song {
|
): Song {
|
||||||
val song: Song
|
val song: Song
|
||||||
|
@ -75,98 +74,79 @@ object SongLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getSong(context: Context, queryId: Int): Song {
|
fun getSong(context: Context, queryId: Long): Song {
|
||||||
val cursor = makeSongCursor(context, AudioColumns._ID + "=?", arrayOf(queryId.toString()))
|
val cursor = makeSongCursor(context, AudioColumns._ID + "=?", arrayOf(queryId.toString()))
|
||||||
return getSong(cursor)
|
return getSong(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSongFromCursorImpl(
|
private fun getSongFromCursorImpl(
|
||||||
cursor: Cursor
|
cursor: Cursor
|
||||||
): Song {
|
): Song = Song.fromCursor(cursor)
|
||||||
val id = cursor.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 ?: ""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun makeSongCursor(
|
fun makeSongCursor(
|
||||||
context: Context,
|
context: Context,
|
||||||
selection: String?,
|
selectionString: String?,
|
||||||
selectionValues: Array<String>?,
|
selectionValuesArray: Array<String>?,
|
||||||
sortOrder: String = PreferenceUtil.getInstance(context).songSortOrder
|
sortOrder: String = PreferenceUtil.getInstance(context).songSortOrder
|
||||||
): Cursor? {
|
): Cursor {
|
||||||
var selectionFinal = selection
|
var selectionValues: Array<String>? = arrayOf()
|
||||||
var selectionValuesFinal = selectionValues
|
var selection = if (selectionString != null && selectionString.trim() != "") {
|
||||||
selectionFinal = if (selection != null && selection.trim { it <= ' ' } != "") {
|
"$baseSelection AND $selectionString"
|
||||||
"$BASE_SELECTION AND $selectionFinal"
|
|
||||||
} else {
|
} else {
|
||||||
BASE_SELECTION
|
baseSelection
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blacklist
|
// Blacklist
|
||||||
val paths = BlacklistStore.getInstance(context).paths
|
/*val paths = BlacklistStore.getInstance(context).paths
|
||||||
if (paths.isNotEmpty()) {
|
if (paths.isNotEmpty()) {
|
||||||
selectionFinal = generateBlacklistSelection(selectionFinal, paths.size)
|
selection = generateBlacklistSelection(selection, paths.size)
|
||||||
selectionValuesFinal = addBlacklistSelectionValues(selectionValuesFinal, paths)
|
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(
|
||||||
return context.contentResolver.query(
|
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
||||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
baseProjection,
|
||||||
baseProjection,
|
selection,
|
||||||
selectionFinal + " AND " + MediaStore.Audio.Media.DURATION + ">= " + (PreferenceUtil.getInstance(
|
selectionValuesArray,
|
||||||
context
|
sortOrder
|
||||||
).filterLength * 1000),
|
)
|
||||||
selectionValuesFinal,
|
?: throw IllegalStateException("Unable to query ${MediaStore.Audio.Media.EXTERNAL_CONTENT_URI}, system returned null.")
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
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
|
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 {
|
data class Album(
|
||||||
val songs: ArrayList<Song>?
|
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
|
companion object {
|
||||||
get() = safeGetFirstSong().albumId
|
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?
|
fun fromSong(song: Song): Album {
|
||||||
get() = safeGetFirstSong().albumName
|
return Album(song.albumId, song.albumName, song.artistName, song.artistId, -1, song.year)
|
||||||
|
}
|
||||||
val artistId: Int
|
}
|
||||||
get() = safeGetFirstSong().artistId
|
}
|
||||||
|
|
||||||
val artistName: String?
|
fun Cursor.valueOrEmpty(name: String): String = valueOrDefault(name, "")
|
||||||
get() = safeGetFirstSong().artistName
|
|
||||||
|
inline fun <reified T> Cursor.value(name: String): T {
|
||||||
val year: Int
|
val index = getColumnIndexOrThrow(name)
|
||||||
get() = safeGetFirstSong().year
|
return when (T::class) {
|
||||||
|
Short::class -> getShort(index) as T
|
||||||
val dateModified: Long
|
Int::class -> getInt(index) as T
|
||||||
get() = safeGetFirstSong().dateModified
|
Long::class -> getLong(index) as T
|
||||||
|
Boolean::class -> (getInt(index) == 1) as T
|
||||||
val songCount: Int
|
String::class -> getString(index) as T
|
||||||
get() = songs!!.size
|
Float::class -> getFloat(index) as T
|
||||||
|
Double::class -> getDouble(index) as T
|
||||||
constructor(songs: ArrayList<Song>) {
|
ByteArray::class -> getBlob(index) as T
|
||||||
this.songs = songs
|
else -> throw IllegalStateException("What do I do with ${T::class.java.simpleName}?")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
constructor() {
|
|
||||||
this.songs = ArrayList()
|
inline fun <reified T> Cursor.valueOrDefault(name: String, defaultValue: T): T {
|
||||||
}
|
val index = getColumnIndex(name)
|
||||||
|
if (index == -1) {
|
||||||
fun safeGetFirstSong(): Song {
|
return defaultValue
|
||||||
return if (songs!!.isEmpty()) Song.emptySong else songs[0]
|
}
|
||||||
|
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
|
package code.name.monkey.retromusic.model
|
||||||
|
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import android.database.Cursor
|
||||||
import java.util.ArrayList
|
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 {
|
class Artist(
|
||||||
val albums: ArrayList<Album>?
|
var id: Long = 0,
|
||||||
|
var name: String = "",
|
||||||
val id: Int
|
var songCount: Int = 0,
|
||||||
get() = safeGetFirstAlbum().artistId
|
var albumCount: Int = 0
|
||||||
|
) {
|
||||||
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]
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
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"
|
const val UNKNOWN_ARTIST_DISPLAY_NAME = "Unknown Artist"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,21 +13,23 @@
|
||||||
*/
|
*/
|
||||||
package code.name.monkey.retromusic.model
|
package code.name.monkey.retromusic.model
|
||||||
|
|
||||||
|
import android.database.Cursor
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import android.provider.MediaStore.Audio.Media
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
open class Song(
|
open class Song(
|
||||||
val id: Int,
|
val id: Long,
|
||||||
val title: String,
|
val title: String,
|
||||||
val trackNumber: Int,
|
val trackNumber: Int,
|
||||||
val year: Int,
|
val year: Int,
|
||||||
val duration: Long,
|
val duration: Long,
|
||||||
val data: String,
|
val data: String,
|
||||||
val dateModified: Long,
|
val dateModified: Long,
|
||||||
val albumId: Int,
|
val albumId: Long,
|
||||||
val albumName: String,
|
val albumName: String,
|
||||||
val artistId: Int,
|
val artistId: Long,
|
||||||
val artistName: String,
|
val artistName: String,
|
||||||
val composer: String?
|
val composer: String?
|
||||||
) : Parcelable {
|
) : 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.Result.Success
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
|
@ -36,21 +37,24 @@ interface AlbumDetailsView {
|
||||||
|
|
||||||
fun album(album: Album)
|
fun album(album: Album)
|
||||||
|
|
||||||
|
fun songs(songs: List<Song>)
|
||||||
|
|
||||||
fun complete()
|
fun complete()
|
||||||
|
|
||||||
fun loadArtistImage(artist: Artist)
|
fun loadArtistImage(artist: Artist)
|
||||||
|
|
||||||
fun moreAlbums(
|
fun moreAlbums(albums: List<Album>)
|
||||||
albums: ArrayList<Album>
|
|
||||||
)
|
|
||||||
|
|
||||||
fun aboutAlbum(lastFmAlbum: LastFmAlbum)
|
fun aboutAlbum(lastFmAlbum: LastFmAlbum)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
|
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)
|
fun aboutAlbum(artist: String, album: String)
|
||||||
|
|
||||||
class AlbumDetailsPresenterImpl @Inject constructor(
|
class AlbumDetailsPresenterImpl @Inject constructor(
|
||||||
|
@ -60,7 +64,7 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
private lateinit var album: Album
|
private lateinit var album: Album
|
||||||
|
|
||||||
override fun loadMore(artistId: Int) {
|
override fun loadMore(artistId: Long) {
|
||||||
launch {
|
launch {
|
||||||
when (val result = repository.artistById(artistId)) {
|
when (val result = repository.artistById(artistId)) {
|
||||||
is Success -> withContext(Dispatchers.Main) { showArtistImage(result.data) }
|
is Success -> withContext(Dispatchers.Main) { showArtistImage(result.data) }
|
||||||
|
@ -80,13 +84,9 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
|
||||||
|
|
||||||
private fun showArtistImage(artist: Artist) {
|
private fun showArtistImage(artist: Artist) {
|
||||||
view?.loadArtistImage(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 {
|
launch {
|
||||||
when (val result = repository.albumById(albumId)) {
|
when (val result = repository.albumById(albumId)) {
|
||||||
is Success -> withContext(Dispatchers.Main) {
|
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() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
job.cancel()
|
job.cancel()
|
||||||
|
|
|
@ -25,7 +25,6 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.ArrayList
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
@ -33,35 +32,37 @@ import kotlin.coroutines.CoroutineContext
|
||||||
* Created by hemanths on 12/08/17.
|
* Created by hemanths on 12/08/17.
|
||||||
*/
|
*/
|
||||||
interface AlbumsView : BaseView {
|
interface AlbumsView : BaseView {
|
||||||
fun albums(albums: ArrayList<Album>)
|
|
||||||
|
fun albums(albums: List<Album>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AlbumsPresenter : Presenter<AlbumsView> {
|
interface AlbumsPresenter : Presenter<AlbumsView> {
|
||||||
|
|
||||||
fun loadAlbums()
|
fun loadAlbums()
|
||||||
|
|
||||||
class AlbumsPresenterImpl @Inject constructor(
|
class AlbumsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<AlbumsView>(), AlbumsPresenter, CoroutineScope {
|
) : PresenterImpl<AlbumsView>(), AlbumsPresenter, CoroutineScope {
|
||||||
private val job = Job()
|
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
private val job = Job()
|
||||||
get() = Dispatchers.IO + job
|
|
||||||
|
|
||||||
override fun detachView() {
|
override val coroutineContext: CoroutineContext
|
||||||
super.detachView()
|
get() = Dispatchers.IO + job
|
||||||
job.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadAlbums() {
|
override fun detachView() {
|
||||||
launch {
|
super.detachView()
|
||||||
when (val result = repository.allAlbums()) {
|
job.cancel()
|
||||||
is Result.Success -> withContext(Dispatchers.Main) {
|
}
|
||||||
view?.albums(result.data)
|
|
||||||
}
|
override fun loadAlbums() {
|
||||||
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
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
|
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.Artist
|
||||||
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
|
@ -35,14 +37,24 @@ import kotlin.coroutines.CoroutineContext
|
||||||
*/
|
*/
|
||||||
interface ArtistDetailsView : BaseView {
|
interface ArtistDetailsView : BaseView {
|
||||||
|
|
||||||
|
fun songs(songs: List<Song>)
|
||||||
|
|
||||||
|
fun albums(albums: List<Album>)
|
||||||
|
|
||||||
fun artist(artist: Artist)
|
fun artist(artist: Artist)
|
||||||
|
|
||||||
fun artistInfo(lastFmArtist: LastFmArtist?)
|
fun artistInfo(lastFmArtist: LastFmArtist?)
|
||||||
|
|
||||||
fun complete()
|
fun complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
|
interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
|
||||||
|
|
||||||
fun loadArtist(artistId: Int)
|
fun loadArtist(artistId: Long)
|
||||||
|
|
||||||
|
fun loadArtistSongs(artistId: Long)
|
||||||
|
|
||||||
|
fun loadArtistAlbums(artistId: Long)
|
||||||
|
|
||||||
fun loadBiography(
|
fun loadBiography(
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -62,26 +74,35 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
|
||||||
override fun loadBiography(name: String, lang: String?, cache: String?) {
|
override fun loadBiography(name: String, lang: String?, cache: String?) {
|
||||||
launch {
|
launch {
|
||||||
when (val result = repository.artistInfo(name, lang, cache)) {
|
when (val result = repository.artistInfo(name, lang, cache)) {
|
||||||
is Result.Success -> withContext(Dispatchers.Main) {
|
is Success -> withContext(Dispatchers.Main) { view?.artistInfo(result.data) }
|
||||||
view?.artistInfo(result.data)
|
is Error -> withContext(Dispatchers.Main) {}
|
||||||
}
|
|
||||||
is Result.Error -> withContext(Dispatchers.Main) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadArtist(artistId: Int) {
|
override fun loadArtist(artistId: Long) {
|
||||||
launch {
|
launch {
|
||||||
when (val result = repository.artistById(artistId)) {
|
when (val result = repository.artistById(artistId)) {
|
||||||
is Result.Success -> withContext(Dispatchers.Main) {
|
is Success -> withContext(Dispatchers.Main) { view?.artist(result.data) }
|
||||||
view?.artist(result.data)
|
is Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
override fun loadArtistSongs(artistId: Long) {
|
||||||
is Result.Error -> withContext(Dispatchers.Main) {
|
launch {
|
||||||
view?.showEmptyView()
|
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.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
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 javax.inject.Inject
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
interface ArtistsView : BaseView {
|
interface ArtistsView : BaseView {
|
||||||
fun artists(artists: ArrayList<Artist>)
|
fun artists(artists: List<Artist>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ArtistsPresenter : Presenter<ArtistsView> {
|
interface ArtistsPresenter : Presenter<ArtistsView> {
|
||||||
|
@ -33,8 +37,9 @@ interface ArtistsPresenter : Presenter<ArtistsView> {
|
||||||
fun loadArtists()
|
fun loadArtists()
|
||||||
|
|
||||||
class ArtistsPresenterImpl @Inject constructor(
|
class ArtistsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<ArtistsView>(), ArtistsPresenter, CoroutineScope {
|
) : PresenterImpl<ArtistsView>(), ArtistsPresenter, CoroutineScope {
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
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.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import java.util.*
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 20/08/17.
|
* Created by hemanths on 20/08/17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface GenreDetailsView : BaseView {
|
interface GenreDetailsView : BaseView {
|
||||||
fun songs(songs: ArrayList<Song>)
|
|
||||||
|
fun songs(songs: List<Song>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GenreDetailsPresenter : Presenter<GenreDetailsView> {
|
interface GenreDetailsPresenter : Presenter<GenreDetailsView> {
|
||||||
fun loadGenreSongs(genreId: Int)
|
fun loadGenreSongs(genreId: Int)
|
||||||
|
|
||||||
class GenreDetailsPresenterImpl @Inject constructor(
|
class GenreDetailsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<GenreDetailsView>(), GenreDetailsPresenter, CoroutineScope {
|
) : PresenterImpl<GenreDetailsView>(), GenreDetailsPresenter, CoroutineScope {
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
|
@ -50,7 +54,6 @@ interface GenreDetailsPresenter : Presenter<GenreDetailsView> {
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun loadGenreSongs(genreId: Int) {
|
override fun loadGenreSongs(genreId: Int) {
|
||||||
launch {
|
launch {
|
||||||
when (val result = repository.getGenre(genreId)) {
|
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.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import java.util.*
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
@ -29,15 +32,17 @@ import kotlin.coroutines.CoroutineContext
|
||||||
* @author Hemanth S (h4h13).
|
* @author Hemanth S (h4h13).
|
||||||
*/
|
*/
|
||||||
interface GenresView : BaseView {
|
interface GenresView : BaseView {
|
||||||
fun genres(genres: ArrayList<Genre>)
|
|
||||||
|
fun genres(genres: List<Genre>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GenresPresenter : Presenter<GenresView> {
|
interface GenresPresenter : Presenter<GenresView> {
|
||||||
fun loadGenres()
|
fun loadGenres()
|
||||||
|
|
||||||
class GenresPresenterImpl @Inject constructor(
|
class GenresPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<GenresView>(), GenresPresenter, CoroutineScope {
|
) : PresenterImpl<GenresView>(), GenresPresenter, CoroutineScope {
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
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.Result
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
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 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 javax.inject.Inject
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 19/08/17.
|
* Created by hemanths on 19/08/17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface PlaylistView : BaseView {
|
interface PlaylistView : BaseView {
|
||||||
fun playlists(playlists: ArrayList<Playlist>)
|
|
||||||
|
fun playlists(playlists: List<Playlist>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PlaylistsPresenter : Presenter<PlaylistView> {
|
interface PlaylistsPresenter : Presenter<PlaylistView> {
|
||||||
|
@ -36,7 +42,7 @@ interface PlaylistsPresenter : Presenter<PlaylistView> {
|
||||||
fun playlists()
|
fun playlists()
|
||||||
|
|
||||||
class PlaylistsPresenterImpl @Inject constructor(
|
class PlaylistsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter, CoroutineScope {
|
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter, CoroutineScope {
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
|
|
|
@ -15,10 +15,17 @@
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
import code.name.monkey.retromusic.Result
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.*
|
import code.name.monkey.retromusic.model.Playlist
|
||||||
import code.name.monkey.retromusic.mvp.*
|
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 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 javax.inject.Inject
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
@ -26,14 +33,15 @@ import kotlin.coroutines.CoroutineContext
|
||||||
* Created by hemanths on 20/08/17.
|
* Created by hemanths on 20/08/17.
|
||||||
*/
|
*/
|
||||||
interface PlaylistSongsView : BaseView {
|
interface PlaylistSongsView : BaseView {
|
||||||
fun songs(songs: ArrayList<Song>)
|
|
||||||
|
fun songs(songs: List<Song>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PlaylistSongsPresenter : Presenter<PlaylistSongsView> {
|
interface PlaylistSongsPresenter : Presenter<PlaylistSongsView> {
|
||||||
fun loadPlaylistSongs(playlist: Playlist)
|
fun loadPlaylistSongs(playlist: Playlist)
|
||||||
|
|
||||||
class PlaylistSongsPresenterImpl @Inject constructor(
|
class PlaylistSongsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<PlaylistSongsView>(), PlaylistSongsPresenter, CoroutineScope {
|
) : PresenterImpl<PlaylistSongsView>(), PlaylistSongsPresenter, CoroutineScope {
|
||||||
|
|
||||||
private var job: Job = Job()
|
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.Result
|
||||||
import code.name.monkey.retromusic.model.Song
|
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 code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import java.util.*
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
@ -27,36 +31,37 @@ import kotlin.coroutines.CoroutineContext
|
||||||
* Created by hemanths on 10/08/17.
|
* Created by hemanths on 10/08/17.
|
||||||
*/
|
*/
|
||||||
interface SongView {
|
interface SongView {
|
||||||
fun songs(songs: ArrayList<Song>)
|
|
||||||
|
|
||||||
fun showEmptyView()
|
fun songs(songs: List<Song>)
|
||||||
|
|
||||||
|
fun showEmptyView()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SongPresenter : Presenter<SongView> {
|
interface SongPresenter : Presenter<SongView> {
|
||||||
fun loadSongs()
|
fun loadSongs()
|
||||||
class SongPresenterImpl @Inject constructor(
|
class SongPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
|
) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
|
||||||
|
|
||||||
private var job: Job = Job()
|
private var job: Job = Job()
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
get() = Dispatchers.IO + job
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
override fun loadSongs() {
|
override fun loadSongs() {
|
||||||
launch {
|
launch {
|
||||||
when (val songs = repository.allSongs()) {
|
when (val songs = repository.allSongs()) {
|
||||||
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
|
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
|
||||||
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun detachView() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
job.cancel();
|
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) : 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 {
|
init {
|
||||||
icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN)
|
icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN)
|
||||||
|
@ -55,23 +60,23 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
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)
|
blacklistFolderChooserDialog?.setCallback(this)
|
||||||
refreshBlacklistData()
|
refreshBlacklistData()
|
||||||
return MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
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)
|
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||||
positiveButton(android.R.string.ok) {
|
positiveButton(android.R.string.ok) {
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
neutralButton(text = getString(R.string.clear_action)) {
|
neutralButton(text = getString(R.string.clear_action)) {
|
||||||
MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
|
||||||
title(code.name.monkey.retromusic.R.string.clear_blacklist)
|
title(R.string.clear_blacklist)
|
||||||
message(code.name.monkey.retromusic.R.string.do_you_want_to_clear_the_blacklist)
|
message(R.string.do_you_want_to_clear_the_blacklist)
|
||||||
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||||
positiveButton(code.name.monkey.retromusic.R.string.clear_action) {
|
positiveButton(R.string.clear_action) {
|
||||||
BlacklistStore.getInstance(context).clear()
|
BlacklistStore.getInstance(context).clear()
|
||||||
refreshBlacklistData()
|
refreshBlacklistData()
|
||||||
}
|
}
|
||||||
|
@ -81,13 +86,20 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
|
||||||
negativeButton(R.string.add_action) {
|
negativeButton(R.string.add_action) {
|
||||||
val dialog = BlacklistFolderChooserDialog.create()
|
val dialog = BlacklistFolderChooserDialog.create()
|
||||||
dialog.setCallback(this@BlacklistPreferenceDialog)
|
dialog.setCallback(this@BlacklistPreferenceDialog)
|
||||||
dialog.show(childFragmentManager, "FOLDER_CHOOSER");
|
dialog.show(childFragmentManager, "FOLDER_CHOOSER")
|
||||||
}
|
}
|
||||||
listItems(items = paths, waitForPositiveButton = false) { _, _, text ->
|
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)
|
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
|
||||||
title(code.name.monkey.retromusic.R.string.remove_from_blacklist)
|
title(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)))
|
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) {
|
positiveButton(code.name.monkey.retromusic.R.string.remove_action) {
|
||||||
BlacklistStore.getInstance(context).removePath(File(text.toString()))
|
BlacklistStore.getInstance(context).removePath(File(text.toString()))
|
||||||
refreshBlacklistData()
|
refreshBlacklistData()
|
||||||
|
@ -108,7 +120,7 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFolderSelection(dialog: BlacklistFolderChooserDialog, folder: File) {
|
override fun onFolderSelection(dialog: BlacklistFolderChooserDialog, folder: File) {
|
||||||
BlacklistStore.getInstance(context!!).addPath(folder);
|
BlacklistStore.getInstance(context!!).addPath(folder)
|
||||||
refreshBlacklistData();
|
refreshBlacklistData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ package code.name.monkey.retromusic.preferences
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
@ -30,8 +31,12 @@ import androidx.viewpager.widget.PagerAdapter
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import code.name.monkey.appthemehelper.ThemeStore
|
import code.name.monkey.appthemehelper.ThemeStore
|
||||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
|
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.App
|
||||||
import code.name.monkey.retromusic.R
|
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.fragments.NowPlayingScreen
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.NavigationUtil
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
|
@ -42,18 +47,23 @@ import com.bumptech.glide.Glide
|
||||||
|
|
||||||
class NowPlayingScreenPreference : ATEDialogPreference {
|
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
|
private val mLayoutRes = R.layout.preference_dialog_now_playing_screen
|
||||||
|
|
||||||
override fun getDialogLayoutResource(): Int {
|
override fun getDialogLayoutResource(): Int {
|
||||||
return mLayoutRes;
|
return mLayoutRes
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -66,11 +76,9 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
|
||||||
private var viewPagerPosition: Int = 0
|
private var viewPagerPosition: Int = 0
|
||||||
|
|
||||||
override fun onPageScrollStateChanged(state: Int) {
|
override fun onPageScrollStateChanged(state: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPageSelected(position: Int) {
|
override fun onPageSelected(position: Int) {
|
||||||
|
@ -78,13 +86,12 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDialogClosed(positiveResult: Boolean) {
|
override fun onDialogClosed(positiveResult: Boolean) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
val view = LayoutInflater.from(activity).inflate(R.layout.preference_dialog_now_playing_screen, null)
|
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)
|
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.adapter = NowPlayingScreenAdapter(activity!!)
|
||||||
viewPager.addOnPageChangeListener(this)
|
viewPager.addOnPageChangeListener(this)
|
||||||
viewPager.pageMargin = ViewUtil.convertDpToPixel(32f, resources).toInt()
|
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 {
|
companion object {
|
||||||
fun newInstance(key: String): NowPlayingScreenPreferenceDialog {
|
fun newInstance(key: String): NowPlayingScreenPreferenceDialog {
|
||||||
val bundle = Bundle()
|
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 {
|
override fun instantiateItem(collection: ViewGroup, position: Int): Any {
|
||||||
val nowPlayingScreen = NowPlayingScreen.values()[position]
|
val nowPlayingScreen = NowPlayingScreen.values()[position]
|
||||||
|
@ -148,16 +137,26 @@ private class NowPlayingScreenAdapter internal constructor(private val context:
|
||||||
collection.addView(layout)
|
collection.addView(layout)
|
||||||
|
|
||||||
val image = layout.findViewById<ImageView>(R.id.image)
|
val image = layout.findViewById<ImageView>(R.id.image)
|
||||||
|
val proText = layout.findViewById<TextView>(R.id.proText)
|
||||||
val title = layout.findViewById<TextView>(R.id.title)
|
val title = layout.findViewById<TextView>(R.id.title)
|
||||||
Glide.with(context).load(nowPlayingScreen.drawableResId).into(image)
|
Glide.with(context).load(nowPlayingScreen.drawableResId).into(image)
|
||||||
title.setText(nowPlayingScreen.titleRes)
|
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
|
return layout
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun destroyItem(collection: ViewGroup,
|
override fun destroyItem(
|
||||||
position: Int,
|
collection: ViewGroup,
|
||||||
view: Any) {
|
position: Int,
|
||||||
|
view: Any
|
||||||
|
) {
|
||||||
collection.removeView(view as View)
|
collection.removeView(view as View)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,3 +172,18 @@ private class NowPlayingScreenAdapter internal constructor(private val context:
|
||||||
return context.getString(NowPlayingScreen.values()[position].titleRes)
|
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 {
|
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 {
|
return try {
|
||||||
val albums = AlbumLoader.getAllAlbums(context)
|
val albums = AlbumLoader.getAllAlbums(context)
|
||||||
if (albums.isNotEmpty()) {
|
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 {
|
return try {
|
||||||
val album = AlbumLoader.getAlbum(context, albumId)
|
val album = AlbumLoader.getAlbum(context, albumId)
|
||||||
if (album != null) {
|
Success(album)
|
||||||
Success(album)
|
} catch (e: Exception) {
|
||||||
} else {
|
Error(e)
|
||||||
Error(Throwable("No album"))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
} catch (e: Exception) {
|
||||||
Error(e)
|
Error(e)
|
||||||
}
|
}
|
||||||
|
@ -289,7 +312,7 @@ class RepositoryImpl @Inject constructor(private val context: Context) : Reposit
|
||||||
errorMessage = "Error"
|
errorMessage = "Error"
|
||||||
)
|
)
|
||||||
|
|
||||||
override suspend fun artistById(artistId: Int): Result<Artist> {
|
override suspend fun artistById(artistId: Long): Result<Artist> {
|
||||||
return try {
|
return try {
|
||||||
val artist = ArtistLoader.getArtist(context, artistId)
|
val artist = ArtistLoader.getArtist(context, artistId)
|
||||||
return Success(artist)
|
return Success(artist)
|
||||||
|
|
|
@ -30,23 +30,29 @@ import code.name.monkey.retromusic.rest.model.LastFmArtist
|
||||||
|
|
||||||
interface Repository {
|
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 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>
|
suspend fun recentArtists(): Result<Home>
|
||||||
|
|
||||||
|
@ -62,5 +68,5 @@ interface Repository {
|
||||||
|
|
||||||
suspend fun albumInfo(artist: String, album: String): Result<LastFmAlbum>
|
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;
|
break;
|
||||||
case SHUFFLE_MODE_NONE:
|
case SHUFFLE_MODE_NONE:
|
||||||
this.shuffleMode = shuffleMode;
|
this.shuffleMode = shuffleMode;
|
||||||
int currentSongId = Objects.requireNonNull(getCurrentSong()).getId();
|
long currentSongId = Objects.requireNonNull(getCurrentSong()).getId();
|
||||||
playingQueue = new ArrayList<>(originalPlayingQueue);
|
playingQueue = new ArrayList<>(originalPlayingQueue);
|
||||||
int newPosition = 0;
|
int newPosition = 0;
|
||||||
if (getPlayingQueue() != null) {
|
if (getPlayingQueue() != null) {
|
||||||
|
@ -844,7 +844,7 @@ public class MusicService extends Service implements
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openQueue(@Nullable final ArrayList<Song> playingQueue, final int startPosition,
|
public void openQueue(@Nullable final List<Song> playingQueue, final int startPosition,
|
||||||
final boolean startPlaying) {
|
final boolean startPlaying) {
|
||||||
if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue
|
if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue
|
||||||
.size()) {
|
.size()) {
|
||||||
|
|
|
@ -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.os.Environment;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.webkit.MimeTypeMap;
|
import android.webkit.MimeTypeMap;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
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.BufferedReader;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -37,137 +38,9 @@ import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
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 {
|
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) {
|
public static boolean fileIsMimeType(File file, String mimeType, MimeTypeMap mimeTypeMap) {
|
||||||
if (mimeType == null || mimeType.equals("*/*")) {
|
if (mimeType == null || mimeType.equals("*/*")) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -209,15 +82,95 @@ public final class FileUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String stripExtension(String str) {
|
public static boolean isExternalMemoryAvailable() {
|
||||||
if (str == null) {
|
Boolean isSDPresent = Environment.getExternalStorageState()
|
||||||
return null;
|
.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 {
|
public static String readFromStream(InputStream is) throws Exception {
|
||||||
|
@ -234,27 +187,6 @@ public final class FileUtil {
|
||||||
return sb.toString();
|
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) {
|
public static File safeGetCanonicalFile(File file) {
|
||||||
try {
|
try {
|
||||||
return file.getCanonicalFile();
|
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();
|
ContentResolver contentResolver = context.getContentResolver();
|
||||||
Uri localUri = Uri.parse("content://media/external/audio/albumart");
|
Uri localUri = Uri.parse("content://media/external/audio/albumart");
|
||||||
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
|
contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null);
|
||||||
|
@ -262,7 +262,7 @@ public class MusicUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Uri getMediaStoreAlbumCoverUri(int albumId) {
|
public static Uri getMediaStoreAlbumCoverUri(long albumId) {
|
||||||
final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
|
final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
|
||||||
return ContentUris.withAppendedId(sArtworkUri, albumId);
|
return ContentUris.withAppendedId(sArtworkUri, albumId);
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ public class MusicUtil {
|
||||||
return songCount + " " + songString;
|
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);
|
return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ public class MusicUtil {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void insertAlbumArt(@NonNull Context context, int albumId, String path) {
|
public static void insertAlbumArt(@NonNull Context context, long albumId, String path) {
|
||||||
ContentResolver contentResolver = context.getContentResolver();
|
ContentResolver contentResolver = context.getContentResolver();
|
||||||
|
|
||||||
Uri artworkUri = Uri.parse("content://media/external/audio/albumart");
|
Uri artworkUri = Uri.parse("content://media/external/audio/albumart");
|
||||||
|
|
|
@ -59,14 +59,14 @@ public class NavigationUtil {
|
||||||
ActivityCompat.startActivity(activity, new Intent(activity, AboutActivity.class), null);
|
ActivityCompat.startActivity(activity, new Intent(activity, AboutActivity.class), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void goToAlbum(@NonNull Activity activity, int albumId) {
|
public static void goToAlbum(@NonNull Activity activity, long albumId) {
|
||||||
Intent intent = new Intent(activity, AlbumDetailsActivity.class);
|
Intent intent = new Intent(activity, AlbumDetailsActivity.class);
|
||||||
intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId);
|
intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId);
|
||||||
ActivityCompat.startActivity(activity, intent, null);
|
ActivityCompat.startActivity(activity, intent, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void goToAlbumOptions(@NonNull Activity activity,
|
public static void goToAlbumOptions(@NonNull Activity activity,
|
||||||
int albumId,
|
long albumId,
|
||||||
@NonNull ActivityOptions options) {
|
@NonNull ActivityOptions options) {
|
||||||
Intent intent = new Intent(activity, AlbumDetailsActivity.class);
|
Intent intent = new Intent(activity, AlbumDetailsActivity.class);
|
||||||
intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId);
|
intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId);
|
||||||
|
@ -80,7 +80,7 @@ public class NavigationUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void goToArtistOptions(@NotNull Activity activity,
|
public static void goToArtistOptions(@NotNull Activity activity,
|
||||||
int artistId,
|
long artistId,
|
||||||
@NonNull ActivityOptions options) {
|
@NonNull ActivityOptions options) {
|
||||||
|
|
||||||
Intent intent = new Intent(activity, ArtistDetailActivity.class);
|
Intent intent = new Intent(activity, ArtistDetailActivity.class);
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class PlaylistsUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean doPlaylistContains(@NonNull final Context context, final long playlistId,
|
static boolean doPlaylistContains(@NonNull final Context context, final long playlistId,
|
||||||
final int songId) {
|
final long songId) {
|
||||||
if (playlistId != -1) {
|
if (playlistId != -1) {
|
||||||
try {
|
try {
|
||||||
Cursor c = context.getContentResolver().query(
|
Cursor c = context.getContentResolver().query(
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.util;
|
package code.name.monkey.retromusic.util;
|
||||||
|
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.ArtistAlbumSortOrder;
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.ArtistSongSortOrder;
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder;
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.GenreSortOrder;
|
||||||
|
import static code.name.monkey.retromusic.helper.SortOrder.SongSortOrder;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
@ -33,8 +39,8 @@ import code.name.monkey.retromusic.activities.MainActivity;
|
||||||
import code.name.monkey.retromusic.fragments.AlbumCoverStyle;
|
import code.name.monkey.retromusic.fragments.AlbumCoverStyle;
|
||||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen;
|
import code.name.monkey.retromusic.fragments.NowPlayingScreen;
|
||||||
import code.name.monkey.retromusic.fragments.mainactivity.folders.FoldersFragment;
|
import code.name.monkey.retromusic.fragments.mainactivity.folders.FoldersFragment;
|
||||||
import code.name.monkey.retromusic.helper.SortOrder;
|
|
||||||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder;
|
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder;
|
||||||
|
import code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder;
|
||||||
import code.name.monkey.retromusic.model.CategoryInfo;
|
import code.name.monkey.retromusic.model.CategoryInfo;
|
||||||
import code.name.monkey.retromusic.transform.CascadingPageTransformer;
|
import code.name.monkey.retromusic.transform.CascadingPageTransformer;
|
||||||
import code.name.monkey.retromusic.transform.DepthTransformation;
|
import code.name.monkey.retromusic.transform.DepthTransformation;
|
||||||
|
@ -365,6 +371,7 @@ public final class PreferenceUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public String getAlbumDetailSongSortOrder() {
|
public String getAlbumDetailSongSortOrder() {
|
||||||
return mPreferences
|
return mPreferences
|
||||||
.getString(ALBUM_DETAIL_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST);
|
.getString(ALBUM_DETAIL_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST);
|
||||||
|
@ -417,8 +424,9 @@ public final class PreferenceUtil {
|
||||||
.getString(ALBUM_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST);
|
.getString(ALBUM_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public final String getAlbumSortOrder() {
|
public final String getAlbumSortOrder() {
|
||||||
return mPreferences.getString(ALBUM_SORT_ORDER, SortOrder.AlbumSortOrder.ALBUM_A_Z);
|
return mPreferences.getString(ALBUM_SORT_ORDER, AlbumSortOrder.ALBUM_A_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAlbumSortOrder(final String sortOrder) {
|
public void setAlbumSortOrder(final String sortOrder) {
|
||||||
|
@ -428,12 +436,12 @@ public final class PreferenceUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getArtistAlbumSortOrder() {
|
public final String getArtistAlbumSortOrder() {
|
||||||
return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR);
|
return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, ArtistAlbumSortOrder.ALBUM_YEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getArtistDetailSongSortOrder() {
|
public String getArtistDetailSongSortOrder() {
|
||||||
return mPreferences
|
return mPreferences
|
||||||
.getString(ARTIST_DETAIL_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z);
|
.getString(ARTIST_DETAIL_SONG_SORT_ORDER, ArtistSongSortOrder.SONG_A_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setArtistDetailSongSortOrder(String sortOrder) {
|
public void setArtistDetailSongSortOrder(String sortOrder) {
|
||||||
|
@ -462,11 +470,12 @@ public final class PreferenceUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getArtistSongSortOrder() {
|
public final String getArtistSongSortOrder() {
|
||||||
return mPreferences.getString(ARTIST_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z);
|
return mPreferences.getString(ARTIST_SONG_SORT_ORDER, ArtistSongSortOrder.SONG_A_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public final String getArtistSortOrder() {
|
public final String getArtistSortOrder() {
|
||||||
return mPreferences.getString(ARTIST_SORT_ORDER, SortOrder.ArtistSortOrder.ARTIST_A_Z);
|
return mPreferences.getString(ARTIST_SORT_ORDER, ArtistSortOrder.ARTIST_A_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setArtistSortOrder(final String sortOrder) {
|
public void setArtistSortOrder(final String sortOrder) {
|
||||||
|
@ -536,7 +545,7 @@ public final class PreferenceUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getGenreSortOrder() {
|
public final String getGenreSortOrder() {
|
||||||
return mPreferences.getString(GENRE_SORT_ORDER, SortOrder.GenreSortOrder.GENRE_A_Z);
|
return mPreferences.getString(GENRE_SORT_ORDER, GenreSortOrder.GENRE_A_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getHeadsetPlugged() {
|
public boolean getHeadsetPlugged() {
|
||||||
|
@ -719,7 +728,7 @@ public final class PreferenceUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getSongSortOrder() {
|
public final String getSongSortOrder() {
|
||||||
return mPreferences.getString(SONG_SORT_ORDER, SortOrder.SongSortOrder.SONG_A_Z);
|
return mPreferences.getString(SONG_SORT_ORDER, SongSortOrder.SONG_A_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSongSortOrder(final String sortOrder) {
|
public void setSongSortOrder(final String sortOrder) {
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
~ Copyright (c) 2020 Hemanth Savarala.
|
||||||
android:shape="oval">
|
~
|
||||||
<corners android:radius="35dp"/>
|
~ Licensed under the GNU General Public License v3
|
||||||
<stroke
|
~
|
||||||
android:color="@color/md_white_1000"
|
~ This is free software: you can redistribute it and/or modify it under
|
||||||
android:width="2dp"/>
|
~ 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>
|
</shape>
|
|
@ -2,9 +2,9 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/gradient_background"
|
android:id="@+id/gradient_background"
|
||||||
android:background="?attr/colorSurface"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -87,6 +87,24 @@
|
||||||
android:maxLines="1" />
|
android:maxLines="1" />
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/artistContainer"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
app:hintEnabled="true">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/artistText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:hint="@string/artist"
|
||||||
|
android:inputType="text|textCapWords"
|
||||||
|
android:maxLines="1" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/albumArtistContainer"
|
android:id="@+id/albumArtistContainer"
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
android:id="@+id/imageContainer"
|
android:id="@+id/imageContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="156dp"
|
android:layout_height="156dp"
|
||||||
app:cardCornerRadius="16dp"
|
android:layout_margin="8dp"
|
||||||
app:cardUseCompatPadding="true">
|
app:cardCornerRadius="16dp">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
|
@ -21,17 +21,6 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@tools:sample/avatars" />
|
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.card.MaterialCardView>
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
android:id="@+id/imageContainer"
|
android:id="@+id/imageContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="256dp"
|
android:layout_height="256dp"
|
||||||
app:cardCornerRadius="16dp"
|
android:layout_margin="8dp"
|
||||||
app:cardUseCompatPadding="true">
|
app:cardCornerRadius="16dp">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
|
@ -22,16 +22,6 @@
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@tools:sample/avatars" />
|
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.card.MaterialCardView>
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
android:id="@+id/imageContainer"
|
android:id="@+id/imageContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="196dp"
|
android:layout_height="196dp"
|
||||||
app:cardCornerRadius="16dp"
|
android:layout_margin="8dp"
|
||||||
app:cardUseCompatPadding="true">
|
app:cardCornerRadius="16dp">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
|
@ -22,16 +22,6 @@
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@tools:sample/avatars" />
|
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.card.MaterialCardView>
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:text="@string/songs"
|
android:text="@string/songs"
|
||||||
android:textAppearance="@style/TextViewHeadline5"
|
android:textAppearance="@style/TextViewHeadline6"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|
|
@ -85,6 +85,26 @@
|
||||||
android:maxLines="1" />
|
android:maxLines="1" />
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/artistContainer"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
app:hintEnabled="true">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/artistText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:hint="@string/artist"
|
||||||
|
android:inputType="text|textCapWords"
|
||||||
|
android:maxLines="1" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/albumArtistContainer"
|
android:id="@+id/albumArtistContainer"
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:text="@string/albums"
|
android:text="@string/albums"
|
||||||
android:textAppearance="@style/TextViewHeadline5"
|
android:textAppearance="@style/TextViewHeadline6"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:text="@string/songs"
|
android:text="@string/songs"
|
||||||
android:textAppearance="@style/TextViewHeadline5"
|
android:textAppearance="@style/TextViewHeadline6"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -83,8 +83,7 @@
|
||||||
android:nestedScrollingEnabled="false"
|
android:nestedScrollingEnabled="false"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/songTitle"
|
app:layout_constraintTop_toBottomOf="@id/songTitle"
|
||||||
tools:listitem="@layout/item_song"
|
tools:listitem="@layout/item_song" />
|
||||||
tools:visibility="gone" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/biographyTitle"
|
android:id="@+id/biographyTitle"
|
||||||
|
@ -92,7 +91,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:text="@string/biography"
|
android:text="@string/biography"
|
||||||
android:textAppearance="@style/TextViewHeadline5"
|
android:textAppearance="@style/TextViewHeadline6"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
|
@ -104,13 +103,13 @@
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/biographyText"
|
android:id="@+id/biographyText"
|
||||||
style="@style/TextAppearance.MaterialComponents.Body1"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:lineSpacingExtra="5dp"
|
android:lineSpacingExtra="5dp"
|
||||||
android:maxLines="4"
|
android:maxLines="4"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
|
android:textAppearance="@style/TextViewBody1"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
|
|
||||||
|
@ -18,10 +19,6 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/shadow_up_full_theme" />
|
android:background="@drawable/shadow_up_full_theme" />
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/mask"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -5,20 +5,16 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
|
android:background="?attr/colorSurface"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/colorBackground"
|
android:id="@+id/colorBackground"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface"
|
||||||
android:scaleType="centerCrop" />
|
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" />
|
<include layout="@layout/shadow_statusbar_toolbar" />
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,5 +82,4 @@
|
||||||
tools:layout="@layout/fragment_card_blur_player_playback_controls" />
|
tools:layout="@layout/fragment_card_blur_player_playback_controls" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -12,58 +12,63 @@
|
||||||
android:id="@+id/playerMenu"
|
android:id="@+id/playerMenu"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
android:background="?attr/roundSelector"
|
android:background="?attr/roundSelector"
|
||||||
android:padding="12dp"
|
android:padding="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/text"
|
app:layout_constraintBottom_toBottomOf="@+id/titleContainer"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:srcCompat="@drawable/ic_more_vert_white_24dp" />
|
app:srcCompat="@drawable/ic_more_vert_white_24dp" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<LinearLayout
|
||||||
android:id="@+id/title"
|
android:id="@+id/titleContainer"
|
||||||
android:layout_width="315dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="marquee"
|
android:orientation="vertical"
|
||||||
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"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/progressSlider"
|
app:layout_constraintBottom_toTopOf="@+id/progressSlider"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
|
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
|
||||||
app:layout_constraintStart_toEndOf="@+id/songFavourite"
|
app:layout_constraintStart_toEndOf="@+id/songFavourite"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
tools:layout_editor_absoluteX="48dp"
|
|
||||||
tools:text="@tools:sample/lorem/random" />
|
<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
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/songFavourite"
|
android:id="@+id/songFavourite"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
android:background="?attr/roundSelector"
|
android:background="?attr/roundSelector"
|
||||||
android:padding="12dp"
|
android:padding="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/text"
|
app:layout_constraintBottom_toBottomOf="@+id/titleContainer"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
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" />
|
app:srcCompat="@drawable/ic_favorite_border_white_24dp" />
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,7 +100,7 @@
|
||||||
android:splitTrack="false"
|
android:splitTrack="false"
|
||||||
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
||||||
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
||||||
app:layout_constraintTop_toBottomOf="@id/text"
|
app:layout_constraintTop_toBottomOf="@id/titleContainer"
|
||||||
tools:ignore="RtlHardcoded,UnusedAttribute"
|
tools:ignore="RtlHardcoded,UnusedAttribute"
|
||||||
tools:progress="20" />
|
tools:progress="20" />
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:srcCompat="@tools:sample/backgrounds/scenic[16]" />
|
tools:srcCompat="@tools:sample/avatars" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/imageText"
|
android:id="@+id/imageText"
|
||||||
|
@ -58,8 +58,7 @@
|
||||||
android:minHeight="40dp"
|
android:minHeight="40dp"
|
||||||
android:textAppearance="@style/TextViewSubtitle2"
|
android:textAppearance="@style/TextViewSubtitle2"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:text="100"
|
tools:text="100" />
|
||||||
tools:visibility="visible" />
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,6 @@
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
tools:src="@tools:sample/avatars" />
|
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.card.MaterialCardView>
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
|
|
@ -25,10 +25,25 @@
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toTopOf="@id/proText"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||||
tools:src="@tools:sample/backgrounds/scenic" />
|
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>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -8,6 +8,7 @@
|
||||||
<item name="action_album_sort_order_desc" type="id" />
|
<item name="action_album_sort_order_desc" type="id" />
|
||||||
<item name="action_album_sort_order_artist" type="id" />
|
<item name="action_album_sort_order_artist" type="id" />
|
||||||
<item name="action_album_sort_order_year" type="id" />
|
<item name="action_album_sort_order_year" type="id" />
|
||||||
|
<item name="action_album_sort_num_songs" type="id" />
|
||||||
<item name="action_artist_sort_order_asc" type="id" />
|
<item name="action_artist_sort_order_asc" type="id" />
|
||||||
<item name="action_artist_sort_order_desc" type="id" />
|
<item name="action_artist_sort_order_desc" type="id" />
|
||||||
<item name="action_song_sort_order_asc" type="id" />
|
<item name="action_song_sort_order_asc" type="id" />
|
||||||
|
|
|
@ -825,4 +825,6 @@
|
||||||
<string name="share_to_stories">Share to Stories</string>
|
<string name="share_to_stories">Share to Stories</string>
|
||||||
<string name="drive_mode">Drive mode</string>
|
<string name="drive_mode">Drive mode</string>
|
||||||
<string name="retro_music_player">Retro Music Player</string>
|
<string name="retro_music_player">Retro Music Player</string>
|
||||||
|
<string name="sort_num_songs">Number of songs</string>
|
||||||
|
<string name="pro">Pro</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
<code.name.monkey.retromusic.preferences.BlacklistPreference
|
<code.name.monkey.retromusic.preferences.BlacklistPreference
|
||||||
android:key="blacklist"
|
android:key="blacklist"
|
||||||
|
app:enabled="false"
|
||||||
android:layout="@layout/list_item_view"
|
android:layout="@layout/list_item_view"
|
||||||
android:summary="@string/pref_summary_blacklist"
|
android:summary="@string/pref_summary_blacklist"
|
||||||
android:title="@string/pref_title_blacklist"
|
android:title="@string/pref_title_blacklist"
|
||||||
|
|
|
@ -54,12 +54,5 @@
|
||||||
android:summary="@string/pref_summary_colored_app_shortcuts"
|
android:summary="@string/pref_summary_colored_app_shortcuts"
|
||||||
android:title="@string/pref_title_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>
|
</code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory>
|
||||||
</androidx.preference.PreferenceScreen>
|
</androidx.preference.PreferenceScreen>
|
|
@ -35,48 +35,6 @@ import java.lang.reflect.Field;
|
||||||
*/
|
*/
|
||||||
public final class TintHelper {
|
public final class TintHelper {
|
||||||
|
|
||||||
@SuppressWarnings("JavaReflectionMemberAccess")
|
|
||||||
public static void colorHandles(@NonNull TextView view, int color) {
|
|
||||||
try {
|
|
||||||
Field editorField = TextView.class.getDeclaredField("mEditor");
|
|
||||||
if (!editorField.isAccessible()) {
|
|
||||||
editorField.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object editor = editorField.get(view);
|
|
||||||
Class<?> editorClass = editor.getClass();
|
|
||||||
|
|
||||||
String[] handleNames = {"mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"};
|
|
||||||
String[] resNames = {"mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"};
|
|
||||||
|
|
||||||
for (int i = 0; i < handleNames.length; i++) {
|
|
||||||
Field handleField = editorClass.getDeclaredField(handleNames[i]);
|
|
||||||
if (!handleField.isAccessible()) {
|
|
||||||
handleField.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Drawable handleDrawable = (Drawable) handleField.get(editor);
|
|
||||||
|
|
||||||
if (handleDrawable == null) {
|
|
||||||
Field resField = TextView.class.getDeclaredField(resNames[i]);
|
|
||||||
if (!resField.isAccessible()) {
|
|
||||||
resField.setAccessible(true);
|
|
||||||
}
|
|
||||||
int resId = resField.getInt(view);
|
|
||||||
handleDrawable = view.getResources().getDrawable(resId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handleDrawable != null) {
|
|
||||||
Drawable drawable = handleDrawable.mutate();
|
|
||||||
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
|
||||||
handleField.set(editor, drawable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@CheckResult
|
@CheckResult
|
||||||
@NonNull
|
@NonNull
|
||||||
public static Drawable createTintedDrawable(Context context,
|
public static Drawable createTintedDrawable(Context context,
|
||||||
|
|
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