Add EventHub, add fav, reblog events, improve timelines (#562)

* Add AppStore, add fav, reblog events

* Add events, add handling to Timeline

* Add event handling to Notifications

* Mostly finish events

* Fix unsubscribing

* Cleanup timeline

* Fix newStatusEvent in thread, fix deleteEvent

* Insert new toots only in specific timelines

* Add missing else

* Rename AppStore to EventHub

* Fix tests

* Use DiffUtils for timeline

* Fix empty timeline bug. Improve loading placeholder

* Fix AsyncListDiff, loading indicator, "load more"

* Timeline fixes & improvements.

Fix infinite loading. Remove spinner correctly.
Don't refresh timeline without need.
This commit is contained in:
Ivan Kupalov 2018-05-27 11:22:12 +03:00 committed by GitHub
commit 3756a1fd20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 1064 additions and 542 deletions

View file

@ -24,9 +24,11 @@ import com.keylesspalace.tusky.entity.Emoji;
import com.keylesspalace.tusky.entity.Status;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* Created by charlag on 11/07/2017.
@ -40,6 +42,10 @@ public abstract class StatusViewData {
private StatusViewData() {
}
public abstract long getViewDataId();
public abstract boolean deepEquals(StatusViewData other);
public static final class Concrete extends StatusViewData {
private final String id;
private final Spanned content;
@ -214,18 +220,84 @@ public abstract class StatusViewData {
return card;
}
@Override public long getViewDataId() {
// Chance of collision is super low and impact of mistake is low as well
return getId().hashCode();
}
public boolean deepEquals(StatusViewData o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Concrete concrete = (Concrete) o;
return reblogged == concrete.reblogged &&
favourited == concrete.favourited &&
isSensitive == concrete.isSensitive &&
isExpanded == concrete.isExpanded &&
isShowingContent == concrete.isShowingContent &&
reblogsCount == concrete.reblogsCount &&
favouritesCount == concrete.favouritesCount &&
rebloggingEnabled == concrete.rebloggingEnabled &&
Objects.equals(id, concrete.id) &&
Objects.equals(content, concrete.content) &&
Objects.equals(spoilerText, concrete.spoilerText) &&
visibility == concrete.visibility &&
Objects.equals(attachments, concrete.attachments) &&
Objects.equals(rebloggedByUsername, concrete.rebloggedByUsername) &&
Objects.equals(rebloggedAvatar, concrete.rebloggedAvatar) &&
Objects.equals(userFullName, concrete.userFullName) &&
Objects.equals(nickname, concrete.nickname) &&
Objects.equals(avatar, concrete.avatar) &&
Objects.equals(createdAt, concrete.createdAt) &&
Objects.equals(inReplyToId, concrete.inReplyToId) &&
Arrays.equals(mentions, concrete.mentions) &&
Objects.equals(senderId, concrete.senderId) &&
Objects.equals(application, concrete.application) &&
Objects.equals(emojis, concrete.emojis) &&
Objects.equals(card, concrete.card);
}
}
public static final class Placeholder extends StatusViewData {
private final boolean isLoading;
private final long id;
public Placeholder(boolean isLoading) {
public Placeholder(long id, boolean isLoading) {
this.id = id;
this.isLoading = isLoading;
}
public boolean isLoading() {
return isLoading;
}
public long getId() {
return id;
}
@Override public long getViewDataId() {
return id;
}
@Override public boolean deepEquals(StatusViewData other) {
if (!(other instanceof Placeholder)) return false;
Placeholder that = (Placeholder) other;
return isLoading == that.isLoading && id == that.id;
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Placeholder that = (Placeholder) o;
return deepEquals(that);
}
@Override public int hashCode() {
int result = (isLoading ? 1 : 0);
result = 31 * result + (int) (id ^ (id >>> 32));
return result;
}
}
public static class Builder {