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 if (clickedContact.getAccount()==null) {
185 clickedContact.setAccount(accounts.get(0));
186 }
187 showIsMucDialogIfNeeded(clickedContact);
188 }
189 }
190 });
191 contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
192
193 @Override
194 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
195 int pos, long arg3) {
196 Contact clickedContact = aggregatedContacts.get(pos);
197 DialogContactDetails dialog = new DialogContactDetails();
198 dialog.setContact(clickedContact);
199 dialog.show(getFragmentManager(), "details");
200 return true;
201 }
202 });
203 }
204
205 public void showIsMucDialogIfNeeded(final Contact clickedContact) {
206 if (clickedContact.couldBeMuc()) {
207 AlertDialog.Builder dialog = new AlertDialog.Builder(this);
208 dialog.setTitle("Multi User Conference");
209 dialog.setMessage("Are you trying to join a conference?");
210 dialog.setPositiveButton("Yes", new OnClickListener() {
211
212 @Override
213 public void onClick(DialogInterface dialog, int which) {
214 startConversation(clickedContact, clickedContact.getAccount(),true);
215 }
216 });
217 dialog.setNegativeButton("No", new OnClickListener() {
218
219 @Override
220 public void onClick(DialogInterface dialog, int which) {
221 startConversation(clickedContact, clickedContact.getAccount(),false);
222 }
223 });
224 dialog.create().show();
225 } else {
226 startConversation(clickedContact, clickedContact.getAccount(),false);
227 }
228 }
229
230 public void startConversation(Contact contact, Account account, boolean muc) {
231 Log.d("xmppService","starting conversation for account:"+account.getJid()+" and contact:"+contact.getJid());
232 Conversation conversation = xmppConnectionService
233 .findOrCreateConversation(account, contact, muc);
234
235 Intent viewConversationIntent = new Intent(this,
236 ConversationActivity.class);
237 viewConversationIntent.setAction(Intent.ACTION_VIEW);
238 viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
239 conversation.getUuid());
240 viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
241 viewConversationIntent.setFlags(viewConversationIntent.getFlags()
242 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
243 startActivity(viewConversationIntent);
244 }
245
246 @Override
247 void onBackendConnected() {
248 if (xmppConnectionService.getConversationCount() == 0) {
249 getActionBar().setDisplayHomeAsUpEnabled(false);
250 getActionBar().setHomeButtonEnabled(false);
251 }
252 this.accounts = xmppConnectionService.getAccounts();
253 this.rosterContacts.clear();
254 for (int i = 0; i < accounts.size(); ++i) {
255 if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
256 xmppConnectionService.getRoster(accounts.get(i),
257 new OnRosterFetchedListener() {
258
259 @Override
260 public void onRosterFetched(List<Contact> roster) {
261 rosterContacts.addAll(roster);
262 runOnUiThread(new Runnable() {
263
264 @Override
265 public void run() {
266 updateAggregatedContacts();
267 }
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 case R.id.action_refresh_contacts:
293 refreshContacts();
294 break;
295 default:
296 break;
297 }
298 return super.onOptionsItemSelected(item);
299 }
300
301 private void refreshContacts() {
302 final ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar1);
303 final EditText searchBar = (EditText) findViewById(R.id.new_conversation_search);
304 final TextView contactsHeader = (TextView) findViewById(R.id.contacts_header);
305 final ListView contactList = (ListView) findViewById(R.id.contactList);
306 searchBar.setVisibility(View.GONE);
307 contactsHeader.setVisibility(View.GONE);
308 contactList.setVisibility(View.GONE);
309 progress.setVisibility(View.VISIBLE);
310 this.accounts = xmppConnectionService.getAccounts();
311 this.rosterContacts.clear();
312 for (int i = 0; i < accounts.size(); ++i) {
313 if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
314 xmppConnectionService.updateRoster(accounts.get(i),
315 new OnRosterFetchedListener() {
316
317 @Override
318 public void onRosterFetched(
319 final List<Contact> roster) {
320 runOnUiThread(new Runnable() {
321
322 @Override
323 public void run() {
324 rosterContacts.addAll(roster);
325 progress.setVisibility(View.GONE);
326 searchBar.setVisibility(View.VISIBLE);
327 contactList.setVisibility(View.VISIBLE);
328 contactList.setVisibility(View.VISIBLE);
329 updateAggregatedContacts();
330 }
331 });
332 }
333 });
334 }
335 }
336 }
337}