PlayerAndroid/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt

364 lines
14 KiB
Kotlin
Raw Normal View History

2019-04-20 05:29:45 +00:00
package code.name.monkey.retromusic.activities
import android.app.Activity
import android.content.Intent
2019-06-23 20:14:27 +00:00
import android.content.res.ColorStateList
import android.graphics.Color
2019-06-04 18:18:27 +00:00
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.text.Html
import android.text.Spanned
import android.transition.Slide
import android.view.*
import android.view.animation.AnimationUtils
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.ThemeStore
2019-06-23 20:14:27 +00:00
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
2019-06-04 18:18:27 +00:00
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
2018-12-12 20:59:07 +00:00
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.misc.AppBarStateChangeListener
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter
import code.name.monkey.retromusic.rest.LastFMRestClient
import code.name.monkey.retromusic.rest.model.LastFmArtist
import code.name.monkey.retromusic.util.*
import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.activity_artist_content.*
import kotlinx.android.synthetic.main.activity_artist_details.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*
2019-01-28 10:45:51 +00:00
import kotlin.collections.ArrayList
class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContract.ArtistsDetailsView {
private var biography: Spanned? = null
2019-03-29 14:17:41 +00:00
private lateinit var artist: Artist
private var lastFMRestClient: LastFMRestClient? = null
2019-06-04 18:18:27 +00:00
private lateinit var artistDetailsPresenter: ArtistDetailsPresenter
2019-01-28 10:45:51 +00:00
private lateinit var songAdapter: SimpleSongAdapter
private lateinit var albumAdapter: AlbumAdapter
private var forceDownload: Boolean = false
2018-12-25 14:58:47 +00:00
private fun setupWindowTransitions() {
val slide = Slide(Gravity.BOTTOM)
slide.interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in)
window.enterTransition = slide
}
override fun createContentView(): View {
return wrapSlidingMusicPanel(R.layout.activity_artist_details)
}
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
2018-12-25 14:58:47 +00:00
setupWindowTransitions()
super.onCreate(savedInstanceState)
2019-06-23 20:14:27 +00:00
//collapsingToolbarLayout?.setBackgroundColor(ThemeStore.primaryColor(this))
contentContainer?.setCardBackgroundColor(ColorStateList.valueOf(ThemeStore.primaryColor(this)))
toggleBottomNavigationView(true)
setNavigationbarColorAuto()
setLightNavigationBar(true)
ActivityCompat.postponeEnterTransition(this)
lastFMRestClient = LastFMRestClient(this)
setUpViews()
2019-01-14 12:17:22 +00:00
artistDetailsPresenter = ArtistDetailsPresenter(this, intent.extras!!)
2019-06-04 18:18:27 +00:00
artistDetailsPresenter.subscribe()
2019-06-04 18:18:27 +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
}
}
}
private fun setUpViews() {
setupRecyclerView()
setupToolbarMarginHeight()
setupContainerHeight()
}
private fun setupContainerHeight() {
if (imageContainer != null) {
val params = imageContainer!!.layoutParams
params.width = DensityUtil.getScreenHeight(this) / 2
imageContainer!!.layoutParams = params
}
}
private fun setupToolbarMarginHeight() {
val primaryColor = ThemeStore.primaryColor(this)
2019-06-23 20:14:27 +00:00
2019-06-04 18:18:27 +00:00
collapsingToolbarLayout?.let {
it.setContentScrimColor(primaryColor)
it.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor))
}
2019-06-04 18:18:27 +00:00
toolbar?.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setSupportActionBar(toolbar)
supportActionBar!!.title = null
if (toolbar != null && !PreferenceUtil.getInstance().fullScreenMode) {
val params = toolbar!!.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = RetroUtil.getStatusBarHeight()
toolbar!!.layoutParams = params
}
2019-01-02 03:55:55 +00:00
appBarLayout?.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
2019-06-04 18:37:43 +00:00
override fun onStateChanged(appBarLayout: AppBarLayout, state: State) {
2019-01-02 03:55:55 +00:00
val color: Int = when (state) {
2019-06-04 18:37:43 +00:00
State.COLLAPSED -> {
2019-01-02 03:55:55 +00:00
setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(appBarLayout.context)))
ThemeStore.primaryColor(appBarLayout.context)
}
2019-06-04 18:37:43 +00:00
State.EXPANDED, State.IDLE -> {
2019-01-02 03:55:55 +00:00
setLightStatusbar(false)
Color.TRANSPARENT
}
2019-01-02 03:55:55 +00:00
}
2019-01-02 03:55:55 +00:00
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(appBarLayout.context, toolbar, color)
}
})
2019-06-04 18:18:27 +00:00
setColors(ThemeStore.accentColor(this))
}
private fun setupRecyclerView() {
albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
albumRecyclerView.apply {
itemAnimator = DefaultItemAnimator()
layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
adapter = albumAdapter
}
2019-03-18 17:46:52 +00:00
songAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song, false)
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) {
2019-07-22 15:26:37 +00:00
data?.data?.let { CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, it) }
}
else -> if (resultCode == Activity.RESULT_OK) {
reload()
}
}
}
override fun onPause() {
super.onPause()
2019-06-04 18:18:27 +00:00
artistDetailsPresenter.unsubscribe()
}
override fun loading() {}
override fun showEmptyView() {
}
override fun completed() {
ActivityCompat.startPostponedEnterTransition(this)
}
2018-12-25 14:58:47 +00:00
override fun showData(list: Artist) {
setArtist(list)
}
private fun getArtist(): Artist {
2019-07-08 13:55:03 +00:00
return this.artist
}
private fun setArtist(artist: Artist) {
if (artist.songCount <= 0) {
finish()
}
this.artist = artist
loadArtistImage()
if (RetroUtil.isAllowedToDownloadMetadata(this)) {
loadBiography()
}
artistTitle.text = artist.name
text.text = String.format("%s • %s", MusicUtil.getArtistInfoString(this, artist), MusicUtil
.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)))
2019-01-28 10:45:51 +00:00
//val songs = artist.songs.sortedWith(compareBy { it.title }) as ArrayList<Song>
songAdapter.swapDataSet(artist.songs)
2019-01-28 10:45:51 +00:00
//val albums = artist.albums?.sortedWith(compareBy { it.artistName }) as ArrayList<Album>
albumAdapter.swapDataSet(artist.albums!!)
}
private fun loadBiography(lang: String? = Locale.getDefault().language) {
biography = null
lastFMRestClient!!.apiService
.getArtistInfo(getArtist().name, lang, null)
.enqueue(object : Callback<LastFmArtist> {
override fun onResponse(call: Call<LastFmArtist>,
response: Response<LastFmArtist>) {
val lastFmArtist = response.body()
if (lastFmArtist != null && lastFmArtist.artist != null) {
val bioContent = lastFmArtist.artist.bio.content
if (bioContent != null && !bioContent.trim { it <= ' ' }.isEmpty()) {
//TransitionManager.beginDelayedTransition(titleContainer);
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
}
}
// If the "lang" parameter is set and no biography is given, retry with default language
if (biography == null && lang != null) {
loadBiography(null)
}
}
override fun onFailure(call: Call<LastFmArtist>, t: Throwable) {
t.printStackTrace()
biography = null
}
})
}
private fun loadArtistImage() {
2018-12-12 20:59:07 +00:00
GlideApp.with(this)
.asBitmapPalette()
2019-04-04 06:07:55 +00:00
.load(RetroGlideExtension.getArtistModel(artist, forceDownload))
2018-12-12 20:59:07 +00:00
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) {
setColors(color)
}
2019-06-04 18:18:27 +00:00
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(defaultFooterColor)
}
})
2018-12-12 20:59:07 +00:00
forceDownload = false;
}
private fun setColors(color: Int) {
val textColor = if (PreferenceUtil.getInstance().adaptiveColor) color else ThemeStore.accentColor(this)
albumTitle.setTextColor(textColor)
songTitle.setTextColor(textColor)
biographyTitle.setTextColor(textColor)
2019-06-08 13:42:57 +00:00
val buttonColor = if (PreferenceUtil.getInstance().adaptiveColor) color
else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor)
2019-06-04 18:18:27 +00:00
2019-06-08 13:42:57 +00:00
MaterialUtil.setTint(button = shuffleAction, color = buttonColor)
MaterialUtil.setTint(button = playAction, color = buttonColor)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return handleSortOrderMenuItem(item)
}
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
val songs = getArtist().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/*"
startActivityForResult(Intent.createChooser(intent, getString(R.string.pick_from_local_storage)), REQUEST_CODE_SELECT_IMAGE)
return true
}
R.id.action_reset_artist_image -> {
Toast.makeText(this@ArtistDetailActivity, resources.getString(R.string.updating),
Toast.LENGTH_SHORT).show()
2019-07-08 13:55:03 +00:00
CustomArtistImageUtil.getInstance(this@ArtistDetailActivity).resetCustomArtistImage(artist)
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() {
2019-06-04 18:18:27 +00:00
artistDetailsPresenter.unsubscribe()
artistDetailsPresenter.subscribe()
}
companion object {
const val EXTRA_ARTIST_ID = "extra_artist_id"
const val REQUEST_CODE_SELECT_IMAGE = 9003
}
}