mirror of
https://github.com/k0shk0sh/FastHub.git
synced 2025-12-08 19:05:54 +00:00
revamping of timeline to use different and more efficient api
This commit is contained in:
parent
e9e0e4023b
commit
0ebcf9701c
@ -0,0 +1,53 @@
|
||||
package com.fastaccess.data.dao;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 15 Nov 2016, 7:04 PM
|
||||
*/
|
||||
|
||||
|
||||
@Getter @Setter @NoArgsConstructor
|
||||
public class IssuesPageable<M> implements Parcelable {
|
||||
|
||||
public int first;
|
||||
public int next;
|
||||
public int prev;
|
||||
public int last;
|
||||
public int totalCount;
|
||||
public boolean incompleteResults;
|
||||
public List<M> items;
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.first);
|
||||
dest.writeInt(this.next);
|
||||
dest.writeInt(this.prev);
|
||||
dest.writeInt(this.last);
|
||||
dest.writeInt(this.totalCount);
|
||||
dest.writeByte(this.incompleteResults ? (byte) 1 : (byte) 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess") protected IssuesPageable(Parcel in) {
|
||||
this.first = in.readInt();
|
||||
this.next = in.readInt();
|
||||
this.prev = in.readInt();
|
||||
this.last = in.readInt();
|
||||
this.totalCount = in.readInt();
|
||||
this.incompleteResults = in.readByte() != 0;
|
||||
}
|
||||
|
||||
public static final Creator<IssuesPageable> CREATOR = new Creator<IssuesPageable>() {
|
||||
@Override public IssuesPageable createFromParcel(Parcel source) {return new IssuesPageable(source);}
|
||||
|
||||
@Override public IssuesPageable[] newArray(int size) {return new IssuesPageable[size];}
|
||||
};
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.fastaccess.data.dao;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.timeline.Timeline;
|
||||
import com.fastaccess.data.dao.types.StatusStateType;
|
||||
|
||||
import java.util.Date;
|
||||
@ -15,7 +16,7 @@ import lombok.Setter;
|
||||
* Created by Kosh on 10 Apr 2017, 3:15 AM
|
||||
*/
|
||||
|
||||
@Getter @Setter public class PullRequestStatusModel implements Parcelable {
|
||||
@Getter @Setter public class PullRequestStatusModel extends Timeline implements Parcelable {
|
||||
|
||||
private StatusStateType state;
|
||||
private String sha;
|
||||
|
||||
@ -4,6 +4,7 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.model.User;
|
||||
import com.fastaccess.data.dao.timeline.Timeline;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ -14,7 +15,7 @@ import lombok.Setter;
|
||||
* Created by Kosh on 04 May 2017, 7:10 PM
|
||||
*/
|
||||
|
||||
@Getter @Setter public class ReviewCommentModel implements Parcelable {
|
||||
@Getter @Setter public class ReviewCommentModel extends Timeline implements Parcelable {
|
||||
|
||||
private long id;
|
||||
private String url;
|
||||
|
||||
@ -2,289 +2,96 @@ package com.fastaccess.data.dao;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.annimon.stream.Collectors;
|
||||
import com.annimon.stream.Stream;
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.model.Issue;
|
||||
import com.fastaccess.data.dao.model.IssueEvent;
|
||||
import com.fastaccess.data.dao.model.PullRequest;
|
||||
import com.fastaccess.data.dao.timeline.GenericEvent;
|
||||
import com.fastaccess.data.dao.types.IssueEventType;
|
||||
import com.fastaccess.data.dao.types.ReviewStateType;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
|
||||
import static com.annimon.stream.Collectors.toList;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 30 Mar 2017, 9:03 PM
|
||||
*/
|
||||
|
||||
@Getter @Setter @NoArgsConstructor public class TimelineModel implements Parcelable {
|
||||
public static final int HEADER = 0;
|
||||
public static final int STATUS = 1;
|
||||
public static final int REVIEW = 2;
|
||||
public static final int GROUPED_REVIEW = 3;
|
||||
public static final int EVENT = 4;
|
||||
public static final int COMMENT = 5;
|
||||
public static final int LINE_COMMENT = 1;
|
||||
public static final int EVENT = 2;
|
||||
public static final int COMMENT = 3;
|
||||
public static final int STATUS = 4;
|
||||
|
||||
private int type;
|
||||
private Issue issue;
|
||||
private IssueEventType event;
|
||||
private Comment comment;
|
||||
private IssueEvent event;
|
||||
private PullRequest pullRequest;
|
||||
private PullRequestStatusModel status;
|
||||
private ReviewModel review;
|
||||
private GroupedReviewModel groupedReview;
|
||||
private GenericEvent genericEvent;
|
||||
private ReviewCommentModel reviewComment;
|
||||
private Date sortedDate;
|
||||
private PullRequestStatusModel status;
|
||||
private Issue issue;
|
||||
private PullRequest pullRequest;
|
||||
|
||||
private TimelineModel(Issue issue) {
|
||||
this.type = HEADER;
|
||||
public TimelineModel(Issue issue) {
|
||||
this.issue = issue;
|
||||
this.sortedDate = issue.getCreatedAt();
|
||||
}
|
||||
|
||||
private TimelineModel(PullRequest pullRequest) {
|
||||
this.type = HEADER;
|
||||
public TimelineModel(PullRequest pullRequest) {
|
||||
this.pullRequest = pullRequest;
|
||||
this.sortedDate = pullRequest.getCreatedAt();
|
||||
}
|
||||
|
||||
private TimelineModel(Comment comment) {
|
||||
this.type = COMMENT;
|
||||
public TimelineModel(Comment comment) {
|
||||
this.comment = comment;
|
||||
this.sortedDate = comment.getCreatedAt() == null ? new Date() : comment.getCreatedAt();
|
||||
this.event = IssueEventType.commented;
|
||||
}
|
||||
|
||||
private TimelineModel(IssueEvent event) {
|
||||
this.type = EVENT;
|
||||
this.event = event;
|
||||
this.sortedDate = event.getCreatedAt();
|
||||
public TimelineModel(PullRequestStatusModel statusModel) {
|
||||
this.status = statusModel;
|
||||
}
|
||||
|
||||
private TimelineModel(PullRequestStatusModel status) {
|
||||
this.type = STATUS;
|
||||
this.status = status;
|
||||
this.sortedDate = status.getCreatedAt();
|
||||
}
|
||||
|
||||
private TimelineModel(ReviewModel review) {
|
||||
this.type = REVIEW;
|
||||
this.review = review;
|
||||
this.sortedDate = review.getSubmittedAt();
|
||||
}
|
||||
|
||||
private TimelineModel(GroupedReviewModel groupedReview) {
|
||||
this.type = GROUPED_REVIEW;
|
||||
this.groupedReview = groupedReview;
|
||||
this.sortedDate = groupedReview.getDate();
|
||||
}
|
||||
|
||||
@NonNull public static TimelineModel constructHeader(@NonNull Issue issue) {
|
||||
return new TimelineModel(issue);
|
||||
}
|
||||
|
||||
@NonNull public static TimelineModel constructHeader(@NonNull PullRequest pullRequest) {
|
||||
return new TimelineModel(pullRequest);
|
||||
}
|
||||
|
||||
@NonNull public static TimelineModel constructComment(@NonNull Comment comment) {
|
||||
return new TimelineModel(comment);
|
||||
}
|
||||
|
||||
@NonNull public static List<TimelineModel> construct(@Nullable List<Comment> commentList) {
|
||||
ArrayList<TimelineModel> list = new ArrayList<>();
|
||||
if (commentList != null && !commentList.isEmpty()) {
|
||||
list.addAll(Stream.of(commentList)
|
||||
.map(TimelineModel::new)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@NonNull public static List<TimelineModel> construct(@Nullable List<Comment> commentList, @Nullable List<IssueEvent> eventList) {
|
||||
ArrayList<TimelineModel> list = new ArrayList<>();
|
||||
if (commentList != null && !commentList.isEmpty()) {
|
||||
list.addAll(Stream.of(commentList)
|
||||
.map(TimelineModel::new)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
if (eventList != null && !eventList.isEmpty()) {
|
||||
list.addAll(constructLabels(eventList));
|
||||
}
|
||||
|
||||
return Stream.of(list).sorted((o1, o2) -> {
|
||||
if (o1.getEvent() != null && o2.getComment() != null) {
|
||||
return o1.getEvent().getCreatedAt().compareTo(o2.getComment().getCreatedAt());
|
||||
} else if (o1.getComment() != null && o2.getEvent() != null) {
|
||||
return o1.getComment().getCreatedAt().compareTo(o2.getEvent().getCreatedAt());
|
||||
} else {
|
||||
return Integer.valueOf(o1.getType()).compareTo(o2.getType());
|
||||
public int getType() {
|
||||
if (getEvent() != null) {
|
||||
switch (getEvent()) {
|
||||
case commented:
|
||||
return COMMENT;
|
||||
case line_commented:
|
||||
return LINE_COMMENT;
|
||||
default:
|
||||
return EVENT;
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NonNull public static List<TimelineModel> construct(@Nullable List<Comment> commentList, @Nullable List<IssueEvent> eventList,
|
||||
@Nullable PullRequestStatusModel status, @Nullable List<ReviewModel> reviews,
|
||||
@Nullable List<ReviewCommentModel> reviewComments) {
|
||||
ArrayList<TimelineModel> list = new ArrayList<>();
|
||||
if (status != null) {
|
||||
list.add(new TimelineModel(status));
|
||||
} else {
|
||||
if (issue != null || pullRequest != null) return HEADER;
|
||||
if (status != null) return STATUS;
|
||||
return EVENT;
|
||||
}
|
||||
if (reviews != null && !reviews.isEmpty()) {
|
||||
list.addAll(constructReviews(reviews, reviewComments));
|
||||
}
|
||||
if (commentList != null && !commentList.isEmpty()) {
|
||||
list.addAll(Stream.of(commentList)
|
||||
.map(TimelineModel::new)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
if (eventList != null && !eventList.isEmpty()) {
|
||||
list.addAll(constructLabels(eventList));
|
||||
}
|
||||
|
||||
return Stream.of(list).sortBy(model -> {
|
||||
if (model.getSortedDate() != null) {
|
||||
return model.getSortedDate().getTime();
|
||||
} else {
|
||||
return (long) model.getType();
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NonNull private static List<TimelineModel> constructLabels(@NonNull List<IssueEvent> eventList) {
|
||||
List<TimelineModel> models = new ArrayList<>();
|
||||
Map<String, List<IssueEvent>> issueEventMap = Stream.of(eventList)
|
||||
.filter(value -> value.getEvent() != null && value.getEvent() != IssueEventType.subscribed &&
|
||||
value.getEvent() != IssueEventType.unsubscribed && value.getEvent() != IssueEventType.mentioned)
|
||||
.collect(Collectors.groupingBy(issueEvent -> {
|
||||
if (issueEvent.getAssigner() != null && issueEvent.getAssignee() != null) {
|
||||
return issueEvent.getAssigner().getLogin();
|
||||
}
|
||||
return issueEvent.getActor().getLogin();
|
||||
}));
|
||||
if (issueEventMap != null && !issueEventMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<IssueEvent>> stringListEntry : issueEventMap.entrySet()) {
|
||||
List<LabelModel> labelModels = new ArrayList<>();
|
||||
List<IssueEvent> events = stringListEntry.getValue();
|
||||
IssueEvent toAdd = null;
|
||||
for (IssueEvent event : events) {
|
||||
if (event.getEvent() == IssueEventType.labeled || event.getEvent() == IssueEventType.unlabeled) {
|
||||
if (toAdd == null) {
|
||||
toAdd = event;
|
||||
}
|
||||
long time = toAdd.getCreatedAt().after(event.getCreatedAt()) ? (toAdd.getCreatedAt().getTime() - event
|
||||
.getCreatedAt().getTime()) : (event.getCreatedAt().getTime() - toAdd.getCreatedAt().getTime());
|
||||
if (TimeUnit.MINUTES.toMinutes(time) <= 2 && toAdd.getEvent() == event.getEvent()) {
|
||||
labelModels.add(event.getLabel());
|
||||
} else {
|
||||
models.add(new TimelineModel(event));
|
||||
}
|
||||
} else {
|
||||
models.add(new TimelineModel(event));
|
||||
}
|
||||
}
|
||||
if (toAdd != null) {
|
||||
toAdd.setLabels(labelModels);
|
||||
models.add(new TimelineModel(toAdd));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Stream.of(models)
|
||||
.sortBy(TimelineModel::getSortedDate)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@NonNull private static List<TimelineModel> constructReviews
|
||||
(@NonNull List<ReviewModel> reviews, @Nullable List<ReviewCommentModel> comments) {
|
||||
List<TimelineModel> models = new ArrayList<>();
|
||||
if (comments == null || comments.isEmpty()) {
|
||||
models.addAll(Stream.of(reviews)
|
||||
.map(TimelineModel::new)
|
||||
.collect(Collectors.toList()));
|
||||
} else { // this is how bad github API is.
|
||||
Map<Integer, List<ReviewCommentModel>> mappedComments = Stream.of(comments)
|
||||
.collect(Collectors.groupingBy(ReviewCommentModel::getOriginalPosition, LinkedHashMap::new,
|
||||
Collectors.mapping(o -> o, toList())));
|
||||
for (Map.Entry<Integer, List<ReviewCommentModel>> entry : mappedComments.entrySet()) {
|
||||
List<ReviewCommentModel> reviewCommentModels = entry.getValue();
|
||||
GroupedReviewModel groupedReviewModel = new GroupedReviewModel();
|
||||
if (!reviewCommentModels.isEmpty()) {
|
||||
ReviewCommentModel reviewCommentModel = reviewCommentModels.get(0);
|
||||
groupedReviewModel.setPath(reviewCommentModel.getPath());
|
||||
groupedReviewModel.setDiffText(reviewCommentModel.getDiffHunk());
|
||||
groupedReviewModel.setDate(reviewCommentModel.getCreatedAt());
|
||||
groupedReviewModel.setPosition(reviewCommentModel.getOriginalPosition());
|
||||
groupedReviewModel.setId(reviewCommentModel.getId());
|
||||
}
|
||||
for (ReviewCommentModel reviewCommentModel : reviewCommentModels) {
|
||||
if (reviewCommentModel.getCreatedAt() != null) {
|
||||
groupedReviewModel.setDate(reviewCommentModel.getCreatedAt());
|
||||
break;
|
||||
}
|
||||
}
|
||||
groupedReviewModel.setComments(reviewCommentModels);
|
||||
models.add(new TimelineModel(groupedReviewModel));
|
||||
}
|
||||
models.addAll(Stream.of(reviews)
|
||||
.filter(reviewModel -> !InputHelper.isEmpty(reviewModel.getBody()) || reviewModel.getState() == ReviewStateType.APPROVED)
|
||||
.map(TimelineModel::new)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return models;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
TimelineModel model = (TimelineModel) o;
|
||||
return (comment != null && model.getComment() != null) && (comment.getId() == model.comment.getId());
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return comment != null ? (int) comment.getId() : 0;
|
||||
}
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.type);
|
||||
dest.writeParcelable(this.issue, flags);
|
||||
dest.writeInt(this.event == null ? -1 : this.event.ordinal());
|
||||
dest.writeParcelable(this.comment, flags);
|
||||
dest.writeParcelable(this.event, flags);
|
||||
dest.writeParcelable(this.pullRequest, flags);
|
||||
dest.writeParcelable(this.status, flags);
|
||||
dest.writeParcelable(this.review, flags);
|
||||
dest.writeParcelable(this.groupedReview, flags);
|
||||
dest.writeParcelable(this.genericEvent, flags);
|
||||
dest.writeParcelable(this.reviewComment, flags);
|
||||
dest.writeLong(this.sortedDate != null ? this.sortedDate.getTime() : -1);
|
||||
dest.writeParcelable(this.status, flags);
|
||||
dest.writeParcelable(this.issue, flags);
|
||||
dest.writeParcelable(this.pullRequest, flags);
|
||||
}
|
||||
|
||||
protected TimelineModel(Parcel in) {
|
||||
this.type = in.readInt();
|
||||
this.issue = in.readParcelable(Issue.class.getClassLoader());
|
||||
int tmpEvent = in.readInt();
|
||||
this.event = tmpEvent == -1 ? null : IssueEventType.values()[tmpEvent];
|
||||
this.comment = in.readParcelable(Comment.class.getClassLoader());
|
||||
this.event = in.readParcelable(IssueEvent.class.getClassLoader());
|
||||
this.pullRequest = in.readParcelable(PullRequest.class.getClassLoader());
|
||||
this.status = in.readParcelable(PullRequestStatusModel.class.getClassLoader());
|
||||
this.review = in.readParcelable(ReviewModel.class.getClassLoader());
|
||||
this.groupedReview = in.readParcelable(GroupedReviewModel.class.getClassLoader());
|
||||
this.genericEvent = in.readParcelable(GenericEvent.class.getClassLoader());
|
||||
this.reviewComment = in.readParcelable(ReviewCommentModel.class.getClassLoader());
|
||||
long tmpSortedDate = in.readLong();
|
||||
this.sortedDate = tmpSortedDate == -1 ? null : new Date(tmpSortedDate);
|
||||
this.status = in.readParcelable(PullRequestStatusModel.class.getClassLoader());
|
||||
this.issue = in.readParcelable(Issue.class.getClassLoader());
|
||||
this.pullRequest = in.readParcelable(PullRequest.class.getClassLoader());
|
||||
}
|
||||
|
||||
public static final Creator<TimelineModel> CREATOR = new Creator<TimelineModel>() {
|
||||
@ -292,4 +99,40 @@ import static com.annimon.stream.Collectors.toList;
|
||||
|
||||
@Override public TimelineModel[] newArray(int size) {return new TimelineModel[size];}
|
||||
};
|
||||
|
||||
public static TimelineModel constructHeader(Issue issue) {
|
||||
return new TimelineModel(issue);
|
||||
}
|
||||
|
||||
public static TimelineModel constructHeader(PullRequest pullRequest) {
|
||||
return new TimelineModel(pullRequest);
|
||||
}
|
||||
|
||||
public static TimelineModel constructComment(Comment comment) {
|
||||
return new TimelineModel(comment);
|
||||
}
|
||||
|
||||
@NonNull public static Observable<List<TimelineModel>> construct(@Nullable List<Comment> comments) {
|
||||
if (comments == null || comments.isEmpty()) return Observable.empty();
|
||||
return Observable.fromIterable(comments)
|
||||
.map(TimelineModel::new)
|
||||
.toList()
|
||||
.toObservable();
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
TimelineModel that = (TimelineModel) o;
|
||||
if (comment != null) {
|
||||
return comment.equals(that.comment);
|
||||
} else if (reviewComment != null) {
|
||||
return reviewComment.equals(that.reviewComment);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return comment != null ? comment.hashCode() : reviewComment != null ? reviewComment.hashCode() : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
package com.fastaccess.data.dao.timeline;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter @Setter public class AuthorModel implements Parcelable {
|
||||
private String name;
|
||||
private String email;
|
||||
private Date date;
|
||||
|
||||
public AuthorModel() {}
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.name);
|
||||
dest.writeString(this.email);
|
||||
dest.writeLong(this.date != null ? this.date.getTime() : -1);
|
||||
}
|
||||
|
||||
protected AuthorModel(Parcel in) {
|
||||
this.name = in.readString();
|
||||
this.email = in.readString();
|
||||
long tmpDate = in.readLong();
|
||||
this.date = tmpDate == -1 ? null : new Date(tmpDate);
|
||||
}
|
||||
|
||||
public static final Creator<AuthorModel> CREATOR = new Creator<AuthorModel>() {
|
||||
@Override public AuthorModel createFromParcel(Parcel source) {return new AuthorModel(source);}
|
||||
|
||||
@Override public AuthorModel[] newArray(int size) {return new AuthorModel[size];}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
package com.fastaccess.data.dao.timeline;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.ReactionsModel;
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.model.User;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Created by Kosh on 16 Mar 2017, 7:24 PM
|
||||
*/
|
||||
@Getter @Setter public class CommentEvent implements Parcelable {
|
||||
private long id;
|
||||
private User user;
|
||||
private String url;
|
||||
private String body;
|
||||
private String bodyHtml;
|
||||
private String htmlUrl;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
private int position;
|
||||
private int line;
|
||||
private String path;
|
||||
private String commitId;
|
||||
private String repoId;
|
||||
private String login;
|
||||
private String gistId;
|
||||
private String issueId;
|
||||
private String pullRequestId;
|
||||
private ReactionsModel reactions;
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Comment that = (Comment) o;
|
||||
return id == that.getId();
|
||||
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
return (int) (id ^ (id >>> 32));
|
||||
}
|
||||
|
||||
public CommentEvent() {}
|
||||
|
||||
@Override public String toString() {
|
||||
return "CommentEvent{" +
|
||||
"id=" + id +
|
||||
", user=" + user +
|
||||
", url='" + url + '\'' +
|
||||
", body='" + body + '\'' +
|
||||
", bodyHtml='" + bodyHtml + '\'' +
|
||||
", htmlUrl='" + htmlUrl + '\'' +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
", position=" + position +
|
||||
", line=" + line +
|
||||
", path='" + path + '\'' +
|
||||
", commitId='" + commitId + '\'' +
|
||||
", repoId='" + repoId + '\'' +
|
||||
", login='" + login + '\'' +
|
||||
", gistId='" + gistId + '\'' +
|
||||
", issueId='" + issueId + '\'' +
|
||||
", pullRequestId='" + pullRequestId + '\'' +
|
||||
", reactions=" + reactions +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeLong(this.id);
|
||||
dest.writeParcelable(this.user, flags);
|
||||
dest.writeString(this.url);
|
||||
dest.writeString(this.body);
|
||||
dest.writeString(this.bodyHtml);
|
||||
dest.writeString(this.htmlUrl);
|
||||
dest.writeLong(this.createdAt != null ? this.createdAt.getTime() : -1);
|
||||
dest.writeLong(this.updatedAt != null ? this.updatedAt.getTime() : -1);
|
||||
dest.writeInt(this.position);
|
||||
dest.writeInt(this.line);
|
||||
dest.writeString(this.path);
|
||||
dest.writeString(this.commitId);
|
||||
dest.writeString(this.repoId);
|
||||
dest.writeString(this.login);
|
||||
dest.writeString(this.gistId);
|
||||
dest.writeString(this.issueId);
|
||||
dest.writeString(this.pullRequestId);
|
||||
dest.writeParcelable(this.reactions, flags);
|
||||
}
|
||||
|
||||
protected CommentEvent(Parcel in) {
|
||||
this.id = in.readLong();
|
||||
this.user = in.readParcelable(User.class.getClassLoader());
|
||||
this.url = in.readString();
|
||||
this.body = in.readString();
|
||||
this.bodyHtml = in.readString();
|
||||
this.htmlUrl = in.readString();
|
||||
long tmpCreatedAt = in.readLong();
|
||||
this.createdAt = tmpCreatedAt == -1 ? null : new Date(tmpCreatedAt);
|
||||
long tmpUpdatedAt = in.readLong();
|
||||
this.updatedAt = tmpUpdatedAt == -1 ? null : new Date(tmpUpdatedAt);
|
||||
this.position = in.readInt();
|
||||
this.line = in.readInt();
|
||||
this.path = in.readString();
|
||||
this.commitId = in.readString();
|
||||
this.repoId = in.readString();
|
||||
this.login = in.readString();
|
||||
this.gistId = in.readString();
|
||||
this.issueId = in.readString();
|
||||
this.pullRequestId = in.readString();
|
||||
this.reactions = in.readParcelable(ReactionsModel.class.getClassLoader());
|
||||
}
|
||||
|
||||
public static final Creator<CommentEvent> CREATOR = new Creator<CommentEvent>() {
|
||||
@Override public CommentEvent createFromParcel(Parcel source) {return new CommentEvent(source);}
|
||||
|
||||
@Override public CommentEvent[] newArray(int size) {return new CommentEvent[size];}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
package com.fastaccess.data.dao.timeline;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.LabelModel;
|
||||
import com.fastaccess.data.dao.MilestoneModel;
|
||||
import com.fastaccess.data.dao.RenameModel;
|
||||
import com.fastaccess.data.dao.TeamsModel;
|
||||
import com.fastaccess.data.dao.model.Issue;
|
||||
import com.fastaccess.data.dao.model.PullRequest;
|
||||
import com.fastaccess.data.dao.model.User;
|
||||
import com.fastaccess.data.dao.types.IssueEventType;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Created by kosh on 25/07/2017.
|
||||
*/
|
||||
|
||||
@NoArgsConstructor @Getter @Setter public class GenericEvent implements Parcelable {
|
||||
|
||||
private long id;
|
||||
private String url;
|
||||
private String commitId;
|
||||
private String commitUrl;
|
||||
private String message;
|
||||
private String sha;
|
||||
private String htmlUrl;
|
||||
private Date createdAt;
|
||||
private User actor;
|
||||
private User requestedReviewer;
|
||||
private User reviewRequester;
|
||||
private User assigner;
|
||||
private User assignee;
|
||||
private User author;
|
||||
private User committer;
|
||||
private LabelModel label;
|
||||
private TeamsModel requestedTeam;
|
||||
private MilestoneModel milestone;
|
||||
private RenameModel rename;
|
||||
private SourceModel source;
|
||||
private Issue issue;
|
||||
private PullRequest pullRequest;
|
||||
private ParentsModel tree;
|
||||
private List<ParentsModel> parents;
|
||||
private IssueEventType event;
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeLong(this.id);
|
||||
dest.writeString(this.url);
|
||||
dest.writeString(this.commitId);
|
||||
dest.writeString(this.commitUrl);
|
||||
dest.writeString(this.message);
|
||||
dest.writeString(this.sha);
|
||||
dest.writeString(this.htmlUrl);
|
||||
dest.writeLong(this.createdAt != null ? this.createdAt.getTime() : -1);
|
||||
dest.writeParcelable(this.actor, flags);
|
||||
dest.writeParcelable(this.requestedReviewer, flags);
|
||||
dest.writeParcelable(this.reviewRequester, flags);
|
||||
dest.writeParcelable(this.assigner, flags);
|
||||
dest.writeParcelable(this.assignee, flags);
|
||||
dest.writeParcelable(this.author, flags);
|
||||
dest.writeParcelable(this.committer, flags);
|
||||
dest.writeParcelable(this.label, flags);
|
||||
dest.writeParcelable(this.requestedTeam, flags);
|
||||
dest.writeParcelable(this.milestone, flags);
|
||||
dest.writeParcelable(this.rename, flags);
|
||||
dest.writeParcelable(this.source, flags);
|
||||
dest.writeParcelable(this.issue, flags);
|
||||
dest.writeParcelable(this.pullRequest, flags);
|
||||
dest.writeParcelable(this.tree, flags);
|
||||
dest.writeTypedList(this.parents);
|
||||
dest.writeInt(this.event == null ? -1 : this.event.ordinal());
|
||||
}
|
||||
|
||||
protected GenericEvent(Parcel in) {
|
||||
this.id = in.readLong();
|
||||
this.url = in.readString();
|
||||
this.commitId = in.readString();
|
||||
this.commitUrl = in.readString();
|
||||
this.message = in.readString();
|
||||
this.sha = in.readString();
|
||||
this.htmlUrl = in.readString();
|
||||
long tmpCreatedAt = in.readLong();
|
||||
this.createdAt = tmpCreatedAt == -1 ? null : new Date(tmpCreatedAt);
|
||||
this.actor = in.readParcelable(User.class.getClassLoader());
|
||||
this.requestedReviewer = in.readParcelable(User.class.getClassLoader());
|
||||
this.reviewRequester = in.readParcelable(User.class.getClassLoader());
|
||||
this.assigner = in.readParcelable(User.class.getClassLoader());
|
||||
this.assignee = in.readParcelable(User.class.getClassLoader());
|
||||
this.author = in.readParcelable(User.class.getClassLoader());
|
||||
this.committer = in.readParcelable(User.class.getClassLoader());
|
||||
this.label = in.readParcelable(LabelModel.class.getClassLoader());
|
||||
this.requestedTeam = in.readParcelable(TeamsModel.class.getClassLoader());
|
||||
this.milestone = in.readParcelable(MilestoneModel.class.getClassLoader());
|
||||
this.rename = in.readParcelable(RenameModel.class.getClassLoader());
|
||||
this.source = in.readParcelable(SourceModel.class.getClassLoader());
|
||||
this.issue = in.readParcelable(Issue.class.getClassLoader());
|
||||
this.pullRequest = in.readParcelable(PullRequest.class.getClassLoader());
|
||||
this.tree = in.readParcelable(ParentsModel.class.getClassLoader());
|
||||
this.parents = in.createTypedArrayList(ParentsModel.CREATOR);
|
||||
int tmpEvent = in.readInt();
|
||||
this.event = tmpEvent == -1 ? null : IssueEventType.values()[tmpEvent];
|
||||
}
|
||||
|
||||
public static final Creator<GenericEvent> CREATOR = new Creator<GenericEvent>() {
|
||||
@Override public GenericEvent createFromParcel(Parcel source) {return new GenericEvent(source);}
|
||||
|
||||
@Override public GenericEvent[] newArray(int size) {return new GenericEvent[size];}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.fastaccess.data.dao.timeline;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter @Setter public class ParentsModel implements Parcelable {
|
||||
private String sha;
|
||||
private String url;
|
||||
private String htmlUrl;
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.sha);
|
||||
dest.writeString(this.url);
|
||||
dest.writeString(this.htmlUrl);
|
||||
}
|
||||
|
||||
public ParentsModel() {}
|
||||
|
||||
protected ParentsModel(Parcel in) {
|
||||
this.sha = in.readString();
|
||||
this.url = in.readString();
|
||||
this.htmlUrl = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<ParentsModel> CREATOR = new Parcelable.Creator<ParentsModel>() {
|
||||
@Override public ParentsModel createFromParcel(Parcel source) {return new ParentsModel(source);}
|
||||
|
||||
@Override public ParentsModel[] newArray(int size) {return new ParentsModel[size];}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.fastaccess.data.dao.timeline;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.model.Commit;
|
||||
import com.fastaccess.data.dao.model.Issue;
|
||||
import com.fastaccess.data.dao.model.PullRequest;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Created by kosh on 26/07/2017.
|
||||
*/
|
||||
|
||||
@Getter @Setter public class SourceModel implements Parcelable {
|
||||
|
||||
private String type;
|
||||
private Issue issue;
|
||||
private PullRequest pullRequest;
|
||||
private Commit commit;
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.type);
|
||||
dest.writeParcelable(this.issue, flags);
|
||||
dest.writeParcelable(this.pullRequest, flags);
|
||||
dest.writeParcelable(this.commit, flags);
|
||||
}
|
||||
|
||||
public SourceModel() {}
|
||||
|
||||
protected SourceModel(Parcel in) {
|
||||
this.type = in.readString();
|
||||
this.issue = in.readParcelable(Issue.class.getClassLoader());
|
||||
this.pullRequest = in.readParcelable(PullRequest.class.getClassLoader());
|
||||
this.commit = in.readParcelable(Commit.class.getClassLoader());
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<SourceModel> CREATOR = new Parcelable.Creator<SourceModel>() {
|
||||
@Override public SourceModel createFromParcel(Parcel source) {return new SourceModel(source);}
|
||||
|
||||
@Override public SourceModel[] newArray(int size) {return new SourceModel[size];}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.fastaccess.data.dao.timeline;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.fastaccess.data.dao.PullRequestStatusModel;
|
||||
import com.fastaccess.data.dao.ReviewCommentModel;
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.types.IssueEventType;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Created by kosh on 25/07/2017.
|
||||
*/
|
||||
|
||||
@Getter @Setter public class Timeline implements Parcelable {
|
||||
public static final int HEADER = 0;
|
||||
public static final int LINE_COMMENT = 1;
|
||||
public static final int EVENT = 2;
|
||||
public static final int COMMENT = 3;
|
||||
public static final int STATUS = 4;
|
||||
|
||||
private IssueEventType event;
|
||||
private Comment comment;
|
||||
private GenericEvent genericEvent;
|
||||
private ReviewCommentModel reviewComment;
|
||||
private PullRequestStatusModel statusModel;
|
||||
|
||||
public int getType() {
|
||||
if (getEvent() != null) {
|
||||
switch (getEvent()) {
|
||||
case commented:
|
||||
return COMMENT;
|
||||
case line_commented:
|
||||
return LINE_COMMENT;
|
||||
default:
|
||||
return EVENT;
|
||||
}
|
||||
} else {
|
||||
if (statusModel != null) return STATUS;
|
||||
return EVENT;
|
||||
}
|
||||
}
|
||||
|
||||
public Timeline() {}
|
||||
|
||||
@Override public int describeContents() { return 0; }
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.event == null ? -1 : this.event.ordinal());
|
||||
dest.writeParcelable(this.comment, flags);
|
||||
dest.writeParcelable(this.genericEvent, flags);
|
||||
dest.writeParcelable(this.reviewComment, flags);
|
||||
dest.writeParcelable(this.statusModel, flags);
|
||||
}
|
||||
|
||||
protected Timeline(Parcel in) {
|
||||
int tmpEvent = in.readInt();
|
||||
this.event = tmpEvent == -1 ? null : IssueEventType.values()[tmpEvent];
|
||||
this.comment = in.readParcelable(Comment.class.getClassLoader());
|
||||
this.genericEvent = in.readParcelable(GenericEvent.class.getClassLoader());
|
||||
this.reviewComment = in.readParcelable(ReviewCommentModel.class.getClassLoader());
|
||||
this.statusModel = in.readParcelable(PullRequestStatusModel.class.getClassLoader());
|
||||
}
|
||||
|
||||
public static final Creator<Timeline> CREATOR = new Creator<Timeline>() {
|
||||
@Override public Timeline createFromParcel(Parcel source) {return new Timeline(source);}
|
||||
|
||||
@Override public Timeline[] newArray(int size) {return new Timeline[size];}
|
||||
};
|
||||
}
|
||||
@ -1,5 +1,9 @@
|
||||
package com.fastaccess.data.dao.types;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
import com.fastaccess.R;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@ -7,7 +11,7 @@ public enum IssueEventType {
|
||||
assigned(R.drawable.ic_profile),
|
||||
closed(R.drawable.ic_issue_closed),
|
||||
commented(R.drawable.ic_comment),
|
||||
committed(R.drawable.ic_announcement),
|
||||
committed(R.drawable.ic_push),
|
||||
demilestoned(R.drawable.ic_milestone),
|
||||
head_ref_deleted(R.drawable.ic_trash),
|
||||
head_ref_restored(R.drawable.ic_redo),
|
||||
@ -27,7 +31,9 @@ public enum IssueEventType {
|
||||
review_requested(R.drawable.ic_eye),
|
||||
review_dismissed(R.drawable.ic_eye_off),
|
||||
review_request_removed(R.drawable.ic_eye_off),
|
||||
@SerializedName("cross-referenced")crossReferenced(R.drawable.ic_format_quote);
|
||||
@SerializedName("cross-referenced")cross_referenced(R.drawable.ic_format_quote),
|
||||
@SerializedName("line-commented")line_commented(R.drawable.ic_comment),
|
||||
reviewed(R.drawable.ic_eye);
|
||||
|
||||
int iconResId;
|
||||
|
||||
@ -36,4 +42,12 @@ public enum IssueEventType {
|
||||
public int getIconResId() {
|
||||
return iconResId == 0 ? R.drawable.ic_label : iconResId;
|
||||
}
|
||||
|
||||
@Nullable public static IssueEventType getType(@NonNull String type) {
|
||||
return Stream.of(values())
|
||||
.filter(value -> value.name().toLowerCase().equalsIgnoreCase(type.toLowerCase()
|
||||
.replaceAll("-", "_")))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
@ -7,14 +7,17 @@ import com.fastaccess.data.dao.AssigneesRequestModel;
|
||||
import com.fastaccess.data.dao.CommentRequestModel;
|
||||
import com.fastaccess.data.dao.CreateIssueModel;
|
||||
import com.fastaccess.data.dao.IssueRequestModel;
|
||||
import com.fastaccess.data.dao.IssuesPageable;
|
||||
import com.fastaccess.data.dao.LabelModel;
|
||||
import com.fastaccess.data.dao.Pageable;
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.model.Issue;
|
||||
import com.fastaccess.data.dao.model.IssueEvent;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.DELETE;
|
||||
@ -25,7 +28,6 @@ import retrofit2.http.POST;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
import retrofit2.http.Query;
|
||||
import io.reactivex.Observable;
|
||||
|
||||
public interface IssueService {
|
||||
|
||||
@ -49,6 +51,12 @@ public interface IssueService {
|
||||
Observable<Pageable<IssueEvent>> getTimeline(@Path("owner") String owner, @Path("repo") String repo,
|
||||
@Path("issue_number") int issue_number);
|
||||
|
||||
@GET("repos/{owner}/{repo}/issues/{issue_number}/timeline")
|
||||
@Headers("Accept: application/vnd.github.mockingbird-preview,application/vnd.github.VERSION.full+json," +
|
||||
" application/vnd.github.squirrel-girl-preview")
|
||||
Observable<IssuesPageable<JsonObject>> getTimeline(@Path("owner") String owner, @Path("repo") String repo,
|
||||
@Path("issue_number") int issue_number, @Query("page") int page);
|
||||
|
||||
@POST("repos/{owner}/{repo}/issues")
|
||||
Observable<Issue> createIssue(@Path("owner") String owner, @Path("repo") String repo,
|
||||
@Body IssueRequestModel issue);
|
||||
|
||||
@ -6,6 +6,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.media.AudioManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
@ -91,6 +92,7 @@ public class NotificationSchedulerJobTask extends JobService {
|
||||
public static void scheduleJob(@NonNull Context context, int duration, boolean cancel) {
|
||||
if (AppHelper.isGoogleAvailable(context)) {
|
||||
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
|
||||
dispatcher.cancel(SINGLE_JOB_ID);
|
||||
if (cancel) dispatcher.cancel(JOB_ID);
|
||||
if (duration == -1) {
|
||||
dispatcher.cancel(JOB_ID);
|
||||
@ -254,7 +256,7 @@ public class NotificationSchedulerJobTask extends JobService {
|
||||
new Intent(getApplicationContext(), NotificationActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
return getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName())
|
||||
.setDefaults(PrefGetter.isNotificationSoundEnabled() ? NotificationCompat.DEFAULT_ALL : 0)
|
||||
.setSound(PrefGetter.getNotificationSound())
|
||||
.setSound(PrefGetter.getNotificationSound(), AudioManager.STREAM_NOTIFICATION)
|
||||
.setContentIntent(toNotificationActivity ? pendingIntent : getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
|
||||
.addAction(R.drawable.ic_github, getString(R.string.open), getPendingIntent(thread.getId(), thread
|
||||
.getSubject().getUrl()))
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
package com.fastaccess.provider.timeline;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.fastaccess.data.dao.ReviewCommentModel;
|
||||
import com.fastaccess.data.dao.TimelineModel;
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.timeline.GenericEvent;
|
||||
import com.fastaccess.data.dao.types.IssueEventType;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.provider.rest.RestProvider;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
|
||||
/**
|
||||
* Created by kosh on 26/07/2017.
|
||||
*/
|
||||
|
||||
public class TimelineConverter {
|
||||
|
||||
@NonNull public static Observable<TimelineModel> convert(@Nullable List<JsonObject> jsonObjects) {
|
||||
if (jsonObjects == null) return Observable.empty();
|
||||
Gson gson = RestProvider.gson;
|
||||
return Observable.fromIterable(jsonObjects)
|
||||
.map(jsonObject -> {
|
||||
String event = jsonObject.get("event").getAsString();
|
||||
TimelineModel timeline = new TimelineModel();
|
||||
if (!InputHelper.isEmpty(event)) {
|
||||
IssueEventType type = IssueEventType.getType(event);
|
||||
timeline.setEvent(type);
|
||||
if (type != null) {
|
||||
if (type == IssueEventType.commented) {
|
||||
timeline.setComment(getComment(jsonObject, gson));
|
||||
} else if (type == IssueEventType.line_commented) {
|
||||
timeline.setReviewComment(getReviewComment(jsonObject, gson));
|
||||
} else {
|
||||
timeline.setGenericEvent(getGenericEvent(jsonObject, gson));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
timeline.setGenericEvent(getGenericEvent(jsonObject, gson));
|
||||
}
|
||||
return timeline;
|
||||
})
|
||||
.filter(timeline -> timeline != null && filterEvents(timeline.getEvent()));
|
||||
}
|
||||
|
||||
private static GenericEvent getGenericEvent(@NonNull JsonObject object, @NonNull Gson gson) {
|
||||
return gson.fromJson(object, GenericEvent.class);
|
||||
}
|
||||
|
||||
private static ReviewCommentModel getReviewComment(@NonNull JsonObject object, @NonNull Gson gson) {
|
||||
return gson.fromJson(object, ReviewCommentModel.class);
|
||||
}
|
||||
|
||||
private static Comment getComment(@NonNull JsonObject object, @NonNull Gson gson) {
|
||||
return gson.fromJson(object, Comment.class);
|
||||
}
|
||||
|
||||
private static boolean filterEvents(@Nullable IssueEventType type) {
|
||||
return type != IssueEventType.subscribed && type != IssueEventType.unsubscribed && type != IssueEventType.mentioned;
|
||||
}
|
||||
}
|
||||
@ -8,14 +8,14 @@ import android.text.style.BackgroundColorSpan;
|
||||
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.LabelModel;
|
||||
import com.fastaccess.data.dao.model.IssueEvent;
|
||||
import com.fastaccess.data.dao.model.User;
|
||||
import com.fastaccess.data.dao.timeline.GenericEvent;
|
||||
import com.fastaccess.data.dao.timeline.SourceModel;
|
||||
import com.fastaccess.data.dao.types.IssueEventType;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.helper.ParseDateFormat;
|
||||
import com.fastaccess.helper.PrefGetter;
|
||||
import com.fastaccess.helper.ViewHelper;
|
||||
import com.fastaccess.ui.widgets.LabelSpan;
|
||||
import com.fastaccess.ui.widgets.SpannableBuilder;
|
||||
import com.zzhoujay.markdown.style.CodeSpan;
|
||||
|
||||
@ -27,9 +27,14 @@ import java.util.Date;
|
||||
|
||||
public class TimelineProvider {
|
||||
|
||||
@NonNull public static SpannableBuilder getStyledEvents(@NonNull IssueEvent issueEventModel, @NonNull Context context, boolean isMerged) {
|
||||
@NonNull public static SpannableBuilder getStyledEvents(@NonNull GenericEvent issueEventModel,
|
||||
@NonNull Context context, boolean isMerged) {
|
||||
IssueEventType event = issueEventModel.getEvent();
|
||||
SpannableBuilder spannableBuilder = SpannableBuilder.builder();
|
||||
Date date = issueEventModel.getCreatedAt() != null
|
||||
? issueEventModel.getCreatedAt()
|
||||
: issueEventModel.getAuthor() != null
|
||||
? issueEventModel.getAuthor().getDate() : null;
|
||||
if (event != null) {
|
||||
String to = context.getString(R.string.to);
|
||||
String from = context.getString(R.string.from);
|
||||
@ -46,20 +51,25 @@ public class TimelineProvider {
|
||||
int color = Color.parseColor("#" + labelModel.getColor());
|
||||
spannableBuilder.append(" ").append(" " + labelModel.getName() + " ", new CodeSpan(color, ViewHelper.generateTextColor(color), 5));
|
||||
spannableBuilder.append(" ").append(getDate(issueEventModel.getCreatedAt()));
|
||||
} else if (event == IssueEventType.committed) {
|
||||
spannableBuilder.append(issueEventModel.getMessage().replaceAll("\n", " "))
|
||||
.append(" ")
|
||||
.url(substring(issueEventModel.getSha()));
|
||||
} else {
|
||||
User user = null;
|
||||
if (issueEventModel.getAssignee() != null && issueEventModel.getAssigner() != null) {
|
||||
user = issueEventModel.getAssigner();
|
||||
} else if (issueEventModel.getActor() != null) {
|
||||
user = issueEventModel.getActor();
|
||||
} else if (issueEventModel.getAuthor() != null) {
|
||||
user = issueEventModel.getAuthor();
|
||||
}
|
||||
if (user != null) {
|
||||
spannableBuilder.bold(user.getLogin());
|
||||
}
|
||||
|
||||
if ((event == IssueEventType.review_requested || (event == IssueEventType.review_dismissed ||
|
||||
event == IssueEventType.review_request_removed)) && user != null) {
|
||||
appendReviews(issueEventModel, event, spannableBuilder, from, user);
|
||||
appendReviews(issueEventModel, event, spannableBuilder, from, issueEventModel.getReviewRequester());
|
||||
} else if (event == IssueEventType.closed || event == IssueEventType.reopened) {
|
||||
if (isMerged) {
|
||||
spannableBuilder.append(" ").append(IssueEventType.merged.name());
|
||||
@ -76,7 +86,6 @@ public class TimelineProvider {
|
||||
.append(in)
|
||||
.append(" ")
|
||||
.url(substring(issueEventModel.getCommitId()));
|
||||
|
||||
}
|
||||
} else if (event == IssueEventType.assigned || event == IssueEventType.unassigned) {
|
||||
spannableBuilder
|
||||
@ -123,18 +132,38 @@ public class TimelineProvider {
|
||||
.append("commit")
|
||||
.append(" ")
|
||||
.url(substring(issueEventModel.getCommitId()));
|
||||
} else if (event == IssueEventType.cross_referenced) {
|
||||
SourceModel sourceModel = issueEventModel.getSource();
|
||||
if (sourceModel != null) {
|
||||
SpannableBuilder title = SpannableBuilder.builder();
|
||||
if (sourceModel.getIssue() != null) {
|
||||
title.url("#" + sourceModel.getIssue().getNumber());
|
||||
} else if (sourceModel.getPullRequest() != null) {
|
||||
title.url("#" + sourceModel.getPullRequest().getNumber());
|
||||
} else if (sourceModel.getCommit() != null) {
|
||||
title.url(substring(sourceModel.getCommit().getSha()));
|
||||
}
|
||||
if (!InputHelper.isEmpty(title)) {
|
||||
spannableBuilder.append(" ")
|
||||
.append(thisString)
|
||||
.append(" in ")
|
||||
.append(sourceModel.getType())
|
||||
.append(" ")
|
||||
.append(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
spannableBuilder.append(" ").append(getDate(issueEventModel.getCreatedAt()));
|
||||
spannableBuilder.append(" ").append(getDate(date));
|
||||
}
|
||||
}
|
||||
return spannableBuilder;
|
||||
}
|
||||
|
||||
private static void appendReviews(@NonNull IssueEvent issueEventModel, @NonNull IssueEventType event,
|
||||
@NonNull SpannableBuilder spannableBuilder, @NonNull String from, @NonNull User user) {
|
||||
private static void appendReviews(@NonNull GenericEvent issueEventModel, @NonNull IssueEventType event,
|
||||
@NonNull SpannableBuilder spannableBuilder, @NonNull String from,
|
||||
@NonNull User user) {
|
||||
spannableBuilder.append(" ");
|
||||
User reviewer = issueEventModel.getRequestedReviewer() != null
|
||||
? issueEventModel.getRequestedReviewer() : issueEventModel.getIssue() != null ? issueEventModel.getIssue().getUser() : null;
|
||||
User reviewer = issueEventModel.getRequestedReviewer();
|
||||
if (reviewer != null && user.getLogin().equalsIgnoreCase(reviewer.getLogin())) {
|
||||
spannableBuilder
|
||||
.append(event == IssueEventType.review_requested
|
||||
@ -158,11 +187,6 @@ public class TimelineProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public static void appendLabels(@NonNull LabelModel labelModel, @NonNull SpannableBuilder spannableBuilder) {
|
||||
int color = Color.parseColor("#" + labelModel.getColor());
|
||||
spannableBuilder.append(" ").append(" " + labelModel.getName() + " ", new LabelSpan(color));
|
||||
}
|
||||
|
||||
@NonNull private static CharSequence getDate(@Nullable Date date) {
|
||||
return ParseDateFormat.getTimeAgo(date);
|
||||
}
|
||||
|
||||
@ -3,14 +3,12 @@ package com.fastaccess.provider.timeline.handler.drawable;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.Html;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.GenericRequestBuilder;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.helper.Logger;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashSet;
|
||||
@ -30,23 +28,10 @@ public class DrawableGetter implements Html.ImageGetter, Drawable.Callback {
|
||||
this.cachedTargets = new HashSet<>();
|
||||
}
|
||||
|
||||
public void clear(@NonNull DrawableGetter drawableGetter) {
|
||||
if (drawableGetter.cachedTargets != null) {
|
||||
for (GifBitmapTarget target : drawableGetter.cachedTargets) {
|
||||
Logger.e("is clearing");
|
||||
Glide.clear(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public Drawable getDrawable(@NonNull String url) {
|
||||
final UrlDrawable urlDrawable = new UrlDrawable();
|
||||
if (container != null && container.get() != null) {
|
||||
Context context = container.get().getContext();
|
||||
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.ic_image);
|
||||
urlDrawable.setDrawable(drawable);
|
||||
container.get().setText(container.get().getText());
|
||||
container.get().invalidate();
|
||||
final GenericRequestBuilder load = Glide.with(context)
|
||||
.load(url)
|
||||
.dontAnimate();
|
||||
@ -66,4 +51,12 @@ public class DrawableGetter implements Html.ImageGetter, Drawable.Callback {
|
||||
@Override public void scheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable, long l) {}
|
||||
|
||||
@Override public void unscheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable) {}
|
||||
|
||||
public void clear(@NonNull DrawableGetter drawableGetter) {
|
||||
if (drawableGetter.cachedTargets != null) {
|
||||
for (GifBitmapTarget target : drawableGetter.cachedTargets) {
|
||||
Glide.clear(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,11 +7,10 @@ import android.view.ViewGroup;
|
||||
import com.fastaccess.data.dao.TimelineModel;
|
||||
import com.fastaccess.ui.adapter.callback.OnToggleView;
|
||||
import com.fastaccess.ui.adapter.callback.ReactionsCallback;
|
||||
import com.fastaccess.ui.adapter.viewholder.GroupedReviewsViewHolder;
|
||||
import com.fastaccess.ui.adapter.viewholder.IssueDetailsViewHolder;
|
||||
import com.fastaccess.ui.adapter.viewholder.IssueTimelineViewHolder;
|
||||
import com.fastaccess.ui.adapter.viewholder.PullStatusViewHolder;
|
||||
import com.fastaccess.ui.adapter.viewholder.ReviewsViewHolder;
|
||||
import com.fastaccess.ui.adapter.viewholder.ReviewCommentsViewHolder;
|
||||
import com.fastaccess.ui.adapter.viewholder.TimelineCommentsViewHolder;
|
||||
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.timeline.timeline.PullRequestTimelineMvp.ReviewCommentCallback;
|
||||
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
|
||||
@ -59,12 +58,14 @@ public class IssuePullsTimelineAdapter extends BaseRecyclerAdapter<TimelineModel
|
||||
return IssueTimelineViewHolder.newInstance(parent, this, isMerged);
|
||||
} else if (viewType == TimelineModel.STATUS) {
|
||||
return PullStatusViewHolder.newInstance(parent);
|
||||
} else if (viewType == TimelineModel.REVIEW) {
|
||||
return ReviewsViewHolder.newInstance(parent, this);
|
||||
} else if (viewType == TimelineModel.GROUPED_REVIEW) {
|
||||
return GroupedReviewsViewHolder.newInstance(parent, this, onToggleView, reactionsCallback,
|
||||
reviewCommentCallback, repoOwner, poster);
|
||||
} else if (viewType == TimelineModel.LINE_COMMENT) {
|
||||
return ReviewCommentsViewHolder.newInstance(parent, this, onToggleView, reactionsCallback, repoOwner, poster);
|
||||
// return ReviewsViewHolder.newInstance(parent, this);
|
||||
}
|
||||
// else if (viewType == TimelineModel.GROUPED_REVIEW) {
|
||||
// return GroupedReviewsViewHolder.newInstance(parent, this, onToggleView, reactionsCallback,
|
||||
// reviewCommentCallback, repoOwner, poster);
|
||||
// }
|
||||
return TimelineCommentsViewHolder.newInstance(parent, this, onToggleView, showEmojies,
|
||||
reactionsCallback, repoOwner, poster);
|
||||
}
|
||||
@ -77,11 +78,15 @@ public class IssuePullsTimelineAdapter extends BaseRecyclerAdapter<TimelineModel
|
||||
((IssueTimelineViewHolder) holder).bind(model);
|
||||
} else if (model.getType() == TimelineModel.COMMENT) {
|
||||
((TimelineCommentsViewHolder) holder).bind(model);
|
||||
} else if (model.getType() == TimelineModel.REVIEW) {
|
||||
((ReviewsViewHolder) holder).bind(model);
|
||||
} else if (model.getType() == TimelineModel.GROUPED_REVIEW) {
|
||||
((GroupedReviewsViewHolder) holder).bind(model);
|
||||
} else {
|
||||
} else if (model.getType() == TimelineModel.LINE_COMMENT) {
|
||||
((ReviewCommentsViewHolder) holder).bind(model.getReviewComment());
|
||||
}
|
||||
// else if (model.getType() == TimelineModel.REVIEW) {
|
||||
// ((ReviewsViewHolder) holder).bind(model);
|
||||
// } else if (model.getType() == TimelineModel.GROUPED_REVIEW) {
|
||||
// ((GroupedReviewsViewHolder) holder).bind(model);
|
||||
// }
|
||||
else {
|
||||
if (model.getStatus() != null) ((PullStatusViewHolder) holder).bind(model.getStatus());
|
||||
}
|
||||
if (model.getType() != TimelineModel.COMMENT) {
|
||||
|
||||
@ -7,11 +7,9 @@ import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.GroupedReviewModel;
|
||||
import com.fastaccess.data.dao.ReviewCommentModel;
|
||||
import com.fastaccess.data.dao.TimelineModel;
|
||||
import com.fastaccess.helper.ViewHelper;
|
||||
import com.fastaccess.ui.adapter.ReviewCommentsAdapter;
|
||||
import com.fastaccess.ui.adapter.callback.OnToggleView;
|
||||
import com.fastaccess.ui.adapter.callback.ReactionsCallback;
|
||||
import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.timeline.timeline.PullRequestTimelineMvp;
|
||||
@ -94,20 +92,20 @@ public class GroupedReviewsViewHolder extends BaseViewHolder<TimelineModel> impl
|
||||
}
|
||||
|
||||
@Override public void bind(@NonNull TimelineModel model) {
|
||||
GroupedReviewModel groupedReviewModel = model.getGroupedReview();
|
||||
this.pathText = groupedReviewModel.getDiffText();
|
||||
name.setText(groupedReviewModel.getPath());
|
||||
stateImage.setImageResource(R.drawable.ic_eye);
|
||||
if (groupedReviewModel.getComments() == null || groupedReviewModel.getComments().isEmpty()) {
|
||||
nestedRecyclerView.setVisibility(View.GONE);
|
||||
nestedRecyclerView.setAdapter(null);
|
||||
} else {
|
||||
nestedRecyclerView.setVisibility(View.VISIBLE);
|
||||
nestedRecyclerView.setAdapter(new ReviewCommentsAdapter(groupedReviewModel.getComments(), this,
|
||||
onToggleView, reactionsCallback, repoOwner, poster));
|
||||
nestedRecyclerView.addDivider();
|
||||
}
|
||||
onToggle(onToggleView.isCollapsed(getId()), false);
|
||||
// GroupedReviewModel groupedReviewModel = model.getGroupedReview();
|
||||
// this.pathText = groupedReviewModel.getDiffText();
|
||||
// name.setText(groupedReviewModel.getPath());
|
||||
// stateImage.setImageResource(R.drawable.ic_eye);
|
||||
// if (groupedReviewModel.getComments() == null || groupedReviewModel.getComments().isEmpty()) {
|
||||
// nestedRecyclerView.setVisibility(View.GONE);
|
||||
// nestedRecyclerView.setAdapter(null);
|
||||
// } else {
|
||||
// nestedRecyclerView.setVisibility(View.VISIBLE);
|
||||
// nestedRecyclerView.setAdapter(new ReviewCommentsAdapter(groupedReviewModel.getComments(), this,
|
||||
// onToggleView, reactionsCallback, repoOwner, poster));
|
||||
// nestedRecyclerView.addDivider();
|
||||
// }
|
||||
// onToggle(onToggleView.isCollapsed(getId()), false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,27 +1,21 @@
|
||||
package com.fastaccess.ui.adapter.viewholder;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.LabelModel;
|
||||
import com.fastaccess.data.dao.TimelineModel;
|
||||
import com.fastaccess.data.dao.model.IssueEvent;
|
||||
import com.fastaccess.data.dao.timeline.GenericEvent;
|
||||
import com.fastaccess.data.dao.types.IssueEventType;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.helper.Logger;
|
||||
import com.fastaccess.helper.ParseDateFormat;
|
||||
import com.fastaccess.provider.scheme.LinkParserHelper;
|
||||
import com.fastaccess.provider.timeline.TimelineProvider;
|
||||
import com.fastaccess.provider.timeline.handler.drawable.DrawableGetter;
|
||||
import com.fastaccess.ui.widgets.AvatarLayout;
|
||||
import com.fastaccess.ui.widgets.FontTextView;
|
||||
import com.fastaccess.ui.widgets.ForegroundImageView;
|
||||
import com.fastaccess.ui.widgets.LabelSpan;
|
||||
import com.fastaccess.ui.widgets.SpannableBuilder;
|
||||
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
|
||||
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
|
||||
|
||||
@ -48,7 +42,7 @@ public class IssueTimelineViewHolder extends BaseViewHolder<TimelineModel> {
|
||||
}
|
||||
|
||||
@Override public void bind(@NonNull TimelineModel timelineModel) {
|
||||
IssueEvent issueEventModel = timelineModel.getEvent();
|
||||
GenericEvent issueEventModel = timelineModel.getGenericEvent();
|
||||
IssueEventType event = issueEventModel.getEvent();
|
||||
if (issueEventModel.getAssignee() != null && issueEventModel.getAssigner() != null) {
|
||||
avatarLayout.setUrl(issueEventModel.getAssigner().getAvatarUrl(), issueEventModel.getAssigner().getLogin(),
|
||||
@ -57,35 +51,20 @@ public class IssueTimelineViewHolder extends BaseViewHolder<TimelineModel> {
|
||||
if (issueEventModel.getActor() != null) {
|
||||
avatarLayout.setUrl(issueEventModel.getActor().getAvatarUrl(), issueEventModel.getActor().getLogin(),
|
||||
false, LinkParserHelper.isEnterprise(issueEventModel.getUrl()));
|
||||
} else if (issueEventModel.getAuthor() != null) {
|
||||
avatarLayout.setUrl(issueEventModel.getAuthor().getAvatarUrl(), issueEventModel.getAuthor().getLogin(),
|
||||
false, LinkParserHelper.isEnterprise(issueEventModel.getUrl()));
|
||||
}
|
||||
}
|
||||
if (event != null) {
|
||||
stateImage.setContentDescription(event.name());
|
||||
stateImage.setImageResource(event.getIconResId());
|
||||
}
|
||||
if (issueEventModel.getLabels() == null || issueEventModel.getLabels().isEmpty()) {
|
||||
if (event != null) {
|
||||
stateText.setText(TimelineProvider.getStyledEvents(issueEventModel, itemView.getContext(), isMerged));
|
||||
} else {
|
||||
stateText.setText("");
|
||||
stateImage.setImageResource(R.drawable.ic_label);
|
||||
}
|
||||
if (event != null) {
|
||||
stateText.setText(TimelineProvider.getStyledEvents(issueEventModel, itemView.getContext(), isMerged));
|
||||
} else {
|
||||
if (event != null) {
|
||||
SpannableBuilder spannableBuilder = SpannableBuilder.builder();
|
||||
if (issueEventModel.getAssignee() != null && issueEventModel.getAssigner() != null) {
|
||||
spannableBuilder.bold(issueEventModel.getAssigner().getLogin(), new LabelSpan(Color.TRANSPARENT));
|
||||
} else if (issueEventModel.getActor() != null) {
|
||||
spannableBuilder.bold(issueEventModel.getActor().getLogin(), new LabelSpan(Color.TRANSPARENT));
|
||||
}
|
||||
spannableBuilder.append(" ").append(event.name().replaceAll("_", " "), new LabelSpan(Color.TRANSPARENT));
|
||||
for (LabelModel labelModel : issueEventModel.getLabels()) {
|
||||
TimelineProvider.appendLabels(labelModel, spannableBuilder);
|
||||
}
|
||||
spannableBuilder.append(" ").append(ParseDateFormat.getTimeAgo(issueEventModel.getCreatedAt()), new LabelSpan(Color.TRANSPARENT));
|
||||
stateText.setText(spannableBuilder);
|
||||
stateImage.setImageResource(R.drawable.ic_label);
|
||||
}
|
||||
stateText.setText("");
|
||||
stateImage.setImageResource(R.drawable.ic_label);
|
||||
}
|
||||
itemView.setEnabled(!InputHelper.isEmpty(issueEventModel.getCommitUrl()));
|
||||
}
|
||||
|
||||
@ -6,17 +6,11 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.ReviewModel;
|
||||
import com.fastaccess.data.dao.TimelineModel;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.helper.ParseDateFormat;
|
||||
import com.fastaccess.provider.scheme.LinkParserHelper;
|
||||
import com.fastaccess.provider.timeline.HtmlHelper;
|
||||
import com.fastaccess.provider.timeline.handler.drawable.DrawableGetter;
|
||||
import com.fastaccess.ui.widgets.AvatarLayout;
|
||||
import com.fastaccess.ui.widgets.FontTextView;
|
||||
import com.fastaccess.ui.widgets.ForegroundImageView;
|
||||
import com.fastaccess.ui.widgets.SpannableBuilder;
|
||||
import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
|
||||
import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
|
||||
|
||||
@ -44,31 +38,31 @@ public class ReviewsViewHolder extends BaseViewHolder<TimelineModel> {
|
||||
}
|
||||
|
||||
@Override public void bind(@NonNull TimelineModel model) {
|
||||
ReviewModel review = model.getReview();
|
||||
if (review != null) {
|
||||
if (review.getUser() != null) {
|
||||
avatarLayout.setUrl(review.getUser().getAvatarUrl(), review.getUser().getLogin(), false,
|
||||
LinkParserHelper.isEnterprise(review.getUser().getHtmlUrl()));
|
||||
} else {
|
||||
avatarLayout.setUrl(null, null, false, false);
|
||||
}
|
||||
if (review.getState() != null) {
|
||||
stateImage.setImageResource(review.getState().getDrawableRes());
|
||||
}
|
||||
if (review.getUser() != null) {
|
||||
stateText.setText(SpannableBuilder.builder().append(review.getUser().getLogin())
|
||||
.append(" ")
|
||||
.append(review.getState() != null ? stateText.getResources().getString(review.getState().getStringRes()) : "")
|
||||
.append(" ")
|
||||
.append(ParseDateFormat.getTimeAgo(review.getSubmittedAt())));
|
||||
}
|
||||
if (!InputHelper.isEmpty(review.getBody())) {
|
||||
body.setVisibility(View.VISIBLE);
|
||||
HtmlHelper.htmlIntoTextView(body, review.getBody());
|
||||
} else {
|
||||
body.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
// ReviewModel review = model.getReview();
|
||||
// if (review != null) {
|
||||
// if (review.getUser() != null) {
|
||||
// avatarLayout.setUrl(review.getUser().getAvatarUrl(), review.getUser().getLogin(), false,
|
||||
// LinkParserHelper.isEnterprise(review.getUser().getHtmlUrl()));
|
||||
// } else {
|
||||
// avatarLayout.setUrl(null, null, false, false);
|
||||
// }
|
||||
// if (review.getState() != null) {
|
||||
// stateImage.setImageResource(review.getState().getDrawableRes());
|
||||
// }
|
||||
// if (review.getUser() != null) {
|
||||
// stateText.setText(SpannableBuilder.builder().append(review.getUser().getLogin())
|
||||
// .append(" ")
|
||||
// .append(review.getState() != null ? stateText.getResources().getString(review.getState().getStringRes()) : "")
|
||||
// .append(" ")
|
||||
// .append(ParseDateFormat.getTimeAgo(review.getSubmittedAt())));
|
||||
// }
|
||||
// if (!InputHelper.isEmpty(review.getBody())) {
|
||||
// body.setVisibility(View.VISIBLE);
|
||||
// HtmlHelper.htmlIntoTextView(body, review.getBody());
|
||||
// } else {
|
||||
// body.setVisibility(View.GONE);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override protected void onViewIsDetaching() {
|
||||
|
||||
@ -22,6 +22,7 @@ import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.evernote.android.state.State;
|
||||
import com.evernote.android.state.StateSaver;
|
||||
import com.fastaccess.App;
|
||||
@ -70,7 +71,6 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
|
||||
@Nullable @BindView(R.id.drawer) public DrawerLayout drawer;
|
||||
@Nullable @BindView(R.id.extrasNav) public NavigationView extraNav;
|
||||
@Nullable @BindView(R.id.accountsNav) NavigationView accountsNav;
|
||||
@Nullable @BindView(R.id.adView) AdView adView;
|
||||
|
||||
@State Bundle presenterStateBundle = new Bundle();
|
||||
|
||||
@ -113,7 +113,6 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
|
||||
getPresenter().onRestoreInstanceState(presenterStateBundle);
|
||||
}
|
||||
setupToolbarAndStatusBar(toolbar);
|
||||
showHideAds();
|
||||
if (savedInstanceState == null) {
|
||||
if (getIntent() != null) {
|
||||
if (getIntent().getExtras() != null) {
|
||||
@ -201,10 +200,12 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
|
||||
|
||||
@Override public void onRequireLogin() {
|
||||
Toasty.warning(App.getInstance(), getString(R.string.unauthorized_user), Toast.LENGTH_LONG).show();
|
||||
Glide glide = Glide.get(this);
|
||||
glide.clearDiskCache();
|
||||
glide.clearMemory();
|
||||
PrefGetter.setToken(null);
|
||||
PrefGetter.setEnterpriseUrl(null);
|
||||
PrefGetter.setOtpCode(null);
|
||||
PrefGetter.setEnterpriseOtpCode(null);
|
||||
PrefGetter.resetEnterprise();
|
||||
Login.logout();
|
||||
Intent intent = new Intent(this, LoginChooserActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
@ -263,27 +264,6 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
|
||||
|
||||
@Override public void onScrollTop(int index) {}
|
||||
|
||||
@Override protected void onPause() {
|
||||
if (adView != null && adView.isShown()) {
|
||||
adView.pause();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
if (adView != null && adView.isShown()) {
|
||||
adView.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onDestroy() {
|
||||
if (adView != null && adView.isShown()) {
|
||||
adView.destroy();
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override public boolean isEnterprise() {
|
||||
return getPresenter() != null && getPresenter().isEnterprise();
|
||||
}
|
||||
@ -297,23 +277,6 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
|
||||
setTaskDescription(new ActivityManager.TaskDescription(name, null, ViewHelper.getPrimaryDarkColor(this)));
|
||||
}
|
||||
|
||||
protected void showHideAds() {
|
||||
if (adView != null) {
|
||||
boolean isAdsEnabled = PrefGetter.isAdsEnabled();
|
||||
if (isAdsEnabled) {
|
||||
adView.setVisibility(View.VISIBLE);
|
||||
MobileAds.initialize(this, getString(R.string.banner_ad_unit_id));
|
||||
AdRequest adRequest = new AdRequest.Builder()
|
||||
.addTestDevice(getString(R.string.test_device_id))
|
||||
.build();
|
||||
adView.loadAd(adRequest);
|
||||
} else {
|
||||
adView.destroy();
|
||||
adView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void selectHome(boolean hideRepo) {
|
||||
if (extraNav != null) {
|
||||
if (hideRepo) {
|
||||
|
||||
@ -101,7 +101,10 @@ public class BasePresenter<V extends BaseMvp.FAView> extends TiPresenter<V> impl
|
||||
manageDisposable(
|
||||
RxHelper.getObservable(observable)
|
||||
.doOnSubscribe(disposable -> onSubscribed(cancelable))
|
||||
.subscribe(onNext, this::onError, () -> apiCalled = true)
|
||||
.subscribe(onNext, this::onError, () -> {
|
||||
apiCalled = true;
|
||||
sendToView(BaseMvp.FAView::hideProgress);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import com.fastaccess.helper.RxHelper;
|
||||
import com.fastaccess.provider.rest.RestProvider;
|
||||
import com.fastaccess.provider.timeline.CommentsHelper;
|
||||
import com.fastaccess.provider.timeline.ReactionsProvider;
|
||||
import com.fastaccess.ui.base.mvp.BaseMvp;
|
||||
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -65,10 +66,12 @@ class CommitCommentsPresenter extends BasePresenter<CommitCommentsMvp.View> impl
|
||||
}
|
||||
setCurrentPage(page);
|
||||
makeRestCall(RestProvider.getRepoService(isEnterprise()).getCommitComments(login, repoId, sha, page)
|
||||
.flatMap(listResponse -> {
|
||||
lastPage = listResponse.getLast();
|
||||
return Observable.just(TimelineModel.construct(listResponse.getItems()));
|
||||
}), listResponse -> sendToView(view -> view.onNotifyAdapter(listResponse, page)));
|
||||
.flatMap(listResponse -> {
|
||||
lastPage = listResponse.getLast();
|
||||
return TimelineModel.construct(listResponse.getItems());
|
||||
})
|
||||
.doFinally(() -> sendToView(BaseMvp.FAView::hideProgress)),
|
||||
listResponse -> sendToView(view -> view.onNotifyAdapter(listResponse, page)));
|
||||
}
|
||||
|
||||
@Override public void onFragmentCreated(@Nullable Bundle bundle) {
|
||||
@ -103,7 +106,7 @@ class CommitCommentsPresenter extends BasePresenter<CommitCommentsMvp.View> impl
|
||||
@Override public void onWorkOffline() {
|
||||
if (comments.isEmpty()) {
|
||||
manageDisposable(RxHelper.getObservable(Comment.getCommitComments(repoId(), login(), sha).toObservable())
|
||||
.flatMap(comments -> Observable.just(TimelineModel.construct(comments)))
|
||||
.flatMap(TimelineModel::construct)
|
||||
.subscribe(models -> sendToView(view -> view.onNotifyAdapter(models, 1))));
|
||||
} else {
|
||||
sendToView(CommitCommentsMvp.View::hideProgress);
|
||||
|
||||
@ -12,8 +12,8 @@ import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.TimelineModel;
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.model.Issue;
|
||||
import com.fastaccess.data.dao.model.IssueEvent;
|
||||
import com.fastaccess.data.dao.model.Login;
|
||||
import com.fastaccess.data.dao.timeline.GenericEvent;
|
||||
import com.fastaccess.data.dao.types.ReactionTypes;
|
||||
import com.fastaccess.helper.ActivityHelper;
|
||||
import com.fastaccess.helper.BundleConstant;
|
||||
@ -22,6 +22,7 @@ import com.fastaccess.provider.rest.RestProvider;
|
||||
import com.fastaccess.provider.scheme.SchemeParser;
|
||||
import com.fastaccess.provider.timeline.CommentsHelper;
|
||||
import com.fastaccess.provider.timeline.ReactionsProvider;
|
||||
import com.fastaccess.provider.timeline.TimelineConverter;
|
||||
import com.fastaccess.ui.base.mvp.BaseMvp;
|
||||
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
|
||||
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueActivity;
|
||||
@ -77,7 +78,7 @@ import lombok.Getter;
|
||||
onHandleReaction(v.getId(), item.getComment().getId(), ReactionsProvider.COMMENT);
|
||||
}
|
||||
} else if (item.getType() == TimelineModel.EVENT) {
|
||||
IssueEvent issueEventModel = item.getEvent();
|
||||
GenericEvent issueEventModel = item.getGenericEvent();
|
||||
if (issueEventModel.getCommitUrl() != null) {
|
||||
SchemeParser.launchUri(v.getContext(), Uri.parse(issueEventModel.getCommitUrl()));
|
||||
}
|
||||
@ -215,22 +216,15 @@ import lombok.Getter;
|
||||
String login = parameter.getLogin();
|
||||
String repoId = parameter.getRepoId();
|
||||
int number = parameter.getNumber();
|
||||
Observable<List<TimelineModel>> observable;
|
||||
if (page > 1) {
|
||||
observable = RestProvider.getIssueService(isEnterprise()).getIssueComments(login, repoId, number, page)
|
||||
.map(comments -> {
|
||||
lastPage = comments != null ? comments.getLast() : 0;
|
||||
return TimelineModel.construct(comments != null ? comments.getItems() : null);
|
||||
});
|
||||
} else {
|
||||
observable = Observable.zip(RestProvider.getIssueService(isEnterprise()).getTimeline(login, repoId, number),
|
||||
RestProvider.getIssueService(isEnterprise()).getIssueComments(login, repoId, number, page),
|
||||
(issueEventPageable, commentPageable) -> {
|
||||
lastPage = commentPageable != null ? commentPageable.getLast() : 0;
|
||||
return TimelineModel.construct(commentPageable != null ? commentPageable.getItems() : null,
|
||||
issueEventPageable != null ? issueEventPageable.getItems() : null);
|
||||
});
|
||||
}
|
||||
makeRestCall(observable, models -> sendToView(view -> view.onNotifyAdapter(models, page)));
|
||||
Observable<List<TimelineModel>> observable = RestProvider.getIssueService(isEnterprise())
|
||||
.getTimeline(login, repoId, number, page)
|
||||
.flatMap(response -> {
|
||||
if (response != null) {
|
||||
lastPage = response.getLast();
|
||||
}
|
||||
return TimelineConverter.convert(response != null ? response.getItems() : null);
|
||||
}).toList()
|
||||
.toObservable();
|
||||
makeRestCall(observable, timeline -> sendToView(view -> view.onNotifyAdapter(timeline, page)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,16 +305,16 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
|
||||
@Override public void onRemoveReviewComment(int groupPosition, int commentPosition) {
|
||||
hideProgress();
|
||||
TimelineModel timelineModel = adapter.getItem(groupPosition);
|
||||
if (timelineModel != null && timelineModel.getGroupedReview() != null) {
|
||||
if (timelineModel.getGroupedReview().getComments() != null) {
|
||||
timelineModel.getGroupedReview().getComments().remove(commentPosition);
|
||||
if (timelineModel.getGroupedReview().getComments().isEmpty()) {
|
||||
adapter.removeItem(groupPosition);
|
||||
} else {
|
||||
adapter.notifyItemChanged(groupPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (timelineModel != null && timelineModel.getGroupedReview() != null) {
|
||||
// if (timelineModel.getGroupedReview().getComments() != null) {
|
||||
// timelineModel.getGroupedReview().getComments().remove(commentPosition);
|
||||
// if (timelineModel.getGroupedReview().getComments().isEmpty()) {
|
||||
// adapter.removeItem(groupPosition);
|
||||
// } else {
|
||||
// adapter.notifyItemChanged(groupPosition);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override public void onSetHeader(@NonNull TimelineModel timelineModel) {
|
||||
@ -336,6 +336,10 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
|
||||
onSetHeader(TimelineModel.constructHeader(getPullRequest()));
|
||||
}
|
||||
|
||||
@Override public void onAddStatus(@NonNull TimelineModel timelineModel) {
|
||||
adapter.addItem(timelineModel, 1);
|
||||
}
|
||||
|
||||
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
@ -372,21 +376,21 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
|
||||
return;
|
||||
}
|
||||
TimelineModel timelineModel = adapter.getItem(commentModel.getGroupPosition());
|
||||
if (isNew) {
|
||||
if (timelineModel.getGroupedReview() != null && timelineModel.getGroupedReview().getComments() != null) {
|
||||
timelineModel.getGroupedReview().getComments().add(commentModel.getCommentModel());
|
||||
adapter.notifyItemChanged(commentModel.getGroupPosition());
|
||||
} else {
|
||||
onRefresh();
|
||||
}
|
||||
} else {
|
||||
if (timelineModel.getGroupedReview() != null && timelineModel.getGroupedReview().getComments() != null) {
|
||||
timelineModel.getGroupedReview().getComments().set(commentModel.getCommentPosition(), commentModel.getCommentModel());
|
||||
adapter.notifyItemChanged(commentModel.getGroupPosition());
|
||||
} else {
|
||||
onRefresh();
|
||||
}
|
||||
}
|
||||
// if (isNew) {
|
||||
// if (timelineModel.getGroupedReview() != null && timelineModel.getGroupedReview().getComments() != null) {
|
||||
// timelineModel.getGroupedReview().getComments().add(commentModel.getCommentModel());
|
||||
// adapter.notifyItemChanged(commentModel.getGroupPosition());
|
||||
// } else {
|
||||
// onRefresh();
|
||||
// }
|
||||
// } else {
|
||||
// if (timelineModel.getGroupedReview() != null && timelineModel.getGroupedReview().getComments() != null) {
|
||||
// timelineModel.getGroupedReview().getComments().set(commentModel.getCommentPosition(), commentModel.getCommentModel());
|
||||
// adapter.notifyItemChanged(commentModel.getGroupPosition());
|
||||
// } else {
|
||||
// onRefresh();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
onRefresh(); // bundle size is too large? refresh the api
|
||||
|
||||
@ -69,6 +69,8 @@ public interface PullRequestTimelineMvp {
|
||||
@Nullable PullRequest getPullRequest();
|
||||
|
||||
void onUpdateHeader();
|
||||
|
||||
void onAddStatus(@NonNull TimelineModel timelineModel);
|
||||
}
|
||||
|
||||
interface Presenter extends BaseMvp.FAPresenter, BaseViewHolder.OnItemClickListener<TimelineModel>,
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.timeline.timeline;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
@ -10,11 +8,10 @@ import android.widget.PopupMenu;
|
||||
|
||||
import com.fastaccess.R;
|
||||
import com.fastaccess.data.dao.EditReviewCommentModel;
|
||||
import com.fastaccess.data.dao.GroupedReviewModel;
|
||||
import com.fastaccess.data.dao.PullRequestStatusModel;
|
||||
import com.fastaccess.data.dao.ReviewCommentModel;
|
||||
import com.fastaccess.data.dao.TimelineModel;
|
||||
import com.fastaccess.data.dao.model.Comment;
|
||||
import com.fastaccess.data.dao.model.IssueEvent;
|
||||
import com.fastaccess.data.dao.model.Login;
|
||||
import com.fastaccess.data.dao.model.PullRequest;
|
||||
import com.fastaccess.data.dao.types.ReactionTypes;
|
||||
@ -22,12 +19,11 @@ import com.fastaccess.helper.ActivityHelper;
|
||||
import com.fastaccess.helper.BundleConstant;
|
||||
import com.fastaccess.helper.InputHelper;
|
||||
import com.fastaccess.provider.rest.RestProvider;
|
||||
import com.fastaccess.provider.scheme.SchemeParser;
|
||||
import com.fastaccess.provider.timeline.CommentsHelper;
|
||||
import com.fastaccess.provider.timeline.ReactionsProvider;
|
||||
import com.fastaccess.provider.timeline.TimelineConverter;
|
||||
import com.fastaccess.ui.base.mvp.BaseMvp;
|
||||
import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
|
||||
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -46,99 +42,99 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
|
||||
private int lastPage = Integer.MAX_VALUE;
|
||||
|
||||
@Override public void onItemClick(int position, View v, TimelineModel item) {
|
||||
if (getView() != null && getView().getPullRequest() != null) {
|
||||
if (item.getType() == TimelineModel.COMMENT) {
|
||||
PullRequest pullRequest = getView().getPullRequest();
|
||||
if (v.getId() == R.id.commentMenu) {
|
||||
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
|
||||
popupMenu.inflate(R.menu.comments_menu);
|
||||
String username = Login.getUser().getLogin();
|
||||
boolean isOwner = CommentsHelper.isOwner(username, pullRequest.getLogin(), item.getComment().getUser().getLogin());
|
||||
popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
|
||||
popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
|
||||
popupMenu.setOnMenuItemClickListener(item1 -> {
|
||||
if (getView() == null) return false;
|
||||
if (item1.getItemId() == R.id.delete) {
|
||||
getView().onShowDeleteMsg(item.getComment().getId());
|
||||
} else if (item1.getItemId() == R.id.reply) {
|
||||
getView().onReply(item.getComment().getUser(), item.getComment().getBody());
|
||||
} else if (item1.getItemId() == R.id.edit) {
|
||||
getView().onEditComment(item.getComment());
|
||||
} else if (item1.getItemId() == R.id.share) {
|
||||
ActivityHelper.shareUrl(v.getContext(), item.getComment().getHtmlUrl());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
popupMenu.show();
|
||||
} else {
|
||||
onHandleReaction(v.getId(), item.getComment().getId(), ReactionsProvider.COMMENT);
|
||||
}
|
||||
} else if (item.getType() == TimelineModel.EVENT) {
|
||||
IssueEvent issueEventModel = item.getEvent();
|
||||
if (issueEventModel.getCommitUrl() != null) {
|
||||
SchemeParser.launchUri(v.getContext(), Uri.parse(issueEventModel.getCommitUrl()));
|
||||
}
|
||||
} else if (item.getType() == TimelineModel.HEADER) {
|
||||
if (v.getId() == R.id.commentMenu) {
|
||||
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
|
||||
popupMenu.inflate(R.menu.comments_menu);
|
||||
String username = Login.getUser().getLogin();
|
||||
boolean isOwner = CommentsHelper.isOwner(username, item.getPullRequest().getLogin(),
|
||||
item.getPullRequest().getUser().getLogin());
|
||||
popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
|
||||
popupMenu.setOnMenuItemClickListener(item1 -> {
|
||||
if (getView() == null) return false;
|
||||
if (item1.getItemId() == R.id.reply) {
|
||||
getView().onReply(item.getPullRequest().getUser(), item.getPullRequest().getBody());
|
||||
} else if (item1.getItemId() == R.id.edit) {
|
||||
Activity activity = ActivityHelper.getActivity(v.getContext());
|
||||
if (activity == null) return false;
|
||||
CreateIssueActivity.startForResult(activity,
|
||||
item.getPullRequest().getLogin(), item.getPullRequest().getRepoId(),
|
||||
item.getPullRequest(), isEnterprise());
|
||||
} else if (item1.getItemId() == R.id.share) {
|
||||
ActivityHelper.shareUrl(v.getContext(), item.getPullRequest().getHtmlUrl());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
popupMenu.show();
|
||||
} else {
|
||||
onHandleReaction(v.getId(), item.getPullRequest().getNumber(), ReactionsProvider.HEADER);
|
||||
}
|
||||
} else if (item.getType() == TimelineModel.GROUPED_REVIEW) {
|
||||
GroupedReviewModel reviewModel = item.getGroupedReview();
|
||||
if (v.getId() == R.id.addCommentPreview) {
|
||||
EditReviewCommentModel model = new EditReviewCommentModel();
|
||||
model.setCommentPosition(-1);
|
||||
model.setGroupPosition(position);
|
||||
model.setInReplyTo(reviewModel.getId());
|
||||
getView().onReplyOrCreateReview(null, null, position, -1, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (getView() != null && getView().getPullRequest() != null) {
|
||||
// if (item.getType() == TimelineModel.COMMENT) {
|
||||
// PullRequest pullRequest = getView().getPullRequest();
|
||||
// if (v.getId() == R.id.commentMenu) {
|
||||
// PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
|
||||
// popupMenu.inflate(R.menu.comments_menu);
|
||||
// String username = Login.getUser().getLogin();
|
||||
// boolean isOwner = CommentsHelper.isOwner(username, pullRequest.getLogin(), item.getComment().getUser().getLogin());
|
||||
// popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
|
||||
// popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
|
||||
// popupMenu.setOnMenuItemClickListener(item1 -> {
|
||||
// if (getView() == null) return false;
|
||||
// if (item1.getItemId() == R.id.delete) {
|
||||
// getView().onShowDeleteMsg(item.getComment().getId());
|
||||
// } else if (item1.getItemId() == R.id.reply) {
|
||||
// getView().onReply(item.getComment().getUser(), item.getComment().getBody());
|
||||
// } else if (item1.getItemId() == R.id.edit) {
|
||||
// getView().onEditComment(item.getComment());
|
||||
// } else if (item1.getItemId() == R.id.share) {
|
||||
// ActivityHelper.shareUrl(v.getContext(), item.getComment().getHtmlUrl());
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
// popupMenu.show();
|
||||
// } else {
|
||||
// onHandleReaction(v.getId(), item.getComment().getId(), ReactionsProvider.COMMENT);
|
||||
// }
|
||||
// } else if (item.getType() == TimelineModel.EVENT) {
|
||||
// IssueEvent issueEventModel = item.getEvent();
|
||||
// if (issueEventModel.getCommitUrl() != null) {
|
||||
// SchemeParser.launchUri(v.getContext(), Uri.parse(issueEventModel.getCommitUrl()));
|
||||
// }
|
||||
// } else if (item.getType() == TimelineModel.HEADER) {
|
||||
// if (v.getId() == R.id.commentMenu) {
|
||||
// PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
|
||||
// popupMenu.inflate(R.menu.comments_menu);
|
||||
// String username = Login.getUser().getLogin();
|
||||
// boolean isOwner = CommentsHelper.isOwner(username, item.getPullRequest().getLogin(),
|
||||
// item.getPullRequest().getUser().getLogin());
|
||||
// popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
|
||||
// popupMenu.setOnMenuItemClickListener(item1 -> {
|
||||
// if (getView() == null) return false;
|
||||
// if (item1.getItemId() == R.id.reply) {
|
||||
// getView().onReply(item.getPullRequest().getUser(), item.getPullRequest().getBody());
|
||||
// } else if (item1.getItemId() == R.id.edit) {
|
||||
// Activity activity = ActivityHelper.getActivity(v.getContext());
|
||||
// if (activity == null) return false;
|
||||
// CreateIssueActivity.startForResult(activity,
|
||||
// item.getPullRequest().getLogin(), item.getPullRequest().getRepoId(),
|
||||
// item.getPullRequest(), isEnterprise());
|
||||
// } else if (item1.getItemId() == R.id.share) {
|
||||
// ActivityHelper.shareUrl(v.getContext(), item.getPullRequest().getHtmlUrl());
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
// popupMenu.show();
|
||||
// } else {
|
||||
// onHandleReaction(v.getId(), item.getPullRequest().getNumber(), ReactionsProvider.HEADER);
|
||||
// }
|
||||
// } else if (item.getType() == TimelineModel.GROUPED_REVIEW) {
|
||||
// GroupedReviewModel reviewModel = item.getGroupedReview();
|
||||
// if (v.getId() == R.id.addCommentPreview) {
|
||||
// EditReviewCommentModel model = new EditReviewCommentModel();
|
||||
// model.setCommentPosition(-1);
|
||||
// model.setGroupPosition(position);
|
||||
// model.setInReplyTo(reviewModel.getId());
|
||||
// getView().onReplyOrCreateReview(null, null, position, -1, model);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override public void onItemLongClick(int position, View v, TimelineModel item) {
|
||||
if (getView() == null || getView().getPullRequest() == null) return;
|
||||
if (item.getType() == TimelineModel.COMMENT || item.getType() == TimelineModel.HEADER) {
|
||||
PullRequest pullRequest = getView().getPullRequest();
|
||||
String login = pullRequest.getLogin();
|
||||
String repoId = pullRequest.getRepoId();
|
||||
if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
|
||||
ReactionTypes type = ReactionTypes.get(v.getId());
|
||||
if (type != null) {
|
||||
if (item.getType() == TimelineModel.HEADER) {
|
||||
getView().showReactionsPopup(type, login, repoId, item.getPullRequest().getNumber(), ReactionsProvider.HEADER);
|
||||
} else {
|
||||
getView().showReactionsPopup(type, login, repoId, item.getComment().getId(), ReactionsProvider.COMMENT);
|
||||
}
|
||||
} else {
|
||||
onItemClick(position, v, item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onItemClick(position, v, item);
|
||||
}
|
||||
// if (getView() == null || getView().getPullRequest() == null) return;
|
||||
// if (item.getType() == TimelineModel.COMMENT || item.getType() == TimelineModel.HEADER) {
|
||||
// PullRequest pullRequest = getView().getPullRequest();
|
||||
// String login = pullRequest.getLogin();
|
||||
// String repoId = pullRequest.getRepoId();
|
||||
// if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
|
||||
// ReactionTypes type = ReactionTypes.get(v.getId());
|
||||
// if (type != null) {
|
||||
// if (item.getType() == TimelineModel.HEADER) {
|
||||
// getView().showReactionsPopup(type, login, repoId, item.getPullRequest().getNumber(), ReactionsProvider.HEADER);
|
||||
// } else {
|
||||
// getView().showReactionsPopup(type, login, repoId, item.getComment().getId(), ReactionsProvider.COMMENT);
|
||||
// }
|
||||
// } else {
|
||||
// onItemClick(position, v, item);
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onItemClick(position, v, item);
|
||||
// }
|
||||
}
|
||||
|
||||
@NonNull @Override public ArrayList<TimelineModel> getEvents() {
|
||||
@ -298,28 +294,23 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
|
||||
}
|
||||
|
||||
private void loadEverything(String login, String repoId, int number, @NonNull String sha, boolean isMergeable, int page) {
|
||||
Observable<List<TimelineModel>> observable;
|
||||
if (page > 1) {
|
||||
observable = RestProvider.getIssueService(isEnterprise()).getIssueComments(login, repoId, number, page)
|
||||
.map(comments -> {
|
||||
lastPage = comments != null ? comments.getLast() : 0;
|
||||
return TimelineModel.construct(comments != null ? comments.getItems() : null);
|
||||
});
|
||||
} else {
|
||||
observable = Observable.zip(RestProvider.getIssueService(isEnterprise()).getTimeline(login, repoId, number),
|
||||
RestProvider.getIssueService(isEnterprise()).getIssueComments(login, repoId, number, page),
|
||||
RestProvider.getPullRequestService(isEnterprise()).getPullStatus(login, repoId, sha),
|
||||
RestProvider.getReviewService(isEnterprise()).getReviews(login, repoId, number),
|
||||
RestProvider.getReviewService(isEnterprise()).getPrReviewComments(login, repoId, number),
|
||||
(issueEventPageable, commentPageable, statuses, reviews, reviewComments) -> {
|
||||
Observable<List<TimelineModel>> timeline = RestProvider.getIssueService(isEnterprise()).getTimeline(login, repoId, number, page)
|
||||
.flatMap(response -> {
|
||||
lastPage = response != null ? response.getLast() : 0;
|
||||
return TimelineConverter.convert(response != null ? response.getItems() : null);
|
||||
})
|
||||
.toList()
|
||||
.toObservable();
|
||||
if (page == 1) {
|
||||
Observable<PullRequestStatusModel> status = RestProvider.getPullRequestService(isEnterprise()).getPullStatus(login, repoId, sha)
|
||||
.map(statuses -> {
|
||||
if (statuses != null) {
|
||||
statuses.setMergable(isMergeable);
|
||||
}
|
||||
lastPage = commentPageable != null ? commentPageable.getLast() : 0;
|
||||
return TimelineModel.construct(commentPageable != null ? commentPageable.getItems() : null,
|
||||
issueEventPageable.getItems(), statuses, reviews.getItems(), reviewComments.getItems());
|
||||
return statuses;
|
||||
});
|
||||
makeRestCall(status.map(TimelineModel::new), timelineModel -> sendToView(view -> view.onAddStatus(timelineModel)));
|
||||
}
|
||||
makeRestCall(observable, models -> sendToView(view -> view.onNotifyAdapter(models, page)));
|
||||
makeRestCall(timeline, timelineModels -> sendToView(view -> view.onNotifyAdapter(timelineModels, page)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,15 +75,11 @@ public class AvatarLayout extends FrameLayout {
|
||||
this.isOrg = isOrg;
|
||||
this.isEnterprise = isEnterprise;
|
||||
avatar.setContentDescription(login);
|
||||
if (url != null) {
|
||||
if (login != null) {
|
||||
TooltipCompat.setTooltipText(avatar, login);
|
||||
}
|
||||
if (login != null) {
|
||||
TooltipCompat.setTooltipText(avatar, login);
|
||||
} else {
|
||||
avatar.setOnClickListener(null);
|
||||
if (login != null) {
|
||||
avatar.setOnLongClickListener(null);
|
||||
}
|
||||
avatar.setOnLongClickListener(null);
|
||||
}
|
||||
Glide.with(getContext())
|
||||
.load(url)
|
||||
@ -92,8 +88,7 @@ public class AvatarLayout extends FrameLayout {
|
||||
.dontAnimate()
|
||||
.into(avatar);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void setBackground() {
|
||||
if (PrefGetter.isRectAvatar()) {
|
||||
setBackgroundResource(R.drawable.rect_shape);
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="@dimen/spacing_xs_large"
|
||||
android:ellipsize="end"
|
||||
android:ellipsize="middle"
|
||||
android:maxLines="3"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:transitionName="@string/title_transition"
|
||||
|
||||
@ -1,45 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="enable_ads"
|
||||
android:icon="@drawable/ic_heart"
|
||||
android:title="@string/enable_ads"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="sent_via_enabled"
|
||||
android:icon="@drawable/ic_checkbox"
|
||||
android:key="sent_via_enabled"
|
||||
android:summary="@string/enable_signature_box_summary"
|
||||
android:title="@string/enable_signature_box"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="sent_via"
|
||||
android:icon="@drawable/ic_edit"
|
||||
android:key="sent_via"
|
||||
android:summary="@string/enable_signature_summary"
|
||||
android:title="@string/enable_signature"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="disable_auto_play_gif"
|
||||
android:icon="@drawable/ic_image"
|
||||
android:key="disable_auto_play_gif"
|
||||
android:summary="@string/disable_auto_gif_summary"
|
||||
android:title="@string/disable_auto_gif_title"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="wrap_code"
|
||||
android:icon="@drawable/ic_wrap_text"
|
||||
android:key="wrap_code"
|
||||
android:summary="@string/wrap_code_summary"
|
||||
android:title="@string/wrap_code_title"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="back_button"
|
||||
android:icon="@drawable/ic_back"
|
||||
android:key="back_button"
|
||||
android:summary="@string/back_button_summary"
|
||||
android:title="@string/back_button_title"/>
|
||||
|
||||
|
||||
@ -5,8 +5,7 @@ buildscript {
|
||||
butterKnifeVersion = '8.5.1'
|
||||
state_version = '1.1.0'
|
||||
lombokVersion = '1.12.6'
|
||||
supportVersion = "26.0.0-beta2"
|
||||
// supportVersion = "25.4.0"
|
||||
supportVersion = "26.0.0"
|
||||
gms = "11.0.2"
|
||||
thirtyinchVersion = '0.8.0'
|
||||
retrofit = '2.3.0'
|
||||
@ -24,10 +23,10 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.0-alpha7'
|
||||
classpath 'com.android.tools.build:gradle:3.0.0-alpha8'
|
||||
classpath 'com.google.gms:google-services:3.0.0'
|
||||
classpath 'com.novoda:gradle-build-properties-plugin:0.3'
|
||||
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
|
||||
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.2'
|
||||
classpath 'io.fabric.tools:gradle:1.22.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user