2019-04-20 05:29:45 +00:00
|
|
|
package code.name.monkey.retromusic.activities
|
2018-12-05 04:29:55 +00:00
|
|
|
|
|
|
|
import android.app.Activity
|
|
|
|
import android.content.Intent
|
2019-11-26 15:27:28 +00:00
|
|
|
import android.os.Build
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.text.Html
|
|
|
|
import android.text.Spanned
|
2020-01-02 03:53:43 +00:00
|
|
|
import android.transition.Slide
|
2019-11-26 15:27:28 +00:00
|
|
|
import android.view.Menu
|
|
|
|
import android.view.MenuItem
|
|
|
|
import android.view.View
|
2018-12-05 04:29:55 +00:00
|
|
|
import android.widget.Toast
|
|
|
|
import androidx.core.app.ActivityCompat
|
2019-11-26 15:27:28 +00:00
|
|
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
|
|
|
import androidx.recyclerview.widget.GridLayoutManager
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
|
import code.name.monkey.appthemehelper.util.ATHUtil
|
|
|
|
import code.name.monkey.appthemehelper.util.MaterialUtil
|
|
|
|
import code.name.monkey.retromusic.App
|
|
|
|
import code.name.monkey.retromusic.R
|
2019-06-04 18:18:27 +00:00
|
|
|
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
|
2019-11-26 15:27:28 +00:00
|
|
|
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
|
2019-06-04 18:18:27 +00:00
|
|
|
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
|
2018-12-05 04:29:55 +00:00
|
|
|
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
|
2019-12-06 17:13:09 +00:00
|
|
|
import code.name.monkey.retromusic.extensions.ripAlpha
|
2020-01-28 17:00:28 +00:00
|
|
|
import code.name.monkey.retromusic.extensions.show
|
2019-11-26 15:27:28 +00:00
|
|
|
import code.name.monkey.retromusic.glide.ArtistGlideRequest
|
|
|
|
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
|
2018-12-05 04:29:55 +00:00
|
|
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
2019-11-26 15:27:28 +00:00
|
|
|
import code.name.monkey.retromusic.interfaces.CabHolder
|
2018-12-05 04:29:55 +00:00
|
|
|
import code.name.monkey.retromusic.model.Artist
|
2019-11-26 15:27:28 +00:00
|
|
|
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter
|
|
|
|
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView
|
2018-12-05 04:29:55 +00:00
|
|
|
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
2019-12-30 11:01:50 +00:00
|
|
|
import code.name.monkey.retromusic.util.CustomArtistImageUtil
|
|
|
|
import code.name.monkey.retromusic.util.MusicUtil
|
|
|
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
|
|
|
import code.name.monkey.retromusic.util.RetroColorUtil
|
|
|
|
import code.name.monkey.retromusic.util.RetroUtil
|
2019-11-26 15:27:28 +00:00
|
|
|
import com.afollestad.materialcab.MaterialCab
|
2019-09-16 18:02:40 +00:00
|
|
|
import com.bumptech.glide.Glide
|
2019-12-30 11:01:50 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.albumRecyclerView
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.albumTitle
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.biographyText
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.biographyTitle
|
2020-01-28 17:00:28 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.listeners
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.listenersLabel
|
2019-12-30 11:01:50 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.playAction
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.recyclerView
|
2020-01-28 17:00:28 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.scrobbles
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.scrobblesLabel
|
2019-12-30 11:01:50 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.shuffleAction
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_content.songTitle
|
2020-01-02 03:53:43 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_details.artistCoverContainer
|
2019-12-30 11:01:50 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_details.artistTitle
|
2020-01-02 03:53:43 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_details.image
|
2019-12-30 11:01:50 +00:00
|
|
|
import kotlinx.android.synthetic.main.activity_artist_details.text
|
|
|
|
import kotlinx.android.synthetic.main.activity_artist_details.toolbar
|
|
|
|
import java.util.Locale
|
2019-09-04 19:30:24 +00:00
|
|
|
import javax.inject.Inject
|
2018-12-05 04:29:55 +00:00
|
|
|
|
2019-11-26 15:27:28 +00:00
|
|
|
class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, CabHolder {
|
|
|
|
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
|
|
|
|
cab?.let {
|
|
|
|
if (it.isActive) it.finish()
|
|
|
|
}
|
|
|
|
cab = MaterialCab(this, R.id.cab_stub)
|
2019-12-30 11:01:50 +00:00
|
|
|
.setMenu(menuRes)
|
|
|
|
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
|
|
|
|
.setBackgroundColor(
|
|
|
|
RetroColorUtil.shiftBackgroundColorForLightText(
|
|
|
|
ATHUtil.resolveColor(
|
|
|
|
this,
|
|
|
|
R.attr.colorSurface
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.start(callback)
|
2019-11-26 15:27:28 +00:00
|
|
|
return cab as MaterialCab
|
|
|
|
}
|
|
|
|
|
|
|
|
private var cab: MaterialCab? = null
|
|
|
|
private var biography: Spanned? = null
|
|
|
|
private lateinit var artist: Artist
|
|
|
|
private lateinit var songAdapter: SimpleSongAdapter
|
2020-01-28 17:00:28 +00:00
|
|
|
private lateinit var albumAdapter: HorizontalAlbumAdapter
|
2019-11-26 15:27:28 +00:00
|
|
|
private var forceDownload: Boolean = false
|
|
|
|
|
|
|
|
override fun createContentView(): View {
|
|
|
|
return wrapSlidingMusicPanel(R.layout.activity_artist_details)
|
|
|
|
}
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
lateinit var artistDetailsPresenter: ArtistDetailsPresenter
|
|
|
|
|
2020-01-02 03:53:43 +00:00
|
|
|
private fun windowEnterTransition() {
|
|
|
|
val slide = Slide()
|
|
|
|
slide.excludeTarget(R.id.appBarLayout, true)
|
|
|
|
slide.excludeTarget(R.id.status_bar, true)
|
|
|
|
slide.excludeTarget(android.R.id.statusBarBackground, true)
|
|
|
|
slide.excludeTarget(android.R.id.navigationBarBackground, true)
|
|
|
|
window.enterTransition = slide
|
|
|
|
}
|
|
|
|
|
2019-11-26 15:27:28 +00:00
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
setDrawUnderStatusBar()
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
toggleBottomNavigationView(true)
|
2019-12-01 15:27:01 +00:00
|
|
|
setStatusbarColorAuto()
|
2019-11-26 15:27:28 +00:00
|
|
|
setNavigationbarColorAuto()
|
|
|
|
setTaskDescriptionColorAuto()
|
|
|
|
setLightNavigationBar(true)
|
2020-01-02 03:53:43 +00:00
|
|
|
window.sharedElementsUseOverlay = true
|
|
|
|
|
|
|
|
App.musicComponent.inject(this)
|
|
|
|
artistDetailsPresenter.attachView(this)
|
|
|
|
|
|
|
|
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
|
|
|
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let {
|
|
|
|
artistDetailsPresenter.loadArtist(it)
|
2020-01-06 18:07:02 +00:00
|
|
|
val name = "${getString(R.string.transition_artist_image)}_$it"
|
|
|
|
artistCoverContainer?.transitionName = name
|
2020-01-02 03:53:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
finish()
|
|
|
|
}
|
2019-11-26 15:27:28 +00:00
|
|
|
|
2020-01-02 03:53:43 +00:00
|
|
|
windowEnterTransition()
|
2019-11-26 15:27:28 +00:00
|
|
|
ActivityCompat.postponeEnterTransition(this)
|
|
|
|
|
2020-01-28 17:00:28 +00:00
|
|
|
setupRecyclerView()
|
2019-11-26 15:27:28 +00:00
|
|
|
|
|
|
|
playAction.apply {
|
|
|
|
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
|
|
|
|
}
|
|
|
|
shuffleAction.apply {
|
|
|
|
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) }
|
|
|
|
}
|
|
|
|
|
|
|
|
biographyText.setOnClickListener {
|
|
|
|
if (biographyText.maxLines == 4) {
|
|
|
|
biographyText.maxLines = Integer.MAX_VALUE
|
|
|
|
} else {
|
|
|
|
biographyText.maxLines = 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onDestroy() {
|
|
|
|
super.onDestroy()
|
|
|
|
artistDetailsPresenter.detachView()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun setupRecyclerView() {
|
2020-02-17 11:20:08 +00:00
|
|
|
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), null)
|
2019-11-26 15:27:28 +00:00
|
|
|
albumRecyclerView.apply {
|
|
|
|
itemAnimator = DefaultItemAnimator()
|
|
|
|
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
|
|
|
|
adapter = albumAdapter
|
|
|
|
}
|
|
|
|
songAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song, this)
|
|
|
|
recyclerView.apply {
|
|
|
|
itemAnimator = DefaultItemAnimator()
|
|
|
|
layoutManager = LinearLayoutManager(this.context)
|
|
|
|
adapter = songAdapter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
|
|
super.onActivityResult(requestCode, resultCode, data)
|
|
|
|
when (requestCode) {
|
|
|
|
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
|
|
|
|
data?.data?.let {
|
|
|
|
CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else -> if (resultCode == Activity.RESULT_OK) {
|
|
|
|
reload()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun showEmptyView() {
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun complete() {
|
|
|
|
ActivityCompat.startPostponedEnterTransition(this)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun artist(artist: Artist) {
|
2020-01-02 03:53:43 +00:00
|
|
|
complete()
|
2019-11-26 15:27:28 +00:00
|
|
|
if (artist.songCount <= 0) {
|
|
|
|
finish()
|
|
|
|
}
|
|
|
|
this.artist = artist
|
|
|
|
loadArtistImage()
|
|
|
|
|
|
|
|
if (RetroUtil.isAllowedToDownloadMetadata(this)) {
|
|
|
|
loadBiography(artist.name)
|
|
|
|
}
|
|
|
|
artistTitle.text = artist.name
|
|
|
|
text.text = String.format(
|
2019-12-30 11:01:50 +00:00
|
|
|
"%s • %s",
|
|
|
|
MusicUtil.getArtistInfoString(this, artist),
|
2020-01-17 17:19:06 +00:00
|
|
|
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs))
|
2019-11-26 15:27:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
songAdapter.swapDataSet(artist.songs)
|
|
|
|
albumAdapter.swapDataSet(artist.albums!!)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun loadBiography(
|
2019-12-30 11:01:50 +00:00
|
|
|
name: String,
|
|
|
|
lang: String? = Locale.getDefault().language
|
2019-11-26 15:27:28 +00:00
|
|
|
) {
|
|
|
|
biography = null
|
|
|
|
this.lang = lang
|
|
|
|
artistDetailsPresenter.loadBiography(name, lang, null)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun artistInfo(lastFmArtist: LastFmArtist?) {
|
|
|
|
if (lastFmArtist != null && lastFmArtist.artist != null) {
|
|
|
|
val bioContent = lastFmArtist.artist.bio.content
|
|
|
|
if (bioContent != null && bioContent.trim { it <= ' ' }.isNotEmpty()) {
|
|
|
|
biographyText.visibility = View.VISIBLE
|
|
|
|
biographyTitle.visibility = View.VISIBLE
|
|
|
|
biography = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
|
|
Html.fromHtml(bioContent, Html.FROM_HTML_MODE_LEGACY)
|
|
|
|
} else {
|
|
|
|
Html.fromHtml(bioContent)
|
|
|
|
}
|
|
|
|
biographyText.text = biography
|
2020-01-28 17:00:28 +00:00
|
|
|
|
|
|
|
if (lastFmArtist.artist.stats.listeners.isNotEmpty()) {
|
|
|
|
listeners.show()
|
|
|
|
listenersLabel.show()
|
|
|
|
scrobbles.show()
|
|
|
|
scrobblesLabel.show()
|
|
|
|
|
|
|
|
listeners.text = RetroUtil.formatValue(lastFmArtist.artist.stats.listeners.toFloat())
|
|
|
|
scrobbles.text = RetroUtil.formatValue(lastFmArtist.artist.stats.playcount.toFloat())
|
|
|
|
}
|
2019-11-26 15:27:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the "lang" parameter is set and no biography is given, retry with default language
|
|
|
|
if (biography == null && lang != null) {
|
|
|
|
loadBiography(artist.name, null)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private var lang: String? = null
|
|
|
|
|
|
|
|
private fun loadArtistImage() {
|
|
|
|
ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build()
|
2020-01-02 03:53:43 +00:00
|
|
|
.dontAnimate().into(object : RetroMusicColoredTarget(image) {
|
2019-12-30 11:01:50 +00:00
|
|
|
override fun onColorReady(color: Int) {
|
|
|
|
setColors(color)
|
|
|
|
}
|
|
|
|
})
|
2019-11-26 15:27:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun setColors(color: Int) {
|
2019-12-06 17:13:09 +00:00
|
|
|
val textColor = if (PreferenceUtil.getInstance(this).adaptiveColor)
|
|
|
|
color.ripAlpha()
|
|
|
|
else
|
2020-01-28 17:00:28 +00:00
|
|
|
ATHUtil.resolveColor(this, android.R.attr.textColorPrimary)
|
2019-11-26 15:27:28 +00:00
|
|
|
|
|
|
|
albumTitle.setTextColor(textColor)
|
|
|
|
songTitle.setTextColor(textColor)
|
|
|
|
biographyTitle.setTextColor(textColor)
|
|
|
|
|
2019-12-06 17:13:09 +00:00
|
|
|
val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor)
|
|
|
|
color.ripAlpha()
|
|
|
|
else
|
|
|
|
ATHUtil.resolveColor(this, R.attr.colorSurface)
|
2019-11-26 15:27:28 +00:00
|
|
|
|
|
|
|
MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
|
|
|
|
MaterialUtil.setTint(button = playAction, color = buttonColor)
|
|
|
|
|
2019-12-01 15:27:01 +00:00
|
|
|
val toolbarColor = ATHUtil.resolveColor(this, R.attr.colorSurface)
|
|
|
|
toolbar.setBackgroundColor(toolbarColor)
|
2019-11-26 15:27:28 +00:00
|
|
|
setSupportActionBar(toolbar)
|
|
|
|
supportActionBar?.title = null
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
|
|
return handleSortOrderMenuItem(item)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
|
|
|
|
val songs = artist.songs
|
|
|
|
when (item.itemId) {
|
|
|
|
android.R.id.home -> {
|
|
|
|
super.onBackPressed()
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.action_play_next -> {
|
|
|
|
MusicPlayerRemote.playNext(songs)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.action_add_to_current_playing -> {
|
|
|
|
MusicPlayerRemote.enqueue(songs)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.action_add_to_playlist -> {
|
|
|
|
AddToPlaylistDialog.create(songs).show(supportFragmentManager, "ADD_PLAYLIST")
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.action_set_artist_image -> {
|
|
|
|
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
|
|
|
intent.type = "image/*"
|
2019-12-30 11:01:50 +00:00
|
|
|
startActivityForResult(
|
|
|
|
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
|
|
|
|
REQUEST_CODE_SELECT_IMAGE
|
|
|
|
)
|
2019-11-26 15:27:28 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.action_reset_artist_image -> {
|
2019-12-30 11:01:50 +00:00
|
|
|
Toast.makeText(this@ArtistDetailActivity, resources.getString(R.string.updating), Toast.LENGTH_SHORT)
|
|
|
|
.show()
|
2019-12-06 17:13:09 +00:00
|
|
|
CustomArtistImageUtil.getInstance(this@ArtistDetailActivity).resetCustomArtistImage(artist)
|
2019-11-26 15:27:28 +00:00
|
|
|
forceDownload = true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
|
|
|
menuInflater.inflate(R.menu.menu_artist_detail, menu)
|
|
|
|
return super.onCreateOptionsMenu(menu)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onMediaStoreChanged() {
|
|
|
|
super.onMediaStoreChanged()
|
|
|
|
reload()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun reload() {
|
|
|
|
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
|
|
|
|
intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) }
|
|
|
|
} else {
|
|
|
|
finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-28 14:22:02 +00:00
|
|
|
override fun onBackPressed() {
|
|
|
|
if (cab != null && cab!!.isActive) {
|
|
|
|
cab?.finish()
|
|
|
|
} else {
|
|
|
|
super.onBackPressed()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-26 15:27:28 +00:00
|
|
|
companion object {
|
|
|
|
|
|
|
|
const val EXTRA_ARTIST_ID = "extra_artist_id"
|
|
|
|
const val REQUEST_CODE_SELECT_IMAGE = 9003
|
|
|
|
}
|
2018-12-05 04:29:55 +00:00
|
|
|
}
|