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 ImageView imageView = (ImageView) view
139 .findViewById(R.id.contact_photo);
140 imageView.setImageBitmap(UIHelper.getContactPicture(contact,null,90,this.getContext()));
141 return view;
142 }
143 };
144 contactsView.setAdapter(contactsAdapter);
145 final Activity activity = this;
146 contactsView.setOnItemClickListener(new OnItemClickListener() {
147
148 @Override
149 public void onItemClick(AdapterView<?> arg0, final View view,
150 int pos, long arg3) {
151 final Contact clickedContact = aggregatedContacts.get(pos);
152
153 if ((clickedContact.getAccount()==null)&&(accounts.size()>1)) {
154 String[] accountList = new String[accounts.size()];
155 for (int i = 0; i < accounts.size(); ++i) {
156 accountList[i] = accounts.get(i).getJid();
157 }
158
159 AlertDialog.Builder accountChooser = new AlertDialog.Builder(
160 activity);
161 accountChooser.setTitle("Choose account");
162 accountChooser.setItems(accountList, new OnClickListener() {
163
164 @Override
165 public void onClick(DialogInterface dialog, int which) {
166 clickedContact.setAccount(accounts.get(which));
167 showIsMucDialogIfNeeded(clickedContact);
168 }
169 });
170 accountChooser.create().show();
171 } else {
172 if (clickedContact.getAccount()==null) {
173 clickedContact.setAccount(accounts.get(0));
174 }
175 showIsMucDialogIfNeeded(clickedContact);
176 }
177 }
178 });
179 contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
180
181 @Override
182 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
183 int pos, long arg3) {
184 Intent intent = new Intent(activity,ContactDetailsActivity.class);
185 intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
186 intent.putExtra("uuid", aggregatedContacts.get(pos).getUuid());
187 startActivity(intent);
188 return true;
189 }
190 });
191 }
192
193 public void showIsMucDialogIfNeeded(final Contact clickedContact) {
194 if (clickedContact.couldBeMuc()) {
195 AlertDialog.Builder dialog = new AlertDialog.Builder(this);
196 dialog.setTitle("Multi User Conference");
197 dialog.setMessage("Are you trying to join a conference?");
198 dialog.setPositiveButton("Yes", new OnClickListener() {
199
200 @Override
201 public void onClick(DialogInterface dialog, int which) {
202 startConversation(clickedContact, clickedContact.getAccount(),true);
203 }
204 });
205 dialog.setNegativeButton("No", new OnClickListener() {
206
207 @Override
208 public void onClick(DialogInterface dialog, int which) {
209 startConversation(clickedContact, clickedContact.getAccount(),false);
210 }
211 });
212 dialog.create().show();
213 } else {
214 startConversation(clickedContact, clickedContact.getAccount(),false);
215 }
216 }
217
218 public void startConversation(Contact contact, Account account, boolean muc) {
219 if (!contact.isInRoster()) {
220 xmppConnectionService.createContact(contact);
221 }
222 Conversation conversation = xmppConnectionService
223 .findOrCreateConversation(account, contact.getJid(), muc);
224
225 Intent viewConversationIntent = new Intent(this,
226 ConversationActivity.class);
227 viewConversationIntent.setAction(Intent.ACTION_VIEW);
228 viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
229 conversation.getUuid());
230 viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
231 viewConversationIntent.setFlags(viewConversationIntent.getFlags()
232 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
233 startActivity(viewConversationIntent);
234 }
235
236 @Override
237 void onBackendConnected() {
238 if (xmppConnectionService.getConversationCount() == 0) {
239 getActionBar().setDisplayHomeAsUpEnabled(false);
240 getActionBar().setHomeButtonEnabled(false);
241 }
242 this.accounts = xmppConnectionService.getAccounts();
243 this.rosterContacts.clear();
244 for (int i = 0; i < accounts.size(); ++i) {
245 xmppConnectionService.getRoster(accounts.get(i),
246 new OnRosterFetchedListener() {
247
248 @Override
249 public void onRosterFetched(List<Contact> roster) {
250 rosterContacts.addAll(roster);
251 runOnUiThread(new Runnable() {
252
253 @Override
254 public void run() {
255 updateAggregatedContacts();
256 }
257 });
258
259 }
260 });
261 }
262 }
263
264 @Override
265 public boolean onCreateOptionsMenu(Menu menu) {
266 // Inflate the menu; this adds items to the action bar if it is present.
267 getMenuInflater().inflate(R.menu.newconversation, menu);
268 return true;
269 }
270
271 @Override
272 public boolean onOptionsItemSelected(MenuItem item) {
273 switch (item.getItemId()) {
274 case R.id.action_refresh_contacts:
275 refreshContacts();
276 break;
277 default:
278 break;
279 }
280 return super.onOptionsItemSelected(item);
281 }
282
283 private void refreshContacts() {
284 final ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar1);
285 final EditText searchBar = (EditText) findViewById(R.id.new_conversation_search);
286 final TextView contactsHeader = (TextView) findViewById(R.id.contacts_header);
287 final ListView contactList = (ListView) findViewById(R.id.contactList);
288 searchBar.setVisibility(View.GONE);
289 contactsHeader.setVisibility(View.GONE);
290 contactList.setVisibility(View.GONE);
291 progress.setVisibility(View.VISIBLE);
292 this.accounts = xmppConnectionService.getAccounts();
293 this.rosterContacts.clear();
294 for (int i = 0; i < accounts.size(); ++i) {
295 if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
296 xmppConnectionService.updateRoster(accounts.get(i),
297 new OnRosterFetchedListener() {
298
299 @Override
300 public void onRosterFetched(
301 final List<Contact> roster) {
302 runOnUiThread(new Runnable() {
303
304 @Override
305 public void run() {
306 rosterContacts.addAll(roster);
307 progress.setVisibility(View.GONE);
308 searchBar.setVisibility(View.VISIBLE);
309 contactList.setVisibility(View.VISIBLE);
310 contactList.setVisibility(View.VISIBLE);
311 updateAggregatedContacts();
312 }
313 });
314 }
315 });
316 }
317 }
318 }
319}