package org.edx.mobile.view.adapters;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.google.inject.Inject;
import com.joanzapata.iconify.IconDrawable;
import com.joanzapata.iconify.fonts.FontAwesomeIcons;
import org.edx.mobile.R;
import org.edx.mobile.discussion.DiscussionComment;
import org.edx.mobile.discussion.DiscussionTextUtils;
import org.edx.mobile.discussion.DiscussionThread;
import org.edx.mobile.module.prefs.LoginPrefs;
import org.edx.mobile.util.Config;
import org.edx.mobile.view.view_holders.AuthorLayoutViewHolder;
import java.util.ArrayList;
import java.util.List;
import roboguice.RoboGuice;
public class DiscussionCommentsAdapter extends RecyclerView.Adapter implements InfiniteScrollUtils.ListContentController<DiscussionComment> {
@Inject
private Config config;
@Inject
private LoginPrefs loginPrefs;
@NonNull
private final Context context;
@NonNull
private final Listener listener;
@NonNull
private DiscussionComment response;
@NonNull
private DiscussionThread thread;
// Record the current time at initialization to keep the display of the elapsed time durations stable.
private long initialTimeStampMs = System.currentTimeMillis();
private final List<DiscussionComment> discussionComments = new ArrayList<>();
private boolean progressVisible = false;
static class RowType {
static final int RESPONSE = 0;
static final int COMMENT = 1;
static final int PROGRESS = 2;
}
public interface Listener {
void reportComment(@NonNull DiscussionComment comment);
void onClickAuthor(@NonNull String username);
}
public DiscussionCommentsAdapter(@NonNull Context context, @NonNull Listener listener,
@NonNull DiscussionThread thread,
@NonNull DiscussionComment response) {
this.context = context;
this.listener = listener;
this.thread = thread;
this.response = response;
RoboGuice.getInjector(context).injectMembers(this);
}
@Override
public void setProgressVisible(boolean visible) {
if (progressVisible != visible) {
progressVisible = visible;
int progressRowIndex = 1 + discussionComments.size();
if (visible) {
notifyItemInserted(progressRowIndex);
} else {
notifyItemRemoved(progressRowIndex);
}
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == RowType.PROGRESS) {
return new RecyclerView.ViewHolder(LayoutInflater.
from(parent.getContext()).
inflate(R.layout.list_view_footer_progress, parent, false)) {
};
}
@LayoutRes
final int layout;
if (viewType == RowType.RESPONSE) {
layout = R.layout.row_discussion_comments_response;
} else {
layout = R.layout.row_discussion_comments_comment;
}
return new ResponseOrCommentViewHolder(LayoutInflater.
from(parent.getContext()).
inflate(layout, parent, false));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (getItemViewType(position) == RowType.PROGRESS) return;
final ResponseOrCommentViewHolder holder = (ResponseOrCommentViewHolder) viewHolder;
final DiscussionComment discussionComment;
final IconDrawable iconDrawable;
if (position == 0) {
discussionComment = response;
DiscussionTextUtils.setEndorsedState(holder.authorLayoutViewHolder.answerTextView, thread, response);
final int childCount = discussionComment.getChildCount();
holder.discussionCommentCountReportTextView.setText(context.getResources().
getQuantityString(R.plurals.number_responses_or_comments_comments_label, childCount, childCount));
iconDrawable = new IconDrawable(context, FontAwesomeIcons.fa_comment)
.sizeRes(context, R.dimen.edx_small)
.colorRes(context, R.color.edx_brand_gray_base);
holder.discussionCommentCountReportTextView.setOnClickListener(null);
holder.discussionCommentCountReportTextView.setClickable(false);
} else {
holder.authorLayoutViewHolder.answerTextView.setVisibility(View.GONE);
discussionComment = discussionComments.get(position - 1);
iconDrawable = new IconDrawable(context, FontAwesomeIcons.fa_flag)
.sizeRes(context, R.dimen.edx_small)
.colorRes(context, discussionComment.isAbuseFlagged() ? R.color.edx_brand_primary_base : R.color.edx_brand_gray_base);
if (TextUtils.equals(loginPrefs.getUsername(), discussionComment.getAuthor())) {
holder.discussionCommentCountReportTextView.setVisibility(View.GONE);
} else {
holder.discussionCommentCountReportTextView.setVisibility(View.VISIBLE);
holder.discussionCommentCountReportTextView.setText(discussionComment.isAbuseFlagged() ? context.getString(R.string.discussion_responses_reported_label) : context.getString(R.string.discussion_responses_report_label));
holder.discussionCommentCountReportTextView.setTextColor(context.getResources().getColor(R.color.edx_brand_gray_base));
holder.discussionCommentCountReportTextView.setOnClickListener(new View.OnClickListener() {
public void onClick(final View v) {
listener.reportComment(discussionComment);
}
});
}
}
holder.authorLayoutViewHolder.populateViewHolder(config, discussionComment,
discussionComment, initialTimeStampMs,
new Runnable() {
@Override
public void run() {
listener.onClickAuthor(discussionComment.getAuthor());
}
});
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
holder.discussionCommentCountReportTextView, iconDrawable, null, null, null);
DiscussionTextUtils.renderHtml(holder.discussionCommentBody, discussionComment.getRenderedBody());
}
@Override
public int getItemCount() {
int total = 1 + discussionComments.size();
if (progressVisible) {
total++;
}
return total;
}
@Override
public int getItemViewType(int position) {
if (progressVisible && position == getItemCount() - 1) {
return RowType.PROGRESS;
}
if (position == 0) {
return RowType.RESPONSE;
}
return RowType.COMMENT;
}
@Override
public void clear() {
int commentsCount = discussionComments.size();
discussionComments.clear();
notifyItemRangeRemoved(1, commentsCount);
}
@Override
public void addAll(List<DiscussionComment> items) {
int lastCommentIndex = discussionComments.size();
discussionComments.addAll(items);
notifyItemRangeInserted(lastCommentIndex + 1, items.size());
notifyItemChanged(lastCommentIndex); // Last item's background is different, so must be refreshed as well
}
private static class ResponseOrCommentViewHolder extends RecyclerView.ViewHolder {
public final View discussionCommentRow;
public final TextView discussionCommentBody;
public final TextView discussionCommentCountReportTextView;
public final AuthorLayoutViewHolder authorLayoutViewHolder;
public ResponseOrCommentViewHolder(View itemView) {
super(itemView);
discussionCommentRow = itemView.findViewById(R.id.row_discussion_comment_layout);
discussionCommentBody = (TextView) itemView.findViewById(R.id.discussion_comment_body);
discussionCommentCountReportTextView = (TextView) itemView.findViewById(R.id.discussion_comment_count_report_text_view);
authorLayoutViewHolder = new AuthorLayoutViewHolder(itemView.findViewById(R.id.discussion_user_profile_row));
}
}
public void insertCommentAtEnd(DiscussionComment comment) {
// Since, we have a added a new comment we need to update timestamps of all comments
initialTimeStampMs = System.currentTimeMillis();
discussionComments.add(comment);
incrementCommentCount();
notifyDataSetChanged();
}
public void incrementCommentCount() {
response.incrementChildCount();
notifyItemChanged(0);
}
public void updateComment(DiscussionComment comment) {
for (int i = 0; i < discussionComments.size(); ++i) {
if (discussionComments.get(i).getIdentifier().equals(comment.getIdentifier())) {
discussionComments.set(i, comment);
notifyItemChanged(1 + i);
break;
}
}
}
}