org.awesomeapp.messenger.ui.ConversationListItem.java Source code

Java tutorial

Introduction

Here is the source code for org.awesomeapp.messenger.ui.ConversationListItem.java

Source

/*
 * Copyright (C) 2007-2008 Esmertec AG. Copyright (C) 2007-2008 The Android Open
 * Source Project
 *
 * 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.awesomeapp.messenger.ui;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.v4.util.LruCache;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

import net.java.otr4j.session.SessionStatus;

import org.awesomeapp.messenger.ImApp;
import org.awesomeapp.messenger.crypto.IOtrChatSession;
import org.awesomeapp.messenger.model.Presence;
import org.awesomeapp.messenger.provider.Imps;
import org.awesomeapp.messenger.service.IChatSession;
import org.awesomeapp.messenger.service.IImConnection;
import org.awesomeapp.messenger.ui.legacy.DatabaseUtils;
import org.awesomeapp.messenger.ui.widgets.ConversationViewHolder;
import org.awesomeapp.messenger.ui.widgets.LetterAvatar;
import org.awesomeapp.messenger.ui.widgets.RoundedAvatarDrawable;
import org.awesomeapp.messenger.util.SecureMediaStore;
import org.awesomeapp.messenger.util.SystemServices;
import org.awesomeapp.messenger.util.SystemServices.FileInfo;
import org.ocpsoft.prettytime.PrettyTime;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Locale;

import im.zom.messenger.R;

public class ConversationListItem extends FrameLayout {
    public static final String[] CONTACT_PROJECTION = { Imps.Contacts._ID, Imps.Contacts.PROVIDER,
            Imps.Contacts.ACCOUNT, Imps.Contacts.USERNAME, Imps.Contacts.NICKNAME, Imps.Contacts.TYPE,
            Imps.Contacts.SUBSCRIPTION_TYPE, Imps.Contacts.SUBSCRIPTION_STATUS, Imps.Presence.PRESENCE_STATUS,
            Imps.Presence.PRESENCE_CUSTOM_STATUS, Imps.Chats.LAST_MESSAGE_DATE, Imps.Chats.LAST_UNREAD_MESSAGE,

    };

    public static final int COLUMN_CONTACT_ID = 0;
    public static final int COLUMN_CONTACT_PROVIDER = 1;
    public static final int COLUMN_CONTACT_ACCOUNT = 2;
    public static final int COLUMN_CONTACT_USERNAME = 3;
    public static final int COLUMN_CONTACT_NICKNAME = 4;
    public static final int COLUMN_CONTACT_TYPE = 5;
    public static final int COLUMN_SUBSCRIPTION_TYPE = 6;
    public static final int COLUMN_SUBSCRIPTION_STATUS = 7;
    public static final int COLUMN_CONTACT_PRESENCE_STATUS = 8;
    public static final int COLUMN_CONTACT_CUSTOM_STATUS = 9;
    public static final int COLUMN_LAST_MESSAGE_DATE = 10;
    public static final int COLUMN_LAST_MESSAGE = 11;

    static Drawable AVATAR_DEFAULT_GROUP = null;
    private PrettyTime sPrettyTime = null;

    public ConversationListItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        sPrettyTime = new PrettyTime(getCurrentLocale());
    }

    /**
        public void bind(ConversationViewHolder holder, Cursor cursor, String underLineText, boolean scrolling) {
    bind(holder, cursor, underLineText, true, scrolling);
        }
    */

    public void bind(ConversationViewHolder holder, long contactId, long providerId, long accountId, String address,
            String nickname, int contactType, String message, long messageDate, int presence, String underLineText,
            boolean showChatMsg, boolean scrolling) {

        //applyStyleColors(holder);

        if (nickname == null) {
            nickname = address.split("@")[0].split("\\.")[0];
        } else {
            nickname = nickname.split("@")[0].split("\\.")[0];
        }

        if (Imps.Contacts.TYPE_GROUP == contactType) {

            String groupCountString = getGroupCount(getContext().getContentResolver(), contactId);
            nickname += groupCountString;
        }

        if (!TextUtils.isEmpty(underLineText)) {
            // highlight/underline the word being searched 
            String lowercase = nickname.toLowerCase();
            int start = lowercase.indexOf(underLineText.toLowerCase());
            if (start >= 0) {
                int end = start + underLineText.length();
                SpannableString str = new SpannableString(nickname);
                str.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);

                holder.mLine1.setText(str);

            } else
                holder.mLine1.setText(nickname);

        } else
            holder.mLine1.setText(nickname);

        holder.mStatusIcon.setVisibility(View.GONE);

        if (holder.mAvatar != null) {
            if (Imps.Contacts.TYPE_GROUP == contactType) {

                holder.mAvatar.setVisibility(View.VISIBLE);

                if (AVATAR_DEFAULT_GROUP == null)
                    AVATAR_DEFAULT_GROUP = new RoundedAvatarDrawable(
                            BitmapFactory.decodeResource(getResources(), R.drawable.group_chat));

                holder.mAvatar.setImageDrawable(AVATAR_DEFAULT_GROUP);

            }
            //   else if (cursor.getColumnIndex(Imps.Contacts.AVATAR_DATA)!=-1)
            else {
                //                holder.mAvatar.setVisibility(View.GONE);

                Drawable avatar = null;

                try {
                    avatar = DatabaseUtils.getAvatarFromAddress(this.getContext().getContentResolver(), address,
                            ImApp.SMALL_AVATAR_WIDTH, ImApp.SMALL_AVATAR_HEIGHT);
                    // avatar = DatabaseUtils.getAvatarFromCursor(cursor, COLUMN_AVATAR_DATA, ImApp.SMALL_AVATAR_WIDTH, ImApp.SMALL_AVATAR_HEIGHT);
                } catch (Exception e) {
                    //problem decoding avatar
                    Log.e(ImApp.LOG_TAG, "error decoding avatar", e);
                }

                try {
                    if (avatar != null) {
                        //if (avatar instanceof RoundedAvatarDrawable)
                        //  setAvatarBorder(presence,(RoundedAvatarDrawable)avatar);

                        holder.mAvatar.setImageDrawable(avatar);
                    } else {
                        // int color = getAvatarBorder(presence);
                        int padding = 24;
                        LetterAvatar lavatar = new LetterAvatar(getContext(), nickname, padding);

                        holder.mAvatar.setImageDrawable(lavatar);

                    }

                    holder.mAvatar.setVisibility(View.VISIBLE);
                } catch (OutOfMemoryError ome) {
                    //this seems to happen now and then even on tiny images; let's catch it and just not set an avatar
                }

            }
        }

        if (showChatMsg && message != null) {

            if (holder.mLine2 != null) {
                if (SecureMediaStore.isVfsUri(message)) {
                    FileInfo fInfo = SystemServices.getFileInfoFromURI(getContext(), Uri.parse(message));

                    if (fInfo.type == null || fInfo.type.startsWith("image")) {

                        if (holder.mMediaThumb != null) {
                            holder.mMediaThumb.setVisibility(View.VISIBLE);

                            if (fInfo.type != null && fInfo.type.equals("image/png")) {
                                holder.mMediaThumb.setScaleType(ImageView.ScaleType.FIT_CENTER);
                            } else {
                                holder.mMediaThumb.setScaleType(ImageView.ScaleType.CENTER_CROP);

                            }

                            setThumbnail(getContext().getContentResolver(), holder, Uri.parse(message));

                            holder.mLine2.setVisibility(View.GONE);

                        }
                    } else {
                        holder.mLine2.setText("");
                    }

                } else if ((!TextUtils.isEmpty(message)) && message.startsWith("/")) {
                    String cmd = message.toString().substring(1);

                    if (cmd.startsWith("sticker")) {
                        String[] cmds = cmd.split(":");

                        String mimeTypeSticker = "image/png";
                        Uri mediaUri = Uri.parse("asset://" + cmds[1]);

                        setThumbnail(getContext().getContentResolver(), holder, mediaUri);
                        holder.mLine2.setVisibility(View.GONE);

                        holder.mMediaThumb.setScaleType(ImageView.ScaleType.FIT_CENTER);

                    }

                } else if ((!TextUtils.isEmpty(message)) && message.startsWith(":")) {
                    String[] cmds = message.split(":");

                    try {
                        String[] stickerParts = cmds[1].split("-");
                        String stickerPath = "stickers/" + stickerParts[0].toLowerCase() + "/"
                                + stickerParts[1].toLowerCase() + ".png";

                        //make sure sticker exists
                        AssetFileDescriptor afd = getContext().getAssets().openFd(stickerPath);
                        afd.getLength();
                        afd.close();

                        //now setup the new URI for loading local sticker asset
                        Uri mediaUri = Uri.parse("asset://localhost/" + stickerPath);
                        setThumbnail(getContext().getContentResolver(), holder, mediaUri);
                        holder.mLine2.setVisibility(View.GONE);
                        holder.mMediaThumb.setScaleType(ImageView.ScaleType.FIT_CENTER);

                    } catch (Exception e) {

                    }
                } else {
                    if (holder.mMediaThumb != null)
                        holder.mMediaThumb.setVisibility(View.GONE);

                    holder.mLine2.setVisibility(View.VISIBLE);

                    try {
                        holder.mLine2.setText(android.text.Html.fromHtml(message).toString());
                    } catch (RuntimeException re) {
                    }
                }
            }

            if (messageDate != -1) {
                Date dateLast = new Date(messageDate);
                holder.mStatusText.setText(sPrettyTime.format(dateLast));

            } else {
                holder.mStatusText.setText("");
            }

        } else if (holder.mLine2 != null) {
            holder.mLine2.setText(address);

            if (holder.mMediaThumb != null)
                holder.mMediaThumb.setVisibility(View.GONE);
        }

        holder.mLine1.setVisibility(View.VISIBLE);

        if (providerId != -1)
            getEncryptionState(providerId, accountId, address, holder);
    }

    private void getEncryptionState(long providerId, long accountId, String address,
            ConversationViewHolder holder) {

        try {

            ImApp app = ((ImApp) ((Activity) getContext()).getApplication());

            IImConnection conn = app.getConnection(providerId, accountId);
            if (conn == null || conn.getChatSessionManager() == null)
                return;

            IChatSession chatSession = conn.getChatSessionManager().getChatSession(address);

            if (chatSession != null) {
                IOtrChatSession otrChatSession = chatSession.getDefaultOtrChatSession();
                if (otrChatSession != null) {
                    SessionStatus chatStatus = SessionStatus.values()[otrChatSession.getChatStatus()];

                    if (chatStatus == SessionStatus.ENCRYPTED) {
                        boolean isVerified = otrChatSession.isKeyVerified(address);
                        // holder.mStatusIcon.setImageDrawable(getResources().getDrawable(R.drawable.ic_lock_outline_black_18dp));
                        holder.mStatusIcon
                                .setImageDrawable(getResources().getDrawable(R.drawable.ic_encrypted_grey));
                        holder.mStatusIcon.setVisibility(View.VISIBLE);
                    }
                }
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //mCurrentChatSession.getOtrChatSession();

    }

    /**
    public void setAvatarBorder(int status, RoundedAvatarDrawable avatar) {
    switch (status) {
    case Presence.AVAILABLE:
        avatar.setBorderColor(getResources().getColor(R.color.holo_green_light));
        break;
        
    case Presence.IDLE:
        avatar.setBorderColor(getResources().getColor(R.color.holo_green_dark));
        
        break;
        
    case Presence.AWAY:
        avatar.setBorderColor(getResources().getColor(R.color.holo_orange_light));
        break;
        
    case Presence.DO_NOT_DISTURB:
        avatar.setBorderColor(getResources().getColor(R.color.holo_red_dark));
        
        break;
        
    case Presence.OFFLINE:
        avatar.setBorderColor(getResources().getColor(android.R.color.transparent));
        break;
        
        
    default:
    }
    }**/

    public int getAvatarBorder(int status) {
        switch (status) {
        case Presence.AVAILABLE:
            return (getResources().getColor(R.color.holo_green_light));

        case Presence.IDLE:
            return (getResources().getColor(R.color.holo_green_dark));
        case Presence.AWAY:
            return (getResources().getColor(R.color.holo_orange_light));

        case Presence.DO_NOT_DISTURB:
            return (getResources().getColor(R.color.holo_red_dark));

        case Presence.OFFLINE:
            return (getResources().getColor(R.color.holo_grey_dark));

        default:
        }

        return Color.TRANSPARENT;
    }

    private Uri mLastMediaUri = null;

    /**
     * @param contentResolver
     * @param aHolder
     * @param mediaUri
     */
    private void setThumbnail(final ContentResolver contentResolver, final ConversationViewHolder aHolder,
            final Uri mediaUri) {

        if (mLastMediaUri != null && mLastMediaUri.getPath().equals(mediaUri.getPath()))
            return;

        mLastMediaUri = mediaUri;

        Glide.clear(aHolder.mMediaThumb);

        if (SecureMediaStore.isVfsUri(mediaUri)) {
            info.guardianproject.iocipher.File fileMedia = new info.guardianproject.iocipher.File(
                    mediaUri.getPath());
            if (fileMedia.exists()) {
                try {
                    Glide.with(getContext()).load(new info.guardianproject.iocipher.FileInputStream(fileMedia))
                            .diskCacheStrategy(DiskCacheStrategy.NONE).into(aHolder.mMediaThumb);
                } catch (Exception e) {
                    Log.e(ImApp.LOG_TAG, "unable to load thumbnail", e);
                }
            }
        } else if (mediaUri.getScheme().equals("asset")) {
            String assetPath = "file:///android_asset/" + mediaUri.getPath().substring(1);
            Glide.with(getContext()).load(assetPath).diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(aHolder.mMediaThumb);
        } else {
            Glide.with(getContext()).load(mediaUri).into(aHolder.mMediaThumb);
        }

    }

    private String getGroupCount(ContentResolver resolver, long groupId) {
        String[] projection = { Imps.GroupMembers.NICKNAME };
        Uri uri = ContentUris.withAppendedId(Imps.GroupMembers.CONTENT_URI, groupId);
        Cursor c = resolver.query(uri, projection, null, null, null);
        StringBuilder buf = new StringBuilder();
        if (c != null) {

            buf.append(" (");
            buf.append(c.getCount());
            buf.append(")");

            c.close();
        }

        return buf.toString();
    }

    /**
    public void applyStyleColors (ConversationViewHolder holder)
    {
    //not set color
    final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getContext());
    int themeColorHeader = settings.getInt("themeColor",-1);
    int themeColorText = settings.getInt("themeColorText",-1);
    int themeColorBg = settings.getInt("themeColorBg",-1);
        
        
    if (themeColorText != -1)
    {
        if (holder.mLine1 != null)
            holder.mLine1.setTextColor(themeColorText);
        
        if (holder.mLine2 != null)
            holder.mLine2.setTextColor(themeColorText);
        
        //holder.mLine2.setTextColor(darker(themeColorText,2.0f));
        
    }
        
    }*/

    /**
     * Returns darker version of specified <code>color</code>.
     */
    public static int darker(int color, float factor) {
        int a = Color.alpha(color);
        int r = Color.red(color);
        int g = Color.green(color);
        int b = Color.blue(color);

        return Color.argb(a, Math.max((int) (r * factor), 0), Math.max((int) (g * factor), 0),
                Math.max((int) (b * factor), 0));
    }

    @TargetApi(Build.VERSION_CODES.N)
    public Locale getCurrentLocale() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return getResources().getConfiguration().getLocales().get(0);
        } else {
            //noinspection deprecation
            return getResources().getConfiguration().locale;
        }
    }
}