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.AdapterView.OnItemLongClickListener;
28import android.widget.ArrayAdapter;
29import android.widget.EditText;
30import android.widget.ListView;
31import android.widget.ProgressBar;
32import android.widget.TextView;
33import android.widget.ImageView;
34import android.annotation.SuppressLint;
35import android.app.Activity;
36import android.app.AlertDialog;
37import android.content.Context;
38import android.content.CursorLoader;
39import android.content.DialogInterface;
40import android.content.DialogInterface.OnClickListener;
41import android.content.Intent;
42import android.content.Loader;
43import android.content.Loader.OnLoadCompleteListener;
44import android.database.Cursor;
45
46public class NewConversationActivity extends XmppActivity {
47
48 protected List<Contact> phoneContacts = new ArrayList<Contact>();
49 protected List<Contact> rosterContacts = new ArrayList<Contact>();
50 protected List<Contact> aggregatedContacts = new ArrayList<Contact>();
51 protected ListView contactsView;
52 protected ArrayAdapter<Contact> contactsAdapter;
53
54 protected EditText search;
55 protected String searchString = "";
56 private TextView contactsHeader;
57 private List<Account> accounts;
58
59 protected void updateAggregatedContacts() {
60
61 aggregatedContacts.clear();
62 for (Contact contact : rosterContacts) {
63 if (contact.match(searchString))
64 aggregatedContacts.add(contact);
65 }
66
67 Collections.sort(aggregatedContacts, new Comparator<Contact>() {
68
69 @SuppressLint("DefaultLocale")
70 @Override
71 public int compare(Contact lhs, Contact rhs) {
72 return lhs.getDisplayName().toLowerCase()
73 .compareTo(rhs.getDisplayName().toLowerCase());
74 }
75 });
76
77 if (aggregatedContacts.size() == 0) {
78
79 if (Validator.isValidJid(searchString)) {
80 String name = searchString.split("@")[0];
81 Contact newContact = new Contact(null, name, searchString, null);
82 newContact.flagAsNotInRoster();
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 @Override
97 protected void onCreate(Bundle savedInstanceState) {
98
99 super.onCreate(savedInstanceState);
100
101 setContentView(R.layout.activity_new_conversation);
102
103 contactsHeader = (TextView) findViewById(R.id.contacts_header);
104
105 search = (EditText) findViewById(R.id.new_conversation_search);
106 search.addTextChangedListener(new TextWatcher() {
107
108 @Override
109 public void onTextChanged(CharSequence s, int start, int before,
110 int count) {
111 searchString = search.getText().toString();
112 updateAggregatedContacts();
113 }
114
115 @Override
116 public void afterTextChanged(Editable s) {
117 // TODO Auto-generated method stub
118
119 }
120
121 @Override
122 public void beforeTextChanged(CharSequence s, int start, int count,
123 int after) {
124 // TODO Auto-generated method stub
125
126 }
127 });
128
129 contactsView = (ListView) findViewById(R.id.contactList);
130 contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(),
131 R.layout.contact, aggregatedContacts) {
132 @Override
133 public View getView(int position, View view, ViewGroup parent) {
134 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
135 Contact contact = getItem(position);
136 if (view == null) {
137 view = (View) inflater.inflate(R.layout.contact, null);
138 }
139
140 ((TextView) view.findViewById(R.id.contact_display_name))
141 .setText(getItem(position).getDisplayName());
142 TextView contactJid = (TextView) view
143 .findViewById(R.id.contact_jid);
144 contactJid.setText(contact.getJid());
145 String profilePhoto = getItem(position).getProfilePhoto();
146 ImageView imageView = (ImageView) view
147 .findViewById(R.id.contact_photo);
148 if (profilePhoto != null) {
149 imageView.setImageURI(Uri.parse(profilePhoto));
150 } else {
151 imageView.setImageBitmap(UIHelper.getUnknownContactPicture(
152 getItem(position).getDisplayName(), 90));
153 }
154 return view;
155 }
156 };
157 contactsView.setAdapter(contactsAdapter);
158 final Activity activity = this;
159 contactsView.setOnItemClickListener(new OnItemClickListener() {
160
161 @Override
162 public void onItemClick(AdapterView<?> arg0, final View view,
163 int pos, long arg3) {
164 final Contact clickedContact = aggregatedContacts.get(pos);
165
166 if ((clickedContact.getAccount()==null)&&(accounts.size()>1)) {
167 String[] accountList = new String[accounts.size()];
168 for (int i = 0; i < accounts.size(); ++i) {
169 accountList[i] = accounts.get(i).getJid();
170 }
171
172 AlertDialog.Builder accountChooser = new AlertDialog.Builder(
173 activity);
174 accountChooser.setTitle("Choose account");
175 accountChooser.setItems(accountList, new OnClickListener() {
176
177 @Override
178 public void onClick(DialogInterface dialog, int which) {
179 clickedContact.setAccount(accounts.get(which));
180 showIsMucDialogIfNeeded(clickedContact);
181 }
182 });
183 accountChooser.create().show();
184 } else {
185 if (clickedContact.getAccount()==null) {
186 clickedContact.setAccount(accounts.get(0));
187 }
188 showIsMucDialogIfNeeded(clickedContact);
189 }
190 }
191 });
192 contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
193
194 @Override
195 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
196 int pos, long arg3) {
197 Contact clickedContact = aggregatedContacts.get(pos);
198 DialogContactDetails dialog = new DialogContactDetails();
199 dialog.setContact(clickedContact);
200 dialog.show(getFragmentManager(), "details");
201 return true;
202 }
203 });
204 }
205
206 public void showIsMucDialogIfNeeded(final Contact clickedContact) {
207 if (clickedContact.couldBeMuc()) {
208 AlertDialog.Builder dialog = new AlertDialog.Builder(this);
209 dialog.setTitle("Multi User Conference");
210 dialog.setMessage("Are you trying to join a conference?");
211 dialog.setPositiveButton("Yes", new OnClickListener() {
212
213 @Override
214 public void onClick(DialogInterface dialog, int which) {
215 startConversation(clickedContact, clickedContact.getAccount(),true);
216 }
217 });
218 dialog.setNegativeButton("No", new OnClickListener() {
219
220 @Override
221 public void onClick(DialogInterface dialog, int which) {
222 startConversation(clickedContact, clickedContact.getAccount(),false);
223 }
224 });
225 dialog.create().show();
226 } else {
227 startConversation(clickedContact, clickedContact.getAccount(),false);
228 }
229 }
230
231 public void startConversation(Contact contact, Account account, boolean muc) {
232 if (!contact.isInRoster()) {
233 xmppConnectionService.createContact(contact);
234 }
235 Conversation conversation = xmppConnectionService
236 .findOrCreateConversation(account, contact.getJid(), muc);
237
238 Intent viewConversationIntent = new Intent(this,
239 ConversationActivity.class);
240 viewConversationIntent.setAction(Intent.ACTION_VIEW);
241 viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
242 conversation.getUuid());
243 viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
244 viewConversationIntent.setFlags(viewConversationIntent.getFlags()
245 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
246 startActivity(viewConversationIntent);
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 (int i = 0; i < accounts.size(); ++i) {
258 xmppConnectionService.getRoster(accounts.get(i),
259 new OnRosterFetchedListener() {
260
261 @Override
262 public void onRosterFetched(List<Contact> roster) {
263 rosterContacts.addAll(roster);
264 runOnUiThread(new Runnable() {
265
266 @Override
267 public void run() {
268 updateAggregatedContacts();
269 }
270 });
271
272 }
273 });
274 }
275 }
276
277 @Override
278 public boolean onCreateOptionsMenu(Menu menu) {
279 // Inflate the menu; this adds items to the action bar if it is present.
280 getMenuInflater().inflate(R.menu.newconversation, menu);
281 return true;
282 }
283
284 @Override
285 public boolean onOptionsItemSelected(MenuItem item) {
286 switch (item.getItemId()) {
287 case R.id.action_settings:
288 startActivity(new Intent(this, SettingsActivity.class));
289 break;
290 case R.id.action_accounts:
291 startActivity(new Intent(this, ManageAccountActivity.class));
292 break;
293 case R.id.action_refresh_contacts:
294 refreshContacts();
295 break;
296 default:
297 break;
298 }
299 return super.onOptionsItemSelected(item);
300 }
301
302 private void refreshContacts() {
303 final ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar1);
304 final EditText searchBar = (EditText) findViewById(R.id.new_conversation_search);
305 final TextView contactsHeader = (TextView) findViewById(R.id.contacts_header);
306 final ListView contactList = (ListView) findViewById(R.id.contactList);
307 searchBar.setVisibility(View.GONE);
308 contactsHeader.setVisibility(View.GONE);
309 contactList.setVisibility(View.GONE);
310 progress.setVisibility(View.VISIBLE);
311 this.accounts = xmppConnectionService.getAccounts();
312 this.rosterContacts.clear();
313 for (int i = 0; i < accounts.size(); ++i) {
314 if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
315 xmppConnectionService.updateRoster(accounts.get(i),
316 new OnRosterFetchedListener() {
317
318 @Override
319 public void onRosterFetched(
320 final List<Contact> roster) {
321 runOnUiThread(new Runnable() {
322
323 @Override
324 public void run() {
325 rosterContacts.addAll(roster);
326 progress.setVisibility(View.GONE);
327 searchBar.setVisibility(View.VISIBLE);
328 contactList.setVisibility(View.VISIBLE);
329 contactList.setVisibility(View.VISIBLE);
330 updateAggregatedContacts();
331 }
332 });
333 }
334 });
335 }
336 }
337 }
338}