/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.sregg.android.tv.spotifyPlayer.fragments; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.support.v17.leanback.app.BackgroundManager; import android.support.v17.leanback.app.BrowseFragment; import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; import android.support.v17.leanback.widget.OnItemViewClickedListener; import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.Row; import android.support.v17.leanback.widget.RowPresenter; import android.support.v7.graphics.Palette; import android.util.DisplayMetrics; import android.util.Log; import com.squareup.picasso.Picasso; import com.squareup.picasso.Target; import com.sregg.android.tv.spotifyPlayer.Constants; import com.sregg.android.tv.spotifyPlayer.R; import com.sregg.android.tv.spotifyPlayer.SpotifyTvApplication; import com.sregg.android.tv.spotifyPlayer.activities.ArtistsAlbumsActivity; import com.sregg.android.tv.spotifyPlayer.controllers.SpotifyPlayerController; import com.sregg.android.tv.spotifyPlayer.presenters.AlbumCardPresenter; import com.sregg.android.tv.spotifyPlayer.presenters.ArtistCardPresenter; import com.sregg.android.tv.spotifyPlayer.presenters.TrackCardPresenter; import com.sregg.android.tv.spotifyPlayer.utils.BlurTransformation; import com.sregg.android.tv.spotifyPlayer.utils.Utils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import kaaes.spotify.webapi.android.SpotifyService; import kaaes.spotify.webapi.android.models.Album; import kaaes.spotify.webapi.android.models.Artist; import kaaes.spotify.webapi.android.models.Artists; import kaaes.spotify.webapi.android.models.Pager; import kaaes.spotify.webapi.android.models.Track; import kaaes.spotify.webapi.android.models.TrackSimple; import kaaes.spotify.webapi.android.models.Tracks; import retrofit.Callback; import retrofit.RetrofitError; import retrofit.client.Response; /* * Show a Grid of an Artist's Albums */ public class ArtistsDetailsFragment extends BrowseFragment { private static final String TAG = "ArtistsDetailsFragment"; private BackgroundManager mBackgroundManager; private DisplayMetrics mMetrics; private Handler mHandler; private BackgroundTarget mTarget; private ArrayObjectAdapter mRowsAdapter; private ArrayObjectAdapter mTopTrackAdapter; private ArrayObjectAdapter mRelatedArtistsAdapter; private enum AlbumType { ALBUM, SINGLE, APPEARS_ON, COMPILATION } private String mArtistId; private Map<AlbumType, ArrayObjectAdapter> mAlbumsAdapters; @Override public void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); mHandler = new Handler(); Intent intent = getActivity().getIntent(); mArtistId = intent.getStringExtra(ArtistsAlbumsActivity.ARG_ARTIST_ID); String artistName = intent.getStringExtra(ArtistsAlbumsActivity.ARG_ARTIST_NAME); setTitle(artistName); setupFragment(); setupBackground(); } private void setupFragment() { mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); setAdapter(mRowsAdapter); setupTopTracksRow(); setupAlbumsRows(); setupRelatedArtistsRows(); setOnItemViewClickedListener(new OnItemViewClickedListener() { @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof Track) { String trackUri = ((Track) item).uri; SpotifyPlayerController spotifyPlayerController = SpotifyTvApplication.getInstance().getSpotifyPlayerController(); if (spotifyPlayerController.getPlayingState().isCurrentTrack(trackUri)) { spotifyPlayerController.togglePauseResume(); } else { // get song and following ones List<String> trackUris = new ArrayList<>(); List<TrackSimple> tracks = new ArrayList<TrackSimple>(); for (int i = mTopTrackAdapter.indexOf(item); i < mTopTrackAdapter.size() && i < Constants.MAX_SONGS_PLAYED; i++) { tracks.add((TrackSimple) mTopTrackAdapter.get(i)); trackUris.add(((Track) mTopTrackAdapter.get(i)).uri); } spotifyPlayerController.play(trackUri, trackUris, tracks); } } else { SpotifyTvApplication.getInstance().launchDetailScreen(getActivity(), item); } } }); } private void setupAlbumsRows() { AlbumType[] albumTypes = AlbumType.values(); mAlbumsAdapters = new HashMap<>(albumTypes.length); for (AlbumType albumType : albumTypes) { ArrayObjectAdapter adapter = new ArrayObjectAdapter(new AlbumCardPresenter()); String headerResourceName = "artists_album_type_" + albumType.name().toLowerCase(); HeaderItem header = new HeaderItem(0, Utils.getStringByName(getActivity(), headerResourceName)); mRowsAdapter.add(new ListRow(header, adapter)); mAlbumsAdapters.put(albumType, adapter); } loadAlbums(0); } private void loadAlbums(final int offset) { HashMap<String, Object> options = new HashMap<>(); options.put(SpotifyService.OFFSET, Integer.toString(offset)); options.put(SpotifyService.LIMIT, Integer.toString(Constants.PAGE_LIMIT)); options.put(SpotifyService.MARKET, SpotifyTvApplication.getCurrentUserCountry()); SpotifyTvApplication.getInstance().getSpotifyService().getArtistAlbums(mArtistId, options, new Callback<Pager<Album>>() { @Override public void success(Pager<Album> albumPager, Response response) { for (Album album : albumPager.items) { try { AlbumType albumType = AlbumType.valueOf(album.album_type.toUpperCase()); // add to corresponding adapter ArrayObjectAdapter adapter = mAlbumsAdapters.get(albumType); adapter.add(adapter.size(), album); } catch (IllegalArgumentException e) { Log.d(TAG, String.format("Album Type %s is unknown", album.album_type), e); } } if (albumPager.next != null) { loadAlbums(albumPager.offset + Constants.PAGE_LIMIT); } } @Override public void failure(RetrofitError error) { } }); } private void setupTopTracksRow() { mTopTrackAdapter = new ArrayObjectAdapter(new TrackCardPresenter()); HeaderItem header = new HeaderItem(0, getString(R.string.artists_top_tracks)); mRowsAdapter.add(new ListRow(header, mTopTrackAdapter)); loadTopTracks(); } private void loadTopTracks() { SpotifyTvApplication.getInstance().getSpotifyService().getArtistTopTrack(mArtistId, SpotifyTvApplication.getCurrentUserCountry(), new Callback<Tracks>() { @Override public void success(Tracks tracks, Response response) { mTopTrackAdapter.addAll(0, tracks.tracks); } @Override public void failure(RetrofitError error) { } }); } private void setupRelatedArtistsRows() { mRelatedArtistsAdapter = new ArrayObjectAdapter(new ArtistCardPresenter()); HeaderItem header = new HeaderItem(0, getString(R.string.artists_related_artists)); mRowsAdapter.add(new ListRow(header, mRelatedArtistsAdapter)); loadRelatedArtists(); } private void loadRelatedArtists() { SpotifyTvApplication.getInstance().getSpotifyService().getRelatedArtists(mArtistId, new Callback<Artists>() { @Override public void success(Artists artists, Response response) { mRelatedArtistsAdapter.addAll(0, artists.artists); } @Override public void failure(RetrofitError error) { } }); } private void setupBackground() { mBackgroundManager = BackgroundManager.getInstance(getActivity()); mBackgroundManager.attach(getActivity().getWindow()); mMetrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); // load artist from API to get their image SpotifyTvApplication.getInstance().getSpotifyService().getArtist(mArtistId, new Callback<Artist>() { @Override public void success(Artist artist, Response response) { if (!isAdded()){ return; } if (artist.images != null && !artist.images.isEmpty()) { final String imageUrl = artist.images.get(0).url; mHandler.post(new Runnable() { @Override public void run() { loadBackgroundImage(imageUrl); } }); } } @Override public void failure(RetrofitError error) { } }); } private void loadBackgroundImage(String imageUrl) { if (!isAdded()){ return; } mTarget = new BackgroundTarget(); Picasso.with(getActivity()) .load(imageUrl) .transform(new BlurTransformation(getActivity().getApplicationContext())) .resize(mMetrics.widthPixels, mMetrics.heightPixels) .centerCrop() .into(mTarget); } @Override public void onDestroy() { super.onDestroy(); Picasso.with(getActivity()).cancelRequest(mTarget); } private void setBackgroundBitmap(Bitmap bitmap) { Drawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap); mBackgroundManager.setDrawable(bitmapDrawable); } private class BackgroundTarget implements Target { @Override public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) { mHandler.post(new Runnable() { @Override public void run() { if (!isAdded() || getActivity() == null) { return; } setBackgroundBitmap(bitmap); } }); // set background based on the color palette Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() { public void onGenerated(Palette palette) { setFastLaneBackgroundColor(palette); } }); } @Override public void onBitmapFailed(Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } } private void setFastLaneBackgroundColor(Palette palette) { Palette.Swatch swatch = palette.getDarkVibrantSwatch(); if (swatch == null) { swatch = palette.getDarkMutedSwatch(); } if (swatch != null) { setBrandColor(swatch.getRgb()); } } }