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 aggregatedContacts.add(newContact);
83 contactsHeader.setText("Create new contact");
84 } else {
85 contactsHeader.setText("Contacts");
86 }
87 } else {
88 contactsHeader.setText("Contacts");
89 }
90
91 contactsAdapter.notifyDataSetChanged();
92 contactsView.setScrollX(0);
93 }
94
95 @Override
96 protected void onCreate(Bundle savedInstanceState) {
97
98 super.onCreate(savedInstanceState);
99
100 setContentView(R.layout.activity_new_conversation);
101
102 contactsHeader = (TextView) findViewById(R.id.contacts_header);
103
104 search = (EditText) findViewById(R.id.new_conversation_search);
105 search.addTextChangedListener(new TextWatcher() {
106
107 @Override
108 public void onTextChanged(CharSequence s, int start, int before,
109 int count) {
110 searchString = search.getText().toString();
111 updateAggregatedContacts();
112 }
113
114 @Override
115 public void afterTextChanged(Editable s) {
116 // TODO Auto-generated method stub
117
118 }
119
120 @Override
121 public void beforeTextChanged(CharSequence s, int start, int count,
122 int after) {
123 // TODO Auto-generated method stub
124
125 }
126 });
127
128 contactsView = (ListView) findViewById(R.id.contactList);
129 contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(),
130 R.layout.contact, aggregatedContacts) {
131 @Override
132 public View getView(int position, View view, ViewGroup parent) {
133 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
134 Contact contact = getItem(position);
135 if (view == null) {
136 view = (View) inflater.inflate(R.layout.contact, null);
137 }
138
139 ((TextView) view.findViewById(R.id.contact_display_name))
140 .setText(getItem(position).getDisplayName());
141 TextView contactJid = (TextView) view
142 .findViewById(R.id.contact_jid);
143 contactJid.setText(contact.getJid());
144 String profilePhoto = getItem(position).getProfilePhoto();
145 ImageView imageView = (ImageView) view
146 .findViewById(R.id.contact_photo);
147 if (profilePhoto != null) {
148 imageView.setImageURI(Uri.parse(profilePhoto));
149 } else {
150 imageView.setImageBitmap(UIHelper.getUnknownContactPicture(
151 getItem(position).getDisplayName(), 90));
152 }
153 return view;
154 }
155 };
156 contactsView.setAdapter(contactsAdapter);
157 final Activity activity = this;
158 contactsView.setOnItemClickListener(new OnItemClickListener() {
159
160 @Override
161 public void onItemClick(AdapterView<?> arg0, final View view,
162 int pos, long arg3) {
163 final Contact clickedContact = aggregatedContacts.get(pos);
164
165 if ((clickedContact.getAccount()==null)&&(accounts.size()>1)) {
166 String[] accountList = new String[accounts.size()];
167 for (int i = 0; i < accounts.size(); ++i) {
168 accountList[i] = accounts.get(i).getJid();
169 }
170
171 AlertDialog.Builder accountChooser = new AlertDialog.Builder(
172 activity);
173 accountChooser.setTitle("Choose account");
174 accountChooser.setItems(accountList, new OnClickListener() {
175
176 @Override
177 public void onClick(DialogInterface dialog, int which) {
178 clickedContact.setAccount(accounts.get(which));
179 showIsMucDialogIfNeeded(clickedContact);
180 }
181 });
182 accountChooser.create().show();
183 } else {
184 clickedContact.setAccount(accounts.get(0));
185 showIsMucDialogIfNeeded(clickedContact);
186 }
187 }
188 });
189 contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
190
191 @Override
192 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
193 int pos, long arg3) {
194 Contact clickedContact = aggregatedContacts.get(pos);
195 DialogContactDetails dialog = new DialogContactDetails();
196 dialog.setContact(clickedContact);
197 dialog.show(getFragmentManager(), "details");
198 return true;
199 }
200 });
201 }
202
203 public void showIsMucDialogIfNeeded(final Contact clickedContact) {
204 if (clickedContact.couldBeMuc()) {
205 AlertDialog.Builder dialog = new AlertDialog.Builder(this);
206 dialog.setTitle("Multi User Conference");
207 dialog.setMessage("Are you trying to join a conference?");
208 dialog.setPositiveButton("Yes", new OnClickListener() {
209
210 @Override
211 public void onClick(DialogInterface dialog, int which) {
212 startConversation(clickedContact, clickedContact.getAccount(),true);
213 }
214 });
215 dialog.setNegativeButton("No", new OnClickListener() {
216
217 @Override
218 public void onClick(DialogInterface dialog, int which) {
219 startConversation(clickedContact, clickedContact.getAccount(),false);
220 }
221 });
222 dialog.create().show();
223 } else {
224 startConversation(clickedContact, clickedContact.getAccount(),false);
225 }
226 }
227
228 public void startConversation(Contact contact, Account account, boolean muc) {
229 Conversation conversation = xmppConnectionService
230 .findOrCreateConversation(account, contact, muc);
231
232 Intent viewConversationIntent = new Intent(this,
233 ConversationActivity.class);
234 viewConversationIntent.setAction(Intent.ACTION_VIEW);
235 viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
236 conversation.getUuid());
237 viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
238 viewConversationIntent.setFlags(viewConversationIntent.getFlags()
239 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
240 startActivity(viewConversationIntent);
241 }
242
243 @Override
244 void onBackendConnected() {
245 if (xmppConnectionService.getConversationCount() == 0) {
246 getActionBar().setDisplayHomeAsUpEnabled(false);
247 getActionBar().setHomeButtonEnabled(false);
248 }
249 this.accounts = xmppConnectionService.getAccounts();
250 this.rosterContacts.clear();
251 for (int i = 0; i < accounts.size(); ++i) {
252 if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
253 xmppConnectionService.getRoster(accounts.get(i),
254 new OnRosterFetchedListener() {
255
256 @Override
257 public void onRosterFetched(List<Contact> roster) {
258 rosterContacts.addAll(roster);
259 runOnUiThread(new Runnable() {
260
261 @Override
262 public void run() {
263 updateAggregatedContacts();
264 }
265 });
266
267 }
268 });
269 }
270 }
271 }
272
273 @Override
274 public boolean onCreateOptionsMenu(Menu menu) {
275 // Inflate the menu; this adds items to the action bar if it is present.
276 getMenuInflater().inflate(R.menu.newconversation, menu);
277 return true;
278 }
279
280 @Override
281 public boolean onOptionsItemSelected(MenuItem item) {
282 switch (item.getItemId()) {
283 case R.id.action_settings:
284 startActivity(new Intent(this, SettingsActivity.class));
285 break;
286 case R.id.action_accounts:
287 startActivity(new Intent(this, ManageAccountActivity.class));
288 break;
289 case R.id.action_refresh_contacts:
290 refreshContacts();
291 break;
292 default:
293 break;
294 }
295 return super.onOptionsItemSelected(item);
296 }
297
298 private void refreshContacts() {
299 final ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar1);
300 final EditText searchBar = (EditText) findViewById(R.id.new_conversation_search);
301 final TextView contactsHeader = (TextView) findViewById(R.id.contacts_header);
302 final ListView contactList = (ListView) findViewById(R.id.contactList);
303 searchBar.setVisibility(View.GONE);
304 contactsHeader.setVisibility(View.GONE);
305 contactList.setVisibility(View.GONE);
306 progress.setVisibility(View.VISIBLE);
307 this.accounts = xmppConnectionService.getAccounts();
308 this.rosterContacts.clear();
309 for (int i = 0; i < accounts.size(); ++i) {
310 if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
311 xmppConnectionService.updateRoster(accounts.get(i),
312 new OnRosterFetchedListener() {
313
314 @Override
315 public void onRosterFetched(
316 final List<Contact> roster) {
317 runOnUiThread(new Runnable() {
318
319 @Override
320 public void run() {
321 rosterContacts.addAll(roster);
322 progress.setVisibility(View.GONE);
323 searchBar.setVisibility(View.VISIBLE);
324 contactList.setVisibility(View.VISIBLE);
325 contactList.setVisibility(View.VISIBLE);
326 updateAggregatedContacts();
327 }
328 });
329 }
330 });
331 }
332 }
333 }
334}