org.andstatus.app.msg.MessageViewItem.java Source code

Java tutorial

Introduction

Here is the source code for org.andstatus.app.msg.MessageViewItem.java

Source

/*
 * Copyright (c) 2016 yvolk (Yuri Volkov), http://yurivolkov.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.andstatus.app.msg;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import org.andstatus.app.R;
import org.andstatus.app.account.MyAccount;
import org.andstatus.app.context.MyContext;
import org.andstatus.app.context.MyContextHolder;
import org.andstatus.app.data.AttachedImageFile;
import org.andstatus.app.data.AvatarFile;
import org.andstatus.app.data.DownloadStatus;
import org.andstatus.app.util.I18n;
import org.andstatus.app.util.MyHtml;
import org.andstatus.app.util.RelativeTime;
import org.andstatus.app.util.SharedPreferencesUtil;
import org.andstatus.app.widget.DuplicatesCollapsible;
import org.andstatus.app.widget.DuplicationLink;
import org.apache.commons.lang3.StringEscapeUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class MessageViewItem implements DuplicatesCollapsible<MessageViewItem> {
    public static final int MIN_LENGTH_TO_COMPARE = 5;
    private MyContext myContext = MyContextHolder.get();
    long createdDate = 0;
    long sentDate = 0;

    DownloadStatus msgStatus = DownloadStatus.UNKNOWN;

    private long mMsgId;
    private long originId;

    String authorName = "";
    long authorId = 0;

    String recipientName = "";

    long inReplyToMsgId = 0;
    long inReplyToUserId = 0;
    String inReplyToName = "";

    String messageSource = "";

    String body = "";

    boolean favorited = false;
    Map<Long, String> rebloggers = new HashMap<>();
    boolean reblogged = false;

    AttachedImageFile attachedImageFile = AttachedImageFile.EMPTY;
    protected Drawable avatarDrawable = null;

    /** A message can be linked to any user, MyAccount or not */
    private long linkedUserId = 0;
    private MyAccount linkedMyAccount = MyAccount.getEmpty();

    private List<TimelineViewItem> children = new ArrayList<>();

    @NonNull
    public MyContext getMyContext() {
        return myContext;
    }

    public void setMyContext(MyContext myContext) {
        this.myContext = myContext;
    }

    long getMsgId() {
        return mMsgId;
    }

    void setMsgId(long mMsgId) {
        this.mMsgId = mMsgId;
    }

    public long getOriginId() {
        return originId;
    }

    void setOriginId(long originId) {
        this.originId = originId;
    }

    public long getLinkedUserId() {
        return linkedUserId;
    }

    public void setLinkedUserAndAccount(long linkedUserId) {
        this.linkedUserId = linkedUserId;
        linkedMyAccount = getMyContext().persistentAccounts().fromUserId(linkedUserId);
        if (!linkedMyAccount.isValid()) {
            linkedMyAccount = getMyContext().persistentAccounts().getFirstSucceededForOriginId(originId);
        }
    }

    public MyAccount getLinkedMyAccount() {
        return linkedMyAccount;
    }

    public boolean isLinkedToMyAccount() {
        return linkedUserId != 0 && linkedMyAccount.getUserId() == linkedUserId;
    }

    protected void setCollapsedStatus(Context context, StringBuilder messageDetails) {
        if (isCollapsed()) {
            I18n.appendWithSpace(messageDetails, "(+" + children.size() + ")");
        }
    }

    public void collapse(TimelineViewItem child) {
        this.children.addAll(child.getChildren());
        child.getChildren().clear();
        this.children.add(child);
    }

    public boolean isCollapsed() {
        return !children.isEmpty();
    }

    public List<TimelineViewItem> getChildren() {
        return children;
    }

    @Override
    public DuplicationLink duplicates(MessageViewItem other) {
        DuplicationLink link = DuplicationLink.NONE;
        if (other == null) {
            return link;
        }
        if (getMsgId() == other.getMsgId()) {
            link = duplicatesByFavoritedAndReblogged(other);
        }
        if (link == DuplicationLink.NONE) {
            if (Math.abs(createdDate - other.createdDate) < TimeUnit.HOURS.toMillis(24)) {
                String thisBody = getCleanedBody(body);
                String otherBody = getCleanedBody(other.body);
                if (thisBody.length() < MIN_LENGTH_TO_COMPARE || otherBody.length() < MIN_LENGTH_TO_COMPARE) {
                    // Too short to compare
                } else if (thisBody.equals(otherBody)) {
                    if (createdDate == other.createdDate) {
                        link = duplicatesByFavoritedAndReblogged(other);
                    } else if (createdDate < other.createdDate) {
                        link = DuplicationLink.IS_DUPLICATED;
                    } else {
                        link = DuplicationLink.DUPLICATES;
                    }
                } else if (thisBody.contains(otherBody)) {
                    link = DuplicationLink.DUPLICATES;
                } else if (otherBody.contains(thisBody)) {
                    link = DuplicationLink.IS_DUPLICATED;
                }
            }
        }
        return link;
    }

    @NonNull
    private String getCleanedBody(String body) {
        String out = MyHtml.fromHtml(body).toLowerCase();
        out = StringEscapeUtils.unescapeHtml4(out);
        return out.replaceAll("\n", " ").replaceAll("  ", " ").replaceFirst(".*(favorited something by.*)", "$1");
    }

    private DuplicationLink duplicatesByFavoritedAndReblogged(MessageViewItem other) {
        DuplicationLink link;
        if (favorited != other.favorited) {
            link = favorited ? DuplicationLink.IS_DUPLICATED : DuplicationLink.DUPLICATES;
        } else if (reblogged != other.reblogged) {
            link = reblogged ? DuplicationLink.IS_DUPLICATED : DuplicationLink.DUPLICATES;
        } else if (!getLinkedMyAccount().equals(other.getLinkedMyAccount())) {
            link = getLinkedMyAccount().compareTo(other.getLinkedMyAccount()) <= 0 ? DuplicationLink.IS_DUPLICATED
                    : DuplicationLink.DUPLICATES;
        } else {
            link = rebloggers.size() > other.rebloggers.size() ? DuplicationLink.IS_DUPLICATED
                    : DuplicationLink.DUPLICATES;
        }
        return link;
    }

    public boolean isReblogged() {
        return !rebloggers.isEmpty();
    }

    public StringBuilder getDetails(Context context) {
        StringBuilder messageDetails = new StringBuilder(RelativeTime.getDifference(context, createdDate));
        setInReplyTo(context, messageDetails);
        setRecipientName(context, messageDetails);
        setMessageSource(context, messageDetails);
        setMessageStatus(context, messageDetails);
        setCollapsedStatus(context, messageDetails);
        return messageDetails;
    }

    protected void setInReplyTo(Context context, StringBuilder messageDetails) {
        if (inReplyToMsgId != 0 && TextUtils.isEmpty(inReplyToName)) {
            inReplyToName = "...";
        }
        if (!TextUtils.isEmpty(inReplyToName)) {
            messageDetails.append(" ").append(
                    String.format(context.getText(R.string.message_source_in_reply_to).toString(), inReplyToName));
        }
    }

    private void setRecipientName(Context context, StringBuilder messageDetails) {
        if (!TextUtils.isEmpty(recipientName)) {
            messageDetails.append(
                    " " + String.format(context.getText(R.string.message_source_to).toString(), recipientName));
        }
    }

    private void setMessageSource(Context context, StringBuilder messageDetails) {
        if (!SharedPreferencesUtil.isEmpty(messageSource) && !"ostatus".equals(messageSource)
                && !"unknown".equals(messageSource)) {
            messageDetails.append(
                    " " + String.format(context.getText(R.string.message_source_from).toString(), messageSource));
        }
    }

    private void setMessageStatus(Context context, StringBuilder messageDetails) {
        if (msgStatus != DownloadStatus.LOADED) {
            messageDetails.append(" (").append(msgStatus.getTitle(context)).append(")");
        }
    }

    @NonNull
    public Drawable getAvatar() {
        return avatarDrawable == null ? AvatarFile.getDefaultDrawable() : avatarDrawable;
    }

    public AttachedImageFile getAttachedImageFile() {
        return attachedImageFile;
    }
}