use of com.meisolsson.githubsdk.model.Review in project gh4a by slapperwan.
the class ReviewViewHolder method bind.
@Override
public void bind(TimelineItem.TimelineReview item) {
Review review = item.review();
mShowDetailsButton.setTag(review);
AvatarHandler.assignAvatar(mAvatarView, review.user());
mAvatarContainer.setTag(review.user());
formatTitle(review);
boolean hasBody = !TextUtils.isEmpty(review.body());
if (hasBody) {
mImageGetter.bind(mBodyView, review.bodyHtml(), review.id());
mBodyView.setVisibility(View.VISIBLE);
} else {
mBodyView.setVisibility(View.GONE);
}
if (mCallback.canQuote()) {
mBodyView.setCustomSelectionActionModeCallback(mQuoteActionModeCallback);
} else {
mBodyView.setCustomSelectionActionModeCallback(null);
}
boolean hasDiffs = !item.getDiffHunks().isEmpty();
if (mDisplayReviewDetails && hasDiffs) {
LayoutInflater inflater = LayoutInflater.from(mContext);
Map<String, FileDetails> files = new HashMap<>();
int viewIndex = 0;
for (TimelineItem.Diff diffHunk : item.getDiffHunks()) {
ReviewComment commitComment = diffHunk.getInitialComment();
String filename = commitComment.path();
int commentCount = diffHunk.comments.size();
boolean isOutdated = commitComment.position() == null;
if (files.containsKey(filename)) {
FileDetails details = files.get(filename);
details.isOutdated = details.isOutdated && isOutdated;
details.count += commentCount;
continue;
}
View row = mDetailsContainer.getChildAt(viewIndex);
if (row == null) {
row = inflater.inflate(R.layout.row_timeline_review_file_details, mDetailsContainer, false);
mDetailsContainer.addView(row);
row.setOnClickListener(this);
}
row.setTag(review);
row.setTag(R.id.review_comment_id, commitComment.id());
files.put(filename, new FileDetails(row, isOutdated, commentCount));
viewIndex += 1;
}
for (Map.Entry<String, FileDetails> detailsEntry : files.entrySet()) {
FileDetails fileDetails = detailsEntry.getValue();
TextView tvFile = fileDetails.row.findViewById(R.id.tv_file);
tvFile.setText("• " + detailsEntry.getKey());
if (fileDetails.isOutdated) {
tvFile.setPaintFlags(tvFile.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
} else {
tvFile.setPaintFlags(tvFile.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
}
TextView tvFileComments = fileDetails.row.findViewById(R.id.tv_file_comments);
tvFileComments.setText(String.valueOf(fileDetails.count));
fileDetails.row.setVisibility(View.VISIBLE);
}
for (int i = viewIndex; i < mDetailsContainer.getChildCount(); i++) {
mDetailsContainer.getChildAt(i).setVisibility(View.GONE);
}
mDetailsContainer.setVisibility(View.VISIBLE);
mShowDetailsButton.setVisibility(View.VISIBLE);
mDetailsHeader.setVisibility(View.VISIBLE);
} else {
mDetailsContainer.setVisibility(View.GONE);
mShowDetailsButton.setVisibility(View.GONE);
mDetailsHeader.setVisibility(View.GONE);
}
if (hasBody && mDisplayReviewDetails && hasDiffs) {
mDetailsDivider.setVisibility(View.VISIBLE);
} else {
mDetailsDivider.setVisibility(View.GONE);
}
ivMenu.setVisibility(mDisplayReviewDetails ? View.VISIBLE : View.GONE);
ivMenu.setTag(review);
mEventIconView.setImageResource(getEventIconResId(review));
}
use of com.meisolsson.githubsdk.model.Review in project gh4a by slapperwan.
the class ReviewFragment method onCreateDataSingle.
@Override
protected Single<List<TimelineItem>> onCreateDataSingle(boolean bypassCache) {
final PullRequestService prService = ServiceFactory.get(PullRequestService.class, bypassCache);
final PullRequestReviewService reviewService = ServiceFactory.get(PullRequestReviewService.class, bypassCache);
final PullRequestReviewCommentService commentService = ServiceFactory.get(PullRequestReviewCommentService.class, bypassCache);
Single<TimelineItem.TimelineReview> reviewItemSingle = reviewService.getReview(mRepoOwner, mRepoName, mIssueNumber, mReview.id()).map(ApiHelpers::throwOnFailure).map(TimelineItem.TimelineReview::new);
Single<List<ReviewComment>> reviewCommentsSingle = ApiHelpers.PageIterator.toSingle(page -> reviewService.getReviewComments(mRepoOwner, mRepoName, mIssueNumber, mReview.id())).compose(RxUtils.sortList(ApiHelpers.COMMENT_COMPARATOR)).cache();
Single<Boolean> hasCommentsSingle = reviewCommentsSingle.map(comments -> !comments.isEmpty());
Single<Optional<List<GitHubFile>>> filesSingle = hasCommentsSingle.flatMap(hasComments -> {
if (!hasComments) {
return Single.just(Optional.absent());
}
return ApiHelpers.PageIterator.toSingle(page -> prService.getPullRequestFiles(mRepoOwner, mRepoName, mIssueNumber, page)).map(Optional::of);
});
Single<Optional<List<ReviewComment>>> commentsSingle = hasCommentsSingle.flatMap(hasComments -> {
if (!hasComments) {
return Single.just(Optional.absent());
}
return ApiHelpers.PageIterator.toSingle(page -> commentService.getPullRequestComments(mRepoOwner, mRepoName, mIssueNumber, page)).compose(RxUtils.sortList(ApiHelpers.COMMENT_COMPARATOR)).map(Optional::of);
});
return Single.zip(reviewItemSingle, reviewCommentsSingle, filesSingle, commentsSingle, (reviewItem, reviewComments, filesOpt, commentsOpt) -> {
if (!reviewComments.isEmpty()) {
HashMap<String, GitHubFile> filesByName = new HashMap<>();
if (filesOpt.isPresent()) {
for (GitHubFile file : filesOpt.get()) {
filesByName.put(file.filename(), file);
}
}
// Add all of the review comments to the review item creating necessary diff hunks
for (ReviewComment reviewComment : reviewComments) {
GitHubFile file = filesByName.get(reviewComment.path());
reviewItem.addComment(reviewComment, file, true);
}
if (commentsOpt.isPresent()) {
for (ReviewComment commitComment : commentsOpt.get()) {
if (reviewComments.contains(commitComment)) {
continue;
}
// Rest of the comments should be added only if they are under the same
// diff hunks as the original review comments.
GitHubFile file = filesByName.get(commitComment.path());
reviewItem.addComment(commitComment, file, false);
}
}
}
List<TimelineItem> items = new ArrayList<>();
items.add(reviewItem);
List<TimelineItem.Diff> diffHunks = new ArrayList<>(reviewItem.getDiffHunks());
Collections.sort(diffHunks);
for (TimelineItem.Diff diffHunk : diffHunks) {
items.add(diffHunk);
items.addAll(diffHunk.comments);
if (!diffHunk.isReply()) {
items.add(new TimelineItem.Reply(diffHunk.getInitialTimelineComment()));
}
}
return items;
});
}
use of com.meisolsson.githubsdk.model.Review in project gh4a by slapperwan.
the class PullRequestFragment method onCreateDataSingle.
@Override
protected Single<List<TimelineItem>> onCreateDataSingle(boolean bypassCache) {
final int issueNumber = mIssue.number();
final IssueEventService eventService = ServiceFactory.get(IssueEventService.class, bypassCache);
final IssueCommentService commentService = ServiceFactory.get(IssueCommentService.class, bypassCache);
final PullRequestService prService = ServiceFactory.get(PullRequestService.class, bypassCache);
final PullRequestReviewService reviewService = ServiceFactory.get(PullRequestReviewService.class, bypassCache);
final PullRequestReviewCommentService prCommentService = ServiceFactory.get(PullRequestReviewCommentService.class, bypassCache);
Single<List<TimelineItem>> issueCommentItemSingle = ApiHelpers.PageIterator.toSingle(page -> commentService.getIssueComments(mRepoOwner, mRepoName, issueNumber, page)).compose(RxUtils.mapList(TimelineItem.TimelineComment::new));
Single<List<TimelineItem>> eventItemSingle = ApiHelpers.PageIterator.toSingle(page -> eventService.getIssueEvents(mRepoOwner, mRepoName, issueNumber, page)).compose(RxUtils.filter(event -> INTERESTING_EVENTS.contains(event.event()))).compose((RxUtils.mapList(TimelineItem.TimelineEvent::new)));
Single<Map<String, GitHubFile>> filesByNameSingle = ApiHelpers.PageIterator.toSingle(page -> prService.getPullRequestFiles(mRepoOwner, mRepoName, issueNumber, page)).map(files -> {
Map<String, GitHubFile> filesByName = new HashMap<>();
for (GitHubFile file : files) {
filesByName.put(file.filename(), file);
}
return filesByName;
}).cache();
Single<List<Review>> reviewSingle = ApiHelpers.PageIterator.toSingle(page -> reviewService.getReviews(mRepoOwner, mRepoName, issueNumber, page)).cache();
Single<List<ReviewComment>> prCommentSingle = ApiHelpers.PageIterator.toSingle(page -> prCommentService.getPullRequestComments(mRepoOwner, mRepoName, issueNumber, page)).compose(RxUtils.sortList(ApiHelpers.COMMENT_COMPARATOR)).cache();
Single<LongSparseArray<List<ReviewComment>>> reviewCommentsByIdSingle = reviewSingle.compose(RxUtils.filter(r -> r.state() == ReviewState.Pending)).toObservable().flatMap(reviews -> {
List<Observable<Pair<Long, List<ReviewComment>>>> obsList = new ArrayList<>();
for (Review r : reviews) {
Single<List<ReviewComment>> single = ApiHelpers.PageIterator.toSingle(page -> reviewService.getReviewComments(mRepoOwner, mRepoName, issueNumber, r.id()));
obsList.add(Single.zip(Single.just(r.id()), single, Pair::create).toObservable());
}
return Observable.concat(obsList);
}).toList().map(list -> {
LongSparseArray<List<ReviewComment>> result = new LongSparseArray<>();
for (Pair<Long, List<ReviewComment>> pair : list) {
result.put(pair.first, pair.second);
}
return result;
});
Single<List<TimelineItem.TimelineReview>> reviewTimelineSingle = Single.zip(reviewSingle, filesByNameSingle, prCommentSingle, reviewCommentsByIdSingle, (prReviews, filesByName, commitComments, pendingCommentsById) -> {
LongSparseArray<TimelineItem.TimelineReview> reviewsById = new LongSparseArray<>();
List<TimelineItem.TimelineReview> reviews = new ArrayList<>();
for (Review review : prReviews) {
TimelineItem.TimelineReview timelineReview = new TimelineItem.TimelineReview(review);
reviewsById.put(review.id(), timelineReview);
reviews.add(timelineReview);
if (review.state() == ReviewState.Pending) {
for (ReviewComment pendingComment : pendingCommentsById.get(review.id())) {
GitHubFile commitFile = filesByName.get(pendingComment.path());
timelineReview.addComment(pendingComment, commitFile, true);
}
}
}
Map<String, TimelineItem.TimelineReview> reviewsBySpecialId = new HashMap<>();
for (ReviewComment commitComment : commitComments) {
GitHubFile file = filesByName.get(commitComment.path());
if (commitComment.pullRequestReviewId() != null) {
String id = TimelineItem.Diff.getDiffHunkId(commitComment);
TimelineItem.TimelineReview review = reviewsBySpecialId.get(id);
if (review == null) {
review = reviewsById.get(commitComment.pullRequestReviewId());
reviewsBySpecialId.put(id, review);
}
review.addComment(commitComment, file, true);
}
}
return reviews;
}).compose(RxUtils.filter(item -> {
// noinspection CodeBlock2Expr
return item.review().state() != ReviewState.Commented || !TextUtils.isEmpty(item.review().body()) || !item.getDiffHunks().isEmpty();
}));
Single<List<TimelineItem.TimelineComment>> commitCommentWithoutReviewSingle = Single.zip(prCommentSingle.compose(RxUtils.filter(comment -> comment.pullRequestReviewId() == 0)), filesByNameSingle, (comments, files) -> {
List<TimelineItem.TimelineComment> items = new ArrayList<>();
for (ReviewComment comment : comments) {
items.add(new TimelineItem.TimelineComment(comment, files.get(comment.path())));
}
return items;
});
return Single.zip(issueCommentItemSingle, eventItemSingle, reviewTimelineSingle, commitCommentWithoutReviewSingle, (comments, events, reviewItems, commentsWithoutReview) -> {
ArrayList<TimelineItem> result = new ArrayList<>();
result.addAll(comments);
result.addAll(events);
result.addAll(reviewItems);
result.addAll(commentsWithoutReview);
Collections.sort(result, TimelineItem.COMPARATOR);
return result;
});
}
use of com.meisolsson.githubsdk.model.Review in project gh4a by slapperwan.
the class PullRequestReviewCommentLoadTask method load.
public static Single<Optional<Intent>> load(Context context, String repoOwner, String repoName, int pullRequestNumber, IntentUtils.InitialCommentMarker marker) {
final PullRequestReviewService reviewService = ServiceFactory.get(PullRequestReviewService.class, false);
final PullRequestReviewCommentService commentService = ServiceFactory.get(PullRequestReviewCommentService.class, false);
return ApiHelpers.PageIterator.toSingle(page -> commentService.getPullRequestComments(repoOwner, repoName, pullRequestNumber, page)).compose(RxUtils.sortList(ApiHelpers.COMMENT_COMPARATOR)).flatMap(comments -> {
Map<String, ReviewComment> commentsByDiffHunkId = new HashMap<>();
for (ReviewComment comment : comments) {
String id = TimelineItem.Diff.getDiffHunkId(comment);
if (!commentsByDiffHunkId.containsKey(id)) {
// Because the comment we are looking for could be a reply to another
// review we have to keep track of initial comments for each diff hunk
commentsByDiffHunkId.put(id, comment);
}
if (marker.matches(comment.id(), null)) {
// Once found the comment we are looking for get a correct review id from
// the initial diff hunk comment
ReviewComment initialComment = commentsByDiffHunkId.get(id);
long reviewId = initialComment.pullRequestReviewId();
return reviewService.getReview(repoOwner, repoName, pullRequestNumber, reviewId).map(ApiHelpers::throwOnFailure).map(Optional::of);
}
}
return Single.just(Optional.<Review>absent());
}).map(reviewOpt -> reviewOpt.map(review -> ReviewActivity.makeIntent(context, repoOwner, repoName, pullRequestNumber, review, marker)));
}
Aggregations