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

361 lines
14 KiB
Kotlin
Raw Normal View History

2019-04-20 05:29:45 +00:00
package code.name.monkey.retromusic.activities
2018-11-30 01:06:16 +00:00
import android.content.Intent
2019-06-23 20:14:27 +00:00
import android.content.res.ColorStateList
2018-11-30 01:06:16 +00:00
import android.graphics.Color
import android.os.Bundle
import android.transition.Slide
import android.view.*
import android.view.animation.AnimationUtils
2018-12-25 14:58:47 +00:00
import android.widget.ImageView
2018-11-30 01:06:16 +00:00
import androidx.core.app.ActivityCompat
import androidx.core.util.Pair
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.ThemeStore
2019-08-05 16:13:44 +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
2019-09-04 19:30:24 +00:00
import code.name.monkey.retromusic.App
2018-11-30 01:06:16 +00:00
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.activities.tageditor.AbsTagEditorActivity
import code.name.monkey.retromusic.activities.tageditor.AlbumTagEditorActivity
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
2018-11-30 01:06:16 +00:00
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
2019-09-04 19:30:24 +00:00
import code.name.monkey.retromusic.extensions.show
2018-12-12 20:59:07 +00:00
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
2018-11-30 01:06:16 +00:00
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
import code.name.monkey.retromusic.loaders.ArtistLoader
import code.name.monkey.retromusic.misc.AppBarStateChangeListener
import code.name.monkey.retromusic.model.Album
2019-09-04 19:30:24 +00:00
import code.name.monkey.retromusic.model.Artist
2018-11-30 01:06:16 +00:00
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter
2019-09-04 19:30:24 +00:00
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView
2018-11-30 01:06:16 +00:00
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.google.android.material.appbar.AppBarLayout
2018-12-25 14:58:47 +00:00
import io.reactivex.disposables.CompositeDisposable
2018-11-30 01:06:16 +00:00
import kotlinx.android.synthetic.main.activity_album.*
import kotlinx.android.synthetic.main.activity_album_content.*
import java.util.*
2019-09-04 19:30:24 +00:00
import javax.inject.Inject
2018-11-30 01:06:16 +00:00
2019-09-04 19:30:24 +00:00
class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
2018-11-30 01:06:16 +00:00
private lateinit var simpleSongAdapter: SimpleSongAdapter
2018-12-25 14:58:47 +00:00
private var disposable = CompositeDisposable()
2018-11-30 01:06:16 +00:00
2019-06-04 18:18:27 +00:00
private lateinit var album: Album
2018-11-30 01:06:16 +00:00
private val savedSortOrder: String
get() = PreferenceUtil.getInstance().albumDetailSongSortOrder
override fun createContentView(): View {
return wrapSlidingMusicPanel(R.layout.activity_album)
}
private fun setupWindowTransition() {
val slide = Slide(Gravity.BOTTOM)
slide.interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in)
window.enterTransition = slide
}
2019-09-04 19:30:24 +00:00
@Inject
lateinit var albumDetailsPresenter: AlbumDetailsPresenter
2018-11-30 01:06:16 +00:00
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
setupWindowTransition()
super.onCreate(savedInstanceState)
2018-12-25 14:58:47 +00:00
toggleBottomNavigationView(true)
2018-11-30 01:06:16 +00:00
setLightNavigationBar(true)
setNavigationbarColorAuto()
2019-08-05 16:13:44 +00:00
contentContainer?.setCardBackgroundColor(ColorStateList.valueOf(ThemeStore.primaryColor(this)))
2018-11-30 01:06:16 +00:00
2019-08-05 16:13:44 +00:00
ActivityCompat.postponeEnterTransition(this)
artistImage = findViewById(R.id.artistImage)
2018-11-30 01:06:16 +00:00
setupRecyclerView()
setupToolbarMarginHeight()
artistImage.setOnClickListener {
val artistPairs = arrayOf<Pair<*, *>>(Pair.create(image, resources.getString(R.string.transition_artist_image)))
2019-06-04 18:18:27 +00:00
NavigationUtil.goToArtist(this, album.artistId, *artistPairs)
}
playAction.apply {
setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) }
}
shuffleAction.apply {
setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album.songs!!, true) }
}
2019-09-04 19:30:24 +00:00
App.musicComponent.inject(this)
albumDetailsPresenter.attachView(this)
if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) {
albumDetailsPresenter.loadAlbum(intent.extras!!.getInt(EXTRA_ALBUM_ID))
} else {
finish()
}
2018-11-30 01:06:16 +00:00
}
private fun setupRecyclerView() {
2019-03-25 12:43:43 +00:00
simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song, false)
2018-11-30 01:06:16 +00:00
recyclerView.apply {
layoutManager = LinearLayoutManager(this@AlbumDetailsActivity)
itemAnimator = DefaultItemAnimator()
isNestedScrollingEnabled = false
adapter = simpleSongAdapter
2018-11-30 01:06:16 +00:00
}
}
private fun setupToolbarMarginHeight() {
setSupportActionBar(toolbar)
supportActionBar!!.title = null
2018-11-30 01:06:16 +00:00
val primaryColor = ThemeStore.primaryColor(this)
2019-06-23 20:14:27 +00:00
//TintHelper.setTintAuto(contentContainer!!, primaryColor, true)
2019-08-05 16:13:44 +00:00
collapsingToolbarLayout?.let {
it.setContentScrimColor(primaryColor)
it.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor))
2018-11-30 01:06:16 +00:00
}
2019-08-05 16:13:44 +00:00
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
2018-11-30 01:06:16 +00:00
if (toolbar != null && !PreferenceUtil.getInstance().fullScreenMode) {
2019-08-05 16:13:44 +00:00
val params = toolbar.layoutParams as ViewGroup.MarginLayoutParams
2018-11-30 01:06:16 +00:00
params.topMargin = RetroUtil.getStatusBarHeight()
2019-08-05 16:13:44 +00:00
toolbar.layoutParams = params
2018-11-30 01:06:16 +00:00
}
2019-01-02 03:55:55 +00:00
appBarLayout?.apply {
2018-12-25 14:58:47 +00:00
addOnOffsetChangedListener(object : AppBarStateChangeListener() {
2019-06-04 18:18:27 +00:00
override fun onStateChanged(appBarLayout: AppBarLayout, state: State) {
2018-12-25 14:58:47 +00:00
val color: Int = when (state) {
2019-06-04 18:18:27 +00:00
State.COLLAPSED -> {
2018-12-25 14:58:47 +00:00
setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this@AlbumDetailsActivity)))
ThemeStore.primaryColor(this@AlbumDetailsActivity)
}
2019-06-04 18:18:27 +00:00
State.EXPANDED, State.IDLE -> {
2018-12-25 14:58:47 +00:00
setLightStatusbar(false)
Color.TRANSPARENT
2018-11-30 01:06:16 +00:00
}
}
2018-12-25 14:58:47 +00:00
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color)
}
})
2018-11-30 01:06:16 +00:00
}
}
2018-12-25 14:58:47 +00:00
override fun onDestroy() {
super.onDestroy()
disposable.dispose()
2019-09-04 19:30:24 +00:00
albumDetailsPresenter.detachView()
2018-12-25 14:58:47 +00:00
}
2019-09-04 19:30:24 +00:00
override fun complete() {
2018-11-30 01:06:16 +00:00
ActivityCompat.startPostponedEnterTransition(this)
}
2019-09-04 19:30:24 +00:00
override fun album(album: Album) {
if (album.songs!!.isEmpty()) {
2018-11-30 01:06:16 +00:00
finish()
return
}
2019-09-04 19:30:24 +00:00
this.album = album
2018-11-30 01:06:16 +00:00
2019-09-04 19:30:24 +00:00
albumTitle.text = album.title
albumText.text = String.format("%s • %s • %s", album.artistName, MusicUtil.getYearString(album.year), MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)))
2018-11-30 01:06:16 +00:00
loadAlbumCover()
2019-09-04 19:30:24 +00:00
simpleSongAdapter.swapDataSet(album.songs)
2019-09-04 19:30:24 +00:00
albumDetailsPresenter.loadMore(album.artistId)
2018-11-30 01:06:16 +00:00
}
2018-12-25 14:58:47 +00:00
private lateinit var artistImage: ImageView
2018-11-30 01:06:16 +00:00
private fun loadMoreFrom(album: Album) {
disposable.add(ArtistLoader.getArtistFlowable(this, album.artistId)
2018-12-25 14:58:47 +00:00
.map {
2019-09-04 19:30:24 +00:00
2018-12-25 14:58:47 +00:00
return@map it.albums!!
}
.map { it.filter { albumSearch -> albumSearch.id != album.id } }
2018-12-25 14:58:47 +00:00
.subscribe {
for (albumFinal in it) {
if (albumFinal.id == album.id)
println("$albumFinal -> $album")
}
if (it.isEmpty()) {
2018-12-25 14:58:47 +00:00
return@subscribe
}
moreTitle.visibility = View.VISIBLE
moreRecyclerView.visibility = View.VISIBLE
2018-12-25 14:58:47 +00:00
moreTitle.text = String.format("More from %s", album.artistName)
2018-11-30 01:06:16 +00:00
val albumAdapter = HorizontalAlbumAdapter(this, it as ArrayList<Album>, false, null)
2018-12-25 14:58:47 +00:00
moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
moreRecyclerView.adapter = albumAdapter
2018-11-30 01:06:16 +00:00
2018-12-25 14:58:47 +00:00
})
2018-11-30 01:06:16 +00:00
}
2019-09-04 19:30:24 +00:00
override fun moreAlbums(albums: ArrayList<Album>) {
moreTitle.show()
moreRecyclerView.show()
moreTitle.text = String.format("More from %s", album.artistName)
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
moreRecyclerView.adapter = albumAdapter
}
override fun loadArtistImage(artist: Artist) {
GlideApp.with(this@AlbumDetailsActivity)
.asBitmapPalette()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) {
}
})
}
2018-11-30 01:06:16 +00:00
private fun loadAlbumCover() {
2018-12-12 20:59:07 +00:00
GlideApp.with(this)
.asBitmapPalette()
2019-06-04 18:18:27 +00:00
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
2018-12-12 20:59:07 +00:00
.transition(RetroGlideExtension.getDefaultTransition())
2019-06-04 18:18:27 +00:00
.songOptions(album.safeGetFirstSong())
2018-11-30 01:06:16 +00:00
.dontAnimate()
2018-12-25 18:45:32 +00:00
.into(object : RetroMusicColoredTarget(image as ImageView) {
2018-11-30 01:06:16 +00:00
override fun onColorReady(color: Int) {
setColors(color)
}
})
}
private fun setColors(color: Int) {
2019-06-08 13:42:57 +00:00
val themeColor = if (PreferenceUtil.getInstance().adaptiveColor) color
else ThemeStore.accentColor(this)
2018-11-30 01:06:16 +00:00
songTitle.setTextColor(themeColor)
moreTitle.setTextColor(themeColor)
2019-03-25 12:43:43 +00:00
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)
2019-08-05 16:13:44 +00:00
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color)
2018-11-30 01:06:16 +00:00
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_album_detail, menu)
val sortOrder = menu.findItem(R.id.action_sort_order)
setUpSortOrderMenu(sortOrder.subMenu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return handleSortOrderMenuItem(item)
}
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
var sortOrder: String? = null
val songs = simpleSongAdapter.dataSet
2018-11-30 01:06:16 +00:00
when (item.itemId) {
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_delete_from_device -> {
DeleteSongsDialog.create(songs).show(supportFragmentManager, "DELETE_SONGS")
return true
}
android.R.id.home -> {
super.onBackPressed()
return true
}
R.id.action_tag_editor -> {
val intent = Intent(this, AlbumTagEditorActivity::class.java)
2019-06-04 18:18:27 +00:00
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id)
2018-11-30 01:06:16 +00:00
startActivityForResult(intent, TAG_EDITOR_REQUEST)
return true
}
R.id.action_go_to_artist -> {
2019-06-04 18:18:27 +00:00
NavigationUtil.goToArtist(this, album.artistId)
2018-11-30 01:06:16 +00:00
return true
}
/*Sort*/
R.id.action_sort_order_title -> sortOrder = AlbumSongSortOrder.SONG_A_Z
R.id.action_sort_order_title_desc -> sortOrder = AlbumSongSortOrder.SONG_Z_A
R.id.action_sort_order_track_list -> sortOrder = AlbumSongSortOrder.SONG_TRACK_LIST
R.id.action_sort_order_artist_song_duration -> sortOrder = AlbumSongSortOrder.SONG_DURATION
}
if (sortOrder != null) {
item.isChecked = true
setSaveSortOrder(sortOrder)
}
return true
}
private fun setUpSortOrderMenu(sortOrder: SubMenu) {
when (savedSortOrder) {
AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked = true
AlbumSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true
AlbumSongSortOrder.SONG_TRACK_LIST -> sortOrder.findItem(R.id.action_sort_order_track_list).isChecked = true
AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration).isChecked = true
}
}
private fun setSaveSortOrder(sortOrder: String?) {
PreferenceUtil.getInstance().albumDetailSongSortOrder = sortOrder
reload()
}
override fun onMediaStoreChanged() {
super.onMediaStoreChanged()
reload()
}
private fun reload() {
2019-09-04 19:30:24 +00:00
albumDetailsPresenter.loadAlbum(intent.extras!!.getInt(ArtistDetailActivity.EXTRA_ARTIST_ID))
2018-11-30 01:06:16 +00:00
}
companion object {
const val EXTRA_ALBUM_ID = "extra_album_id"
private const val TAG_EDITOR_REQUEST = 2001
}
}