1package eu.siacs.conversations.ui;
2
3import java.io.UnsupportedEncodingException;
4import java.net.URLDecoder;
5import java.util.ArrayList;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.List;
9
10import eu.siacs.conversations.R;
11import eu.siacs.conversations.entities.Account;
12import eu.siacs.conversations.entities.Contact;
13import eu.siacs.conversations.entities.Conversation;
14import eu.siacs.conversations.utils.UIHelper;
15import eu.siacs.conversations.utils.Validator;
16import android.os.Bundle;
17import android.text.Editable;
18import android.text.TextWatcher;
19import android.view.LayoutInflater;
20import android.view.Menu;
21import android.view.MenuItem;
22import android.view.View;
23import android.view.ViewGroup;
24import android.widget.AdapterView;
25import android.widget.AdapterView.OnItemClickListener;
26import android.widget.AdapterView.OnItemLongClickListener;
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.DialogInterface;
38import android.content.DialogInterface.OnClickListener;
39import android.content.Intent;
40
41public class NewConversationActivity extends XmppActivity {
42
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 ImageView imageView = (ImageView) view
140 .findViewById(R.id.contact_photo);
141 imageView.setImageBitmap(UIHelper.getContactPicture(contact,null,90,this.getContext()));
142 return view;
143 }
144 };
145 contactsView.setAdapter(contactsAdapter);
146 final Activity activity = this;
147 contactsView.setOnItemClickListener(new OnItemClickListener() {
148
149 @Override
150 public void onItemClick(AdapterView<?> arg0, final View view,
151 int pos, long arg3) {
152 final Contact clickedContact = aggregatedContacts.get(pos);
153
154 if ((clickedContact.getAccount()==null)&&(accounts.size()>1)) {
155 getAccountChooser(new OnClickListener() {
156
157 @Override
158 public void onClick(DialogInterface dialog, int which) {
159 clickedContact.setAccount(accounts.get(which));
160 showIsMucDialogIfNeeded(clickedContact);
161 }
162 }).show();
163 } else {
164 if (clickedContact.getAccount()==null) {
165 clickedContact.setAccount(accounts.get(0));
166 }
167 showIsMucDialogIfNeeded(clickedContact);
168 }
169 }
170 });
171 contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
172
173 @Override
174 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
175 int pos, long arg3) {
176 Intent intent = new Intent(activity,ContactDetailsActivity.class);
177 intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
178 intent.putExtra("uuid", aggregatedContacts.get(pos).getUuid());
179 startActivity(intent);
180 return true;
181 }
182 });
183 }
184
185 protected AlertDialog getAccountChooser(OnClickListener listener) {
186 String[] accountList = new String[accounts.size()];
187 for (int i = 0; i < accounts.size(); ++i) {
188 accountList[i] = accounts.get(i).getJid();
189 }
190
191 AlertDialog.Builder accountChooser = new AlertDialog.Builder(
192 this);
193 accountChooser.setTitle("Choose account");
194 accountChooser.setItems(accountList, listener);
195 return accountChooser.create();
196 }
197
198 public void showIsMucDialogIfNeeded(final Contact clickedContact) {
199 if (clickedContact.couldBeMuc()) {
200 AlertDialog.Builder dialog = new AlertDialog.Builder(this);
201 dialog.setTitle("Multi User Conference");
202 dialog.setMessage("Are you trying to join a conference?");
203 dialog.setPositiveButton("Yes", new OnClickListener() {
204
205 @Override
206 public void onClick(DialogInterface dialog, int which) {
207 startConversation(clickedContact, clickedContact.getAccount(),true);
208 }
209 });
210 dialog.setNegativeButton("No", new OnClickListener() {
211
212 @Override
213 public void onClick(DialogInterface dialog, int which) {
214 startConversation(clickedContact, clickedContact.getAccount(),false);
215 }
216 });
217 dialog.create().show();
218 } else {
219 startConversation(clickedContact, clickedContact.getAccount(),false);
220 }
221 }
222
223 public void startConversation(Contact contact, Account account, boolean muc) {
224 if (!contact.isInRoster()) {
225 xmppConnectionService.createContact(contact);
226 }
227 Conversation conversation = xmppConnectionService
228 .findOrCreateConversation(account, contact.getJid(), muc);
229
230 switchToConversation(conversation,null);
231 }
232
233 @Override
234 void onBackendConnected() {
235 this.accounts = xmppConnectionService.getAccounts();
236 if (Intent.ACTION_SENDTO.equals(getIntent().getAction())) {
237 getActionBar().setDisplayHomeAsUpEnabled(false);
238 getActionBar().setHomeButtonEnabled(false);
239 String jid;
240 try {
241 jid = URLDecoder.decode(getIntent().getData().getEncodedPath(),"UTF-8").split("/")[1];
242 } catch (UnsupportedEncodingException e) {
243 jid = null;
244 }
245 if (jid!=null) {
246 final String finalJid = jid;
247 if (this.accounts.size() > 1) {
248 getAccountChooser(new OnClickListener() {
249
250 @Override
251 public void onClick(DialogInterface dialog, int which) {
252 Conversation conversation = xmppConnectionService.findOrCreateConversation(accounts.get(which), finalJid, false);
253 switchToConversation(conversation,null);
254 finish();
255 }
256 }).show();
257 } else {
258 Conversation conversation = xmppConnectionService.findOrCreateConversation(this.accounts.get(0), jid, false);
259 switchToConversation(conversation,null);
260 finish();
261 }
262 }
263 }
264
265
266 if (xmppConnectionService.getConversationCount() == 0) {
267 getActionBar().setDisplayHomeAsUpEnabled(false);
268 getActionBar().setHomeButtonEnabled(false);
269 }
270 this.rosterContacts.clear();
271 for (int i = 0; i < accounts.size(); ++i) {
272 rosterContacts.addAll(xmppConnectionService.getRoster(accounts.get(i)));
273 }
274 updateAggregatedContacts();
275 }
276
277 @Override
278 public boolean onCreateOptionsMenu(Menu menu) {
279 // Inflate the menu; this adds items to the action bar if it is present.
280 getMenuInflater().inflate(R.menu.newconversation, menu);
281 return true;
282 }
283
284 @Override
285 public boolean onOptionsItemSelected(MenuItem item) {
286 switch (item.getItemId()) {
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}