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