/*
* 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 info.guardianproject.otr.app.im.app;
import info.guardianproject.otr.IOtrChatSession;
import info.guardianproject.otr.app.im.IChatSession;
import info.guardianproject.otr.app.im.IImConnection;
import info.guardianproject.otr.app.im.R;
import info.guardianproject.otr.app.im.engine.Presence;
import info.guardianproject.otr.app.im.provider.Imps;
import info.guardianproject.otr.app.im.ui.LetterAvatar;
import info.guardianproject.otr.app.im.ui.RoundedAvatarDrawable;
import info.guardianproject.util.SystemServices;
import info.guardianproject.util.SystemServices.FileInfo;
import net.java.otr4j.session.SessionStatus;
import android.app.Activity;
import android.content.Context;
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.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;
public class ContactView extends FrameLayout {
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,
Imps.Contacts.AVATAR_HASH,
Imps.Contacts.AVATAR_DATA
};
static final int COLUMN_CONTACT_ID = 0;
static final int COLUMN_CONTACT_PROVIDER = 1;
static final int COLUMN_CONTACT_ACCOUNT = 2;
static final int COLUMN_CONTACT_USERNAME = 3;
static final int COLUMN_CONTACT_NICKNAME = 4;
static final int COLUMN_CONTACT_TYPE = 5;
static final int COLUMN_SUBSCRIPTION_TYPE = 6;
static final int COLUMN_SUBSCRIPTION_STATUS = 7;
static final int COLUMN_CONTACT_PRESENCE_STATUS = 8;
static final int COLUMN_CONTACT_CUSTOM_STATUS = 9;
static final int COLUMN_LAST_MESSAGE_DATE = 10;
static final int COLUMN_LAST_MESSAGE = 11;
static final int COLUMN_AVATAR_HASH = 12;
static final int COLUMN_AVATAR_DATA = 13;
private ImApp app = null;
static Drawable AVATAR_DEFAULT_GROUP = null;
public ContactView(Context context, AttributeSet attrs) {
super(context, attrs);
app = ((ImApp)((Activity) getContext()).getApplication());
}
static class ViewHolder
{
TextView mLine1;
TextView mLine2;
ImageView mAvatar;
ImageView mStatusIcon;
ImageView mEncryptionIcon;
View mContainer;
ImageView mMediaThumb;
}
public void bind(Cursor cursor, String underLineText, boolean scrolling) {
bind(cursor, underLineText, true, scrolling);
}
public void bind(Cursor cursor, String underLineText, boolean showChatMsg, boolean scrolling) {
/*
if (Debug.DEBUG_ENABLED)
{
StringBuffer debug = new StringBuffer();
for (int i = 0; i < cursor.getColumnCount();i++)
{
String name = cursor.getColumnName(i);
String value = cursor.getString(i);
if (value != null && value.length() < 100)
debug.append(name+":" + value+",");
else if (value == null)
debug.append(name+":(null)");
}
Log.d(ImApp.LOG_TAG,"contact:" + debug.toString());
}*/
ViewHolder holder = (ViewHolder)getTag();
final long providerId = cursor.getLong(COLUMN_CONTACT_PROVIDER);
final String address = cursor.getString(COLUMN_CONTACT_USERNAME);
final String displayName = cursor.getString(COLUMN_CONTACT_NICKNAME);
final int type = cursor.getInt(COLUMN_CONTACT_TYPE);
final String lastMsg = cursor.getString(COLUMN_LAST_MESSAGE);
final int presence = cursor.getInt(COLUMN_CONTACT_PRESENCE_STATUS);
final int subType = cursor.getInt(COLUMN_SUBSCRIPTION_TYPE);
final int subStatus = cursor.getInt(COLUMN_SUBSCRIPTION_STATUS);
String statusText = cursor.getString(COLUMN_CONTACT_CUSTOM_STATUS);
String nickname = displayName;
if (nickname == null)
{
nickname = address.split("@")[0];
}
else if (nickname.indexOf('@')!=-1)
{
nickname = nickname.split("@")[0];
}
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);
/*
if (holder.mStatusIcon != null)
{
Drawable statusIcon = brandingRes.getDrawable(PresenceUtils.getStatusIconId(presence));
//statusIcon.setBounds(0, 0, statusIcon.getIntrinsicWidth(),
// statusIcon.getIntrinsicHeight());
holder.mStatusIcon.setImageDrawable(statusIcon);address
}*/
holder.mStatusIcon.setVisibility(View.GONE);
if (holder.mAvatar != null)
{
if (Imps.Contacts.TYPE_GROUP == type) {
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)
{
// holder.mAvatar.setVisibility(View.GONE);
RoundedAvatarDrawable avatar = null;
try
{
// avatar = DatabaseUtils.getAvatarFromAddress(this.getContext().getContentResolver(),address, ImApp.DEFAULT_AVATAR_WIDTH,ImApp.DEFAULT_AVATAR_HEIGHT);
avatar = DatabaseUtils.getAvatarFromCursor(cursor, COLUMN_AVATAR_DATA, ImApp.DEFAULT_AVATAR_WIDTH,ImApp.DEFAULT_AVATAR_HEIGHT);
}
catch (Exception e)
{
//problem decoding avatar
Log.e(ImApp.LOG_TAG,"error decoding avatar",e);
}
try
{
if (avatar != null)
{
setAvatarBorder(presence,avatar);
holder.mAvatar.setImageDrawable(avatar);
}
else
{
String letterString = null;
if (nickname.length() > 0)
letterString = nickname.substring(0,1).toUpperCase();
else
letterString = "?"; //the unknown name!
int color = getAvatarBorder(presence);
int padding = 24;
LetterAvatar lavatar = new LetterAvatar(getContext(), color, letterString, 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
}
}
else
{
//holder.mAvatar.setImageDrawable(getContext().getResources().getDrawable(R.drawable.avatar_unknown));
holder.mAvatar.setVisibility(View.GONE);
}
}
if (showChatMsg && lastMsg != null) {
if (holder.mLine2 != null)
{
if (ChatFileStore.isVfsUri(lastMsg))
{
FileInfo fInfo = SystemServices.getFileInfoFromURI(getContext(), Uri.parse(lastMsg));
if (fInfo.type == null || fInfo.type.startsWith("image"))
{
if (holder.mMediaThumb != null)
{
holder.mMediaThumb.setVisibility(View.VISIBLE);
Bitmap b = MessageView.getThumbnail(getContext().getContentResolver(), Uri.parse(lastMsg));
holder.mMediaThumb.setImageBitmap(b);
holder.mLine2.setVisibility(View.GONE);
}
}
else
{
holder.mLine2.setText("");
}
}
else
{
if (holder.mMediaThumb != null)
holder.mMediaThumb.setVisibility(View.GONE);
holder.mLine2.setVisibility(View.VISIBLE);
holder.mLine2.setText(android.text.Html.fromHtml(lastMsg).toString());
}
}
}
else if (holder.mLine2 != null)
{
/*
if (statusText == null || statusText.length() == 0)
{
if (Imps.Contacts.TYPE_GROUP == type)
{
statusText = getContext().getString(R.string.menu_new_group_chat);
}
else
{
statusText = address;//brandingRes.getString(PresenceUtils.getStatusStringRes(presence));
}
}
holder.mLine2.setText(statusText);
*/
statusText = address;
holder.mLine2.setText(statusText);
}
if (subType == Imps.ContactsColumns.SUBSCRIPTION_TYPE_INVITATIONS)
{
// if (holder.mLine2 != null)
// holder.mLine2.setText("Contact List Request");
}
holder.mLine1.setVisibility(View.VISIBLE);
getEncryptionState (providerId, address, holder);
}
private void getEncryptionState (long providerId, String address, ViewHolder holder)
{
try {
IImConnection conn = app.getConnection(providerId);
if (conn == null || conn.getChatSessionManager() == null)
return;
IChatSession chatSession = conn.getChatSessionManager().getChatSession(address);
if (chatSession != null)
{
IOtrChatSession otrChatSession = chatSession.getOtrChatSession();
if (otrChatSession != null)
{
SessionStatus chatStatus = SessionStatus.values()[otrChatSession.getChatStatus()];
if (chatStatus == SessionStatus.ENCRYPTED)
{
boolean isVerified = otrChatSession.isKeyVerified(address);
if (isVerified)
holder.mStatusIcon.setImageDrawable(getResources().getDrawable(R.drawable.ic_black_encrypted_and_verified));
else
holder.mStatusIcon.setImageDrawable(getResources().getDrawable(R.drawable.ic_black_encrypted_not_verified));
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));
avatar.setAlpha(255);
break;
case Presence.IDLE:
avatar.setBorderColor(getResources().getColor(R.color.holo_green_dark));
avatar.setAlpha(255);
break;
case Presence.AWAY:
avatar.setBorderColor(getResources().getColor(R.color.holo_orange_light));
avatar.setAlpha(255);
break;
case Presence.DO_NOT_DISTURB:
avatar.setBorderColor(getResources().getColor(R.color.holo_red_dark));
avatar.setAlpha(255);
break;
case Presence.OFFLINE:
avatar.setBorderColor(getResources().getColor(android.R.color.transparent));
avatar.setAlpha(100);
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 String queryGroupMembers(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) {
while (c.moveToNext()) {
buf.append(c.getString(0));
Imps.Avatars.DATA
if (!c.isLast()) {
buf.append(',');
}
}
}
c.close();
return buf.toString();
}*/
}