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