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.services.XmppConnectionService;
 35import eu.siacs.conversations.utils.UIHelper;
 36import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
 37
 38public class ContactDetailsActivity extends XmppActivity {
 39	public static final String ACTION_VIEW_CONTACT = "view_contact";
 40
 41	protected ContactDetailsActivity activity = this;
 42
 43	private Contact contact;
 44	
 45	private String accountJid;
 46	private String contactJid;
 47	
 48	private EditText name;
 49	private TextView contactJidTv;
 50	private TextView accountJidTv;
 51	private TextView status;
 52	private TextView lastseen;
 53	private CheckBox send;
 54	private CheckBox receive;
 55	private QuickContactBadge badge;
 56
 57	private DialogInterface.OnClickListener removeFromRoster = new DialogInterface.OnClickListener() {
 58
 59		@Override
 60		public void onClick(DialogInterface dialog, int which) {
 61			activity.xmppConnectionService.deleteContactOnServer(contact);
 62			activity.finish();
 63		}
 64	};
 65
 66	private DialogInterface.OnClickListener editContactNameListener = new DialogInterface.OnClickListener() {
 67
 68		@Override
 69		public void onClick(DialogInterface dialog, int which) {
 70			contact.setServerName(name.getText().toString());
 71			activity.xmppConnectionService.pushContactToServer(contact);
 72			populateView();
 73		}
 74	};
 75
 76	private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() {
 77
 78		@Override
 79		public void onClick(DialogInterface dialog, int which) {
 80			Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
 81			intent.setType(Contacts.CONTENT_ITEM_TYPE);
 82			intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid());
 83			intent.putExtra(Intents.Insert.IM_PROTOCOL,
 84					CommonDataKinds.Im.PROTOCOL_JABBER);
 85			intent.putExtra("finishActivityOnSaveCompleted", true);
 86			activity.startActivityForResult(intent, 0);
 87		}
 88	};
 89	private OnClickListener onBadgeClick = new OnClickListener() {
 90
 91		@Override
 92		public void onClick(View v) {
 93			AlertDialog.Builder builder = new AlertDialog.Builder(activity);
 94			builder.setTitle(getString(R.string.action_add_phone_book));
 95			builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid()));
 96			builder.setNegativeButton(getString(R.string.cancel), null);
 97			builder.setPositiveButton(getString(R.string.add), addToPhonebook);
 98			builder.create().show();
 99		}
100	};
101
102	private LinearLayout keys;
103
104	@Override
105	protected void onCreate(Bundle savedInstanceState) {
106		super.onCreate(savedInstanceState);
107		if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
108			this.accountJid = getIntent().getExtras().getString("account");
109			this.contactJid = getIntent().getExtras().getString("contact");
110		}
111		setContentView(R.layout.activity_contact_details);
112
113		contactJidTv = (TextView) findViewById(R.id.details_contactjid);
114		accountJidTv = (TextView) findViewById(R.id.details_account);
115		status = (TextView) findViewById(R.id.details_contactstatus);
116		lastseen = (TextView) findViewById(R.id.details_lastseen);
117		send = (CheckBox) findViewById(R.id.details_send_presence);
118		receive = (CheckBox) findViewById(R.id.details_receive_presence);
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 if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)){
178			send.setChecked(false);
179		} else {
180			send.setText(R.string.preemptively_grant);
181			if (contact
182					.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
183				send.setChecked(true);
184			} else {
185				send.setChecked(false);
186			}
187		}
188		if (contact.getOption(Contact.Options.TO)) {
189			receive.setChecked(true);
190		} else {
191			receive.setText(R.string.ask_for_presence_updates);
192			if (contact.getOption(Contact.Options.ASKING)) {
193				receive.setChecked(true);
194			} else {
195				receive.setChecked(false);
196			}
197		}
198		
199		lastseen.setText(UIHelper.lastseen(getApplicationContext(),contact.lastseen.time));
200
201		switch (contact.getMostAvailableStatus()) {
202		case Presences.CHAT:
203			status.setText(R.string.contact_status_free_to_chat);
204			status.setTextColor(0xFF83b600);
205			break;
206		case Presences.ONLINE:
207			status.setText(R.string.contact_status_online);
208			status.setTextColor(0xFF83b600);
209			break;
210		case Presences.AWAY:
211			status.setText(R.string.contact_status_away);
212			status.setTextColor(0xFFffa713);
213			break;
214		case Presences.XA:
215			status.setText(R.string.contact_status_extended_away);
216			status.setTextColor(0xFFffa713);
217			break;
218		case Presences.DND:
219			status.setText(R.string.contact_status_do_not_disturb);
220			status.setTextColor(0xFFe92727);
221			break;
222		case Presences.OFFLINE:
223			status.setText(R.string.contact_status_offline);
224			status.setTextColor(0xFFe92727);
225			break;
226		default:
227			status.setText(R.string.contact_status_offline);
228			status.setTextColor(0xFFe92727);
229			break;
230		}
231		if (contact.getPresences().size() > 1) {
232			contactJidTv.setText(contact.getJid()+" ("+contact.getPresences().size()+")");
233		} else {
234			contactJidTv.setText(contact.getJid());
235		}
236		accountJidTv.setText(contact.getAccount().getJid());
237
238		UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext());
239
240		if (contact.getSystemAccount() == null) {
241			badge.setOnClickListener(onBadgeClick);
242		}
243
244		keys.removeAllViews();
245		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
246		for (Iterator<String> iterator = contact.getOtrFingerprints()
247				.iterator(); iterator.hasNext();) {
248			String otrFingerprint = iterator.next();
249			View view = (View) inflater.inflate(R.layout.contact_key, null);
250			TextView key = (TextView) view.findViewById(R.id.key);
251			TextView keyType = (TextView) view.findViewById(R.id.key_type);
252			keyType.setText("OTR Fingerprint");
253			key.setText(otrFingerprint);
254			keys.addView(view);
255		}
256		if (contact.getPgpKeyId() != 0) {
257			View view = (View) inflater.inflate(R.layout.contact_key, null);
258			TextView key = (TextView) view.findViewById(R.id.key);
259			TextView keyType = (TextView) view.findViewById(R.id.key_type);
260			keyType.setText("PGP Key ID");
261			key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
262			view.setOnClickListener(new OnClickListener() {
263				
264				@Override
265				public void onClick(View v) {
266					PgpEngine pgp = activity.xmppConnectionService.getPgpEngine();
267					if (pgp!=null) {
268						PendingIntent intent = pgp.getIntentForKey(contact);
269						if (intent!=null) {
270							try {
271								startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0);
272							} catch (SendIntentException e) {
273								
274							}
275						}
276					}
277				}
278			});
279			keys.addView(view);
280		}
281	}
282
283	@Override
284	public void onBackendConnected() {
285		if ((accountJid != null)&&(contactJid != null)) {
286			Account account = xmppConnectionService.findAccountByJid(accountJid);
287			if (account==null) {
288				return;
289			}
290			this.contact = account.getRoster().getContact(contactJid);
291			populateView();
292		}
293	}
294
295	@Override
296	protected void onStop() {
297		super.onStop();
298		XmppConnectionService xcs = activity.xmppConnectionService;
299		PresencePacket packet = null;
300		boolean updated = false;
301		if (contact!=null) {
302			boolean online = contact.getAccount().getStatus() == Account.STATUS_ONLINE;
303			if (contact.getOption(Contact.Options.FROM)) {
304				if (!send.isChecked()) {
305					if (online) {
306						contact.resetOption(Contact.Options.FROM);
307						contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
308						packet = xcs.getPresenceGenerator().stopPresenceUpdatesTo(contact);
309					}
310					updated = true;
311				}
312			} else {
313				if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
314					if (!send.isChecked()) {
315						if (online) {
316							contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
317						}
318						updated = true;
319					}
320				} else {
321					if (send.isChecked()) {
322						if (online) {
323							if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
324								packet = xcs.getPresenceGenerator().sendPresenceUpdatesTo(contact);
325							} else {
326								contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
327							}
328						}
329						updated = true;
330					}
331				}
332			}
333			if (contact.getOption(Contact.Options.TO)) {
334				if (!receive.isChecked()) {
335					if (online) {
336						contact.resetOption(Contact.Options.TO);
337						packet = xcs.getPresenceGenerator().stopPresenceUpdatesFrom(contact);
338					}
339					updated = true;
340				}
341			} else {
342				if (contact.getOption(Contact.Options.ASKING)) {
343					if (!receive.isChecked()) {
344						if (online) {
345							contact.resetOption(Contact.Options.ASKING);
346							packet = xcs.getPresenceGenerator().stopPresenceUpdatesFrom(contact);
347						}
348						updated = true;
349					}
350				} else {
351					if (receive.isChecked()) {
352						if (online) {
353							contact.setOption(Contact.Options.ASKING);
354							packet = xcs.getPresenceGenerator().requestPresenceUpdatesFrom(contact);
355						}
356						updated = true;
357					}
358				}
359			}
360			if (updated) {
361				if (online) {
362					if (packet!=null) {
363						xcs.sendPresencePacket(contact.getAccount(), packet);
364					}
365					Toast.makeText(getApplicationContext(), getString(R.string.subscription_updated), Toast.LENGTH_SHORT).show();
366				} else {
367					Toast.makeText(getApplicationContext(), getString(R.string.subscription_not_updated_offline), Toast.LENGTH_SHORT).show();
368				}
369			}
370		}
371	}
372
373}