diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d5b40b4..fefe7ce 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,6 +41,11 @@ + + + diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmAlbum.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmAlbum.kt index 76d954a..58925a7 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmAlbum.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmAlbum.kt @@ -24,5 +24,5 @@ class LastFmAlbum( val url: String, val artist: LastFmArtist, @SerializedName("image") val images: List, - val tracks: LastFmTracklist + val tracks: LastFmTracklist? ) diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmTrack.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmTrack.kt index bcad735..16f4fbc 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmTrack.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/lastfm/model/LastFmTrack.kt @@ -19,7 +19,7 @@ package com.antonioleiva.bandhookkotlin.data.lastfm.model class LastFmTrack ( val name: String, val duration: Int = 0, - val mbid: String, - val url: String, + val mbid: String?, + val url: String?, val artist: LastFmArtist ) diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/data/mapper/AlbumMapper.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/mapper/AlbumMapper.kt index 5327251..385c256 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/data/mapper/AlbumMapper.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/mapper/AlbumMapper.kt @@ -11,7 +11,8 @@ import com.antonioleiva.bandhookkotlin.domain.entity.Artist * 03/07/16. */ -class AlbumMapper(val artistMapper: ArtistMapper = ArtistMapper(), val imageMapper: ImageMapper = ImageMapper()) { +class AlbumMapper(val artistMapper: ArtistMapper = ArtistMapper(), val imageMapper: ImageMapper = ImageMapper(), + val trackMapper: TrackMapper = TrackMapper()) { fun transform(albums: List): List { return albums.filter { albumHasQualityInfo(it) }.mapNotNull { transform(it) } @@ -31,7 +32,8 @@ class AlbumMapper(val artistMapper: ArtistMapper = ArtistMapper(), val imageMapp album.mbid, album.name, imageMapper.getMainImageUrl(album.images), - Artist("", album.artist)) + Artist("", album.artist), + trackMapper.transform(album.tracks.tracks)) } else { return null } @@ -43,7 +45,8 @@ class AlbumMapper(val artistMapper: ArtistMapper = ArtistMapper(), val imageMapp album.mbid, album.name, imageMapper.getMainImageUrl(album.images), - artistMapper.transform(album.artist)) + artistMapper.transform(album.artist), + trackMapper.transform(album.tracks?.tracks)) } else { return null } diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/data/mapper/TrackMapper.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/mapper/TrackMapper.kt new file mode 100644 index 0000000..017a26a --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/data/mapper/TrackMapper.kt @@ -0,0 +1,19 @@ +package com.antonioleiva.bandhookkotlin.data.mapper + +import com.antonioleiva.bandhookkotlin.data.lastfm.model.LastFmTrack +import com.antonioleiva.bandhookkotlin.domain.entity.Track + +/** + * @author alexey@plainvanillagames.com + * + * 05/07/16. + */ + +class TrackMapper() { + + fun transform(tracks: List?) : List { + return tracks?.map { transform(it) } ?: emptyList() + } + + fun transform(track: LastFmTrack) : Track = Track(track.name, track.duration) +} \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Album.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Album.kt index 0332352..f98a489 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Album.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Album.kt @@ -16,4 +16,4 @@ package com.antonioleiva.bandhookkotlin.domain.entity -data class Album(val id: String, val name: String, val url: String?, val artist: Artist) \ No newline at end of file +data class Album(val id: String, val name: String, val url: String?, val artist: Artist, val tracks: List) \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Track.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Track.kt index 8c6c213..7d856bb 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Track.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/domain/entity/Track.kt @@ -16,4 +16,4 @@ package com.antonioleiva.bandhookkotlin.domain.entity -public data class Track(val id: String, val name: String, val album: Album) \ No newline at end of file +data class Track(val name: String, val duration: Int) \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/entity/AlbumDetail.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/entity/AlbumDetail.kt new file mode 100644 index 0000000..79e7c87 --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/entity/AlbumDetail.kt @@ -0,0 +1,13 @@ +package com.antonioleiva.bandhookkotlin.ui.entity + +import com.antonioleiva.bandhookkotlin.domain.entity.Track + +/** + * @author alexey@plainvanillagames.com + * + * 05/07/16. + */ +data class AlbumDetail(val id: String, + val name: String, + val url: String?, + val tracks: List) \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/entity/mapper/AlbumDetailDataMapper.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/entity/mapper/AlbumDetailDataMapper.kt new file mode 100644 index 0000000..12220db --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/entity/mapper/AlbumDetailDataMapper.kt @@ -0,0 +1,18 @@ +package com.antonioleiva.bandhookkotlin.ui.entity.mapper + +import com.antonioleiva.bandhookkotlin.domain.entity.Album +import com.antonioleiva.bandhookkotlin.ui.entity.AlbumDetail + +/** + * @author alexey@plainvanillagames.com + * + * 05/07/16. + */ +class AlbumDetailDataMapper { + + fun transform(album: Album?): AlbumDetail? = if (album != null) AlbumDetail( + album.id, + album.name, + album.url, + album.tracks) else null +} \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/fragment/AlbumsFragmentContainer.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/fragment/AlbumsFragmentContainer.kt new file mode 100644 index 0000000..af5f77f --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/fragment/AlbumsFragmentContainer.kt @@ -0,0 +1,12 @@ +package com.antonioleiva.bandhookkotlin.ui.fragment + +import com.antonioleiva.bandhookkotlin.ui.presenter.AlbumsPresenter + +/** + * @author tpom6oh@gmail.com + * + * 05/07/16. + */ +interface AlbumsFragmentContainer { + fun getAlbumsPresenter(): AlbumsPresenter +} \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/AlbumPresenter.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/AlbumPresenter.kt new file mode 100644 index 0000000..97a6174 --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/AlbumPresenter.kt @@ -0,0 +1,31 @@ +package com.antonioleiva.bandhookkotlin.ui.presenter + +import com.antonioleiva.bandhookkotlin.domain.interactor.GetAlbumDetailInteractor +import com.antonioleiva.bandhookkotlin.domain.interactor.base.Bus +import com.antonioleiva.bandhookkotlin.domain.interactor.base.InteractorExecutor +import com.antonioleiva.bandhookkotlin.domain.interactor.event.AlbumDetailEvent +import com.antonioleiva.bandhookkotlin.ui.entity.mapper.AlbumDetailDataMapper +import com.antonioleiva.bandhookkotlin.ui.view.AlbumView + +/** + * @author tpom6oh@gmail.com + * + * 05/07/16. + */ +class AlbumPresenter( + override val view: AlbumView, + override val bus: Bus, + val albumInteractor: GetAlbumDetailInteractor, + val interactorExecutor: InteractorExecutor, + val albumDetailMapper: AlbumDetailDataMapper) : Presenter { + + fun init(albumId: String) { + val albumDetailInteractor = albumInteractor; + albumInteractor.albumId = albumId + interactorExecutor.execute(albumDetailInteractor) + } + + fun onEvent(event: AlbumDetailEvent) { + view.showAlbum(albumDetailMapper.transform(event.album)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/AlbumsPresenter.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/AlbumsPresenter.kt new file mode 100644 index 0000000..968650e --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/AlbumsPresenter.kt @@ -0,0 +1,13 @@ +package com.antonioleiva.bandhookkotlin.ui.presenter + +import com.antonioleiva.bandhookkotlin.ui.entity.ImageTitle + +/** + * @author tpom6oh@gmail.com + * + * 05/07/16. + */ + +interface AlbumsPresenter { + fun onAlbumClicked(item: ImageTitle) +} \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/ArtistPresenter.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/ArtistPresenter.kt index feea893..32b9ea1 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/ArtistPresenter.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/presenter/ArtistPresenter.kt @@ -22,6 +22,7 @@ import com.antonioleiva.bandhookkotlin.domain.interactor.base.Bus import com.antonioleiva.bandhookkotlin.domain.interactor.base.InteractorExecutor import com.antonioleiva.bandhookkotlin.domain.interactor.event.ArtistDetailEvent import com.antonioleiva.bandhookkotlin.domain.interactor.event.TopAlbumsEvent +import com.antonioleiva.bandhookkotlin.ui.entity.ImageTitle import com.antonioleiva.bandhookkotlin.ui.entity.mapper.ArtistDetailDataMapper import com.antonioleiva.bandhookkotlin.ui.entity.mapper.ImageTitleDataMapper import com.antonioleiva.bandhookkotlin.ui.view.ArtistView @@ -33,7 +34,7 @@ open class ArtistPresenter( val topAlbumsInteractor: GetTopAlbumsInteractor, val interactorExecutor: InteractorExecutor, val artistDetailMapper: ArtistDetailDataMapper, - val albumsMapper: ImageTitleDataMapper) : Presenter { + val albumsMapper: ImageTitleDataMapper) : Presenter, AlbumsPresenter { open fun init(artistId: String) { val artistDetailInteractor = artistDetailInteractor; @@ -52,4 +53,8 @@ open class ArtistPresenter( fun onEvent(event: TopAlbumsEvent) { view.showAlbums(albumsMapper.transformAlbums(event.topAlbums)) } + + override fun onAlbumClicked(item: ImageTitle) { + view.navigateToAlbum(item.id) + } } \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/album/AlbumActivity.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/album/AlbumActivity.kt new file mode 100644 index 0000000..97c782c --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/album/AlbumActivity.kt @@ -0,0 +1,68 @@ +package com.antonioleiva.bandhookkotlin.ui.screens.album + +import android.os.Bundle +import android.widget.ImageView +import android.widget.TextView +import com.antonioleiva.bandhookkotlin.R +import com.antonioleiva.bandhookkotlin.di.Inject +import com.antonioleiva.bandhookkotlin.di.Injector +import com.antonioleiva.bandhookkotlin.ui.activity.BaseActivity +import com.antonioleiva.bandhookkotlin.ui.entity.AlbumDetail +import com.antonioleiva.bandhookkotlin.ui.entity.mapper.AlbumDetailDataMapper +import com.antonioleiva.bandhookkotlin.ui.presenter.AlbumPresenter +import com.antonioleiva.bandhookkotlin.ui.util.getNavigationId +import com.antonioleiva.bandhookkotlin.ui.util.supportsLollipop +import com.antonioleiva.bandhookkotlin.ui.view.AlbumView +import com.squareup.picasso.Callback +import org.jetbrains.anko.find + +/** + * @author alexey@plainvanillagames.com + * + * 05/07/16. + */ + +class AlbumActivity : BaseActivity(), AlbumView, Injector by Inject.instance { + + override val layoutResource = R.layout.activity_album + + val image by lazy { find(R.id.album_image) } + val text by lazy { find(R.id.albums) } + + var presenter = AlbumPresenter(this, bus, albumInteractorProvider, + interactorExecutor, AlbumDetailDataMapper()) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + supportPostponeEnterTransition() + supportsLollipop { image.transitionName = IMAGE_TRANSITION_NAME } + } + + override fun onResume() { + super.onResume() + presenter.onResume() + presenter.init(getNavigationId()) + } + + override fun onPause() { + super.onPause() + presenter.onPause() + } + + override fun showAlbum(albumDetail: AlbumDetail?) { + if (albumDetail != null) { + picasso.load(albumDetail.url).fit().centerCrop().into(image, object : Callback.EmptyCallback() { + override fun onSuccess() { + supportStartPostponedEnterTransition() + + val tracks = albumDetail.tracks.map { it.name }.joinToString() + text.text = tracks + } + }) + } else { + supportStartPostponedEnterTransition(); + supportFinishAfterTransition(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/AlbumsFragment.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/AlbumsFragment.kt index fbec5c0..0a7a0bf 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/AlbumsFragment.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/AlbumsFragment.kt @@ -1,6 +1,7 @@ package com.antonioleiva.bandhookkotlin.ui.screens.detail +import android.content.Context import android.os.Bundle import android.support.v4.app.Fragment import android.support.v7.widget.RecyclerView @@ -9,6 +10,7 @@ import android.view.View import android.view.ViewGroup import com.antonioleiva.bandhookkotlin.R import com.antonioleiva.bandhookkotlin.ui.adapter.ImageTitleAdapter +import com.antonioleiva.bandhookkotlin.ui.fragment.AlbumsFragmentContainer /** * @author tpom6oh@gmail.com @@ -20,6 +22,11 @@ class AlbumsFragment: Fragment() { lateinit var adapter: ImageTitleAdapter private set + lateinit var recycler: RecyclerView + private set + + var albumsFragmentContainer: AlbumsFragmentContainer? = null + private set override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -33,8 +40,26 @@ class AlbumsFragment: Fragment() { } private fun setUpRecyclerView(view: View) { - val recyclerView = view.findViewById(R.id.albums_view) as RecyclerView + recycler = view.findViewById(R.id.albums_view) as RecyclerView adapter = ImageTitleAdapter(); - recyclerView.adapter = adapter; + recycler.adapter = adapter; + + adapter.onItemClickListener = { + albumsFragmentContainer?.getAlbumsPresenter()?.onAlbumClicked(it) + } + } + + override fun onAttach(context: Context?) { + super.onAttach(context) + + if (context is AlbumsFragmentContainer) { + albumsFragmentContainer = context + } + } + + override fun onDetach() { + super.onDetach() + + albumsFragmentContainer = null } } \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/ArtistActivity.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/ArtistActivity.kt index f704bb8..aa36cb5 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/ArtistActivity.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/screens/detail/ArtistActivity.kt @@ -7,6 +7,7 @@ import android.support.design.widget.TabLayout import android.support.v4.view.ViewPager import android.support.v7.graphics.Palette import android.view.MenuItem +import android.view.View import android.view.WindowManager import android.widget.ImageView import com.antonioleiva.bandhookkotlin.R @@ -18,8 +19,12 @@ import com.antonioleiva.bandhookkotlin.ui.entity.ArtistDetail import com.antonioleiva.bandhookkotlin.ui.entity.ImageTitle import com.antonioleiva.bandhookkotlin.ui.entity.mapper.ArtistDetailDataMapper import com.antonioleiva.bandhookkotlin.ui.entity.mapper.ImageTitleDataMapper +import com.antonioleiva.bandhookkotlin.ui.fragment.AlbumsFragmentContainer +import com.antonioleiva.bandhookkotlin.ui.presenter.AlbumsPresenter import com.antonioleiva.bandhookkotlin.ui.presenter.ArtistPresenter +import com.antonioleiva.bandhookkotlin.ui.screens.album.AlbumActivity import com.antonioleiva.bandhookkotlin.ui.util.getNavigationId +import com.antonioleiva.bandhookkotlin.ui.util.navigate import com.antonioleiva.bandhookkotlin.ui.util.supportsLollipop import com.antonioleiva.bandhookkotlin.ui.view.ArtistView import com.squareup.picasso.Callback @@ -31,7 +36,7 @@ import org.jetbrains.anko.find * 01/07/16. */ -class ArtistActivity: BaseActivity(), ArtistView, Injector by Inject.instance { +class ArtistActivity: BaseActivity(), ArtistView, AlbumsFragmentContainer, Injector by Inject.instance { override val layoutResource: Int = R.layout.activity_artist @@ -67,7 +72,7 @@ class ArtistActivity: BaseActivity(), ArtistView, Injector by Inject.instance { private fun setUpTabLayout() { tabLayout.setupWithViewPager(viewPager); - tabLayout.setOnTabSelectedListener(object : OnTabSelected { + tabLayout.addOnTabSelectedListener(object : OnTabSelected { override fun onTabSelected(tab: TabLayout.Tab?) { viewPager.currentItem = tab?.position ?: 0 } @@ -138,6 +143,19 @@ class ArtistActivity: BaseActivity(), ArtistView, Injector by Inject.instance { } return super.onOptionsItemSelected(item); } + + override fun navigateToAlbum(albumId: String) { + navigate(albumId, findItemById(albumId), BaseActivity.IMAGE_TRANSITION_NAME) + } + + private fun findItemById(id: String): View? { + val pos = albumsFragment.adapter.findPositionById(id) + return albumsFragment.recycler.layoutManager.findViewByPosition(pos).findViewById(R.id.image) + } + + override fun getAlbumsPresenter(): AlbumsPresenter { + return presenter + } } interface OnTabSelected: TabLayout.OnTabSelectedListener { diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/util/ContextExtensions.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/util/ContextExtensions.kt index e8cb712..9efdb9f 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/util/ContextExtensions.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/util/ContextExtensions.kt @@ -23,7 +23,7 @@ import android.support.v4.app.ActivityCompat import android.support.v4.app.ActivityOptionsCompat import android.view.View -inline public fun Activity.navigate(id: String, sharedView: View? = null, +inline fun Activity.navigate(id: String, sharedView: View? = null, transitionName: String? = null) { val intent = Intent(this, T::class.java) intent.putExtra("id", id) @@ -37,16 +37,16 @@ inline public fun Activity.navigate(id: String, sharedVie ActivityCompat.startActivity(this, intent, options?.toBundle()) } -public fun Activity.getNavigationId(): String { +fun Activity.getNavigationId(): String { val intent = intent return intent.getStringExtra("id") } -public fun Context.getDimen(dimenRes: Int): Int { +fun Context.getDimen(dimenRes: Int): Int { return resources.getDimensionPixelSize(dimenRes) } -public fun Context.getAttrId(themeRes: Int, attrRes: Int): Int { +fun Context.getAttrId(themeRes: Int, attrRes: Int): Int { val a = theme.obtainStyledAttributes(themeRes, intArrayOf(attrRes)); val attributeResourceId = a.getResourceId(0, 0); a.recycle() diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/view/AlbumView.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/view/AlbumView.kt new file mode 100644 index 0000000..436e69a --- /dev/null +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/view/AlbumView.kt @@ -0,0 +1,12 @@ +package com.antonioleiva.bandhookkotlin.ui.view + +import com.antonioleiva.bandhookkotlin.ui.entity.AlbumDetail + +/** + * @author alexey@plainvanillagames.com + * + * 05/07/16. + */ +interface AlbumView: PresentationView { + fun showAlbum(albumDetail: AlbumDetail?) +} \ No newline at end of file diff --git a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/view/ArtistView.kt b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/view/ArtistView.kt index c15a68e..b25c89a 100644 --- a/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/view/ArtistView.kt +++ b/app/src/main/java/com/antonioleiva/bandhookkotlin/ui/view/ArtistView.kt @@ -23,4 +23,6 @@ interface ArtistView : PresentationView { fun showArtist(artistDetail: ArtistDetail) fun showAlbums(albums: List) + + fun navigateToAlbum(albumId: String) } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml new file mode 100644 index 0000000..f042c3f --- /dev/null +++ b/app/src/main/res/layout/activity_album.xml @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file