package org.edx.mobile.view;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.inject.Inject;
import org.edx.mobile.R;
import org.edx.mobile.base.BaseFragment;
import org.edx.mobile.base.BaseFragmentActivity;
import org.edx.mobile.discussion.DiscussionComment;
import org.edx.mobile.discussion.DiscussionCommentPostedEvent;
import org.edx.mobile.discussion.DiscussionRequestFields;
import org.edx.mobile.discussion.DiscussionService;
import org.edx.mobile.discussion.DiscussionService.FlagBody;
import org.edx.mobile.discussion.DiscussionThread;
import org.edx.mobile.discussion.DiscussionUtils;
import org.edx.mobile.http.CallTrigger;
import org.edx.mobile.http.ErrorHandlingCallback;
import org.edx.mobile.model.Page;
import org.edx.mobile.module.analytics.ISegment;
import org.edx.mobile.view.adapters.DiscussionCommentsAdapter;
import org.edx.mobile.view.adapters.InfiniteScrollUtils;
import org.edx.mobile.view.common.TaskProgressCallback;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.greenrobot.event.EventBus;
import retrofit2.Call;
import roboguice.inject.InjectExtra;
import roboguice.inject.InjectView;
public class CourseDiscussionCommentsFragment extends BaseFragment implements DiscussionCommentsAdapter.Listener {
@InjectView(R.id.discussion_recycler_view)
private RecyclerView discussionCommentsListView;
@InjectView(R.id.create_new_item_text_view)
private TextView createNewCommentTextView;
@InjectView(R.id.create_new_item_layout)
private ViewGroup createNewCommentLayout;
@Inject
private Router router;
@Inject
private Context context;
@InjectExtra(Router.EXTRA_DISCUSSION_THREAD)
private DiscussionThread discussionThread;
@InjectExtra(Router.EXTRA_DISCUSSION_COMMENT)
private DiscussionComment discussionResponse;
@Inject
private DiscussionService discussionService;
@Inject
ISegment segIO;
private DiscussionCommentsAdapter discussionCommentsAdapter;
@Nullable
private Call<Page<DiscussionComment>> getCommentsListCall;
private int nextPage = 1;
private boolean hasMorePages = true;
private InfiniteScrollUtils.InfiniteListController controller;
@Nullable
private Call<DiscussionComment> setCommentFlaggedCall;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_discussion_responses_or_comments, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
discussionCommentsAdapter = new DiscussionCommentsAdapter(getActivity(), this,
discussionThread, discussionResponse);
controller = InfiniteScrollUtils.configureRecyclerViewWithInfiniteList(discussionCommentsListView,
discussionCommentsAdapter, new InfiniteScrollUtils.PageLoader<DiscussionComment>() {
@Override
public void loadNextPage(@NonNull InfiniteScrollUtils.PageLoadCallback<DiscussionComment> callback) {
getCommentsList(callback);
}
});
final int overlap = getResources().getDimensionPixelSize(R.dimen.edx_hairline);
discussionCommentsListView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.set(0, -overlap, 0, 0);
}
});
discussionCommentsListView.setAdapter(discussionCommentsAdapter);
DiscussionUtils.setStateOnTopicClosed(discussionThread.isClosed(),
createNewCommentTextView, R.string.discussion_post_create_new_comment,
R.string.discussion_add_comment_disabled_title, createNewCommentLayout,
new View.OnClickListener() {
@Override
public void onClick(View v) {
router.showCourseDiscussionAddComment(context, discussionResponse, discussionThread);
}
});
}
protected void getCommentsList(@NonNull final InfiniteScrollUtils.PageLoadCallback<DiscussionComment> callback) {
if (getCommentsListCall != null) {
getCommentsListCall.cancel();
}
final List<String> requestedFields = Collections.singletonList(
DiscussionRequestFields.PROFILE_IMAGE.getQueryParamValue());
getCommentsListCall = discussionService.getCommentsList(
discussionResponse.getIdentifier(), nextPage, requestedFields);
getCommentsListCall.enqueue(new ErrorHandlingCallback<Page<DiscussionComment>>(
getActivity(), CallTrigger.LOADING_UNCACHED, (TaskProgressCallback) null) {
@Override
protected void onResponse(@NonNull final Page<DiscussionComment> threadCommentsPage) {
++nextPage;
callback.onPageLoaded(threadCommentsPage);
discussionCommentsAdapter.notifyDataSetChanged();
hasMorePages = threadCommentsPage.hasNext();
}
@Override
protected void onFailure(@NonNull final Throwable error) {
callback.onError();
nextPage = 1;
hasMorePages = false;
}
});
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
Map<String, String> values = new HashMap<>();
values.put(ISegment.Keys.TOPIC_ID, discussionThread.getTopicId());
values.put(ISegment.Keys.THREAD_ID, discussionThread.getIdentifier());
values.put(ISegment.Keys.RESPONSE_ID, discussionResponse.getIdentifier());
segIO.trackScreenView(ISegment.Screens.FORUM_VIEW_RESPONSE_COMMENTS,
discussionThread.getCourseId(), discussionThread.getTitle(), values);
}
@Override
public void onDestroy() {
super.onDestroy();
if (getCommentsListCall != null) {
getCommentsListCall.cancel();
}
EventBus.getDefault().unregister(this);
}
@SuppressWarnings("unused")
public void onEventMainThread(DiscussionCommentPostedEvent event) {
if (null != event.getParent() && event.getParent().getIdentifier().equals(discussionResponse.getIdentifier())) {
((BaseFragmentActivity) getActivity()).showInfoMessage(getString(R.string.discussion_comment_posted));
if (!hasMorePages) {
discussionCommentsAdapter.insertCommentAtEnd(event.getComment());
discussionCommentsListView.smoothScrollToPosition(discussionCommentsAdapter.getItemCount() - 1);
} else {
// We still need to update the comment count locally
discussionCommentsAdapter.incrementCommentCount();
}
}
}
@Override
public void reportComment(@NonNull DiscussionComment comment) {
setCommentFlaggedCall = discussionService.setCommentFlagged(
comment.getIdentifier(), new FlagBody(!comment.isAbuseFlagged()));
setCommentFlaggedCall.enqueue(new ErrorHandlingCallback<DiscussionComment>(
context, CallTrigger.LOADING_UNCACHED, (TaskProgressCallback) null) {
@Override
protected void onResponse(@NonNull final DiscussionComment comment) {
discussionCommentsAdapter.updateComment(comment);
}
});
}
@Override
public void onClickAuthor(@NonNull String username) {
router.showUserProfile(getActivity(), username);
}
}