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}