package com.battlelancer.seriesguide.ui;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import com.battlelancer.seriesguide.R;
import com.battlelancer.seriesguide.adapters.MoviesNowAdapter;
import com.battlelancer.seriesguide.adapters.NowAdapter;
import com.battlelancer.seriesguide.loaders.TraktFriendsMovieHistoryLoader;
import com.battlelancer.seriesguide.loaders.TraktRecentMovieHistoryLoader;
import com.battlelancer.seriesguide.settings.TraktCredentials;
import com.battlelancer.seriesguide.util.GridInsetDecoration;
import com.battlelancer.seriesguide.util.Utils;
import com.battlelancer.seriesguide.widgets.EmptyViewSwipeRefreshLayout;
import java.util.List;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* Displays recently watched movies, today's releases and recent watches from trakt friends (if
* connected to trakt).
*/
public class MoviesNowFragment extends Fragment {
@BindView(R.id.swipeRefreshLayoutNow) EmptyViewSwipeRefreshLayout swipeRefreshLayout;
@BindView(R.id.recyclerViewNow) RecyclerView recyclerView;
@BindView(R.id.emptyViewNow) TextView emptyView;
@BindView(R.id.containerSnackbar) View snackbar;
@BindView(R.id.textViewSnackbar) TextView snackbarText;
@BindView(R.id.buttonSnackbar) Button snackbarButton;
private MoviesNowAdapter adapter;
private boolean isLoadingRecentlyWatched;
private boolean isLoadingFriends;
private Unbinder unbinder;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_now, container, false);
unbinder = ButterKnife.bind(this, v);
swipeRefreshLayout.setSwipeableChildren(R.id.scrollViewNow, R.id.recyclerViewNow);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshStream();
}
});
swipeRefreshLayout.setProgressViewOffset(false,
getResources().getDimensionPixelSize(
R.dimen.swipe_refresh_progress_bar_start_margin),
getResources().getDimensionPixelSize(
R.dimen.swipe_refresh_progress_bar_end_margin));
emptyView.setText(R.string.now_movies_empty);
showError(null);
snackbarButton.setText(R.string.refresh);
snackbarButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
refreshStream();
}
});
// recycler view layout manager
final int spanCount = getResources().getInteger(R.integer.grid_column_count);
final GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), spanCount);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (adapter == null) {
return 1;
}
if (position >= adapter.getItemCount()) {
return 1;
}
// make headers and more links span all columns
int type = adapter.getItem(position).type;
return (type == NowAdapter.ItemType.HEADER || type == NowAdapter.ItemType.MORE_LINK)
? spanCount : 1;
}
});
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new GridInsetDecoration(getResources()));
recyclerView.setHasFixedSize(true);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Utils.setSwipeRefreshLayoutColors(getActivity().getTheme(), swipeRefreshLayout);
// define dataset
adapter = new MoviesNowAdapter(getContext(), itemClickListener);
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
updateEmptyState();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
updateEmptyState();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
updateEmptyState();
}
});
recyclerView.setAdapter(adapter);
// if connected to trakt, replace local history with trakt history, show friends history
if (TraktCredentials.get(getActivity()).hasCredentials()) {
isLoadingRecentlyWatched = true;
isLoadingFriends = true;
showProgressBar(true);
getLoaderManager().initLoader(MoviesActivity.NOW_TRAKT_USER_LOADER_ID, null,
recentlyTraktCallbacks);
getLoaderManager().initLoader(MoviesActivity.NOW_TRAKT_FRIENDS_LOADER_ID, null,
traktFriendsHistoryCallbacks);
}
setHasOptionsMenu(true);
}
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// guard against not attached to activity
if (!isAdded()) {
return;
}
inflater.inflate(R.menu.now_menu, menu);
// TODO ut: not currently using this
MenuItem todayFilterItem = menu.findItem(R.id.menu_action_now_filter_released_today);
todayFilterItem.setEnabled(false);
todayFilterItem.setVisible(false);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.menu_action_now_refresh) {
refreshStream();
return true;
}
return super.onOptionsItemSelected(item);
}
private void refreshStream() {
showProgressBar(true);
showError(null);
// user might get disconnected during our life-time,
// so properly clean up old loaders so they won't interfere
if (TraktCredentials.get(getActivity()).hasCredentials()) {
isLoadingRecentlyWatched = true;
getLoaderManager().restartLoader(MoviesActivity.NOW_TRAKT_USER_LOADER_ID, null,
recentlyTraktCallbacks);
isLoadingFriends = true;
getLoaderManager().restartLoader(ShowsActivity.NOW_TRAKT_FRIENDS_LOADER_ID, null,
traktFriendsHistoryCallbacks);
} else {
// destroy trakt loaders and remove any shown error message
destroyLoaderIfExists(MoviesActivity.NOW_TRAKT_USER_LOADER_ID);
destroyLoaderIfExists(MoviesActivity.NOW_TRAKT_FRIENDS_LOADER_ID);
showError(null);
}
}
private void destroyLoaderIfExists(int loaderId) {
if (getLoaderManager().getLoader(loaderId) != null) {
getLoaderManager().destroyLoader(loaderId);
}
}
private void showError(@Nullable String errorText) {
boolean show = errorText != null;
if (show) {
snackbarText.setText(errorText);
}
if (snackbar.getVisibility() == (show ? View.VISIBLE : View.GONE)) {
// already in desired state, avoid replaying animation
return;
}
snackbar.startAnimation(AnimationUtils.loadAnimation(snackbar.getContext(),
show ? R.anim.fade_in : R.anim.fade_out));
snackbar.setVisibility(show ? View.VISIBLE : View.GONE);
}
/**
* Show or hide the progress bar of the {@link android.support.v4.widget.SwipeRefreshLayout}
* wrapping view.
*/
private void showProgressBar(boolean show) {
// only hide if everybody has finished loading
if (!show) {
if (isLoadingRecentlyWatched || isLoadingFriends) {
return;
}
}
swipeRefreshLayout.setRefreshing(show);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventTabClick(MoviesActivity.MoviesTabClickEvent event) {
if (event.position == MoviesActivity.TAB_POSITION_NOW) {
recyclerView.smoothScrollToPosition(0);
}
}
private void updateEmptyState() {
boolean isEmpty = adapter.getItemCount() == 0;
recyclerView.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
emptyView.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
}
private NowAdapter.ItemClickListener itemClickListener = new NowAdapter.ItemClickListener() {
@Override
public void onItemClick(View view, int position) {
NowAdapter.NowItem item = adapter.getItem(position);
if (item == null) {
return;
}
// more history link?
if (item.type == NowAdapter.ItemType.MORE_LINK) {
startActivity(new Intent(getActivity(), HistoryActivity.class).putExtra(
HistoryActivity.InitBundle.HISTORY_TYPE,
HistoryActivity.DISPLAY_MOVIE_HISTORY));
return;
}
if (item.movieTmdbId == null) {
return;
}
// display movie details
Intent i = new Intent(getActivity(), MovieDetailsActivity.class);
i.putExtra(MovieDetailsFragment.InitBundle.TMDB_ID, item.movieTmdbId);
// simple scale up animation as there are no images
Utils.startActivityWithAnimation(getActivity(), i, view);
}
};
private LoaderManager.LoaderCallbacks<TraktRecentMovieHistoryLoader.Result>
recentlyTraktCallbacks
= new LoaderManager.LoaderCallbacks<TraktRecentMovieHistoryLoader.Result>() {
@Override
public Loader<TraktRecentMovieHistoryLoader.Result> onCreateLoader(int id, Bundle args) {
return new TraktRecentMovieHistoryLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<TraktRecentMovieHistoryLoader.Result> loader,
TraktRecentMovieHistoryLoader.Result data) {
if (!isAdded()) {
return;
}
adapter.setRecentlyWatched(data.items);
isLoadingRecentlyWatched = false;
showProgressBar(false);
showError(data.errorText);
}
@Override
public void onLoaderReset(Loader<TraktRecentMovieHistoryLoader.Result> loader) {
if (!isVisible()) {
return;
}
// clear existing data
adapter.setRecentlyWatched(null);
}
};
private LoaderManager.LoaderCallbacks<List<NowAdapter.NowItem>> traktFriendsHistoryCallbacks
= new LoaderManager.LoaderCallbacks<List<NowAdapter.NowItem>>() {
@Override
public Loader<List<NowAdapter.NowItem>> onCreateLoader(int id, Bundle args) {
return new TraktFriendsMovieHistoryLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<List<NowAdapter.NowItem>> loader,
List<NowAdapter.NowItem> data) {
if (!isAdded()) {
return;
}
adapter.setFriendsRecentlyWatched(data);
isLoadingFriends = false;
showProgressBar(false);
}
@Override
public void onLoaderReset(Loader<List<NowAdapter.NowItem>> loader) {
if (!isVisible()) {
return;
}
// clear existing data
adapter.setFriendsRecentlyWatched(null);
}
};
}