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 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("Add to phone book");
93 builder.setMessage("Do you want to add " + contact.getJid()
94 + " to your phones contact list?");
95 builder.setNegativeButton("Cancel", null);
96 builder.setPositiveButton("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 send = (CheckBox) findViewById(R.id.details_send_presence);
116 receive = (CheckBox) findViewById(R.id.details_receive_presence);
117 askAgain = (TextView) findViewById(R.id.ask_again);
118 badge = (QuickContactBadge) findViewById(R.id.details_contact_badge);
119 keys = (LinearLayout) findViewById(R.id.details_contact_keys);
120 getActionBar().setHomeButtonEnabled(true);
121 getActionBar().setDisplayHomeAsUpEnabled(true);
122
123 }
124
125 @Override
126 public boolean onOptionsItemSelected(MenuItem menuItem) {
127 AlertDialog.Builder builder = new AlertDialog.Builder(this);
128 builder.setNegativeButton("Cancel", null);
129 switch (menuItem.getItemId()) {
130 case android.R.id.home:
131 finish();
132 break;
133 case R.id.action_delete_contact:
134 builder.setTitle("Delete from roster")
135 .setMessage(
136 getString(R.string.remove_contact_text,
137 contact.getJid()))
138 .setPositiveButton("Delete", removeFromRoster).create()
139 .show();
140 break;
141 case R.id.action_edit_contact:
142 if (contact.getSystemAccount() == null) {
143
144 View view = (View) getLayoutInflater().inflate(
145 R.layout.edit_contact_name, null);
146 name = (EditText) view.findViewById(R.id.editText1);
147 name.setText(contact.getDisplayName());
148 builder.setView(view).setTitle(contact.getJid())
149 .setPositiveButton("Edit", editContactNameListener)
150 .create().show();
151
152 } else {
153 Intent intent = new Intent(Intent.ACTION_EDIT);
154 String[] systemAccount = contact.getSystemAccount().split("#");
155 long id = Long.parseLong(systemAccount[0]);
156 Uri uri = Contacts.getLookupUri(id, systemAccount[1]);
157 intent.setDataAndType(uri, Contacts.CONTENT_ITEM_TYPE);
158 intent.putExtra("finishActivityOnSaveCompleted", true);
159 startActivity(intent);
160 }
161 break;
162 }
163 return super.onOptionsItemSelected(menuItem);
164 }
165
166 @Override
167 public boolean onCreateOptionsMenu(Menu menu) {
168 getMenuInflater().inflate(R.menu.contact_details, menu);
169 return true;
170 }
171
172 private void populateView() {
173 setTitle(contact.getDisplayName());
174 if (contact.getOption(Contact.Options.FROM)) {
175 send.setChecked(true);
176 } else {
177 send.setText(R.string.preemptively_grant);
178 if (contact
179 .getOption(Contact.Options.PREEMPTIVE_GRANT)) {
180 send.setChecked(true);
181 } else {
182 send.setChecked(false);
183 }
184 }
185 if (contact.getOption(Contact.Options.TO)) {
186 receive.setChecked(true);
187 } else {
188 receive.setText(R.string.ask_for_presence_updates);
189 askAgain.setVisibility(View.VISIBLE);
190 askAgain.setOnClickListener(new OnClickListener() {
191
192 @Override
193 public void onClick(View v) {
194 Toast.makeText(getApplicationContext(), "Asked for presence updates",Toast.LENGTH_SHORT).show();
195 xmppConnectionService.requestPresenceUpdatesFrom(contact);
196
197 }
198 });
199 if (contact.getOption(Contact.Options.ASKING)) {
200 receive.setChecked(true);
201 } else {
202 receive.setChecked(false);
203 }
204 }
205
206 switch (contact.getMostAvailableStatus()) {
207 case Presences.CHAT:
208 status.setText("free to chat");
209 status.setTextColor(0xFF83b600);
210 break;
211 case Presences.ONLINE:
212 status.setText("online");
213 status.setTextColor(0xFF83b600);
214 break;
215 case Presences.AWAY:
216 status.setText("away");
217 status.setTextColor(0xFFffa713);
218 break;
219 case Presences.XA:
220 status.setText("extended away");
221 status.setTextColor(0xFFffa713);
222 break;
223 case Presences.DND:
224 status.setText("do not disturb");
225 status.setTextColor(0xFFe92727);
226 break;
227 case Presences.OFFLINE:
228 status.setText("offline");
229 status.setTextColor(0xFFe92727);
230 break;
231 default:
232 status.setText("offline");
233 status.setTextColor(0xFFe92727);
234 break;
235 }
236 if (contact.getPresences().size() > 1) {
237 contactJidTv.setText(contact.getJid()+" ("+contact.getPresences().size()+")");
238 } else {
239 contactJidTv.setText(contact.getJid());
240 }
241 accountJidTv.setText(contact.getAccount().getJid());
242
243 UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext());
244
245 if (contact.getSystemAccount() == null) {
246 badge.setOnClickListener(onBadgeClick);
247 }
248
249 keys.removeAllViews();
250 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
251 for (Iterator<String> iterator = contact.getOtrFingerprints()
252 .iterator(); iterator.hasNext();) {
253 String otrFingerprint = iterator.next();
254 View view = (View) inflater.inflate(R.layout.contact_key, null);
255 TextView key = (TextView) view.findViewById(R.id.key);
256 TextView keyType = (TextView) view.findViewById(R.id.key_type);
257 keyType.setText("OTR Fingerprint");
258 key.setText(otrFingerprint);
259 keys.addView(view);
260 }
261 if (contact.getPgpKeyId() != 0) {
262 View view = (View) inflater.inflate(R.layout.contact_key, null);
263 TextView key = (TextView) view.findViewById(R.id.key);
264 TextView keyType = (TextView) view.findViewById(R.id.key_type);
265 keyType.setText("PGP Key ID");
266 key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId()));
267 view.setOnClickListener(new OnClickListener() {
268
269 @Override
270 public void onClick(View v) {
271 PgpEngine pgp = activity.xmppConnectionService.getPgpEngine();
272 if (pgp!=null) {
273 PendingIntent intent = pgp.getIntentForKey(contact);
274 if (intent!=null) {
275 try {
276 startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0);
277 } catch (SendIntentException e) {
278
279 }
280 }
281 }
282 }
283 });
284 keys.addView(view);
285 }
286 }
287
288 @Override
289 public void onBackendConnected() {
290 if ((accountJid != null)&&(contactJid != null)) {
291 Account account = xmppConnectionService.findAccountByJid(accountJid);
292 if (account==null) {
293 return;
294 }
295 this.contact = account.getRoster().getContact(contactJid);
296 populateView();
297 }
298 }
299
300 @Override
301 protected void onStop() {
302 super.onStop();
303 boolean updated = false;
304 if (contact.getOption(Contact.Options.FROM)) {
305 if (!send.isChecked()) {
306 contact.resetOption(Contact.Options.FROM);
307 contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
308 activity.xmppConnectionService.stopPresenceUpdatesTo(contact);
309 updated = true;
310 }
311 } else {
312 if (contact
313 .getOption(Contact.Options.PREEMPTIVE_GRANT)) {
314 if (!send.isChecked()) {
315 contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
316 updated = true;
317 }
318 } else {
319 if (send.isChecked()) {
320 contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
321 updated = true;
322 }
323 }
324 }
325 if (contact.getOption(Contact.Options.TO)) {
326 if (!receive.isChecked()) {
327 contact.resetOption(Contact.Options.TO);
328 activity.xmppConnectionService.stopPresenceUpdatesFrom(contact);
329 updated = true;
330 }
331 } else {
332 if (contact.getOption(Contact.Options.ASKING)) {
333 if (!receive.isChecked()) {
334 contact.resetOption(Contact.Options.ASKING);
335 activity.xmppConnectionService
336 .stopPresenceUpdatesFrom(contact);
337 updated = true;
338 }
339 } else {
340 if (receive.isChecked()) {
341 contact.setOption(Contact.Options.ASKING);
342 activity.xmppConnectionService
343 .requestPresenceUpdatesFrom(contact);
344 updated = true;
345 }
346 }
347 }
348 if (updated) {
349 Toast.makeText(getApplicationContext(), "Subscription updated", Toast.LENGTH_SHORT).show();
350 }
351 }
352
353}