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