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