Leanback: start building new DetailsFragment

This commit is contained in:
Felix 2018-09-17 00:29:10 +02:00
parent 72a9ef966c
commit ee7bf82193
8 changed files with 377 additions and 156 deletions

View file

@ -24,15 +24,15 @@ class EventDetailsDescriptionPresenter(private val context: Context) : Presenter
} }
val dataHolder: DetailDataHolder val dataHolder: DetailDataHolder
if (item is PersistentEvent) { if (item is PersistentEvent) {
val (_, _, _, _, title, subtitle, _, _, description, _, _, releaseDate, _, _, _, _, _, _, _, _, _, persons, tags) = item val persistentEvent = item
val sb = StringBuilder() val sb = StringBuilder()
val speaker = TextUtils.join(", ", persons!!) val speaker = TextUtils.join(", ", persistentEvent.persons)
sb.append(description) sb.append(persistentEvent.description)
.append("\n") .append("\n")
.append("\nreleased at: ").append(releaseDate) .append("\nreleased at: ").append(persistentEvent.releaseDate)
.append("\nTags: ").append(android.text.TextUtils.join(", ", tags!!)) .append("\nTags: ").append(android.text.TextUtils.join(", ", persistentEvent.tags!!))
dataHolder = DetailDataHolder(title, dataHolder = DetailDataHolder(persistentEvent.title,
subtitle, persistentEvent.subtitle,
speaker, speaker,
sb.toString()) sb.toString())
} else if (item is Room) { } else if (item is Room) {

View file

@ -34,12 +34,12 @@ public class ItemViewClickedListener implements OnItemViewClickedListener {
FragmentActivity activity = fragment.requireActivity(); FragmentActivity activity = fragment.requireActivity();
if (item instanceof PersistentConference) { if (item instanceof PersistentConference) {
PersistentConference conference = (PersistentConference) item; PersistentConference conference = (PersistentConference) item;
// Start EventsActivity for this conference
Bundle transition = ActivityOptionsCompat.makeSceneTransitionAnimation( Bundle transition = ActivityOptionsCompat.makeSceneTransitionAnimation(
activity, activity,
((ImageCardView) itemViewHolder.view).getMainImageView(), ((ImageCardView) itemViewHolder.view).getMainImageView(),
EventsActivity.Companion.getSHARED_ELEMENT_NAME()).toBundle(); EventsActivity.Companion.getSHARED_ELEMENT_NAME()).toBundle();
EventsActivity.start(fragment.requireContext(),conference,transition); EventsActivity.start(fragment.requireContext(),conference,transition);
// EventsActivity.start(fragment.requireContext(),conference);
} else if (item instanceof PersistentEvent) { } else if (item instanceof PersistentEvent) {
Bundle transistion = ActivityOptionsCompat.makeSceneTransitionAnimation( Bundle transistion = ActivityOptionsCompat.makeSceneTransitionAnimation(
activity, activity,
@ -54,7 +54,6 @@ public class ItemViewClickedListener implements OnItemViewClickedListener {
EventDetailsActivity.Companion.getSHARED_ELEMENT_NAME()).toBundle(); EventDetailsActivity.Companion.getSHARED_ELEMENT_NAME()).toBundle();
Room room = (Room) item; Room room = (Room) item;
DetailsActivity.start(fragment.requireContext(), room, transition); DetailsActivity.start(fragment.requireContext(), room, transition);
} }
} }
} }

View file

@ -42,19 +42,27 @@ class DetailsActivity : FragmentActivity() {
val TYPE_STREAM = 1 val TYPE_STREAM = 1
@JvmStatic @JvmStatic
fun start(context: Context, event: PersistentEvent, transistion: Bundle? = null){ fun start(context: Context, event: PersistentEvent, transition: Bundle? = null){
val i = Intent(context, DetailsActivity::class.java) val i = Intent(context, DetailsActivity::class.java)
i.putExtra(DetailsActivity.TYPE, DetailsActivity.TYPE_RECORDING) i.putExtra(DetailsActivity.TYPE, DetailsActivity.TYPE_RECORDING)
i.putExtra(DetailsActivity.EVENT, event) i.putExtra(DetailsActivity.EVENT, event)
context.startActivity(i, transistion) if(transition != null){
context.startActivity(i, transition)
} else {
context.startActivity(i)
}
} }
@JvmStatic @JvmStatic
fun start(context: Context, room: Room, transition: Bundle){ fun start(context: Context, room: Room, transition: Bundle? = null){
val i = Intent(context, DetailsActivity::class.java) val i = Intent(context, DetailsActivity::class.java)
i.putExtra(DetailsActivity.TYPE, DetailsActivity.TYPE_STREAM) i.putExtra(DetailsActivity.TYPE, DetailsActivity.TYPE_STREAM)
i.putExtra(DetailsActivity.ROOM, room) i.putExtra(DetailsActivity.ROOM, room)
context.startActivity(i, transition) if(transition != null){
context.startActivity(i, transition)
} else {
context.startActivity(i)
}
} }
} }

View file

@ -30,10 +30,15 @@ class EventsActivity : FragmentActivity() {
val SHARED_ELEMENT_NAME = "shared_element" val SHARED_ELEMENT_NAME = "shared_element"
@JvmStatic @JvmStatic
fun start(context: Context ,conference: PersistentConference, transition: Bundle){ @JvmOverloads
fun start(context: Context ,conference: PersistentConference, transition: Bundle? = null){
val i = Intent(context, EventsActivity::class.java) val i = Intent(context, EventsActivity::class.java)
i.putExtra(EventsActivity.CONFERENCE, conference) i.putExtra(EventsActivity.CONFERENCE, conference)
context.startActivity(i, transition) if(transition != null){
context.startActivity(i, transition)
} else {
context.startActivity(i)
}
} }
} }
} }

View file

@ -87,21 +87,21 @@ class EventsBrowseFragment : BrowseSupportFragment() {
} }
} }
} }
val events = it?.data // val events = it?.data
if (events != null) { // if (events != null) {
Log.d(TAG, "Got ${events.size} events") // Log.d(TAG, "Got ${events.size} events")
val eventsByTags = getEventsByTags(events, conference.acronym) // val eventsByTags = getEventsByTags(events, conference.acronym)
Log.d(TAG, "Got ${eventsByTags.keys.size} Tags") // Log.d(TAG, "Got ${eventsByTags.keys.size} Tags")
for (item in eventsByTags) { // for (item in eventsByTags) {
updateRowForTag(cardPresenter, item.key, item.value) // updateRowForTag(cardPresenter, item.key, item.value)
} // }
errorFragment?.dismiss() // errorFragment?.dismiss()
} // }
}) })
viewModel.getEventsforConference(conference).observe( viewModel.getEventsforConference(conference).observe(
this, this,
Observer { Observer {
if (it != null) { if (it != null && it.size > 0) {
val eventsByTags = getEventsByTags(it, conference.acronym) val eventsByTags = getEventsByTags(it, conference.acronym)
for (item in eventsByTags) { for (item in eventsByTags) {
updateRowForTag(cardPresenter, item.key, item.value) updateRowForTag(cardPresenter, item.key, item.value)

View file

@ -1,6 +1,7 @@
package de.nicidienase.chaosflix.leanback.fragments; package de.nicidienase.chaosflix.leanback.fragments;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -8,6 +9,7 @@ import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v17.leanback.app.BackgroundManager; import android.support.v17.leanback.app.BackgroundManager;
import android.support.v17.leanback.app.DetailsSupportFragment; import android.support.v17.leanback.app.DetailsSupportFragment;
@ -47,8 +49,10 @@ import de.nicidienase.chaosflix.common.mediadata.entities.streaming.LiveConferen
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Room; import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Room;
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Stream; import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Stream;
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl; import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl;
import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem; import de.nicidienase.chaosflix.common.viewmodel.DetailsViewModel;
import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory;
import de.nicidienase.chaosflix.leanback.EventDetailsDescriptionPresenter; import de.nicidienase.chaosflix.leanback.EventDetailsDescriptionPresenter;
import de.nicidienase.chaosflix.leanback.ItemViewClickedListener;
import de.nicidienase.chaosflix.leanback.activities.ConferencesActivity; import de.nicidienase.chaosflix.leanback.activities.ConferencesActivity;
import de.nicidienase.chaosflix.leanback.activities.DetailsActivity; import de.nicidienase.chaosflix.leanback.activities.DetailsActivity;
import de.nicidienase.chaosflix.leanback.activities.EventDetailsActivity; import de.nicidienase.chaosflix.leanback.activities.EventDetailsActivity;
@ -66,26 +70,29 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
private static final String TAG = EventsDetailsFragment.class.getSimpleName(); private static final String TAG = EventsDetailsFragment.class.getSimpleName();
public static final int FRAGMENT = R.id.details_fragment; public static final int FRAGMENT = R.id.details_fragment;
public static final int DUMMY_ID = 1646465164;
public static final int DEFAULT_DRAWABLE = R.drawable.default_background; public static final int DEFAULT_DRAWABLE = R.drawable.default_background;
private static final long ADD_WATCHLIST_ACTION = 1646465165;
private static final long REMOVE_WATCHLIST_ACTION = 1646465166; private static final long ACTION_PLAY = 1646465164;
private static final long ACTION_ADD_WATCHLIST = 1646465165;
private static final long ACTION_REMOVE_WATCHLIST = 1646465166;
private PersistentEvent event; private PersistentEvent event;
private Room room; private Room room;
private int eventType; private int eventType;
private ArrayList<StreamUrl> streamUrlList; private ArrayList<StreamUrl> streamUrlList;
private BackgroundManager backgroundManager; private BackgroundManager backgroundManager;
private DisplayMetrics metrics;
private WatchlistItem watchlistItem;
private ArrayObjectAdapter recordingActionsAdapter; private ArrayObjectAdapter recordingActionsAdapter;
private OnActionClickedListener onActionClickedListener = new DetailActionClickedListener(); private OnActionClickedListener onActionClickedListener = new DetailActionClickedListener();
private DetailsViewModel viewModel;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate"); Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
prepareBackgroundManager(); viewModel = ViewModelProviders.of(this, new ViewModelFactory(requireContext())).get(DetailsViewModel.class);
// prepareBackgroundManager();
final BrowseErrorFragment browseErrorFragment = final BrowseErrorFragment browseErrorFragment =
BrowseErrorFragment.showErrorFragment(getFragmentManager(), FRAGMENT); BrowseErrorFragment.showErrorFragment(getFragmentManager(), FRAGMENT);
eventType = getActivity().getIntent().getIntExtra(DetailsActivity.Companion.getTYPE(), -1); eventType = getActivity().getIntent().getIntExtra(DetailsActivity.Companion.getTYPE(), -1);
@ -93,7 +100,23 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
if (eventType == DetailsActivity.Companion.getTYPE_RECORDING()) { if (eventType == DetailsActivity.Companion.getTYPE_RECORDING()) {
event = getActivity().getIntent() event = getActivity().getIntent()
.getParcelableExtra(DetailsActivity.Companion.getEVENT()); .getParcelableExtra(DetailsActivity.Companion.getEVENT());
// watchlistItem = WatchlistItem.findById(WatchlistItem.class, event.getApiID()); setTitle(event.getTitle());
// viewModel.setEvent(event).observe(this, event1 -> {
// List<PersistentRecording> recordings = event1.getRecordings();
// if(recordings != null){
// recordingActionsAdapter.setItems(recordings, new DiffCallback<PersistentRecording>() {
// @Override
// public boolean areItemsTheSame(@NonNull PersistentRecording oldItem, @NonNull PersistentRecording newItem) {
// return oldItem.getUrl().equals(newItem.getUrl());
// }
//
// @Override
// public boolean areContentsTheSame(@NonNull PersistentRecording oldItem, @NonNull PersistentRecording newItem) {
// return oldItem.getRecordingUrl().equals(newItem.getRecordingUrl());
// }
// });
// }
// });
} else if (eventType == DetailsActivity.Companion.getTYPE_STREAM()) { } else if (eventType == DetailsActivity.Companion.getTYPE_STREAM()) {
room = getActivity().getIntent() room = getActivity().getIntent()
.getParcelableExtra(DetailsActivity.Companion.getROOM()); .getParcelableExtra(DetailsActivity.Companion.getROOM());
@ -101,83 +124,91 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
FullWidthDetailsOverviewRowPresenter mDetailsPresenter FullWidthDetailsOverviewRowPresenter mDetailsPresenter
= setupDetailsOverviewRowPresenter(); = setupDetailsOverviewRowPresenter();
ClassPresenterSelector mPresenterSelector = new ClassPresenterSelector(); ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
mPresenterSelector.addClassPresenter(DetailsOverviewRow.class, mDetailsPresenter); presenterSelector.addClassPresenter(DetailsOverviewRow.class, mDetailsPresenter);
mPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter()); presenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
final ArrayObjectAdapter adapter = new ArrayObjectAdapter(mPresenterSelector); final ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector);
final DetailsOverviewRow detailsOverviewRow = setupDetailsOverviewRow(event);
recordingActionsAdapter = getRecordingActionsAdapter();
detailsOverviewRow.setActionsAdapter(recordingActionsAdapter);
adapter.add(detailsOverviewRow);
setOnItemViewClickedListener(new ItemViewClickedListener(this));
setAdapter(adapter);
browseErrorFragment.dismiss();
// ((LeanbackBaseActivity) getActivity()).getApiServiceObservable() // ((LeanbackBaseActivity) getActivity()).getApiServiceObservable()
// .doOnError(t -> browseErrorFragment.setErrorContent(t.getMessage())) // .doOnError(t -> browseErrorFragment.setErrorContent(t.getMessage()))
// .subscribe(mediaApiService -> { // .subscribe(mediaApiService -> {
// mMediaApiService = mediaApiService; // mMediaApiService = mediaApiService;
// if (eventType == DetailsActivity.Companion.getTYPE_RECORDING()) { // if (eventType == DetailsActivity.Companion.getTYPE_RECORDING()) {
// final DetailsOverviewRow detailsOverviewRow = setupDetailsOverviewRow(event); // final DetailsOverviewRow detailsOverviewRow = setupDetailsOverviewRow(event);
// mediaApiService.getEvent(event.getApiID()) // mediaApiService.getEvent(event.getApiID())
// .doOnError(t -> browseErrorFragment.setErrorContent(t.getMessage())) // .doOnError(t -> browseErrorFragment.setErrorContent(t.getMessage()))
// .subscribe(event -> { // .subscribe(event -> {
// this.event = event; // this.event = event;
// recordingActionsAdapter = // recordingActionsAdapter =
// getRecordingActionsAdapter(this.event.getRecordings()); // getRecordingActionsAdapter(this.event.getRecordings());
// detailsOverviewRow.setActionsAdapter(recordingActionsAdapter); // detailsOverviewRow.setActionsAdapter(recordingActionsAdapter);
// adapter.add(detailsOverviewRow); // adapter.add(detailsOverviewRow);
// mediaApiService.getConference( // mediaApiService.getConference(
// this.event.getConferenceId()) // this.event.getConferenceId())
// .observeOn(AndroidSchedulers.mainThread()) // .observeOn(AndroidSchedulers.mainThread())
// .subscribe(conference -> { // .subscribe(conference -> {
// String tag = null; // String tag = null;
// if (this.event.getTags().size() > 0) { // if (this.event.getTags().size() > 0) {
// tag = this.event.getTags().get(0); // tag = this.event.getTags().get(0);
// List<Event> relatedEvents = conference.getEventsByTags().get(tag); // List<Event> relatedEvents = conference.getEventsByTags().get(tag);
// relatedEvents.remove(this.event); // relatedEvents.remove(this.event);
// Collections.shuffle(relatedEvents); // Collections.shuffle(relatedEvents);
// if (relatedEvents.size() > 5) { // if (relatedEvents.size() > 5) {
// relatedEvents = relatedEvents.subList(0, NUM_RELATED_TALKS); // relatedEvents = relatedEvents.subList(0, NUM_RELATED_TALKS);
// } // }
// ArrayObjectAdapter relatedEventsAdapter // ArrayObjectAdapter relatedEventsAdapter
// = new ArrayObjectAdapter(new CardPresenter()); // = new ArrayObjectAdapter(new CardPresenter());
// relatedEventsAdapter.addAll(0, relatedEvents); // relatedEventsAdapter.addAll(0, relatedEvents);
// HeaderItem header = new HeaderItem(getString(R.string.random_talks_on_this_track)); // HeaderItem header = new HeaderItem(getString(R.string.random_talks_on_this_track));
// adapter.add(new ListRow(header, relatedEventsAdapter)); // adapter.add(new ListRow(header, relatedEventsAdapter));
// } // }
// //
// List<Event> selectedEvents = getRandomEvents(conference, tag); // List<Event> selectedEvents = getRandomEvents(conference, tag);
// if (selectedEvents.size() > 0) { // if (selectedEvents.size() > 0) {
// ArrayObjectAdapter randomEventAdapter // ArrayObjectAdapter randomEventAdapter
// = new ArrayObjectAdapter(new CardPresenter()); // = new ArrayObjectAdapter(new CardPresenter());
// randomEventAdapter.addAll(0, selectedEvents); // randomEventAdapter.addAll(0, selectedEvents);
// HeaderItem header = new HeaderItem(getString(R.string.random_talks)); // HeaderItem header = new HeaderItem(getString(R.string.random_talks));
// adapter.add(new ListRow(header, randomEventAdapter)); // adapter.add(new ListRow(header, randomEventAdapter));
// } // }
// //
// setOnItemViewClickedListener(new ItemViewClickedListener(this)); // setOnItemViewClickedListener(new ItemViewClickedListener(this));
// setAdapter(adapter); // setAdapter(adapter);
// browseErrorFragment.dismiss(); // browseErrorFragment.dismiss();
// }); // });
// }); // });
// } else if (eventType == DetailsActivity.Companion.getTYPE_STREAM()) { // } else if (eventType == DetailsActivity.Companion.getTYPE_STREAM()) {
// mediaApiService.getStreamingConferences() // mediaApiService.getStreamingConferences()
// .observeOn(AndroidSchedulers.mainThread()) // .observeOn(AndroidSchedulers.mainThread())
// .subscribe(liveConferences -> { // .subscribe(liveConferences -> {
// if(room.getStreams() == null){ // if(room.getStreams() == null){
// room = getRoom(room, liveConferences); // room = getRoom(room, liveConferences);
// } // }
// final DetailsOverviewRow detailsOverviewRow = setupDetailsOverviewRow(room); // final DetailsOverviewRow detailsOverviewRow = setupDetailsOverviewRow(room);
// ArrayObjectAdapter actionsAdapter = getStreamActionsAdapter(room.getStreams()); // ArrayObjectAdapter actionsAdapter = getStreamActionsAdapter(room.getStreams());
// detailsOverviewRow.setActionsAdapter(actionsAdapter); // detailsOverviewRow.setActionsAdapter(actionsAdapter);
// adapter.add(detailsOverviewRow); // adapter.add(detailsOverviewRow);
// setOnItemViewClickedListener(new ItemViewClickedListener(EventsDetailsFragment.this)); // setOnItemViewClickedListener(new ItemViewClickedListener(EventsDetailsFragment.this));
// setAdapter(adapter); // browseErrorFragment.dismiss();
// browseErrorFragment.dismiss(); // setAdapter(adapter);
// // TODO add other streams // // TODO add other streams
// }); // });
// } // }
// }); // });
// new Handler().postDelayed(this::startEntranceTransition, 500);
Log.d(TAG, "create finished");
} }
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
startEntranceTransition();
} }
@Override @Override
@ -189,7 +220,7 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
private void prepareBackgroundManager() { private void prepareBackgroundManager() {
backgroundManager = BackgroundManager.getInstance(getActivity()); backgroundManager = BackgroundManager.getInstance(getActivity());
backgroundManager.attach(getActivity().getWindow()); backgroundManager.attach(getActivity().getWindow());
metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
} }
@ -241,22 +272,22 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
} }
private FullWidthDetailsOverviewRowPresenter setupDetailsOverviewRowPresenter() { private FullWidthDetailsOverviewRowPresenter setupDetailsOverviewRowPresenter() {
FullWidthDetailsOverviewRowPresenter mDetailsPresenter = new FullWidthDetailsOverviewRowPresenter( FullWidthDetailsOverviewRowPresenter detailsPresenter = new FullWidthDetailsOverviewRowPresenter(
new EventDetailsDescriptionPresenter(getActivity()), new EventDetailsDescriptionPresenter(getActivity()),
new EventDetailsOverviewLogoPresenter()); new EventDetailsOverviewLogoPresenter());
mDetailsPresenter.setBackgroundColor(getResources().getColor(R.color.selected_background)); detailsPresenter.setBackgroundColor(getResources().getColor(R.color.selected_background));
mDetailsPresenter.setInitialState(FullWidthDetailsOverviewRowPresenter.STATE_HALF); detailsPresenter.setInitialState(FullWidthDetailsOverviewRowPresenter.STATE_HALF);
mDetailsPresenter.setAlignmentMode(FullWidthDetailsOverviewRowPresenter.ALIGN_MODE_START); detailsPresenter.setAlignmentMode(FullWidthDetailsOverviewRowPresenter.ALIGN_MODE_START);
FullWidthDetailsOverviewSharedElementHelper helper FullWidthDetailsOverviewSharedElementHelper helper
= new FullWidthDetailsOverviewSharedElementHelper(); = new FullWidthDetailsOverviewSharedElementHelper();
helper.setSharedElementEnterTransition(getActivity(), helper.setSharedElementEnterTransition(getActivity(),
EventDetailsActivity.Companion.getSHARED_ELEMENT_NAME()); EventDetailsActivity.Companion.getSHARED_ELEMENT_NAME());
mDetailsPresenter.setListener(helper); detailsPresenter.setListener(helper);
prepareEntranceTransition(); prepareEntranceTransition();
mDetailsPresenter.setOnActionClickedListener(onActionClickedListener); detailsPresenter.setOnActionClickedListener(onActionClickedListener);
return mDetailsPresenter; return detailsPresenter;
} }
private DetailsOverviewRow setupDetailsOverviewRow(Object event) { private DetailsOverviewRow setupDetailsOverviewRow(Object event) {
@ -274,7 +305,7 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
@Override @Override
public void onResourceReady(Bitmap resource, public void onResourceReady(Bitmap resource,
GlideAnimation<? super Bitmap> glideAnimation) { GlideAnimation<? super Bitmap> glideAnimation) {
row.setImageBitmap(getActivity(), resource); row.setImageBitmap(requireActivity(), resource);
} }
@Override @Override
@ -286,25 +317,35 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
return row; return row;
} }
private ArrayObjectAdapter getRecordingActionsAdapter(List<PersistentRecording> recordings) { private ArrayObjectAdapter getRecordingActionsAdapter() {
ArrayObjectAdapter actionsAdapter = new ArrayObjectAdapter(); ArrayObjectAdapter actionsAdapter = new ArrayObjectAdapter();
if(watchlistItem != null){ final Action watchlistAction = new Action(ACTION_ADD_WATCHLIST, getString(R.string.add_to_watchlist));
actionsAdapter.add(new Action(REMOVE_WATCHLIST_ACTION,getString(R.string.remove_from_watchlist))); actionsAdapter.add(watchlistAction);
} else { viewModel.getBookmarkForEvent(event.getGuid()).observe(this, watchlistItem -> {
actionsAdapter.add(new Action(ADD_WATCHLIST_ACTION,getString(R.string.add_to_watchlist))); if (watchlistItem != null) {
} watchlistAction.setId(ACTION_REMOVE_WATCHLIST);
if (recordings != null) { watchlistAction.setLabel1(getString(R.string.remove_from_watchlist));
for (int i = 0; i < recordings.size(); i++) { } else {
PersistentRecording recording = recordings.get(i); watchlistAction.setId(ACTION_ADD_WATCHLIST);
if (recording.getMimeType().startsWith("video/") && !recording.getMimeType().equals("video/webm")) { watchlistAction.setLabel1(getString(R.string.add_to_watchlist));
String quality = recording.isHighQuality() ? "HD" : "SD";
String title = quality + " (" + recording.getLanguage() + ")";
actionsAdapter.add(new Action(recording.getId(), title, recording.getMimeType().substring(6)));
}
} }
} else { });
actionsAdapter.add(new Action(DUMMY_ID, "Dummy", "HLS"));
} Action playAction = new Action(ACTION_PLAY, "Play");
actionsAdapter.add(playAction);
// if (recordings != null) {
// for (int i = 0; i < recordings.size(); i++) {
// PersistentRecording recording = recordings.get(i);
// if (recording.getMimeType().startsWith("video/") && !recording.getMimeType().equals("video/webm")) {
// String quality = recording.isHighQuality() ? "HD" : "SD";
// String title = quality + " (" + recording.getLanguage() + ")";
// actionsAdapter.add(new Action(recording.getId(), title, recording.getMimeType().substring(6)));
// }
// }
// } else {
// actionsAdapter.add(new Action(DUMMY_ID, "Dummy", "HLS"));
// }
return actionsAdapter; return actionsAdapter;
} }
@ -377,49 +418,38 @@ public class EventsDetailsFragment extends DetailsSupportFragment {
@Override @Override
public void onActionClicked(Action action) { public void onActionClicked(Action action) {
Log.d(TAG, "OnActionClicked"); Log.d(TAG, "OnActionClicked");
if (action.getId() == ADD_WATCHLIST_ACTION) { if (action.getId() == ACTION_ADD_WATCHLIST) {
// new WatchlistItem(event.getApiID()).save(); // new WatchlistItem(event.getApiID()).save();
recordingActionsAdapter.replace(0, new Action(REMOVE_WATCHLIST_ACTION, EventsDetailsFragment.this.getString(R.string.remove_from_watchlist))); recordingActionsAdapter.replace(0, new Action(ACTION_REMOVE_WATCHLIST, EventsDetailsFragment.this.getString(R.string.remove_from_watchlist)));
SharedPreferences preferences = getActivity().getSharedPreferences(getString(R.string.watchlist_preferences_key), Context.MODE_PRIVATE); SharedPreferences preferences = requireActivity().getSharedPreferences(getString(R.string.watchlist_preferences_key), Context.MODE_PRIVATE);
if(preferences.getBoolean(getString(R.string.watchlist_dialog_needed), true)) { // new item if (preferences.getBoolean(getString(R.string.watchlist_dialog_needed), true)) { // new item
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.watchlist_message); builder.setTitle(R.string.watchlist_message);
builder.setNegativeButton(R.string.return_to_homescreen,(dialog, which) -> { builder.setNegativeButton(R.string.return_to_homescreen, (dialog, which) -> {
Intent i = new Intent(getActivity(), ConferencesActivity.class); Intent i = new Intent(getActivity(), ConferencesActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i); startActivity(i);
getActivity().finish(); // getActivity().finish();
});
builder.setPositiveButton("OK", (dialog, which) -> {
}); });
builder.setPositiveButton("OK",(dialog, which) -> {});
SharedPreferences.Editor edit = preferences.edit(); SharedPreferences.Editor edit = preferences.edit();
edit.putBoolean(getString(R.string.watchlist_dialog_needed), false); edit.putBoolean(getString(R.string.watchlist_dialog_needed), false);
edit.commit(); edit.apply();
builder.create().show(); builder.create().show();
} }
} else if (action.getId() == REMOVE_WATCHLIST_ACTION) { } else if (action.getId() == ACTION_REMOVE_WATCHLIST) {
if (watchlistItem != null) { viewModel.removeBookmark(event.getGuid());
// watchlistItem.delete(); } else if (action.getId() == ACTION_PLAY) {
}
recordingActionsAdapter.replace(0, new Action(ADD_WATCHLIST_ACTION, EventsDetailsFragment.this.getString(R.string.add_to_watchlist)));
} else {
Intent i = new Intent(EventsDetailsFragment.this.getActivity(), PlayerActivity.class); Intent i = new Intent(EventsDetailsFragment.this.getActivity(), PlayerActivity.class);
i.putExtra(DetailsActivity.Companion.getTYPE(), eventType); i.putExtra(DetailsActivity.Companion.getTYPE(), eventType);
if (eventType == DetailsActivity.Companion.getTYPE_RECORDING()) { if (eventType == DetailsActivity.Companion.getTYPE_RECORDING()) {
i.putExtra(DetailsActivity.Companion.getEVENT(), event); i.putExtra(DetailsActivity.Companion.getEVENT(), event);
if (action.getId() == DUMMY_ID) { for (PersistentRecording r : event.getRecordings()) {
PersistentRecording dummy = new PersistentRecording(); if (r.getId() == action.getId()) {
dummy.setRecordingUrl("https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8"); i.putExtra(DetailsActivity.Companion.getRECORDING(), r);
dummy.setMimeType("video/hls"); break;
dummy.setLanguage("eng");
dummy.setHighQuality(true);
i.putExtra(DetailsActivity.Companion.getRECORDING(), dummy);
} else {
for (PersistentRecording r : event.getRecordings()) {
if (r.getId() == action.getId()) {
i.putExtra(DetailsActivity.Companion.getRECORDING(), r);
break;
}
} }
} }
} else if (eventType == DetailsActivity.Companion.getTYPE_STREAM()) { } else if (eventType == DetailsActivity.Companion.getTYPE_STREAM()) {

View file

@ -0,0 +1,179 @@
package de.nicidienase.chaosflix.leanback.fragments
import android.app.AlertDialog
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Handler
import android.support.design.widget.Snackbar
import android.support.v17.leanback.app.DetailsSupportFragment
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.FullWidthDetailsOverviewRowPresenter
import android.support.v17.leanback.widget.FullWidthDetailsOverviewSharedElementHelper
import android.support.v17.leanback.widget.ListRow
import android.support.v17.leanback.widget.ListRowPresenter
import android.support.v17.leanback.widget.OnActionClickedListener
import android.util.Log
import android.widget.Toast
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import de.nicidienase.chaosflix.R
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.PersistentEvent
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Room
import de.nicidienase.chaosflix.common.viewmodel.DetailsViewModel
import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory
import de.nicidienase.chaosflix.leanback.EventDetailsDescriptionPresenter
import de.nicidienase.chaosflix.leanback.activities.ConferencesActivity
import de.nicidienase.chaosflix.leanback.activities.DetailsActivity
import de.nicidienase.chaosflix.leanback.activities.EventDetailsActivity
import de.nicidienase.chaosflix.leanback.activities.PlayerActivity
class NewEventsDetailsFragment : DetailsSupportFragment() {
private lateinit var viewModel: DetailsViewModel
private var eventType: Int = DetailsActivity.TYPE_RECORDING
private var event: PersistentEvent? = null
private lateinit var rowsAdapter: ArrayObjectAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(this, ViewModelFactory(requireContext())).get(DetailsViewModel::class.java)
eventType = activity!!.intent.getIntExtra(DetailsActivity.TYPE, -1)
event = requireActivity().intent.getParcelableExtra<PersistentEvent>(DetailsActivity.EVENT)
if (eventType != DetailsActivity.TYPE_RECORDING || event == null) {
return
}
title = event?.title
val selector = ClassPresenterSelector()
val detailsPresenter = FullWidthDetailsOverviewRowPresenter(
EventDetailsDescriptionPresenter(requireContext()))
val helper = FullWidthDetailsOverviewSharedElementHelper()
helper.setSharedElementEnterTransition(activity,
EventDetailsActivity.SHARED_ELEMENT_NAME)
detailsPresenter.setListener(helper)
prepareEntranceTransition()
detailsPresenter.onActionClickedListener = DetailActionClickedListener()
selector.addClassPresenter(DetailsOverviewRow::class.java, detailsPresenter)
selector.addClassPresenter(ListRow::class.java,
ListRowPresenter())
rowsAdapter = ArrayObjectAdapter(selector)
val detailsOverview = DetailsOverviewRow(event)
Glide.with(activity)
.load(event?.thumbUrl)
.asBitmap()
.into(object : SimpleTarget<Bitmap>(DETAIL_THUMB_WIDTH, DETAIL_THUMB_HEIGHT) {
override fun onResourceReady(resource: Bitmap,
glideAnimation: GlideAnimation<in Bitmap>) {
detailsOverview.setImageBitmap(requireActivity(), resource)
}
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
// super.onLoadFailed(e, errorDrawable);
detailsOverview.setImageDrawable(resources.getDrawable(DEFAULT_DRAWABLE))
}
})
val actionAdapter = ArrayObjectAdapter()
val playAction = Action(ACTION_PLAY, "Play")
actionAdapter.add(playAction)
val watchlistAction = Action(ACTION_ADD_WATCHLIST, getString(R.string.add_to_watchlist))
actionAdapter.add(watchlistAction)
event?.guid?.let {
viewModel.getBookmarkForEvent(it).observe(this, Observer { watchlistItem ->
if (watchlistItem != null) {
watchlistAction.id = ACTION_REMOVE_WATCHLIST
watchlistAction.label1 = getString(R.string.remove_from_watchlist)
actionAdapter.notifyItemRangeChanged(actionAdapter.indexOf(watchlistAction),1)
} else {
watchlistAction.id = ACTION_ADD_WATCHLIST
watchlistAction.label1 = getString(R.string.add_to_watchlist)
actionAdapter.notifyItemRangeChanged(actionAdapter.indexOf(watchlistAction),1)
}
})
}
detailsOverview.actionsAdapter = actionAdapter
rowsAdapter.add(detailsOverview);
adapter = rowsAdapter
Handler().postDelayed(this::startEntranceTransition, 500);
}
companion object {
@JvmStatic
val TAG = NewEventsDetailsFragment::class.java.simpleName
@JvmStatic
private val DETAIL_THUMB_WIDTH = 254
@JvmStatic
private val DETAIL_THUMB_HEIGHT = 143
@JvmStatic
val DEFAULT_DRAWABLE = R.drawable.default_background
@JvmStatic
private val ACTION_PLAY: Long = 0
@JvmStatic
private val ACTION_ADD_WATCHLIST: Long = 1
@JvmStatic
private val ACTION_REMOVE_WATCHLIST: Long = 2
}
private inner class DetailActionClickedListener : OnActionClickedListener {
override fun onActionClicked(action: Action) {
Log.d(TAG, "OnActionClicked")
if (action.id == ACTION_ADD_WATCHLIST) {
event?.guid?.let { viewModel.createBookmark(it) }
val preferences = requireActivity().getSharedPreferences(getString(R.string.watchlist_preferences_key), Context.MODE_PRIVATE)
if (preferences.getBoolean(getString(R.string.watchlist_dialog_needed), true)) { // new item
showWatchlistInfoDialog(preferences)
}
} else if (action.id == ACTION_REMOVE_WATCHLIST) {
event?.guid?.let { viewModel.removeBookmark(it) }
} else if (action.id == ACTION_PLAY) {
// TODO play!
Toast.makeText(requireContext(), "Play", Toast.LENGTH_SHORT).show()
}
}
fun showWatchlistInfoDialog(preferences: SharedPreferences) {
val builder = AlertDialog.Builder(activity)
builder.setTitle(R.string.watchlist_message)
builder.setNegativeButton(R.string.return_to_homescreen) { dialog, which ->
val i = Intent(activity, ConferencesActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(i)
// getActivity().finish();
}
builder.setPositiveButton("OK") { dialog, which -> }
val edit = preferences.edit()
edit.putBoolean(getString(R.string.watchlist_dialog_needed), false)
edit.apply()
builder.create().show()
}
}
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<fragment android:id="@+id/details_fragment" <fragment android:id="@+id/details_fragment"
android:name="de.nicidienase.chaosflix.leanback.fragments.EventsDetailsFragment" android:name="de.nicidienase.chaosflix.leanback.fragments.NewEventsDetailsFragment"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"