mirror of
https://github.com/k0shk0sh/FastHub.git
synced 2025-12-08 19:05:54 +00:00
270 lines
11 KiB
Java
270 lines
11 KiB
Java
package com.fastaccess.data.dao;
|
|
|
|
import android.graphics.Color;
|
|
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.types.IssueEventType;
|
|
import com.fastaccess.helper.ParseDateFormat;
|
|
import com.fastaccess.ui.widgets.LabelSpan;
|
|
import com.fastaccess.ui.widgets.SpannableBuilder;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import lombok.Getter;
|
|
import lombok.NoArgsConstructor;
|
|
import lombok.Setter;
|
|
|
|
/**
|
|
* 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 EVENT = 3;
|
|
public static final int COMMENT = 4;
|
|
|
|
private int type;
|
|
private Issue issue;
|
|
private Comment comment;
|
|
private IssueEvent event;
|
|
private PullRequest pullRequest;
|
|
private PullRequestStatusModel status;
|
|
private ReviewModel review;
|
|
private Date sortedDate;
|
|
|
|
private TimelineModel(Issue issue) {
|
|
this.type = HEADER;
|
|
this.issue = issue;
|
|
this.sortedDate = issue.getCreatedAt();
|
|
}
|
|
|
|
private TimelineModel(PullRequest pullRequest) {
|
|
this.type = HEADER;
|
|
this.pullRequest = pullRequest;
|
|
this.sortedDate = pullRequest.getCreatedAt();
|
|
}
|
|
|
|
private TimelineModel(Comment comment) {
|
|
this.type = COMMENT;
|
|
this.comment = comment;
|
|
this.sortedDate = comment.getCreatedAt() == null ? new Date() : comment.getCreatedAt();
|
|
}
|
|
|
|
private TimelineModel(IssueEvent event) {
|
|
this.type = EVENT;
|
|
this.event = event;
|
|
this.sortedDate = event.getCreatedAt();
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
@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(@NonNull List<Comment> commentList, @NonNull List<IssueEvent> eventList) {
|
|
ArrayList<TimelineModel> list = new ArrayList<>();
|
|
if (!commentList.isEmpty()) {
|
|
list.addAll(Stream.of(commentList)
|
|
.map(TimelineModel::new)
|
|
.collect(Collectors.toList()));
|
|
}
|
|
|
|
if (!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());
|
|
}
|
|
}).collect(Collectors.toList());
|
|
}
|
|
|
|
@NonNull public static List<TimelineModel> construct(@NonNull List<Comment> commentList, @NonNull List<IssueEvent> eventList,
|
|
@Nullable PullRequestStatusModel status, @Nullable List<ReviewModel> reviews) {
|
|
ArrayList<TimelineModel> list = new ArrayList<>();
|
|
if (status != null) {
|
|
list.add(new TimelineModel(status));
|
|
}
|
|
if (reviews != null && !reviews.isEmpty()) {
|
|
list.addAll(Stream.of(reviews)
|
|
.map(TimelineModel::new)
|
|
.collect(Collectors.toList()));
|
|
}
|
|
if (!commentList.isEmpty()) {
|
|
list.addAll(Stream.of(commentList)
|
|
.map(TimelineModel::new)
|
|
.collect(Collectors.toList()));
|
|
}
|
|
if (!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();
|
|
}));
|
|
for (List<IssueEvent> issueEvents : issueEventMap.values()) {
|
|
IssueEvent toAdd = null;
|
|
SpannableBuilder spannableBuilder = SpannableBuilder.builder();
|
|
for (IssueEvent issueEventModel : issueEvents) {
|
|
if (issueEventModel != null) {
|
|
IssueEventType event = issueEventModel.getEvent();
|
|
if (event != null) {
|
|
if (toAdd == null) {
|
|
toAdd = issueEventModel;
|
|
}
|
|
long time = toAdd.getCreatedAt().after(issueEventModel.getCreatedAt()) ? (toAdd.getCreatedAt().getTime() - issueEventModel
|
|
.getCreatedAt().getTime()) : (issueEventModel.getCreatedAt().getTime() - toAdd.getCreatedAt().getTime());
|
|
if (TimeUnit.MINUTES.toMinutes(time) <= 2 && toAdd.getEvent() == event) {
|
|
if (event == IssueEventType.labeled || event == IssueEventType.unlabeled) {
|
|
LabelModel labelModel = issueEventModel.getLabel();
|
|
int color = Color.parseColor("#" + labelModel.getColor());
|
|
spannableBuilder.append(" ")
|
|
.append(" " + labelModel.getName() + " ", new LabelSpan(color))
|
|
.append(" ");
|
|
} else if (event == IssueEventType.assigned || event == IssueEventType.unassigned) {
|
|
spannableBuilder.append(" ")
|
|
.bold(issueEventModel.getAssignee() != null ? issueEventModel.getAssignee().getLogin() : "",
|
|
new LabelSpan(Color.TRANSPARENT))
|
|
.append(" ");
|
|
}
|
|
} else {
|
|
models.add(new TimelineModel(issueEventModel));
|
|
}
|
|
} else {
|
|
models.add(new TimelineModel(issueEventModel));
|
|
}
|
|
}
|
|
}
|
|
if (toAdd != null) {
|
|
SpannableBuilder builder = SpannableBuilder.builder();
|
|
if (toAdd.getAssignee() != null && toAdd.getAssigner() != null) {
|
|
builder.bold(toAdd.getAssigner().getLogin(), new LabelSpan(Color.TRANSPARENT));
|
|
} else {
|
|
if (toAdd.getActor() != null) {
|
|
builder.bold(toAdd.getActor().getLogin(), new LabelSpan(Color.TRANSPARENT));
|
|
}
|
|
}
|
|
builder.append(" ")
|
|
.append(toAdd.getEvent().name().replaceAll("_", " "), new LabelSpan(Color.TRANSPARENT));
|
|
toAdd.setLabels(SpannableBuilder.builder()
|
|
.append(builder)
|
|
.append(spannableBuilder)
|
|
.append(" ")
|
|
.append(ParseDateFormat.getTimeAgo(toAdd.getCreatedAt()), new LabelSpan(Color.TRANSPARENT)));
|
|
models.add(new TimelineModel(toAdd));
|
|
}
|
|
}
|
|
return Stream.of(models)
|
|
.sortBy(timelineModel -> timelineModel.getEvent().getCreatedAt())
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@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.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.writeLong(this.sortedDate != null ? this.sortedDate.getTime() : -1);
|
|
}
|
|
|
|
protected TimelineModel(Parcel in) {
|
|
this.type = in.readInt();
|
|
this.issue = in.readParcelable(Issue.class.getClassLoader());
|
|
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());
|
|
long tmpSortedDate = in.readLong();
|
|
this.sortedDate = tmpSortedDate == -1 ? null : new Date(tmpSortedDate);
|
|
}
|
|
|
|
public static final Creator<TimelineModel> CREATOR = new Creator<TimelineModel>() {
|
|
@Override public TimelineModel createFromParcel(Parcel source) {return new TimelineModel(source);}
|
|
|
|
@Override public TimelineModel[] newArray(int size) {return new TimelineModel[size];}
|
|
};
|
|
}
|