package com.gh4a.fragment; import android.app.Activity; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentManager; import android.support.v4.content.Loader; import android.support.v7.app.AlertDialog; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import com.gh4a.BaseActivity; import com.gh4a.Gh4Application; import com.gh4a.ProgressDialogTask; import com.gh4a.R; import com.gh4a.activities.EditCommitCommentActivity; import com.gh4a.adapter.CommitNoteAdapter; import com.gh4a.adapter.RootAdapter; import com.gh4a.loader.CommitCommentListLoader; import com.gh4a.loader.LoaderResult; import com.gh4a.utils.IntentUtils; import org.eclipse.egit.github.core.CommitComment; import org.eclipse.egit.github.core.RepositoryCommit; import org.eclipse.egit.github.core.RepositoryId; import org.eclipse.egit.github.core.User; import org.eclipse.egit.github.core.service.CommitService; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; public class CommitNoteFragment extends ListDataBaseFragment<CommitComment> implements CommitNoteAdapter.OnCommentAction<CommitComment>, CommentBoxFragment.Callback { public static CommitNoteFragment newInstance(String repoOwner, String repoName, String commitSha, RepositoryCommit commit, List<CommitComment> allComments, IntentUtils.InitialCommentMarker initialComment) { CommitNoteFragment f = new CommitNoteFragment(); ArrayList<CommitComment> comments = new ArrayList<>(); // we're only interested in unpositional comments for (CommitComment comment : allComments) { if (comment.getPosition() < 0) { comments.add(comment); } } Bundle args = new Bundle(); args.putString("owner", repoOwner); args.putString("repo", repoName); args.putString("sha", commitSha); args.putSerializable("commit", commit); args.putSerializable("comments", comments); args.putParcelable("initial_comment", initialComment); f.setArguments(args); return f; } public interface CommentUpdateListener { void onCommentsUpdated(); } private static final int REQUEST_EDIT = 1000; private String mRepoOwner; private String mRepoName; private String mObjectSha; private RepositoryCommit mCommit; private IntentUtils.InitialCommentMarker mInitialComment; private CommitNoteAdapter mAdapter; private CommentBoxFragment mCommentFragment; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle args = getArguments(); mRepoOwner = args.getString("owner"); mRepoName = args.getString("repo"); mObjectSha = args.getString("sha"); mCommit = (RepositoryCommit) args.getSerializable("commit"); mInitialComment = args.getParcelable("initial_comment"); args.remove("initial_comment"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View listContent = super.onCreateView(inflater, container, savedInstanceState); View v = inflater.inflate(R.layout.commit_comment_list, container, false); FrameLayout listContainer = (FrameLayout) v.findViewById(R.id.list_container); listContainer.addView(listContent); if (!Gh4Application.get().isAuthorized()) { v.findViewById(R.id.comment_box).setVisibility(View.GONE); } return v; } @Override public void onDestroyView() { super.onDestroyView(); if (mAdapter != null) { mAdapter.destroy(); mAdapter = null; } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); FragmentManager fm = getChildFragmentManager(); mCommentFragment = (CommentBoxFragment) fm.findFragmentById(R.id.comment_box); } @Override public void onResume() { super.onResume(); mAdapter.resume(); } @Override public void onPause() { super.onPause(); mAdapter.pause(); } @Override public boolean canChildScrollUp() { if (mCommentFragment != null && mCommentFragment.canChildScrollUp()) { return true; } return super.canChildScrollUp(); } @Override protected RootAdapter<CommitComment, ? extends RecyclerView.ViewHolder> onCreateAdapter() { mAdapter = new CommitNoteAdapter(getActivity(), mRepoOwner, mRepoName, this); return mAdapter; } @Override protected void onAddData(RootAdapter<CommitComment, ?> adapter, List<CommitComment> data) { super.onAddData(adapter, data); Set<User> users = mAdapter.getUsers(); if (mCommit.getAuthor() != null) { users.add(mCommit.getAuthor()); } if (mCommit.getCommitter() != null) { users.add(mCommit.getCommitter()); } mCommentFragment.setMentionUsers(users); if (mInitialComment != null) { for (int i = 0; i < data.size(); i++) { if (mInitialComment.matches(data.get(i).getId(), data.get(i).getCreatedAt())) { scrollToAndHighlightPosition(i); break; } } mInitialComment = null; } } @Override protected int getEmptyTextResId() { return R.string.no_comments_found; } @Override public Loader<LoaderResult<List<CommitComment>>> onCreateLoader() { CommitCommentListLoader loader = new CommitCommentListLoader(getActivity(), mRepoOwner, mRepoName, mObjectSha, true, false); loader.prefillData((List<CommitComment>) getArguments().getSerializable("comments")); return loader; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_EDIT) { if (resultCode == Activity.RESULT_OK) { refreshComments(); } } else { super.onActivityResult(requestCode, resultCode, data); } } @Override public void editComment(CommitComment comment) { Intent intent = EditCommitCommentActivity.makeIntent(getActivity(), mRepoOwner, mRepoName, mObjectSha, comment); startActivityForResult(intent, REQUEST_EDIT); } @Override public void deleteComment(final CommitComment comment) { new AlertDialog.Builder(getActivity()) .setMessage(R.string.delete_comment_message) .setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { new DeleteCommentTask(getBaseActivity(), comment.getId()).schedule(); } }) .setNegativeButton(R.string.cancel, null) .show(); } @Override public void quoteText(CharSequence text) { mCommentFragment.addQuote(text); } @Override public int getCommentEditorHintResId() { return R.string.commit_comment_hint; } @Override public void onSendCommentInBackground(String comment) throws IOException { CommitService commitService = (CommitService) Gh4Application.get().getService(Gh4Application.COMMIT_SERVICE); CommitComment commitComment = new CommitComment(); commitComment.setBody(comment); commitService.addComment(new RepositoryId(mRepoOwner, mRepoName), mObjectSha, commitComment); } @Override public void onCommentSent() { refreshComments(); } private void refreshComments() { if (getActivity() instanceof CommentUpdateListener) { ((CommentUpdateListener) getActivity()).onCommentsUpdated(); } } private class DeleteCommentTask extends ProgressDialogTask<Void> { private final long mId; public DeleteCommentTask(BaseActivity activity, long id) { super(activity, R.string.deleting_msg); mId = id; } @Override protected ProgressDialogTask<Void> clone() { return new DeleteCommentTask(getBaseActivity(), mId); } @Override protected Void run() throws Exception { RepositoryId repoId = new RepositoryId(mRepoOwner, mRepoName); Gh4Application app = Gh4Application.get(); CommitService commitService = (CommitService) app.getService(Gh4Application.COMMIT_SERVICE); commitService.deleteComment(repoId, mId); return null; } @Override protected void onSuccess(Void result) { refreshComments(); } @Override protected String getErrorMessage() { return getContext().getString(R.string.error_delete_comment); } } }