package me.ccrama.redditslide.Fragments;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.view.MarginLayoutParamsCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.view.ContextThemeWrapper;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.mikepenz.itemanimators.AlphaInAnimator;
import com.mikepenz.itemanimators.SlideUpAlphaAnimator;
import net.dean.jraw.models.Submission;
import java.util.List;
import me.ccrama.redditslide.Activities.BaseActivity;
import me.ccrama.redditslide.Activities.MainActivity;
import me.ccrama.redditslide.Activities.Submit;
import me.ccrama.redditslide.Activities.SubredditView;
import me.ccrama.redditslide.Adapters.SubmissionAdapter;
import me.ccrama.redditslide.Adapters.SubmissionDisplay;
import me.ccrama.redditslide.Adapters.SubredditPosts;
import me.ccrama.redditslide.ColorPreferences;
import me.ccrama.redditslide.Constants;
import me.ccrama.redditslide.HasSeen;
import me.ccrama.redditslide.Hidden;
import me.ccrama.redditslide.OfflineSubreddit;
import me.ccrama.redditslide.R;
import me.ccrama.redditslide.Reddit;
import me.ccrama.redditslide.SettingValues;
import me.ccrama.redditslide.Views.CatchStaggeredGridLayoutManager;
import me.ccrama.redditslide.Views.CreateCardView;
import me.ccrama.redditslide.Visuals.Palette;
import me.ccrama.redditslide.handler.ToolbarScrollHideHandler;
import me.ccrama.redditslide.util.LogUtil;
public class SubmissionsView extends Fragment implements SubmissionDisplay {
private static int adapterPosition;
private static int currentPosition;
public SubredditPosts posts;
public RecyclerView rv;
public SubmissionAdapter adapter;
public String id;
public boolean main;
public boolean forced;
int diff;
boolean forceLoad;
private FloatingActionButton fab;
private int visibleItemCount;
private int pastVisiblesItems;
private int totalItemCount;
private SwipeRefreshLayout mSwipeRefreshLayout;
private static Submission currentSubmission;
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
final int currentOrientation = newConfig.orientation;
final CatchStaggeredGridLayoutManager mLayoutManager =
(CatchStaggeredGridLayoutManager) rv.getLayoutManager();
mLayoutManager.setSpanCount(getNumColumns(currentOrientation));
}
Runnable mLongPressRunnable;
GestureDetector detector = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener());
float origY;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(),
new ColorPreferences(inflater.getContext()).getThemeSubreddit(id));
final View v = ((LayoutInflater) contextThemeWrapper.getSystemService(
Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.fragment_verticalcontent,
container, false);
if (getActivity() instanceof MainActivity) {
v.findViewById(R.id.back).setBackgroundResource(0);
}
rv = ((RecyclerView) v.findViewById(R.id.vertical_content));
rv.setHasFixedSize(true);
final RecyclerView.LayoutManager mLayoutManager;
mLayoutManager =
createLayoutManager(getNumColumns(getResources().getConfiguration().orientation));
if (!(getActivity() instanceof SubredditView)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
v.findViewById(R.id.back).setBackground(null);
} else {
v.findViewById(R.id.back).setBackgroundDrawable(null);
}
}
rv.setLayoutManager(mLayoutManager);
rv.setItemAnimator(new SlideUpAlphaAnimator());
rv.getLayoutManager().scrollToPosition(0);
mSwipeRefreshLayout =
(SwipeRefreshLayout) v.findViewById(R.id.activity_main_swipe_refresh_layout);
mSwipeRefreshLayout.setColorSchemeColors(Palette.getColors(id, getContext()));
/**
* If using List view mode, we need to remove the start margin from the SwipeRefreshLayout.
* The scrollbar style of "outsideInset" creates a 4dp padding around it. To counter this,
* change the scrollbar style to "insideOverlay" when list view is enabled.
* To recap: this removes the margins from the start/end so list view is full-width.
*/
if (SettingValues.defaultCardView == CreateCardView.CardEnum.LIST) {
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginStart(0);
} else {
MarginLayoutParamsCompat.setMarginStart(params, 0);
}
rv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mSwipeRefreshLayout.setLayoutParams(params);
}
/**
* If we use 'findViewById(R.id.header).getMeasuredHeight()', 0 is always returned.
* So, we estimate the height of the header in dp.
* If the view type is "single" (and therefore "commentPager"), we need a different offset
*/
final int HEADER_OFFSET = (SettingValues.single || getActivity() instanceof SubredditView)
? Constants.SINGLE_HEADER_VIEW_OFFSET : Constants.TAB_HEADER_VIEW_OFFSET;
mSwipeRefreshLayout.setProgressViewOffset(false, HEADER_OFFSET - Constants.PTR_OFFSET_TOP,
HEADER_OFFSET + Constants.PTR_OFFSET_BOTTOM);
if (SettingValues.fab) {
fab = (FloatingActionButton) v.findViewById(R.id.post_floating_action_button);
if (SettingValues.fabType == Constants.FAB_POST) {
fab.setImageResource(R.drawable.add);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent inte = new Intent(getActivity(), Submit.class);
inte.putExtra(Submit.EXTRA_SUBREDDIT, id);
getActivity().startActivity(inte);
}
});
} else {
fab.setImageResource(R.drawable.hide);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!Reddit.fabClear) {
new AlertDialogWrapper.Builder(getActivity()).setTitle(
R.string.settings_fabclear)
.setMessage(R.string.settings_fabclear_msg)
.setPositiveButton(R.string.btn_ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
Reddit.colors.edit()
.putBoolean(
SettingValues.PREF_FAB_CLEAR,
true)
.apply();
Reddit.fabClear = true;
clearSeenPosts(false);
}
})
.show();
} else {
clearSeenPosts(false);
}
}
});
final Handler handler = new Handler();
fab.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
origY = event.getY();
handler.postDelayed(mLongPressRunnable, android.view.ViewConfiguration.getLongPressTimeout());
}
if (((event.getAction() == MotionEvent.ACTION_MOVE) && Math.abs(event.getY() - origY) > fab.getHeight()/2)|| (event.getAction() == MotionEvent.ACTION_UP)) {
handler.removeCallbacks(mLongPressRunnable);
}
return false;
}
});
mLongPressRunnable = new Runnable() {
public void run() {
fab.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
if (!Reddit.fabClear) {
new AlertDialogWrapper.Builder(getActivity()).setTitle(
R.string.settings_fabclear)
.setMessage(R.string.settings_fabclear_msg)
.setPositiveButton(R.string.btn_ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
Reddit.colors.edit()
.putBoolean(
SettingValues.PREF_FAB_CLEAR,
true)
.apply();
Reddit.fabClear = true;
clearSeenPosts(true);
}
})
.show();
} else {
clearSeenPosts(true);
}
Snackbar s = Snackbar.make(rv,
getResources().getString(R.string.posts_hidden_forever),
Snackbar.LENGTH_LONG);
/*Todo a way to unhide
s.setAction(R.string.btn_undo, new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});*/
View view = s.getView();
TextView tv = (TextView) view.findViewById(
android.support.design.R.id.snackbar_text);
tv.setTextColor(Color.WHITE);
s.show();
}
};
}
} else {
v.findViewById(R.id.post_floating_action_button).setVisibility(View.GONE);
}
if (fab != null) fab.show();
header = getActivity().findViewById(R.id.header);
//TODO, have it so that if the user clicks anywhere in the rv to hide and cancel GoToSubreddit?
// final TextInputEditText GO_TO_SUB_FIELD = (TextInputEditText) getActivity().findViewById(R.id.toolbar_search);
// final Toolbar TOOLBAR = ((Toolbar) getActivity().findViewById(R.id.toolbar));
// final String PREV_TITLE = TOOLBAR.getTitle().toString();
// final ImageView CLOSE_BUTTON = (ImageView) getActivity().findViewById(R.id.close);
//
// rv.setOnTouchListener(new View.OnTouchListener() {
// @Override
// public boolean onTouch(View v, MotionEvent event) {
// System.out.println("touched");
// InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
//
// GO_TO_SUB_FIELD.setText("");
// GO_TO_SUB_FIELD.setVisibility(View.GONE);
// CLOSE_BUTTON.setVisibility(View.GONE);
// TOOLBAR.setTitle(PREV_TITLE);
//
// return false;
// }
// });
resetScroll();
Reddit.isLoading = false;
if (MainActivity.shouldLoad == null
|| id == null
|| (MainActivity.shouldLoad != null
&& MainActivity.shouldLoad.equals(id))
|| !(getActivity() instanceof MainActivity)) {
doAdapter();
}
return v;
}
View header;
ToolbarScrollHideHandler toolbarScroll;
@NonNull
public static RecyclerView.LayoutManager createLayoutManager(final int numColumns) {
return new CatchStaggeredGridLayoutManager(numColumns,
CatchStaggeredGridLayoutManager.VERTICAL);
}
public static int getNumColumns(final int orientation) {
final int numColumns;
if (orientation == Configuration.ORIENTATION_LANDSCAPE && SettingValues.tabletUI) {
numColumns = Reddit.dpWidth;
} else if (orientation == Configuration.ORIENTATION_PORTRAIT
&& SettingValues.dualPortrait) {
numColumns = 2;
} else {
numColumns = 1;
}
return numColumns;
}
public void doAdapter() {
if (!MainActivity.isRestart) {
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});
}
posts = new SubredditPosts(id, getContext());
adapter = new SubmissionAdapter(getActivity(), posts, rv, id, this);
adapter.setHasStableIds(true);
rv.setAdapter(adapter);
posts.loadMore(getActivity(), this, true);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refresh();
}
});
}
public void doAdapter(boolean force18) {
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});
posts = new SubredditPosts(id, getContext(), force18);
adapter = new SubmissionAdapter(getActivity(), posts, rv, id, this);
adapter.setHasStableIds(true);
rv.setAdapter(adapter);
posts.loadMore(getActivity(), this, true);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refresh();
}
});
}
public List<Submission> clearSeenPosts(boolean forever) {
if (adapter.dataSet.posts != null) {
List<Submission> originalDataSetPosts = adapter.dataSet.posts;
OfflineSubreddit o =
OfflineSubreddit.getSubreddit(id.toLowerCase(), false, getActivity());
for (int i = adapter.dataSet.posts.size(); i > -1; i--) {
try {
if (HasSeen.getSeen(adapter.dataSet.posts.get(i))) {
if (forever) {
Hidden.setHidden(adapter.dataSet.posts.get(i));
}
o.clearPost(adapter.dataSet.posts.get(i));
adapter.dataSet.posts.remove(i);
if (adapter.dataSet.posts.isEmpty()) {
adapter.notifyDataSetChanged();
} else {
rv.setItemAnimator(new AlphaInAnimator());
adapter.notifyItemRemoved(i + 1);
}
}
} catch (IndexOutOfBoundsException e) {
//Let the loop reset itself
}
}
adapter.notifyItemRangeChanged(0, adapter.dataSet.posts.size());
o.writeToMemoryNoStorage();
rv.setItemAnimator(new SlideUpAlphaAnimator());
return originalDataSetPosts;
}
return null;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
id = bundle.getString("id", "");
main = bundle.getBoolean("main", false);
forceLoad = bundle.getBoolean("load", false);
}
@Override
public void onResume() {
super.onResume();
if (adapter != null && adapterPosition > 0 && currentPosition == adapterPosition) {
if (adapter.dataSet.getPosts().size() >= adapterPosition - 1
&& adapter.dataSet.getPosts().get(adapterPosition - 1) == currentSubmission) {
adapter.performClick(adapterPosition);
adapterPosition = -1;
}
}
}
public static void datachanged(int adaptorPosition2) {
adapterPosition = adaptorPosition2;
}
private void refresh() {
posts.forced = true;
forced = true;
posts.loadMore(mSwipeRefreshLayout.getContext(), this, true, id);
}
public void forceRefresh() {
rv.scrollToPosition(0);
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
refresh();
}
});
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void updateSuccess(final List<Submission> submissions, final int startIndex) {
if (getActivity() != null) {
if (getActivity() instanceof MainActivity) {
if (((MainActivity) getActivity()).runAfterLoad != null) {
new Handler().post(((MainActivity) getActivity()).runAfterLoad);
}
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (mSwipeRefreshLayout != null) {
mSwipeRefreshLayout.setRefreshing(false);
}
if (startIndex != -1 && !forced ) {
adapter.notifyItemRangeInserted(startIndex + 1, posts.posts.size());
adapter.notifyDataSetChanged();
} else {
forced = false;
rv.scrollToPosition(0);
adapter.notifyDataSetChanged();
}
}
});
if (MainActivity.isRestart) {
MainActivity.isRestart = false;
posts.offline = false;
rv.getLayoutManager().scrollToPosition(MainActivity.restartPage + 1);
}
if (startIndex < 10) resetScroll();
}
}
@Override
public void updateOffline(List<Submission> submissions, final long cacheTime) {
if (getActivity() instanceof MainActivity) {
if (((MainActivity) getActivity()).runAfterLoad != null) {
new Handler().post(((MainActivity) getActivity()).runAfterLoad);
}
}
if (this.isAdded()) {
if (mSwipeRefreshLayout != null) {
mSwipeRefreshLayout.setRefreshing(false);
}
adapter.notifyDataSetChanged();
}
}
@Override
public void updateOfflineError() {
if (getActivity() instanceof MainActivity) {
if (((MainActivity) getActivity()).runAfterLoad != null) {
new Handler().post(((MainActivity) getActivity()).runAfterLoad);
}
}
mSwipeRefreshLayout.setRefreshing(false);
adapter.setError(true);
}
@Override
public void updateError() {
if (getActivity() instanceof MainActivity) {
if (((MainActivity) getActivity()).runAfterLoad != null) {
new Handler().post(((MainActivity) getActivity()).runAfterLoad);
}
}
mSwipeRefreshLayout.setRefreshing(false);
adapter.setError(true);
}
@Override
public void updateViews() {
if (adapter.dataSet.posts != null) {
for (int i = adapter.dataSet.posts.size(); i > -1; i--) {
try {
if (HasSeen.getSeen(adapter.dataSet.posts.get(i))) {
adapter.notifyItemChanged(i + 1);
}
} catch (IndexOutOfBoundsException e) {
//Let the loop reset itself
}
}
}
}
public void resetScroll() {
if (toolbarScroll == null) {
toolbarScroll =
new ToolbarScrollHideHandler(((BaseActivity) getActivity()).mToolbar, header) {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!posts.loading && !posts.nomore && !posts.offline && !adapter.isError){
visibleItemCount = rv.getLayoutManager().getChildCount();
totalItemCount = rv.getLayoutManager().getItemCount();
int[] firstVisibleItems;
firstVisibleItems =
((CatchStaggeredGridLayoutManager) rv.getLayoutManager()).findFirstVisibleItemPositions(
null);
if (firstVisibleItems != null && firstVisibleItems.length > 0) {
for (int firstVisibleItem : firstVisibleItems) {
pastVisiblesItems = firstVisibleItem;
if (SettingValues.scrollSeen
&& pastVisiblesItems > 0
&& SettingValues.storeHistory) {
HasSeen.addSeenScrolling(posts.posts.get(pastVisiblesItems - 1)
.getFullName());
}
}
}
if ((visibleItemCount + pastVisiblesItems) + 5 >= totalItemCount) {
posts.loading = true;
posts.loadMore(mSwipeRefreshLayout.getContext(),
SubmissionsView.this, false, posts.subreddit);
}
}
/*
if(dy <= 0 && !down){
(getActivity()).findViewById(R.id.header).animate().translationY(((BaseActivity)getActivity()).mToolbar.getTop()).setInterpolator(new AccelerateInterpolator()).start();
down = true;
} else if(down){
(getActivity()).findViewById(R.id.header).animate().translationY(((BaseActivity)getActivity()).mToolbar.getTop()).setInterpolator(new AccelerateInterpolator()).start();
down = false;
}*///todo For future implementation instead of scrollFlags
if (recyclerView.getScrollState()
== RecyclerView.SCROLL_STATE_DRAGGING) {
diff += dy;
} else {
diff = 0;
}
if (fab != null) {
if (dy <= 0 && fab.getId() != 0 && SettingValues.fab) {
if (recyclerView.getScrollState()
!= RecyclerView.SCROLL_STATE_DRAGGING
|| diff < -fab.getHeight() * 2) {
fab.show();
}
} else {
fab.hide();
}
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
// switch (newState) {
// case RecyclerView.SCROLL_STATE_IDLE:
// ((Reddit)getActivity().getApplicationContext()).getImageLoader().resume();
// break;
// case RecyclerView.SCROLL_STATE_DRAGGING:
// ((Reddit)getActivity().getApplicationContext()).getImageLoader().resume();
// break;
// case RecyclerView.SCROLL_STATE_SETTLING:
// ((Reddit)getActivity().getApplicationContext()).getImageLoader().pause();
// break;
// }
super.onScrollStateChanged(recyclerView, newState);
//If the toolbar search is open, and the user scrolls in the Main view--close the search UI
if (getActivity() instanceof MainActivity
&& (SettingValues.subredditSearchMethod
== Constants.SUBREDDIT_SEARCH_METHOD_TOOLBAR
|| SettingValues.subredditSearchMethod
== Constants.SUBREDDIT_SEARCH_METHOD_BOTH)
&& ((MainActivity) getContext()).findViewById(
R.id.toolbar_search).getVisibility() == View.VISIBLE) {
((MainActivity) getContext()).findViewById(
R.id.close_search_toolbar).performClick();
}
}
};
rv.addOnScrollListener(toolbarScroll);
} else {
toolbarScroll.reset = true;
}
}
public static void currentPosition(int adapterPosition) {
currentPosition = adapterPosition;
}
public static void currentSubmission(Submission current) {
currentSubmission = current;
}
}