• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007-2008 Esmertec AG.
3  * Copyright (C) 2007-2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.im.app;
19 
20 import android.app.Activity;
21 import android.content.ContentResolver;
22 import android.content.ContentUris;
23 import android.content.Context;
24 import android.content.res.Resources;
25 import android.database.Cursor;
26 import android.net.Uri;
27 import android.provider.Im;
28 import android.text.Spannable;
29 import android.text.SpannableString;
30 import android.text.SpannableStringBuilder;
31 import android.text.TextUtils;
32 import android.text.style.RelativeSizeSpan;
33 import android.text.style.UnderlineSpan;
34 import android.util.AttributeSet;
35 import android.view.View;
36 import android.widget.ImageView;
37 import android.widget.LinearLayout;
38 import android.widget.TextView;
39 import android.graphics.drawable.Drawable;
40 
41 import com.android.im.R;
42 import com.android.im.plugin.BrandingResourceIDs;
43 
44 import java.text.DateFormat;
45 import java.util.Calendar;
46 
47 public class ContactView extends LinearLayout {
48     static final String[] CONTACT_PROJECTION = {
49         Im.Contacts._ID,
50         Im.Contacts.PROVIDER,
51         Im.Contacts.ACCOUNT,
52         Im.Contacts.USERNAME,
53         Im.Contacts.NICKNAME,
54         Im.Contacts.TYPE,
55         Im.Contacts.SUBSCRIPTION_TYPE,
56         Im.Contacts.SUBSCRIPTION_STATUS,
57         Im.Presence.PRESENCE_STATUS,
58         Im.Presence.PRESENCE_CUSTOM_STATUS,
59         Im.Chats.LAST_MESSAGE_DATE,
60         Im.Chats.LAST_UNREAD_MESSAGE,
61     };
62 
63     static final int COLUMN_CONTACT_ID = 0;
64     static final int COLUMN_CONTACT_PROVIDER = 1;
65     static final int COLUMN_CONTACT_ACCOUNT = 2;
66     static final int COLUMN_CONTACT_USERNAME = 3;
67     static final int COLUMN_CONTACT_NICKNAME = 4;
68     static final int COLUMN_CONTACT_TYPE = 5;
69     static final int COLUMN_SUBSCRIPTION_TYPE = 6;
70     static final int COLUMN_SUBSCRIPTION_STATUS = 7;
71     static final int COLUMN_CONTACT_PRESENCE_STATUS = 8;
72     static final int COLUMN_CONTACT_CUSTOM_STATUS = 9;
73     static final int COLUMN_LAST_MESSAGE_DATE = 10;
74     static final int COLUMN_LAST_MESSAGE = 11;
75 
76     //private ImageView mPresence;
77     private TextView mLine1;
78     private TextView mLine2;
79     private TextView mTimeStamp;
80 
ContactView(Context context, AttributeSet attrs)81     public ContactView(Context context, AttributeSet attrs) {
82         super(context, attrs);
83     }
84 
85     @Override
onFinishInflate()86     protected void onFinishInflate() {
87         super.onFinishInflate();
88 
89         //mPresence = (ImageView) findViewById(R.id.presence);
90         mLine1 = (TextView) findViewById(R.id.line1);
91         mLine2 = (TextView) findViewById(R.id.line2);
92         mLine2.setCompoundDrawablePadding(5);
93         mTimeStamp = (TextView)findViewById(R.id.timestamp);
94     }
95 
bind(Cursor cursor, String underLineText, boolean scrolling)96     public void bind(Cursor cursor, String underLineText, boolean scrolling) {
97         bind(cursor, underLineText, true, scrolling);
98     }
99 
bind(Cursor cursor, String underLineText, boolean showChatMsg, boolean scrolling)100     public void bind(Cursor cursor, String underLineText, boolean showChatMsg, boolean scrolling) {
101         Resources r = getResources();
102         long providerId = cursor.getLong(COLUMN_CONTACT_PROVIDER);
103         String username = cursor.getString(COLUMN_CONTACT_USERNAME);
104         String nickname = cursor.getString(COLUMN_CONTACT_NICKNAME);
105         int type = cursor.getInt(COLUMN_CONTACT_TYPE);
106         String statusText = cursor.getString(COLUMN_CONTACT_CUSTOM_STATUS);
107         String lastMsg = cursor.getString(COLUMN_LAST_MESSAGE);
108 
109         boolean hasChat = !cursor.isNull(COLUMN_LAST_MESSAGE_DATE);
110 
111         ImApp app = ImApp.getApplication((Activity)mContext);
112         BrandingResources brandingRes = app.getBrandingResource(providerId);
113 
114         int presence = cursor.getInt(COLUMN_CONTACT_PRESENCE_STATUS);
115         int iconId = 0;
116 
117         // status icon
118 
119         if (Im.Contacts.TYPE_GROUP == type) {
120             iconId = lastMsg == null ? R.drawable.group_chat : R.drawable.group_chat_new;
121         } else if (hasChat) {
122             iconId = lastMsg == null ? BrandingResourceIDs.DRAWABLE_READ_CHAT
123                     : BrandingResourceIDs.DRAWABLE_UNREAD_CHAT;
124         } else {
125             iconId = PresenceUtils.getStatusIconId(presence);
126         }
127 
128         //mPresence.setImageDrawable(brandingRes.getDrawable(iconId));
129         Drawable presenceIcon = brandingRes.getDrawable(iconId);
130 
131         // line1
132         CharSequence line1;
133         if (Im.Contacts.TYPE_GROUP == type) {
134             ContentResolver resolver = getContext().getContentResolver();
135             long id = cursor.getLong(ContactView.COLUMN_CONTACT_ID);
136             line1 = queryGroupMembers(resolver, id);
137         } else {
138             line1 = TextUtils.isEmpty(nickname) ?
139                     ImpsAddressUtils.getDisplayableAddress(username) : nickname;
140 
141             if (!TextUtils.isEmpty(underLineText)) {
142                 // highlight/underline the word being searched
143                 String lowercase = line1.toString().toLowerCase();
144                 int start = lowercase.indexOf(underLineText.toLowerCase());
145                 if (start >= 0) {
146                     int end = start + underLineText.length();
147                     SpannableString str = new SpannableString(line1);
148                     str.setSpan(new UnderlineSpan(), start, end,
149                             Spannable.SPAN_INCLUSIVE_INCLUSIVE);
150                     line1 = str;
151                 }
152             }
153 
154             if (Im.Contacts.TYPE_TEMPORARY == type) {
155                 // Add a mark at the front of name if it's only a temporary
156                 // contact.
157                 SpannableStringBuilder str = new SpannableStringBuilder(
158                         r.getText(R.string.unknown_contact));
159                 str.setSpan(new RelativeSizeSpan(0.8f), 0, str.length(),
160                         Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
161                 str.append(line1);
162                 line1 = str;
163             }
164         }
165         mLine1.setText(line1);
166 
167         // time stamp
168         if (showChatMsg && hasChat) {
169             mTimeStamp.setVisibility(VISIBLE);
170             Calendar cal = Calendar.getInstance();
171             cal.setTimeInMillis(cursor.getLong(COLUMN_LAST_MESSAGE_DATE));
172             DateFormat formatter = DateFormat.getTimeInstance(DateFormat.SHORT);
173             mTimeStamp.setText(formatter.format(cal.getTime()));
174         } else {
175             mTimeStamp.setVisibility(GONE);
176         }
177 
178         // line2
179         CharSequence line2 = null;
180         if (showChatMsg) {
181             line2 = lastMsg;
182         }
183 
184         if (TextUtils.isEmpty(line2)){
185             if (Im.Contacts.TYPE_GROUP == type) {
186                 // Show nothing in line2 if it's a group and don't
187                 // have any unread message.
188                 line2 = null;
189             } else {
190                 // Show the custom status text if there's no new message.
191                 line2 = statusText;
192             }
193         }
194 
195         if (TextUtils.isEmpty(line2)) {
196             // Show a string of presence if there is neither new message nor
197             // custom status text.
198             line2 = brandingRes.getString(PresenceUtils.getStatusStringRes(presence));
199         }
200 
201         mLine2.setText(line2);
202         mLine2.setCompoundDrawablesWithIntrinsicBounds(null, null, presenceIcon, null);
203 
204 
205         View contactInfoPanel = findViewById(R.id.contactInfo);
206         if (hasChat && showChatMsg) {
207             contactInfoPanel.setBackgroundResource(R.drawable.bubble);
208             mLine1.setTextColor(r.getColor(R.color.chat_contact));
209         } else {
210             contactInfoPanel.setBackgroundDrawable(null);
211             contactInfoPanel.setPadding(4, 0, 0, 0);
212             mLine1.setTextColor(r.getColor(R.color.nonchat_contact));
213         }
214     }
215 
queryGroupMembers(ContentResolver resolver, long groupId)216     private String queryGroupMembers(ContentResolver resolver, long groupId) {
217         String[] projection = { Im.GroupMembers.NICKNAME };
218         Uri uri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, groupId);
219         Cursor c = resolver.query(uri, projection, null, null, null);
220         StringBuilder buf = new StringBuilder();
221         if(c != null) {
222             while(c.moveToNext()) {
223                 buf.append(c.getString(0));
224                 if(!c.isLast()) {
225                     buf.append(',');
226                 }
227             }
228             c.close();
229         }
230         return buf.toString();
231     }
232 }
233