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