ContactDetailsActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import java.util.Iterator;
  4
  5import org.openintents.openpgp.util.OpenPgpUtils;
  6
  7import android.app.AlertDialog;
  8import android.app.PendingIntent;
  9import android.content.Context;
 10import android.content.DialogInterface;
 11import android.content.Intent;
 12import android.content.IntentSender.SendIntentException;
 13import android.net.Uri;
 14import android.os.Bundle;
 15import android.provider.ContactsContract.CommonDataKinds;
 16import android.provider.ContactsContract.Contacts;
 17import android.provider.ContactsContract.Intents;
 18import android.view.LayoutInflater;
 19import android.view.Menu;
 20import android.view.MenuItem;
 21import android.view.View;
 22import android.view.View.OnClickListener;
 23import android.widget.CheckBox;
 24import android.widget.EditText;
 25import android.widget.LinearLayout;
 26import android.widget.QuickContactBadge;
 27import android.widget.TextView;
 28import android.widget.Toast;
 29import eu.siacs.conversations.R;
 30import eu.siacs.conversations.crypto.PgpEngine;
 31import eu.siacs.conversations.entities.Account;
 32import eu.siacs.conversations.entities.Contact;
 33import eu.siacs.conversations.entities.Presences;
 34import eu.siacs.conversations.utils.UIHelper;
 35
 36public class ContactDetailsActivity extends XmppActivity {
 37	public static final String ACTION_VIEW_CONTACT = "view_contact";
 38
 39	protected ContactDetailsActivity activity = this;
 40
 41	private Contact contact;
 42	
 43	private String accountJid;
 44	private String contactJid;
 45	
 46	private EditText name;
 47	private TextView contactJidTv;
 48	private TextView accountJidTv;
 49	private TextView status;
 50	private TextView askAgain;
 51	private TextView lastseen;
 52	private CheckBox send;
 53	private CheckBox receive;
 54	private QuickContactBadge badge;
 55
 56	private DialogInterface.OnClickListener removeFromRoster = new DialogInterface.OnClickListener() {
 57
 58		@Override
 59		public void onClick(DialogInterface dialog, int which) {
 60			activity.xmppConnectionService.deleteContactOnServer(contact);
 61			activity.finish();
 62		}
 63	};
 64
 65	private DialogInterface.OnClickListener editContactNameListener = new DialogInterface.OnClickListener() {
 66
 67		@Override
 68		public void onClick(DialogInterface dialog, int which) {
 69			contact.setServerName(name.getText().toString());
 70			activity.xmppConnectionService.pushContactToServer(contact);
 71			populateView();
 72		}
 73	};
 74
 75	private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() {
 76
 77		@Override
 78		public void onClick(DialogInterface dialog, int which) {
 79			Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
 80			intent.setType(Contacts.CONTENT_ITEM_TYPE);
 81			intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid());
 82			intent.putExtra(Intents.Insert.IM_PROTOCOL,
 83					CommonDataKinds.Im.PROTOCOL_JABBER);
 84			intent.putExtra("finishActivityOnSaveCompleted", true);
 85			activity.startActivityForResult(intent, 0);
 86		}
 87	};
 88	private OnClickListener onBadgeClick = new OnClickListener() {
 89
 90		@Override
 91		public void onClick(View v) {
 92			AlertDialog.Builder builder = new AlertDialog.Builder(activity);
 93			builder.setTitle(getString(R.string.action_add_phone_book));
 94			builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid()));
 95			builder.setNegativeButton(getString(R.string.cancel), null);
 96			builder.setPositiveButton(getString(R.string.add), addToPhonebook);
 97			builder.create().show();
 98		}
 99	};
100
101	private LinearLayout keys;
102
103	@Override
104	protected void onCreate(Bundle savedInstanceState) {
105		super.onCreate(savedInstanceState);
106		if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
107			this.accountJid = getIntent().getExtras().getString("account");
108			this.contactJid = getIntent().getExtras().getString("contact");
109		}
110		setContentView(R.layout.activity_contact_details);
111
112		contactJidTv = (TextView) findViewById(R.id.details_contactjid);
113		accountJidTv = (TextView) findViewById(R.id.details_account);
114		status = (TextView) findViewById(R.id.details_contactstatus);
115		lastseen = (TextView) findViewById(R.id.details_lastseen);
116		send = (CheckBox) findViewById(R.id.details_send_presence);
117		receive = (CheckBox) findViewById(R.id.details_receive_presence);
118		askAgain = (TextView) findViewById(R.id.ask_again);
119		badge = (QuickContactBadge) findViewById(R.id.details_contact_badge);
120		keys = (LinearLayout) findViewById(R.id.details_contact_keys);
121		getActionBar().setHomeButtonEnabled(true);
122		getActionBar().setDisplayHomeAsUpEnabled(true);
123
124	}
125
126	@Override
127	public boolean onOptionsItemSelected(MenuItem menuItem) {
128		AlertDialog.Builder builder = new AlertDialog.Builder(this);
129		builder.setNegativeButton(getString(R.string.cancel), null);
130		switch (menuItem.getItemId()) {
131		case android.R.id.home:
132			finish();
133			break;
134		case R.id.action_delete_contact:
135			builder.setTitle(getString(R.string.action_delete_contact))
136					.setMessage(
137							getString(R.string.remove_contact_text,
138									contact.getJid()))
139					.setPositiveButton(getString(R.string.delete), removeFromRoster).create()
140					.show();
141			break;
142		case R.id.action_edit_contact:
143			if (contact.getSystemAccount() == null) {
144
145				View view = (View) getLayoutInflater().inflate(
146						R.layout.edit_contact_name, null);
147				name = (EditText) view.findViewById(R.id.editText1);
148				name.setText(contact.getDisplayName());
149				builder.setView(view).setTitle(contact.getJid())
150						.setPositiveButton(getString(R.string.edit), editContactNameListener)
151						.create().show();
152
153			} else {
154				Intent intent = new Intent(Intent.ACTION_EDIT);
155				String[] systemAccount = contact.getSystemAccount().split("#");
156				long id = Long.parseLong(systemAccount[0]);
157				Uri uri = Contacts.getLookupUri(id, systemAccount[1]);
158				intent.setDataAndType(uri, Contacts.CONTENT_ITEM_TYPE);
159				intent.putExtra("finishActivityOnSaveCompleted", true);
160				startActivity(intent);
161			}
162			break;
163		}
164		return super.onOptionsItemSelected(menuItem);
165	}
166
167	@Override
168	public boolean onCreateOptionsMenu(Menu menu) {
169		getMenuInflater().inflate(R.menu.contact_details, menu);
170		return true;
171	}
172
173	private void populateView() {
174		setTitle(contact.getDisplayName());
175		if (contact.getOption(Contact.Options.FROM)) {
176			send.setChecked(true);
177		} else {
178			send.setText(R.string.preemptively_grant);
179			if (contact
180					.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
181				send.setChecked(true);
182			} else {
183				send.setChecked(false);
184			}
185		}
186		if (contact.getOption(Contact.Options.TO)) {
187			receive.setChecked(true);
188		} else {
189			receive.setText(R.string.ask_for_presence_updates);
190			askAgain.setVisibility(View.VISIBLE);
191			askAgain.setOnClickListener(new OnClickListener() {
192				
193				@Override
194				public void onClick(View v) {
195					Toast.makeText(getApplicationContext(), getString(R.string.asked_for_presence_updates),
196                            Toast.LENGTH_SHORT).show();
197					xmppConnectionService.requestPresenceUpdatesFrom(contact);
198					
199				}
200			});
201			if (contact.getOption(Contact.Options.ASKING)) {
202				receive.setChecked(true);
203			} else {
204				receive.setChecked(false);
205			}
206		}
207		
208		lastseen.setText(UIHelper.lastseen(getApplicationContext(),contact.lastseen.time));
209
210		switch (contact.getMostAvailableStatus()) {
211		case Presences.CHAT:
212			status.setText(R.string.contact_status_free_to_chat);
213			status.setTextColor(0xFF83b600);
214			break;
215		case Presences.ONLINE:
216			status.setText(R.string.contact_status_online);
217			status.setTextColor(0xFF83b600);
218			break;
219		case Presences.AWAY:
220			status.setText(R.string.contact_status_away);
221			status.setTextColor(0xFFffa713);
222			break;
223		case Presences.XA:
224			status.setText(R.string.contact_status_extended_away);
225			status.setTextColor(0xFFffa713);
226			break;
227		case Presences.DND:
228			status.setText(R.string.contact_status_do_not_disturb);
229			status.setTextColor(0xFFe92727);
230			break;
231		case Presences.OFFLINE:
232			status.setText(R.string.contact_status_offline);
233			status.setTextColor(0xFFe92727);
234			break;
235		default:
236			status.setText(R.string.contact_status_offline);
237			status.setTextColor(0xFFe92727);
238			break;
239		}
240		if (contact.getPresences().size() > 1) {
241			contactJidTv.setText(contact.getJid()+" ("+contact.getPresences().size()+")");
242		} else {
243			contactJidTv.setText(contact.getJid());
244		}
245		accountJidTv.setText(contact.getAccount().getJid());
246
247		UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext());
248
249		if (contact.getSystemAccount() == null) {
250			badge.setOnClickListener(onBadgeClick);
251		}
252
253		keys.removeAllViews();
254		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
255		for (Iterator<String> iterator = contact.getOtrFingerprints()
256				.iterator(); iterator.hasNext();) {
257			String otrFingerprint = iterator.next();
258			View view = (View) inflater.inflate(R.layout.contact_key, null);
259			TextView key = (TextView) view.findViewById(R.id.key);
260			TextView keyType = (TextView) view.findViewById(R.id.key_type);
261			keyType.setText("OTR Fingerprint");
262			key.setText(otrFingerprint);
263			keys.addView(view);
264		}
265		if (contact.getPgpKeyId() != 0) {
266			View view = (View) inflater.inflate(R.layout.contact_key, null);
267			TextView key = (TextView) view.findViewById(R.id.key);
268			TextView keyType = (TextView) view.findViewById(R.id.key_type);
269			keyType.setText("PGP Key ID");
270			key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
271			view.setOnClickListener(new OnClickListener() {
272				
273				@Override
274				public void onClick(View v) {
275					PgpEngine pgp = activity.xmppConnectionService.getPgpEngine();
276					if (pgp!=null) {
277						PendingIntent intent = pgp.getIntentForKey(contact);
278						if (intent!=null) {
279							try {
280								startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0);
281							} catch (SendIntentException e) {
282								
283							}
284						}
285					}
286				}
287			});
288			keys.addView(view);
289		}
290	}
291
292	@Override
293	public void onBackendConnected() {
294		if ((accountJid != null)&&(contactJid != null)) {
295			Account account = xmppConnectionService.findAccountByJid(accountJid);
296			if (account==null) {
297				return;
298			}
299			this.contact = account.getRoster().getContact(contactJid);
300			populateView();
301		}
302	}
303
304	@Override
305	protected void onStop() {
306		super.onStop();
307		boolean updated = false;
308		if (contact!=null) {
309			boolean online = contact.getAccount().getStatus() == Account.STATUS_ONLINE;
310			if (contact.getOption(Contact.Options.FROM)) {
311				if (!send.isChecked()) {
312					if (online) {
313						contact.resetOption(Contact.Options.FROM);
314						contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
315						activity.xmppConnectionService.stopPresenceUpdatesTo(contact);
316					}
317					updated = true;
318				}
319			} else {
320				if (contact
321						.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
322					if (!send.isChecked()) {
323						if (online) {
324							contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
325						}
326						updated = true;
327					}
328				} else {
329					if (send.isChecked()) {
330						if (online) {
331							contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
332						}
333						updated = true;
334					}
335				}
336			}
337			if (contact.getOption(Contact.Options.TO)) {
338				if (!receive.isChecked()) {
339					if (online) {
340						contact.resetOption(Contact.Options.TO);
341						activity.xmppConnectionService.stopPresenceUpdatesFrom(contact);
342					}
343					updated = true;
344				}
345			} else {
346				if (contact.getOption(Contact.Options.ASKING)) {
347					if (!receive.isChecked()) {
348						if (online) {
349							contact.resetOption(Contact.Options.ASKING);
350							activity.xmppConnectionService
351								.stopPresenceUpdatesFrom(contact);
352						}
353						updated = true;
354					}
355				} else {
356					if (receive.isChecked()) {
357						if (online) {
358							contact.setOption(Contact.Options.ASKING);
359							activity.xmppConnectionService
360								.requestPresenceUpdatesFrom(contact);
361						}
362						updated = true;
363					}
364				}
365			}
366			if (updated) {
367				if (online) {
368					Toast.makeText(getApplicationContext(), getString(R.string.subscription_updated), Toast.LENGTH_SHORT).show();
369				} else {
370					Toast.makeText(getApplicationContext(), getString(R.string.subscription_not_updated_offline), Toast.LENGTH_SHORT).show();
371				}
372			}
373		}
374	}
375
376}