1package de.gultsch.chat.ui;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.List;
7
8import de.gultsch.chat.R;
9import de.gultsch.chat.entities.Account;
10import de.gultsch.chat.entities.Contact;
11import de.gultsch.chat.entities.Conversation;
12import de.gultsch.chat.utils.UIHelper;
13import de.gultsch.chat.utils.Validator;
14import android.net.Uri;
15import android.os.Bundle;
16import android.provider.ContactsContract;
17import android.text.Editable;
18import android.text.TextWatcher;
19import android.util.Log;
20import android.view.LayoutInflater;
21import android.view.Menu;
22import android.view.MenuItem;
23import android.view.View;
24import android.view.ViewGroup;
25import android.widget.AdapterView;
26import android.widget.AdapterView.OnItemClickListener;
27import android.widget.ArrayAdapter;
28import android.widget.EditText;
29import android.widget.ListView;
30import android.widget.TextView;
31import android.widget.ImageView;
32import android.annotation.SuppressLint;
33import android.app.Activity;
34import android.app.AlertDialog;
35import android.content.Context;
36import android.content.CursorLoader;
37import android.content.DialogInterface;
38import android.content.DialogInterface.OnClickListener;
39import android.content.Intent;
40import android.content.Loader;
41import android.content.Loader.OnLoadCompleteListener;
42import android.database.Cursor;
43
44public class NewConversationActivity extends XmppActivity {
45
46 protected List<Contact> phoneContacts = new ArrayList<Contact>();
47 protected List<Contact> rosterContacts = new ArrayList<Contact>();
48 protected List<Contact> aggregatedContacts = new ArrayList<Contact>();
49 protected ListView contactsView;
50 protected ArrayAdapter<Contact> contactsAdapter;
51
52 protected EditText search;
53 protected String searchString = "";
54 private TextView contactsHeader;
55 private List<Account> accounts;
56
57 protected void updateAggregatedContacts() {
58
59 aggregatedContacts.clear();
60 for (Contact contact : phoneContacts) {
61 if (contact.match(searchString))
62 aggregatedContacts.add(contact);
63 }
64 for (Contact contact : rosterContacts) {
65 if (contact.match(searchString))
66 aggregatedContacts.add(contact);
67 }
68
69 Collections.sort(aggregatedContacts, new Comparator<Contact>() {
70
71 @SuppressLint("DefaultLocale")
72 @Override
73 public int compare(Contact lhs, Contact rhs) {
74 return lhs.getDisplayName().toLowerCase().compareTo(rhs.getDisplayName().toLowerCase());
75 }
76 });
77
78 if (aggregatedContacts.size() == 0) {
79
80 if (Validator.isValidJid(searchString)) {
81 String name = searchString.split("@")[0];
82 Contact newContact = new Contact(null,name, searchString,null);
83 aggregatedContacts.add(newContact);
84 contactsHeader.setText("Create new contact");
85 } else {
86 contactsHeader.setText("Contacts");
87 }
88 } else {
89 contactsHeader.setText("Contacts");
90 }
91
92 contactsAdapter.notifyDataSetChanged();
93 contactsView.setScrollX(0);
94 }
95
96 static final String[] PROJECTION = new String[] {
97 ContactsContract.Data.CONTACT_ID,
98 ContactsContract.Data.DISPLAY_NAME,
99 ContactsContract.Data.PHOTO_THUMBNAIL_URI,
100 ContactsContract.CommonDataKinds.Im.DATA };
101
102 // This is the select criteria
103 static final String SELECTION = "(" + ContactsContract.Data.MIMETYPE
104 + "=\"" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE
105 + "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL
106 + "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER
107 + "\")";
108
109 @Override
110 protected void onCreate(Bundle savedInstanceState) {
111
112 super.onCreate(savedInstanceState);
113
114 setContentView(R.layout.activity_new_conversation);
115
116 contactsHeader = (TextView) findViewById(R.id.contacts_header);
117
118 search = (EditText) findViewById(R.id.new_conversation_search);
119 search.addTextChangedListener(new TextWatcher() {
120
121 @Override
122 public void onTextChanged(CharSequence s, int start, int before,
123 int count) {
124 searchString = search.getText().toString();
125 updateAggregatedContacts();
126 }
127
128 @Override
129 public void afterTextChanged(Editable s) {
130 // TODO Auto-generated method stub
131
132 }
133
134 @Override
135 public void beforeTextChanged(CharSequence s, int start, int count,
136 int after) {
137 // TODO Auto-generated method stub
138
139 }
140 });
141
142 contactsView = (ListView) findViewById(R.id.contactList);
143 contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(),
144 R.layout.contact, aggregatedContacts) {
145 @Override
146 public View getView(int position, View view, ViewGroup parent) {
147 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
148 if (view == null) {
149 view = (View) inflater.inflate(R.layout.contact, null);
150 }
151
152 ((TextView) view.findViewById(R.id.contact_display_name))
153 .setText(getItem(position).getDisplayName());
154 ((TextView) view.findViewById(R.id.contact_jid))
155 .setText(getItem(position).getJid());
156 String profilePhoto = getItem(position).getProfilePhoto();
157 ImageView imageView = (ImageView) view.findViewById(R.id.contact_photo);
158 if (profilePhoto!=null) {
159 imageView.setImageURI(Uri.parse(profilePhoto));
160 } else {
161 imageView.setImageBitmap(UIHelper.getUnknownContactPicture(getItem(position).getDisplayName(),90));
162 }
163 return view;
164 }
165 };
166 contactsView.setAdapter(contactsAdapter);
167 final Activity activity = this;
168 contactsView.setOnItemClickListener(new OnItemClickListener() {
169
170 @Override
171 public void onItemClick(AdapterView<?> arg0, final View view, int pos,
172 long arg3) {
173 final Contact clickedContact = aggregatedContacts.get(pos);
174 Log.d("gultsch",
175 "clicked on " + clickedContact.getDisplayName());
176
177 final List<Account> accounts = xmppConnectionService.getAccounts();
178 if (accounts.size() == 1) {
179 startConversation(clickedContact, accounts.get(0));
180 } else {
181 String[] accountList = new String[accounts.size()];
182 for(int i = 0; i < accounts.size(); ++i) {
183 accountList[i] = accounts.get(i).getJid();
184 }
185
186 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
187 builder.setTitle("Choose account");
188 builder.setItems(accountList,new OnClickListener() {
189
190 @Override
191 public void onClick(DialogInterface dialog, int which) {
192 Account account = accounts.get(which);
193 startConversation(clickedContact, account);
194 }
195 });
196 builder.create().show();
197 }
198 }
199 });
200 }
201
202 public void startConversation(Contact contact, Account account) {
203 Conversation conversation = xmppConnectionService
204 .findOrCreateConversation(account, contact);
205
206 Intent viewConversationIntent = new Intent(this,ConversationActivity.class);
207 viewConversationIntent.setAction(Intent.ACTION_VIEW);
208 viewConversationIntent.putExtra(
209 ConversationActivity.CONVERSATION,
210 conversation.getUuid());
211 viewConversationIntent
212 .setType(ConversationActivity.VIEW_CONVERSATION);
213 viewConversationIntent.setFlags(viewConversationIntent
214 .getFlags() | Intent.FLAG_ACTIVITY_CLEAR_TOP);
215 startActivity(viewConversationIntent);
216 }
217
218 @Override
219 public void onStart() {
220 super.onStart();
221
222 CursorLoader mCursorLoader = new CursorLoader(this,
223 ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null,
224 null);
225 mCursorLoader.registerListener(0, new OnLoadCompleteListener<Cursor>() {
226
227 @Override
228 public void onLoadComplete(Loader<Cursor> arg0, Cursor cursor) {
229 phoneContacts.clear();
230 while (cursor.moveToNext()) {
231 String profilePhoto = cursor.getString(cursor
232 .getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI));
233 /*if (profilePhoto == null) {
234 profilePhoto = DEFAULT_PROFILE_PHOTO;
235 }*/
236 Contact contact = new Contact(null,
237 cursor.getString(cursor
238 .getColumnIndex(ContactsContract.Data.DISPLAY_NAME)),
239 cursor.getString(cursor
240 .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)),
241 profilePhoto);
242 phoneContacts.add(contact);
243 }
244 updateAggregatedContacts();
245 }
246 });
247 mCursorLoader.startLoading();
248
249 }
250
251 @Override
252 void onBackendConnected() {
253 if (xmppConnectionService.getConversationCount() == 0) {
254 getActionBar().setDisplayHomeAsUpEnabled(false);
255 getActionBar().setHomeButtonEnabled(false);
256 }
257 this.accounts = xmppConnectionService.getAccounts();
258 this.rosterContacts.clear();
259 for(Account account : this.accounts) {
260 xmppConnectionService.getRoster(account, new OnRosterFetchedListener() {
261
262 @Override
263 public void onRosterFetched(List<Contact> roster) {
264 rosterContacts.addAll(roster);
265 runOnUiThread(new Runnable() {
266
267 @Override
268 public void run() {
269 updateAggregatedContacts();
270 }
271 });
272
273 }
274 });
275 }
276 }
277
278 @Override
279 public boolean onCreateOptionsMenu(Menu menu) {
280 // Inflate the menu; this adds items to the action bar if it is present.
281 getMenuInflater().inflate(R.menu.newconversation, menu);
282 return true;
283 }
284
285 @Override
286 public boolean onOptionsItemSelected(MenuItem item) {
287 switch (item.getItemId()) {
288 case R.id.action_settings:
289 startActivity(new Intent(this, SettingsActivity.class));
290 break;
291 case R.id.action_accounts:
292 startActivity(new Intent(this, ManageAccountActivity.class));
293 break;
294 default:
295 break;
296 }
297 return super.onOptionsItemSelected(item);
298 }
299
300}