/* Copyright 2017 Andrew Dawson * * This file is a part of Tusky. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along with Tusky; if not, * see . */ package com.keylesspalace.tusky.viewdata; import android.support.annotation.Nullable; import android.text.Spanned; import com.keylesspalace.tusky.entity.Attachment; import com.keylesspalace.tusky.entity.Card; 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. *

* Class to represent data required to display either a notification or a placeholder. * It is either a {@link StatusViewData.Concrete} or a {@link StatusViewData.Placeholder}. */ 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; private final boolean reblogged; private final boolean favourited; @Nullable private final String spoilerText; private final Status.Visibility visibility; private final List attachments; @Nullable private final String rebloggedByUsername; @Nullable private final String rebloggedAvatar; private final boolean isSensitive; private final boolean isExpanded; private final boolean isShowingContent; private final String userFullName; private final String nickname; private final String avatar; private final Date createdAt; private final int reblogsCount; private final int favouritesCount; @Nullable private final String inReplyToId; // I would rather have something else but it would be too much of a rewrite @Nullable private final Status.Mention[] mentions; private final String senderId; private final boolean rebloggingEnabled; private final Status.Application application; private final List statusEmojis; private final List accountEmojis; @Nullable private final Card card; public Concrete(String id, Spanned content, boolean reblogged, boolean favourited, @Nullable String spoilerText, Status.Visibility visibility, List attachments, @Nullable String rebloggedByUsername, @Nullable String rebloggedAvatar, boolean sensitive, boolean isExpanded, boolean isShowingContent, String userFullName, String nickname, String avatar, Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId, @Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled, Status.Application application, List statusEmojis, List accountEmojis, @Nullable Card card) { this.id = id; this.content = content; this.reblogged = reblogged; this.favourited = favourited; this.spoilerText = spoilerText; this.visibility = visibility; this.attachments = attachments; this.rebloggedByUsername = rebloggedByUsername; this.rebloggedAvatar = rebloggedAvatar; this.isSensitive = sensitive; this.isExpanded = isExpanded; this.isShowingContent = isShowingContent; this.userFullName = userFullName; this.nickname = nickname; this.avatar = avatar; this.createdAt = createdAt; this.reblogsCount = reblogsCount; this.favouritesCount = favouritesCount; this.inReplyToId = inReplyToId; this.mentions = mentions; this.senderId = senderId; this.rebloggingEnabled = rebloggingEnabled; this.application = application; this.statusEmojis = statusEmojis; this.accountEmojis = accountEmojis; this.card = card; } public String getId() { return id; } public Spanned getContent() { return content; } public boolean isReblogged() { return reblogged; } public boolean isFavourited() { return favourited; } @Nullable public String getSpoilerText() { return spoilerText; } public Status.Visibility getVisibility() { return visibility; } public List getAttachments() { return attachments; } @Nullable public String getRebloggedByUsername() { return rebloggedByUsername; } public boolean isSensitive() { return isSensitive; } public boolean isExpanded() { return isExpanded; } public boolean isShowingContent() { return isShowingContent; } @Nullable public String getRebloggedAvatar() { return rebloggedAvatar; } public String getUserFullName() { return userFullName; } public String getNickname() { return nickname; } public String getAvatar() { return avatar; } public Date getCreatedAt() { return createdAt; } public int getReblogsCount() { return reblogsCount; } public int getFavouritesCount() { return favouritesCount; } @Nullable public String getInReplyToId() { return inReplyToId; } public String getSenderId() { return senderId; } public Boolean getRebloggingEnabled() { return rebloggingEnabled; } @Nullable public Status.Mention[] getMentions() { return mentions; } public Status.Application getApplication() { return application; } public List getStatusEmojis() { return statusEmojis; } public List getAccountEmojis() { return accountEmojis; } @Nullable public Card getCard() { 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(statusEmojis, concrete.statusEmojis) && Objects.equals(accountEmojis, concrete.accountEmojis) && Objects.equals(card, concrete.card); } } public static final class Placeholder extends StatusViewData { private final boolean isLoading; private final long id; 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 { private String id; private Spanned content; private boolean reblogged; private boolean favourited; private String spoilerText; private Status.Visibility visibility; private List attachments; private String rebloggedByUsername; private String rebloggedAvatar; private boolean isSensitive; private boolean isExpanded; private boolean isShowingContent; private String userFullName; private String nickname; private String avatar; private Date createdAt; private int reblogsCount; private int favouritesCount; private String inReplyToId; private Status.Mention[] mentions; private String senderId; private boolean rebloggingEnabled; private Status.Application application; private List statusEmojis; private List accountEmojis; private Card card; public Builder() { } public Builder(final StatusViewData.Concrete viewData) { id = viewData.id; content = viewData.content; reblogged = viewData.reblogged; favourited = viewData.favourited; spoilerText = viewData.spoilerText; visibility = viewData.visibility; attachments = viewData.attachments == null ? null : new ArrayList<>(viewData.attachments); rebloggedByUsername = viewData.rebloggedByUsername; rebloggedAvatar = viewData.rebloggedAvatar; isSensitive = viewData.isSensitive; isExpanded = viewData.isExpanded; isShowingContent = viewData.isShowingContent; userFullName = viewData.userFullName; nickname = viewData.nickname; avatar = viewData.avatar; createdAt = new Date(viewData.createdAt.getTime()); reblogsCount = viewData.reblogsCount; favouritesCount = viewData.favouritesCount; inReplyToId = viewData.inReplyToId; mentions = viewData.mentions == null ? null : viewData.mentions.clone(); senderId = viewData.senderId; rebloggingEnabled = viewData.rebloggingEnabled; application = viewData.application; statusEmojis = viewData.getStatusEmojis(); accountEmojis = viewData.getAccountEmojis(); card = viewData.getCard(); } public Builder setId(String id) { this.id = id; return this; } public Builder setContent(Spanned content) { this.content = content; return this; } public Builder setReblogged(boolean reblogged) { this.reblogged = reblogged; return this; } public Builder setFavourited(boolean favourited) { this.favourited = favourited; return this; } public Builder setSpoilerText(String spoilerText) { this.spoilerText = spoilerText; return this; } public Builder setVisibility(Status.Visibility visibility) { this.visibility = visibility; return this; } public Builder setAttachments(List attachments) { this.attachments = attachments; return this; } public Builder setRebloggedByUsername(String rebloggedByUsername) { this.rebloggedByUsername = rebloggedByUsername; return this; } public Builder setRebloggedAvatar(String rebloggedAvatar) { this.rebloggedAvatar = rebloggedAvatar; return this; } public Builder setSensitive(boolean sensitive) { this.isSensitive = sensitive; return this; } public Builder setIsExpanded(boolean isExpanded) { this.isExpanded = isExpanded; return this; } public Builder setIsShowingSensitiveContent(boolean isShowingSensitiveContent) { this.isShowingContent = isShowingSensitiveContent; return this; } public Builder setUserFullName(String userFullName) { this.userFullName = userFullName; return this; } public Builder setNickname(String nickname) { this.nickname = nickname; return this; } public Builder setAvatar(String avatar) { this.avatar = avatar; return this; } public Builder setCreatedAt(Date createdAt) { this.createdAt = createdAt; return this; } public Builder setReblogsCount(int reblogsCount) { this.reblogsCount = reblogsCount; return this; } public Builder setFavouritesCount(int favouritesCount) { this.favouritesCount = favouritesCount; return this; } public Builder setInReplyToId(String inReplyToId) { this.inReplyToId = inReplyToId; return this; } public Builder setMentions(Status.Mention[] mentions) { this.mentions = mentions; return this; } public Builder setSenderId(String senderId) { this.senderId = senderId; return this; } public Builder setRebloggingEnabled(boolean rebloggingEnabled) { this.rebloggingEnabled = rebloggingEnabled; return this; } public Builder setApplication(Status.Application application) { this.application = application; return this; } public Builder setStatusEmojis(List emojis) { this.statusEmojis = emojis; return this; } public Builder setAccountEmojis(List emojis) { this.accountEmojis = emojis; return this; } public Builder setCard(Card card) { this.card = card; return this; } public StatusViewData.Concrete createStatusViewData() { if (this.statusEmojis == null) statusEmojis = Collections.emptyList(); if (this.accountEmojis == null) accountEmojis = Collections.emptyList(); if (this.createdAt == null) createdAt = new Date(); return new StatusViewData.Concrete(id, content, reblogged, favourited, spoilerText, visibility, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded, isShowingContent, userFullName, nickname, avatar, createdAt, reblogsCount, favouritesCount, inReplyToId, mentions, senderId, rebloggingEnabled, application, statusEmojis, accountEmojis, card); } } }