diff --git a/MediaBrowserTv/app/src/main/AndroidManifest.xml b/MediaBrowserTv/app/src/main/AndroidManifest.xml index 5291d491c..16568b5e5 100644 --- a/MediaBrowserTv/app/src/main/AndroidManifest.xml +++ b/MediaBrowserTv/app/src/main/AndroidManifest.xml @@ -45,6 +45,11 @@ android:name="tv.mediabrowser.mediabrowsertv.SelectUserActivity" android:label="@string/title_activity_select_user" > + + + + diff --git a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/BaseItemDetailsFragment.java b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/BaseItemDetailsFragment.java new file mode 100644 index 000000000..be21e10da --- /dev/null +++ b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/BaseItemDetailsFragment.java @@ -0,0 +1,197 @@ +package tv.mediabrowser.mediabrowsertv; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v17.leanback.app.BackgroundManager; +import android.support.v17.leanback.app.DetailsFragment; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ClassPresenterSelector; +import android.support.v17.leanback.widget.DetailsOverviewRow; +import android.support.v17.leanback.widget.DetailsOverviewRowPresenter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ImageCardView; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.OnActionClickedListener; +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.v4.app.ActivityOptionsCompat; +import android.util.DisplayMetrics; +import android.util.Log; +import android.widget.Toast; + +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Target; + +import mediabrowser.apiinteraction.ApiClient; +import mediabrowser.model.dto.BaseItemDto; + + +public class BaseItemDetailsFragment extends DetailsFragment { + private static final String TAG = "BaseItemDetailsFragment"; + + private static final int ACTION_WATCH_TRAILER = 1; + private static final int ACTION_RENT = 2; + private static final int ACTION_BUY = 3; + + private static final int DETAIL_THUMB_WIDTH = 274; + private static final int DETAIL_THUMB_HEIGHT = 274; + + private static final int NUM_COLS = 10; + + private BaseItemDto mBaseItem; + private ApiClient mApiClient; + + private Drawable mDefaultBackground; + private Target mBackgroundTarget; + private DisplayMetrics mMetrics; + private DetailsOverviewRowPresenter mDorPresenter; + private DetailRowBuilderTask mDetailRowBuilderTask; + + @Override + public void onCreate(Bundle savedInstanceState) { + Log.i(TAG, "onCreate DetailsFragment"); + super.onCreate(savedInstanceState); + + mDorPresenter = + new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter()); + + BackgroundManager backgroundManager = BackgroundManager.getInstance(getActivity()); + backgroundManager.attach(getActivity().getWindow()); + mBackgroundTarget = new PicassoBackgroundManagerTarget(backgroundManager); + + mDefaultBackground = getResources().getDrawable(R.drawable.default_background); + + mMetrics = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); + + mBaseItem = TvApp.getApplication().getSerializer().DeserializeFromString(getActivity().getIntent().getStringExtra("BaseItemDto"),BaseItemDto.class); + mDetailRowBuilderTask = (DetailRowBuilderTask) new DetailRowBuilderTask().execute(mBaseItem); + mDorPresenter.setSharedElementEnterTransition(getActivity(), + DetailsActivity.SHARED_ELEMENT_NAME); + + mApiClient = TvApp.getApplication().getApiClient(); + + updateBackground(Utils.getBackdropImageUrl(mBaseItem, TvApp.getApplication().getApiClient())); + setOnItemViewClickedListener(new ItemViewClickedListener()); + + } + + @Override + public void onStop() { + mDetailRowBuilderTask.cancel(true); + super.onStop(); + } + + private class DetailRowBuilderTask extends AsyncTask { + @Override + protected DetailsOverviewRow doInBackground(BaseItemDto... baseItem) { + BaseItemDetailsFragment.this.mBaseItem = baseItem[0]; + + DetailsOverviewRow row = new DetailsOverviewRow(BaseItemDetailsFragment.this.mBaseItem); + try { + Bitmap poster = Picasso.with(getActivity()) + .load(Utils.getPrimaryImageUrl(BaseItemDetailsFragment.this.mBaseItem, mApiClient)) + .resize(Utils.convertDpToPixel(getActivity().getApplicationContext(), DETAIL_THUMB_WIDTH), + Utils.convertDpToPixel(getActivity().getApplicationContext(), DETAIL_THUMB_HEIGHT)) + .centerCrop() + .get(); + row.setImageBitmap(getActivity(), poster); + } catch (IOException e) { + } + + row.addAction(new Action(ACTION_WATCH_TRAILER, getResources().getString( + R.string.watch_trailer_1), getResources().getString(R.string.watch_trailer_2))); + row.addAction(new Action(ACTION_RENT, getResources().getString(R.string.rent_1), + getResources().getString(R.string.rent_2))); + row.addAction(new Action(ACTION_BUY, getResources().getString(R.string.buy_1), + getResources().getString(R.string.buy_2))); + return row; + } + + @Override + protected void onPostExecute(DetailsOverviewRow detailRow) { + ClassPresenterSelector ps = new ClassPresenterSelector(); + // set detail background and style + mDorPresenter.setBackgroundColor(getResources().getColor(R.color.detail_background)); + mDorPresenter.setStyleLarge(true); + mDorPresenter.setOnActionClickedListener(new OnActionClickedListener() { + @Override + public void onActionClicked(Action action) { + if (action.getId() == ACTION_WATCH_TRAILER) { + Intent intent = new Intent(getActivity(), PlaybackOverlayActivity.class); + intent.putExtra("BaseItemDto", TvApp.getApplication().getSerializer().SerializeToString(mBaseItem)); + intent.putExtra(getResources().getString(R.string.should_start), true); + startActivity(intent); + } else { + Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show(); + } + } + }); + + ps.addClassPresenter(DetailsOverviewRow.class, mDorPresenter); + ps.addClassPresenter(ListRow.class, + new ListRowPresenter()); + + ArrayObjectAdapter adapter = new ArrayObjectAdapter(ps); + adapter.add(detailRow); + +// String subcategories[] = { +// getString(R.string.related_movies) +// }; +// List list = MovieList.list; +// Collections.shuffle(list); +// ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter()); +// for (int j = 0; j < NUM_COLS; j++) { +// listRowAdapter.add(list.get(j % 5)); +// } +// +// HeaderItem header = new HeaderItem(0, subcategories[0], null); +// adapter.add(new ListRow(header, listRowAdapter)); + + setAdapter(adapter); + } + + } + + private final class ItemViewClickedListener implements OnItemViewClickedListener { + @Override + public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + RowPresenter.ViewHolder rowViewHolder, Row row) { + + if (item instanceof Movie) { + Movie movie = (Movie) item; + Log.d(TAG, "Item: " + item.toString()); + Intent intent = new Intent(getActivity(), DetailsActivity.class); + intent.putExtra(DetailsActivity.MOVIE, movie); + + Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( + getActivity(), + ((ImageCardView) itemViewHolder.view).getMainImageView(), + DetailsActivity.SHARED_ELEMENT_NAME).toBundle(); + getActivity().startActivity(intent, bundle); + } + } + } + + protected void updateBackground(String url) { + Log.d(TAG, "url" + url); + Log.d(TAG, "metrics" + mMetrics.toString()); + Picasso.with(getActivity()) + .load(url) + .resize(mMetrics.widthPixels, mMetrics.heightPixels) + .error(mDefaultBackground) + .into(mBackgroundTarget); + } + +} diff --git a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/DetailsDescriptionPresenter.java b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/DetailsDescriptionPresenter.java index f01a3f63b..3902244b6 100644 --- a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/DetailsDescriptionPresenter.java +++ b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/DetailsDescriptionPresenter.java @@ -2,15 +2,17 @@ package tv.mediabrowser.mediabrowsertv; import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter; +import mediabrowser.model.dto.BaseItemDto; + public class DetailsDescriptionPresenter extends AbstractDetailsDescriptionPresenter { @Override protected void onBindDescription(ViewHolder viewHolder, Object item) { - Movie movie = (Movie) item; + BaseItemDto baseItem = (BaseItemDto) item; - if (movie != null) { - viewHolder.getTitle().setText(movie.getTitle()); - viewHolder.getSubtitle().setText(movie.getStudio()); - viewHolder.getBody().setText(movie.getDescription()); + if (baseItem != null) { + viewHolder.getTitle().setText(baseItem.getName()); + viewHolder.getSubtitle().setText(baseItem.getOfficialRating()); + viewHolder.getBody().setText(baseItem.getOverview()); } } } diff --git a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/HomeFragment.java b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/HomeFragment.java index 2cba091b5..1cdf3967e 100644 --- a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/HomeFragment.java +++ b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/HomeFragment.java @@ -95,8 +95,8 @@ public class HomeFragment extends StdBrowseFragment { Intent intent = new Intent(getActivity(), BrowseErrorActivity.class); startActivity(intent); } else if (((String) item).indexOf("Logout ") >= 0) { - apiClient = TvApp.getApplication().getConnectionManager().GetApiClient(TvApp.getApplication().getCurrentUser()); - apiClient.Logout(new EmptyResponse() { + mApiClient = TvApp.getApplication().getConnectionManager().GetApiClient(TvApp.getApplication().getCurrentUser()); + mApiClient.Logout(new EmptyResponse() { @Override public void onResponse() { super.onResponse(); diff --git a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StartupActivity.java b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StartupActivity.java index d36b324dd..ac1dedee4 100644 --- a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StartupActivity.java +++ b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StartupActivity.java @@ -63,7 +63,7 @@ public class StartupActivity extends Activity { apiEventListener); application.setConnectionManager(connectionManager); - application.setSerializer(jsonSerializer); + application.setSerializer((GsonJsonSerializer)jsonSerializer); connectionManager.Connect(new Response() { @Override diff --git a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StdBrowseFragment.java b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StdBrowseFragment.java index e6ca044ed..db3cd1b3f 100644 --- a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StdBrowseFragment.java +++ b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/StdBrowseFragment.java @@ -45,6 +45,7 @@ import java.util.Timer; import java.util.TimerTask; import mediabrowser.apiinteraction.ApiClient; +import mediabrowser.apiinteraction.Response; import mediabrowser.model.dto.BaseItemDto; @@ -54,7 +55,8 @@ public class StdBrowseFragment extends BrowseFragment { private static final int BACKGROUND_UPDATE_DELAY = 200; protected String MainTitle; - protected ApiClient apiClient; + protected ApiClient mApiClient; + protected TvApp mApplication; protected CompositeClickedListener mClickedListener = new CompositeClickedListener(); protected CompositeSelectedListener mSelectedListener = new CompositeSelectedListener(); private ArrayObjectAdapter mRowsAdapter; @@ -72,6 +74,8 @@ public class StdBrowseFragment extends BrowseFragment { Log.i(TAG, "onCreate"); super.onActivityCreated(savedInstanceState); + mApplication = TvApp.getApplication(); + prepareBackgroundManager(); setupUIElements(); @@ -175,20 +179,33 @@ public class StdBrowseFragment extends BrowseFragment { private final class ItemViewClickedListener implements OnItemViewClickedListener { @Override - public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, + public void onItemClicked(final Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof BaseItemDto) { - BaseItemDto baseItem = (BaseItemDto) item; + final BaseItemDto baseItem = (BaseItemDto) item; TvApp.getApplication().getLogger().Debug("Item selected: " + item.toString()); - Intent intent = new Intent(getActivity(), DetailsActivity.class); - intent.putExtra("BaseItemDto", TvApp.getApplication().getSerializer().SerializeToString(baseItem)); + //Retrieve full item for display and playback + mApplication.getApiClient().GetItemAsync(baseItem.getId(), mApplication.getCurrentUser().getId(), new Response() { + @Override + public void onResponse(BaseItemDto response) { + Intent intent = new Intent(getActivity(), DetailsActivity.class); + intent.putExtra("BaseItemDto", TvApp.getApplication().getSerializer().SerializeToString(response)); - Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( - getActivity(), - ((ImageCardView) itemViewHolder.view).getMainImageView(), - DetailsActivity.SHARED_ELEMENT_NAME).toBundle(); - getActivity().startActivity(intent, bundle); + Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( + getActivity(), + ((ImageCardView) itemViewHolder.view).getMainImageView(), + DetailsActivity.SHARED_ELEMENT_NAME).toBundle(); + getActivity().startActivity(intent, bundle); + + } + + @Override + public void onError(Exception exception) { + mApplication.getLogger().ErrorException("Error retrieving full object", exception); + exception.printStackTrace(); + } + }); } } } diff --git a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/TvApp.java b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/TvApp.java index 675cb8c1c..4a1ffef09 100644 --- a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/TvApp.java +++ b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/TvApp.java @@ -5,6 +5,7 @@ import android.util.Log; import mediabrowser.apiinteraction.ApiClient; import mediabrowser.apiinteraction.IConnectionManager; +import mediabrowser.apiinteraction.android.GsonJsonSerializer; import mediabrowser.logging.ConsoleLogger; import mediabrowser.model.dto.UserDto; import mediabrowser.model.logging.ILogger; @@ -17,7 +18,7 @@ public class TvApp extends Application { private ILogger logger; private IConnectionManager connectionManager; - private IJsonSerializer serializer; + private GsonJsonSerializer serializer; private static TvApp app; private UserDto currentUser; @@ -65,11 +66,11 @@ public class TvApp extends Application { this.currentUser = currentUser; } - public IJsonSerializer getSerializer() { + public GsonJsonSerializer getSerializer() { return serializer; } - public void setSerializer(IJsonSerializer serializer) { + public void setSerializer(GsonJsonSerializer serializer) { this.serializer = serializer; } diff --git a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/VideoDetailsFragment.java b/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/VideoDetailsFragment.java deleted file mode 100644 index bada33987..000000000 --- a/MediaBrowserTv/app/src/main/java/tv/mediabrowser/mediabrowsertv/VideoDetailsFragment.java +++ /dev/null @@ -1,177 +0,0 @@ -package tv.mediabrowser.mediabrowsertv; - -import java.io.IOException; -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.v17.leanback.app.BackgroundManager; -import android.support.v17.leanback.app.DetailsFragment; -import android.support.v17.leanback.widget.Action; -import android.support.v17.leanback.widget.ArrayObjectAdapter; -import android.support.v17.leanback.widget.ClassPresenterSelector; -import android.support.v17.leanback.widget.DetailsOverviewRow; -import android.support.v17.leanback.widget.DetailsOverviewRowPresenter; -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.OnActionClickedListener; -import android.support.v17.leanback.widget.OnItemClickedListener; -import android.support.v17.leanback.widget.Row; -import android.util.DisplayMetrics; -import android.util.Log; -import android.widget.Toast; - -import com.squareup.picasso.Picasso; -import com.squareup.picasso.Target; - -public class VideoDetailsFragment extends DetailsFragment { - private static final String TAG = "VideoDetailsFragment"; - - private static final int ACTION_WATCH_TRAILER = 1; - private static final int ACTION_RENT = 2; - private static final int ACTION_BUY = 3; - - private static final int DETAIL_THUMB_WIDTH = 274; - private static final int DETAIL_THUMB_HEIGHT = 274; - - private static final int NUM_COLS = 10; - - private static final String MOVIE = "Movie"; - - private Movie selectedMovie; - - private Drawable mDefaultBackground; - private Target mBackgroundTarget; - private DisplayMetrics mMetrics; - - @Override - public void onCreate(Bundle savedInstanceState) { - Log.i(TAG, "onCreate DetailsFragment"); - super.onCreate(savedInstanceState); - - BackgroundManager backgroundManager = BackgroundManager.getInstance(getActivity()); - backgroundManager.attach(getActivity().getWindow()); - mBackgroundTarget = new PicassoBackgroundManagerTarget(backgroundManager); - - mDefaultBackground = getResources().getDrawable(R.drawable.default_background); - - mMetrics = new DisplayMetrics(); - getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); - - selectedMovie = (Movie) getActivity().getIntent().getSerializableExtra(MOVIE); - new DetailRowBuilderTask().execute(selectedMovie); - - setOnItemClickedListener(getDefaultItemClickedListener()); - updateBackground(selectedMovie.getBackgroundImageURI()); - - } - - private class DetailRowBuilderTask extends AsyncTask { - @Override - protected DetailsOverviewRow doInBackground(Movie... movies) { - selectedMovie = movies[0]; - - DetailsOverviewRow row = new DetailsOverviewRow(selectedMovie); - try { - Bitmap poster = Picasso.with(getActivity()) - .load(selectedMovie.getCardImageUrl()) - .resize(dpToPx(DETAIL_THUMB_WIDTH, getActivity().getApplicationContext()), - dpToPx(DETAIL_THUMB_HEIGHT, getActivity().getApplicationContext())) - .centerCrop() - .get(); - row.setImageBitmap(getActivity(), poster); - } catch (IOException e) { - } - - row.addAction(new Action(ACTION_WATCH_TRAILER, getResources().getString( - R.string.watch_trailer_1), getResources().getString(R.string.watch_trailer_2))); - row.addAction(new Action(ACTION_RENT, getResources().getString(R.string.rent_1), - getResources().getString(R.string.rent_2))); - row.addAction(new Action(ACTION_BUY, getResources().getString(R.string.buy_1), - getResources().getString(R.string.buy_2))); - return row; - } - - @Override - protected void onPostExecute(DetailsOverviewRow detailRow) { - ClassPresenterSelector ps = new ClassPresenterSelector(); - DetailsOverviewRowPresenter dorPresenter = - new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter()); - // set detail background and style - dorPresenter.setBackgroundColor(getResources().getColor(R.color.detail_background)); - dorPresenter.setStyleLarge(true); - dorPresenter.setOnActionClickedListener(new OnActionClickedListener() { - @Override - public void onActionClicked(Action action) { - if (action.getId() == ACTION_WATCH_TRAILER) { - Intent intent = new Intent(getActivity(), PlayerActivity.class); - intent.putExtra(getResources().getString(R.string.movie), selectedMovie); - intent.putExtra(getResources().getString(R.string.should_start), true); - startActivity(intent); - } else { - Toast.makeText(getActivity(), action.toString(), Toast.LENGTH_SHORT).show(); - } - } - }); - - ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter); - ps.addClassPresenter(ListRow.class, - new ListRowPresenter()); - - ArrayObjectAdapter adapter = new ArrayObjectAdapter(ps); - adapter.add(detailRow); - - String subcategories[] = { - getString(R.string.related_movies) - }; - List list = MovieList.list; - Collections.shuffle(list); - ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter()); - for (int j = 0; j < NUM_COLS; j++) { - listRowAdapter.add(list.get(j % 5)); - } - - HeaderItem header = new HeaderItem(0, subcategories[0], null); - adapter.add(new ListRow(header, listRowAdapter)); - - setAdapter(adapter); - } - - } - - protected OnItemClickedListener getDefaultItemClickedListener() { - return new OnItemClickedListener() { - @Override - public void onItemClicked(Object item, Row row) { - if (item instanceof Movie) { - Movie movie = (Movie) item; - Intent intent = new Intent(getActivity(), DetailsActivity.class); - intent.putExtra(MOVIE, movie); - startActivity(intent); - } - } - }; - } - - protected void updateBackground(URI uri) { - Log.d(TAG, "uri" + uri); - Log.d(TAG, "metrics" + mMetrics.toString()); - Picasso.with(getActivity()) - .load(uri.toString()) - .resize(mMetrics.widthPixels, mMetrics.heightPixels) - .error(mDefaultBackground) - .into(mBackgroundTarget); - } - - public static int dpToPx(int dp, Context ctx) { - float density = ctx.getResources().getDisplayMetrics().density; - return Math.round((float) dp * density); - } -} diff --git a/MediaBrowserTv/app/src/main/res/layout/activity_details.xml b/MediaBrowserTv/app/src/main/res/layout/activity_details.xml index ac20aab25..f38d586e9 100644 --- a/MediaBrowserTv/app/src/main/res/layout/activity_details.xml +++ b/MediaBrowserTv/app/src/main/res/layout/activity_details.xml @@ -1,6 +1,6 @@