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