diff --git a/app/build.gradle b/app/build.gradle index bb32248b..5a880777 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -126,6 +126,7 @@ dependencies { implementation 'com.squareup.retrofit2:retrofit:2.6.2' implementation 'com.squareup.retrofit2:converter-gson:2.6.2' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.2' + implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' implementation 'com.afollestad.material-dialogs:core:3.1.1' implementation 'com.afollestad.material-dialogs:input:3.1.1' diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt index 41244be4..94075cff 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt @@ -4,25 +4,44 @@ import android.app.ActivityOptions import android.content.Intent import android.graphics.Color import android.os.Bundle -import android.view.* +import android.view.Menu +import android.view.MenuItem +import android.view.SubMenu +import android.view.View import android.widget.ImageView import androidx.core.app.ActivityCompat -import androidx.recyclerview.widget.* +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager import code.name.monkey.appthemehelper.ThemeStore -import code.name.monkey.appthemehelper.util.* -import code.name.monkey.retromusic.* +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.retromusic.App +import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity -import code.name.monkey.retromusic.activities.tageditor.* +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 -import code.name.monkey.retromusic.dialogs.* +import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog +import code.name.monkey.retromusic.dialogs.DeleteSongsDialog import code.name.monkey.retromusic.extensions.show -import code.name.monkey.retromusic.glide.* +import code.name.monkey.retromusic.glide.ArtistGlideRequest +import code.name.monkey.retromusic.glide.RetroMusicColoredTarget +import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder -import code.name.monkey.retromusic.model.* -import code.name.monkey.retromusic.mvp.presenter.* -import code.name.monkey.retromusic.util.* +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.mvp.presenter.AlbumDetailsPresenter +import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView +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.RetroColorUtil +import com.afollestad.materialcab.MaterialCab import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.activity_album.* import kotlinx.android.synthetic.main.activity_album_content.* @@ -30,263 +49,251 @@ import java.util.* import javax.inject.Inject import android.util.Pair as UtilPair -class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView { - private lateinit var simpleSongAdapter: SimpleSongAdapter - private lateinit var album: Album - private lateinit var artistImage: ImageView - private val savedSortOrder: String - get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder +class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, CabHolder { + override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab { + cab?.let { + if (it.isActive) it.finish() + } + cab = MaterialCab(this, R.id.cab_stub) + .setMenu(menuRes) + .setCloseDrawableRes(R.drawable.ic_close_white_24dp) + .setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(ATHUtil.resolveColor(this, R.attr.colorPrimary))) + .start(callback) + return cab as MaterialCab + } - override fun createContentView(): View { - return wrapSlidingMusicPanel(R.layout.activity_album) - } + private lateinit var simpleSongAdapter: SimpleSongAdapter + private lateinit var album: Album + private lateinit var artistImage: ImageView + private var cab: MaterialCab? = null + private val savedSortOrder: String + get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder - @Inject - lateinit var albumDetailsPresenter: AlbumDetailsPresenter + override fun createContentView(): View { + return wrapSlidingMusicPanel(R.layout.activity_album) + } - override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() - super.onCreate(savedInstanceState) - toggleBottomNavigationView(true) - setStatusbarColor(Color.TRANSPARENT) - setNavigationbarColorAuto() - setTaskDescriptionColorAuto() - setLightNavigationBar(true) - setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary))) + @Inject + lateinit var albumDetailsPresenter: AlbumDetailsPresenter - ActivityCompat.postponeEnterTransition(this) + override fun onCreate(savedInstanceState: Bundle?) { + setDrawUnderStatusBar() + super.onCreate(savedInstanceState) + toggleBottomNavigationView(true) + setStatusbarColor(Color.TRANSPARENT) + setNavigationbarColorAuto() + setTaskDescriptionColorAuto() + setLightNavigationBar(true) + setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary))) - App.musicComponent.inject(this) - artistImage = findViewById(R.id.artistImage) + ActivityCompat.postponeEnterTransition(this) - setupRecyclerView() + App.musicComponent.inject(this) + artistImage = findViewById(R.id.artistImage) - artistImage.setOnClickListener { - val artistPairs = ActivityOptions.makeSceneTransitionAnimation( - this, - UtilPair.create( - artistImage, - getString(R.string.transition_artist_image) - ) - ) - NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs) - } - playAction.apply { - setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) } - } - shuffleAction.apply { - setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album.songs!!, true) } - } + setupRecyclerView() + + artistImage.setOnClickListener { + val artistPairs = ActivityOptions.makeSceneTransitionAnimation(this, UtilPair.create(artistImage, getString(R.string.transition_artist_image))) + NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs) + } + playAction.apply { + setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) } + } + shuffleAction.apply { + setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album.songs!!, true) } + } - albumDetailsPresenter.attachView(this) + albumDetailsPresenter.attachView(this) - if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) { - intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) } - } else { - finish() - } - } + if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) { + intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) } + } else { + finish() + } + } - private fun setupRecyclerView() { - simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song) - recyclerView.apply { - layoutManager = LinearLayoutManager(this@AlbumDetailsActivity) - itemAnimator = DefaultItemAnimator() - isNestedScrollingEnabled = false - adapter = simpleSongAdapter - } - } + private fun setupRecyclerView() { + simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song, this) + recyclerView.apply { + layoutManager = LinearLayoutManager(this@AlbumDetailsActivity) + itemAnimator = DefaultItemAnimator() + isNestedScrollingEnabled = false + adapter = simpleSongAdapter + } + } - override fun onDestroy() { - super.onDestroy() - albumDetailsPresenter.detachView() - } + override fun onDestroy() { + super.onDestroy() + albumDetailsPresenter.detachView() + } - override fun complete() { - ActivityCompat.startPostponedEnterTransition(this) - } + override fun complete() { + ActivityCompat.startPostponedEnterTransition(this) + } - override fun album(album: Album) { + override fun album(album: Album) { - if (album.songs!!.isEmpty()) { - finish() - return - } - this.album = album + if (album.songs!!.isEmpty()) { + finish() + return + } + this.album = album - albumTitle.text = album.title - if (MusicUtil.getYearString(album.year) == "-") { - albumText.text = String.format( - "%s • %s", - album.artistName, - MusicUtil.getReadableDurationString( - MusicUtil.getTotalDuration( - this, - album.songs - ) - ) - ) - } else { - albumText.text = String.format( - "%s • %s • %s", - album.artistName, - MusicUtil.getYearString(album.year), - MusicUtil.getReadableDurationString( - MusicUtil.getTotalDuration( - this, - album.songs - ) - ) - ) - } - loadAlbumCover() - simpleSongAdapter.swapDataSet(album.songs) - albumDetailsPresenter.loadMore(album.artistId) - } + albumTitle.text = album.title + if (MusicUtil.getYearString(album.year) == "-") { + albumText.text = String.format("%s • %s", album.artistName, MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs))) + } else { + albumText.text = String.format("%s • %s • %s", album.artistName, MusicUtil.getYearString(album.year), MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs))) + } + loadAlbumCover() + simpleSongAdapter.swapDataSet(album.songs) + albumDetailsPresenter.loadMore(album.artistId) + } - override fun moreAlbums(albums: ArrayList) { - moreTitle.show() - moreRecyclerView.show() - moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName) + override fun moreAlbums(albums: ArrayList) { + moreTitle.show() + moreRecyclerView.show() + moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName) - val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null) - moreRecyclerView.layoutManager = GridLayoutManager( - this, - 1, - GridLayoutManager.HORIZONTAL, - false - ) - moreRecyclerView.adapter = albumAdapter - } + val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null) + moreRecyclerView.layoutManager = GridLayoutManager( + this, + 1, + GridLayoutManager.HORIZONTAL, + false + ) + moreRecyclerView.adapter = albumAdapter + } - override fun loadArtistImage(artist: Artist) { - ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build() - .dontAnimate().dontTransform().into(object : RetroMusicColoredTarget(artistImage) { - override fun onColorReady(color: Int) { + override fun loadArtistImage(artist: Artist) { + ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build() + .dontAnimate().dontTransform().into(object : RetroMusicColoredTarget(artistImage) { + override fun onColorReady(color: Int) { - } - }) + } + }) - } + } - private fun loadAlbumCover() { - SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong()) - .checkIgnoreMediaStore(this).generatePalette(this).build().dontAnimate().dontTransform() - .into(object : RetroMusicColoredTarget(image) { - override fun onColorReady(color: Int) { - setColors(color) - } - }) - } + private fun loadAlbumCover() { + SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong()) + .checkIgnoreMediaStore(this).generatePalette(this).build().dontAnimate().dontTransform() + .into(object : RetroMusicColoredTarget(image) { + override fun onColorReady(color: Int) { + setColors(color) + } + }) + } - private fun setColors(color: Int) { - val themeColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color - else ThemeStore.accentColor(this) + private fun setColors(color: Int) { + val themeColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color + else ThemeStore.accentColor(this) - songTitle.setTextColor(themeColor) - moreTitle.setTextColor(themeColor) + songTitle.setTextColor(themeColor) + moreTitle.setTextColor(themeColor) - val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color - else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor) + val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color + else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor) - MaterialUtil.setTint(button = shuffleAction, color = buttonColor) - MaterialUtil.setTint(button = playAction, color = buttonColor) + MaterialUtil.setTint(button = shuffleAction, color = buttonColor) + MaterialUtil.setTint(button = playAction, color = buttonColor) - toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary)) - setSupportActionBar(toolbar) - supportActionBar?.title = null - } + toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary)) + setSupportActionBar(toolbar) + supportActionBar?.title = null + } - 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 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) - } + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return handleSortOrderMenuItem(item) + } - private fun handleSortOrderMenuItem(item: MenuItem): Boolean { - var sortOrder: String? = null - val songs = simpleSongAdapter.dataSet - 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) - intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id) - startActivityForResult(intent, TAG_EDITOR_REQUEST) - 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 handleSortOrderMenuItem(item: MenuItem): Boolean { + var sortOrder: String? = null + val songs = simpleSongAdapter.dataSet + 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) + intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id) + startActivityForResult(intent, TAG_EDITOR_REQUEST) + 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 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(this).albumDetailSongSortOrder = sortOrder - reload() - } + private fun setSaveSortOrder(sortOrder: String?) { + PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder + reload() + } - override fun onMediaStoreChanged() { - super.onMediaStoreChanged() - reload() - } + override fun onMediaStoreChanged() { + super.onMediaStoreChanged() + reload() + } - private fun reload() { - if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) { - intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) } - } else { - finish() - } - } + private fun reload() { + if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) { + intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) } + } else { + finish() + } + } - companion object { + companion object { - const val EXTRA_ALBUM_ID = "extra_album_id" - private const val TAG_EDITOR_REQUEST = 2001 - } + const val EXTRA_ALBUM_ID = "extra_album_id" + private const val TAG_EDITOR_REQUEST = 2001 + } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt index 0ababef3..34858e55 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt @@ -3,26 +3,39 @@ package code.name.monkey.retromusic.activities import android.app.Activity import android.content.Intent import android.graphics.Color -import android.os.* -import android.text.* -import android.view.* +import android.os.Build +import android.os.Bundle +import android.text.Html +import android.text.Spanned +import android.view.Menu +import android.view.MenuItem +import android.view.View import android.widget.Toast import androidx.core.app.ActivityCompat -import androidx.recyclerview.widget.* +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager import code.name.monkey.appthemehelper.ThemeStore -import code.name.monkey.appthemehelper.util.* -import code.name.monkey.retromusic.* +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.retromusic.App +import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity -import code.name.monkey.retromusic.adapter.album.* +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 -import code.name.monkey.retromusic.glide.* +import code.name.monkey.retromusic.glide.ArtistGlideRequest +import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.helper.MusicPlayerRemote +import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Artist -import code.name.monkey.retromusic.mvp.presenter.* -import code.name.monkey.retromusic.rest.LastFMRestClient +import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter +import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView import code.name.monkey.retromusic.rest.model.LastFmArtist import code.name.monkey.retromusic.util.* +import com.afollestad.materialcab.MaterialCab import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.activity_artist_content.* import kotlinx.android.synthetic.main.activity_artist_details.* @@ -30,269 +43,277 @@ import java.util.* import javax.inject.Inject import kotlin.collections.ArrayList -class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView { +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) + .setMenu(menuRes) + .setCloseDrawableRes(R.drawable.ic_close_white_24dp) + .setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(ATHUtil.resolveColor(this, R.attr.colorPrimary))) + .start(callback) + return cab as MaterialCab + } - private var biography: Spanned? = null - private lateinit var artist: Artist - private var lastFMRestClient: LastFMRestClient? = null - private lateinit var songAdapter: SimpleSongAdapter - private lateinit var albumAdapter: AlbumAdapter - private var forceDownload: Boolean = false + private var cab: MaterialCab? = null + private var biography: Spanned? = null + private lateinit var artist: Artist + private lateinit var songAdapter: SimpleSongAdapter + private lateinit var albumAdapter: AlbumAdapter + private var forceDownload: Boolean = false - override fun createContentView(): View { - return wrapSlidingMusicPanel(R.layout.activity_artist_details) - } + override fun createContentView(): View { + return wrapSlidingMusicPanel(R.layout.activity_artist_details) + } - @Inject - lateinit var artistDetailsPresenter: ArtistDetailsPresenter + @Inject + lateinit var artistDetailsPresenter: ArtistDetailsPresenter - override fun onCreate(savedInstanceState: Bundle?) { - setDrawUnderStatusBar() - super.onCreate(savedInstanceState) - toggleBottomNavigationView(true) - setStatusbarColor(Color.TRANSPARENT) - setNavigationbarColorAuto() - setTaskDescriptionColorAuto() - setLightNavigationBar(true) - setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary))) + override fun onCreate(savedInstanceState: Bundle?) { + setDrawUnderStatusBar() + super.onCreate(savedInstanceState) + toggleBottomNavigationView(true) + setStatusbarColor(Color.TRANSPARENT) + setNavigationbarColorAuto() + setTaskDescriptionColorAuto() + setLightNavigationBar(true) + setLightStatusbar(ColorUtil.isColorLight(ATHUtil.resolveColor(this, R.attr.colorPrimary))) - ActivityCompat.postponeEnterTransition(this) + ActivityCompat.postponeEnterTransition(this) - lastFMRestClient = LastFMRestClient(this) + setUpViews() - setUpViews() + playAction.apply { + setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) } + } + shuffleAction.apply { + setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) } + } - 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 + } + } - biographyText.setOnClickListener { - if (biographyText.maxLines == 4) { - biographyText.maxLines = Integer.MAX_VALUE - } else { - biographyText.maxLines = 4 - } - } + App.musicComponent.inject(this) + artistDetailsPresenter.attachView(this) - App.musicComponent.inject(this) - artistDetailsPresenter.attachView(this) + if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) { + intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) } + } else { + finish() + } + } - if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) { - intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) } - } else { - finish() - } - } + override fun onDestroy() { + super.onDestroy() + artistDetailsPresenter.detachView() + } - override fun onDestroy() { - super.onDestroy() - artistDetailsPresenter.detachView() - } + private fun setUpViews() { + setupRecyclerView() + setupContainerHeight() + } - private fun setUpViews() { - setupRecyclerView() - setupContainerHeight() - } + private fun setupContainerHeight() { + imageContainer?.let { + val params = it.layoutParams + params.width = DensityUtil.getScreenHeight(this) / 2 + it.layoutParams = params + } + } - private fun setupContainerHeight() { - imageContainer?.let { - val params = it.layoutParams - params.width = DensityUtil.getScreenHeight(this) / 2 - it.layoutParams = params - } - } + private fun setupRecyclerView() { + albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null) + 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 + } + } - private fun setupRecyclerView() { - albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null) - albumRecyclerView.apply { - itemAnimator = DefaultItemAnimator() - layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false) - adapter = albumAdapter - } - songAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song) - 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 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 showEmptyView() { + } - } + override fun complete() { + ActivityCompat.startPostponedEnterTransition(this) + } - override fun complete() { - ActivityCompat.startPostponedEnterTransition(this) - } + override fun artist(artist: Artist) { + if (artist.songCount <= 0) { + finish() + } + this.artist = artist + loadArtistImage() - override fun artist(artist: Artist) { - if (artist.songCount <= 0) { - finish() - } - this.artist = artist - loadArtistImage() + if (RetroUtil.isAllowedToDownloadMetadata(this)) { + loadBiography(artist.name) + } + artistTitle.text = artist.name + text.text = String.format( + "%s • %s", + MusicUtil.getArtistInfoString(this, artist), + MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)) + ) - if (RetroUtil.isAllowedToDownloadMetadata(this)) { - loadBiography(artist.name) - } - artistTitle.text = artist.name - text.text = String.format( - "%s • %s", - MusicUtil.getArtistInfoString(this, artist), - MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)) - ) + songAdapter.swapDataSet(artist.songs) + albumAdapter.swapDataSet(artist.albums!!) + } - songAdapter.swapDataSet(artist.songs) - albumAdapter.swapDataSet(artist.albums!!) - } + private fun loadBiography( + name: String, lang: String? = Locale.getDefault().language + ) { + biography = null + this.lang = lang + artistDetailsPresenter.loadBiography(name, lang, null) + } - private fun loadBiography( - name: String, lang: String? = Locale.getDefault().language - ) { - 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 + } + } - 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 - } - } + // If the "lang" parameter is set and no biography is given, retry with default language + if (biography == null && lang != null) { + loadBiography(artist.name, null) + } + } - // 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 var lang: String? = null + private fun loadArtistImage() { + ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build() + .dontAnimate().into(object : RetroMusicColoredTarget(artistImage) { + override fun onColorReady(color: Int) { + setColors(color) + } + }) + } - private fun loadArtistImage() { - ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build() - .dontAnimate().into(object : RetroMusicColoredTarget(artistImage) { - override fun onColorReady(color: Int) { - setColors(color) - } - }) - } + private fun setColors(color: Int) { - private fun setColors(color: Int) { + val textColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color + else ThemeStore.accentColor(this) - val textColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color - else ThemeStore.accentColor(this) + albumTitle.setTextColor(textColor) + songTitle.setTextColor(textColor) + biographyTitle.setTextColor(textColor) - albumTitle.setTextColor(textColor) - songTitle.setTextColor(textColor) - biographyTitle.setTextColor(textColor) + val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color + else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor) - val buttonColor = if (PreferenceUtil.getInstance(this).adaptiveColor) color - else ATHUtil.resolveColor(this, R.attr.cardBackgroundColor) + MaterialUtil.setTint(button = shuffleAction, color = buttonColor) + MaterialUtil.setTint(button = playAction, color = buttonColor) - MaterialUtil.setTint(button = shuffleAction, color = buttonColor) - MaterialUtil.setTint(button = playAction, color = buttonColor) + toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary)) + setSupportActionBar(toolbar) + supportActionBar?.title = null + } - toolbar.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary)) - setSupportActionBar(toolbar) - supportActionBar?.title = null - } + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return handleSortOrderMenuItem(item) + } - 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/*" + 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() + CustomArtistImageUtil.getInstance(this@ArtistDetailActivity) + .resetCustomArtistImage(artist) + forceDownload = true + return true + } + } + return true + } - 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/*" - 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() - 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 onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.menu_artist_detail, menu) - return super.onCreateOptionsMenu(menu) - } + override fun onMediaStoreChanged() { + super.onMediaStoreChanged() + reload() + } - 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() + } + } - private fun reload() { - if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) { - intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) } - } else { - finish() - } - } + companion object { - companion object { - - const val EXTRA_ARTIST_ID = "extra_artist_id" - const val REQUEST_CODE_SELECT_IMAGE = 9003 - } + const val EXTRA_ARTIST_ID = "extra_artist_id" + const val REQUEST_CODE_SELECT_IMAGE = 9003 + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt index 5c5b9608..c2d40a27 100755 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt @@ -1,34 +1,39 @@ package code.name.monkey.retromusic.adapter.song -import android.view.* +import android.view.LayoutInflater +import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity +import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.MusicUtil import java.util.* class SimpleSongAdapter( - context: AppCompatActivity, songs: ArrayList, i: Int -) : SongAdapter(context, songs, i, false, null) { + context: AppCompatActivity, + songs: ArrayList, + i: Int, + cabHolder: CabHolder? +) : SongAdapter(context, songs, i, false, cabHolder) { - override fun swapDataSet(dataSet: ArrayList) { - this.dataSet.clear() - this.dataSet = dataSet - notifyDataSetChanged() - } + override fun swapDataSet(dataSet: ArrayList) { + this.dataSet.clear() + this.dataSet = dataSet + notifyDataSetChanged() + } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)) - } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false)) + } - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - super.onBindViewHolder(holder, position) - val fixedTrackNumber = MusicUtil.getFixedTrackNumber(dataSet[position].trackNumber) + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + super.onBindViewHolder(holder, position) + val fixedTrackNumber = MusicUtil.getFixedTrackNumber(dataSet[position].trackNumber) - holder.imageText?.text = if (fixedTrackNumber > 0) fixedTrackNumber.toString() else "-" - holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration) - } + holder.imageText?.text = if (fixedTrackNumber > 0) fixedTrackNumber.toString() else "-" + holder.time?.text = MusicUtil.getReadableDurationString(dataSet[position].duration) + } - override fun getItemCount(): Int { - return dataSet.size - } + override fun getItemCount(): Int { + return dataSet.size + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java index c53c3046..911326fd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/LibraryFragment.java @@ -148,7 +148,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde }); getMainActivity().setSupportActionBar(toolbar); toolbar.setNavigationOnClickListener(v -> showMainMenu(OptionsSheetDialogFragment.LIBRARY)); - ToolbarContentTintHelper.colorBackButton(toolbar ); + ToolbarContentTintHelper.colorBackButton(toolbar); toolbar.setTitleTextColor(ATHUtil.INSTANCE.resolveColor(requireContext(), R.attr.colorOnSecondary)); } diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt index 47acc114..ed242c56 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt @@ -46,7 +46,9 @@ interface AlbumDetailsPresenter : Presenter { ) : PresenterImpl(), AlbumDetailsPresenter { private lateinit var album: Album + private var disposable: CompositeDisposable = CompositeDisposable() + override fun loadMore(artistId: Int) { disposable += repository.getArtistByIdFlowable(artistId) .map { diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt index ca24a318..ad5ffdc9 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt @@ -14,16 +14,17 @@ package code.name.monkey.retromusic.mvp.presenter +import code.name.monkey.retromusic.Result import code.name.monkey.retromusic.model.Artist 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.rest.model.LastFmArtist -import io.reactivex.disposables.CompositeDisposable +import kotlinx.coroutines.* import java.util.* import javax.inject.Inject - +import kotlin.coroutines.CoroutineContext /** * Created by hemanths on 20/08/17. @@ -38,38 +39,48 @@ interface ArtistDetailsPresenter : Presenter { fun loadArtist(artistId: Int) - fun loadBiography(name: String, - lang: String? = Locale.getDefault().language, - cache: String?) + fun loadBiography( + name: String, lang: String? = Locale.getDefault().language, cache: String? + ) class ArtistDetailsPresenterImpl @Inject constructor( private val repository: Repository - ) : PresenterImpl(), ArtistDetailsPresenter { + ) : PresenterImpl(), ArtistDetailsPresenter, CoroutineScope { + override val coroutineContext: CoroutineContext + get() = Dispatchers.IO + job - override fun loadBiography(name: String, - lang: String?, - cache: String?) { - disposable += repository.artistInfoFloable(name, lang, cache) - .subscribe { - view?.artistInfo(it) + private val job = Job() + + override fun loadBiography(name: String, lang: String?, cache: String?) { + launch { + when (val result = repository.artistInfo(name, lang, cache)) { + is Result.Success -> withContext(Dispatchers.Main) { + view?.artistInfo(result.data) } + is Result.Error -> withContext(Dispatchers.Main) { + + } + } + } } - private var disposable = CompositeDisposable() - override fun loadArtist(artistId: Int) { - disposable += repository.getArtistByIdFlowable(artistId) - .doOnComplete { + launch { + when (val result = repository.artistById(artistId)) { + is Result.Success -> withContext(Dispatchers.Main) { + view?.artist(result.data) view?.complete() } - .subscribe({ - view?.artist(it) - }, { t -> println(t) }) + is Result.Error -> withContext(Dispatchers.Main) { + view?.showEmptyView() + } + } + } } override fun detachView() { super.detachView() - disposable.dispose() + job.cancel() } } } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt b/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt index 6944e579..4d61ab3a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt +++ b/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt @@ -28,6 +28,7 @@ import code.name.monkey.retromusic.rest.model.LastFmArtist import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers +import java.io.IOException class RepositoryImpl(private val context: Context) : Repository { @@ -98,14 +99,14 @@ class RepositoryImpl(private val context: Context) : Repository { override suspend fun allSongs(): Result> { return try { - val songs = SongLoader.getAllSongs(context); + val songs = SongLoader.getAllSongs(context) if (songs.isEmpty()) { Error(Throwable("No items found")) } else { - Success(songs); + Success(songs) } } catch (e: Exception) { - Error(e); + Error(e) } } @@ -116,7 +117,7 @@ class RepositoryImpl(private val context: Context) : Repository { } else { PlaylistSongsLoader.getPlaylistSongList(context, playlist.id) } - Success(songs); + Success(songs) } catch (e: Exception) { Error(e) } @@ -128,7 +129,7 @@ class RepositoryImpl(private val context: Context) : Repository { if (songs.isEmpty()) { Error(Throwable("No items found")) } else { - Success(songs); + Success(songs) } } catch (e: Exception) { Error(e) @@ -165,7 +166,7 @@ class RepositoryImpl(private val context: Context) : Repository { albums, HomeAdapter.RECENT_ALBUMS, R.drawable.ic_album_white_24dp - )); + )) } } catch (e: Exception) { Error(e) @@ -184,7 +185,7 @@ class RepositoryImpl(private val context: Context) : Repository { albums, HomeAdapter.TOP_ALBUMS, R.drawable.ic_album_white_24dp - )); + )) } } catch (e: Exception) { Error(e) @@ -204,7 +205,7 @@ class RepositoryImpl(private val context: Context) : Repository { artists, HomeAdapter.TOP_ARTISTS, R.drawable.ic_artist_white_24dp - )); + )) } } catch (e: Exception) { Error(e) @@ -223,23 +224,33 @@ class RepositoryImpl(private val context: Context) : Repository { playlists, HomeAdapter.PLAYLISTS, R.drawable.ic_favorite_white_24dp - )); + )) } } catch (e: Exception) { Error(e) } } - override fun artistInfoFloable( + override suspend fun artistInfo( name: String, lang: String?, cache: String? - ): Observable { - return LastFMRestClient(context).apiService.getArtistInfoFloable(name, lang, cache) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - } + ): Result = safeApiCall( + call = { + Success(LastFMRestClient(context).apiService.artistInfo(name, lang, cache)) + }, + errorMessage = "Error" + ) + + override suspend fun artistById(artistId: Int): Result { + return try { + val artist = ArtistLoader.getArtist(context, artistId) + return Success(artist) + } catch (e: Exception) { + Error(Throwable("Error loading artist")) + } + } override fun getSongFlowable(id: Int): Observable { return SongLoader.getSongFlowable(context, id) @@ -343,3 +354,9 @@ class RepositoryImpl(private val context: Context) : Repository { } + +suspend fun safeApiCall(call: suspend () -> Result, errorMessage: String): Result = try { + call.invoke() +} catch (e: Exception) { + Result.Error(IOException(errorMessage, e)) +} diff --git a/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt b/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt index b815fd27..11222725 100644 --- a/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt @@ -51,6 +51,10 @@ interface Repository { suspend fun favoritePlaylist(): Result + suspend fun artistInfo(name: String, lang: String?, cache: String?): Result + + suspend fun artistById(artistId: Int): Result + val allSongsFlowable: Observable> val suggestionSongsFlowable: Observable> @@ -91,7 +95,4 @@ interface Repository { val favoritePlaylistFlowable: Observable> - fun artistInfoFloable(name: String, - lang: String?, - cache: String?): Observable } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/service/LastFMService.java b/app/src/main/java/code/name/monkey/retromusic/rest/service/LastFMService.java deleted file mode 100644 index f8b24725..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/rest/service/LastFMService.java +++ /dev/null @@ -1,47 +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.rest.service; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import code.name.monkey.retromusic.rest.model.LastFmAlbum; -import code.name.monkey.retromusic.rest.model.LastFmArtist; -import io.reactivex.Observable; -import retrofit2.Call; -import retrofit2.http.GET; -import retrofit2.http.Header; -import retrofit2.http.Query; - - -public interface LastFMService { - String API_KEY_BAK = "bd9c6ea4d55ec9ed3af7d276e5ece304"; - String API_KEY = "c679c8d3efa84613dc7dcb2e8d42da4c"; - String BASE_QUERY_PARAMETERS = "?format=json&autocorrect=1&api_key=" + API_KEY; - String METHOD_TRACK = "track.getInfo"; - - @NonNull - @GET(BASE_QUERY_PARAMETERS + "&method=album.getinfo") - Observable getAlbumInfo(@Query("album") @NonNull String albumName, @Query("artist") @NonNull String artistName, @Nullable @Query("lang") String language); - - @NonNull - @GET(BASE_QUERY_PARAMETERS + "&method=artist.getinfo") - Call getArtistInfo(@Query("artist") @NonNull String artistName, @Nullable @Query("lang") String language, @Nullable @Header("Cache-Control") String cacheControl); - - @NonNull - @GET(BASE_QUERY_PARAMETERS + "&method=artist.getinfo") - Observable getArtistInfoFloable(@Query("artist") @NonNull String artistName, @Nullable @Query("lang") String language, @Nullable @Header("Cache-Control") String cacheControl); - -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/service/LastFMService.kt b/app/src/main/java/code/name/monkey/retromusic/rest/service/LastFMService.kt new file mode 100644 index 00000000..6dcd5c76 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/rest/service/LastFMService.kt @@ -0,0 +1,37 @@ +/* + * 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.rest.service + +import code.name.monkey.retromusic.rest.model.LastFmArtist +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Query + +/** + * Created by hemanths on 2019-11-26. + */ + +interface LastFMService { + companion object { + const val API_KEY = "c679c8d3efa84613dc7dcb2e8d42da4c" + const val BASE_QUERY_PARAMETERS = "?format=json&autocorrect=1&api_key=$API_KEY" + } + + @GET("$BASE_QUERY_PARAMETERS&method=artist.getinfo") + suspend fun artistInfo(@Query("artist") artistName: String, + @Query("lang") language: String?, + @Header("Cache-Control") cacheControl: String? + ): LastFmArtist +} \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_album.xml b/app/src/main/res/layout-land/activity_album.xml index a08a8304..a85f8113 100644 --- a/app/src/main/res/layout-land/activity_album.xml +++ b/app/src/main/res/layout-land/activity_album.xml @@ -25,10 +25,21 @@ android:layout_weight="1" android:orientation="vertical"> - + + + + + + + - + + + + + - + + + + + + + diff --git a/app/src/main/res/layout-xlarge-land/activity_artist_details.xml b/app/src/main/res/layout-xlarge-land/activity_artist_details.xml index 5fb48f71..c6aea634 100644 --- a/app/src/main/res/layout-xlarge-land/activity_artist_details.xml +++ b/app/src/main/res/layout-xlarge-land/activity_artist_details.xml @@ -34,10 +34,21 @@ android:layout_height="wrap_content" app:layout_collapseMode="parallax" /> - + + + + + + @@ -55,8 +66,8 @@ android:id="@+id/contentContainer" android:layout_width="match_parent" android:layout_height="wrap_content" - app:cardElevation="8dp" android:layout_marginTop="6dp" + app:cardElevation="8dp" app:shapeAppearanceOverlay="@style/TopCornerCardView"> - + + + + + + + diff --git a/app/src/main/res/layout-xlarge/activity_artist_details.xml b/app/src/main/res/layout-xlarge/activity_artist_details.xml index 54aeecd6..b2668338 100644 --- a/app/src/main/res/layout-xlarge/activity_artist_details.xml +++ b/app/src/main/res/layout-xlarge/activity_artist_details.xml @@ -35,10 +35,21 @@ android:layout_height="wrap_content" app:layout_collapseMode="parallax" /> - + + + + + + @@ -56,8 +67,8 @@ android:id="@+id/contentContainer" android:layout_width="match_parent" android:layout_height="wrap_content" - app:cardElevation="8dp" android:layout_marginTop="6dp" + app:cardElevation="8dp" app:shapeAppearanceOverlay="@style/TopCornerCardView"> diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml index 26e3b6b1..0b4f98c6 100755 --- a/app/src/main/res/layout/activity_album.xml +++ b/app/src/main/res/layout/activity_album.xml @@ -24,10 +24,20 @@ android:layout_height="wrap_content" app:liftOnScroll="true"> - + + + + + + diff --git a/app/src/main/res/layout/activity_artist_details.xml b/app/src/main/res/layout/activity_artist_details.xml index d02b0813..c39a18a8 100755 --- a/app/src/main/res/layout/activity_artist_details.xml +++ b/app/src/main/res/layout/activity_artist_details.xml @@ -24,11 +24,20 @@ android:layout_height="wrap_content" app:liftOnScroll="true"> - + + + + + simple none @font/circular + 14sp \ No newline at end of file diff --git a/app/src/main/res/values/styles_parents.xml b/app/src/main/res/values/styles_parents.xml index 5b477656..6d41d393 100644 --- a/app/src/main/res/values/styles_parents.xml +++ b/app/src/main/res/values/styles_parents.xml @@ -169,7 +169,7 @@