1package eu.siacs.conversations.ui;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import eu.siacs.conversations.R;
7import eu.siacs.conversations.entities.Contact;
8import eu.siacs.conversations.entities.Conversation;
9import eu.siacs.conversations.entities.Message;
10import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
11import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
12import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
13import eu.siacs.conversations.ui.adapter.ConversationAdapter;
14import eu.siacs.conversations.utils.ExceptionHelper;
15import eu.siacs.conversations.utils.UIHelper;
16import android.net.Uri;
17import android.os.Bundle;
18import android.os.SystemClock;
19import android.provider.MediaStore;
20import android.annotation.SuppressLint;
21import android.app.ActionBar;
22import android.app.AlertDialog;
23import android.app.FragmentTransaction;
24import android.app.PendingIntent;
25import android.content.DialogInterface;
26import android.content.DialogInterface.OnClickListener;
27import android.content.IntentSender.SendIntentException;
28import android.content.Intent;
29import android.support.v4.widget.SlidingPaneLayout;
30import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
31import android.view.KeyEvent;
32import android.view.Menu;
33import android.view.MenuItem;
34import android.view.View;
35import android.widget.AdapterView;
36import android.widget.AdapterView.OnItemClickListener;
37import android.widget.ArrayAdapter;
38import android.widget.CheckBox;
39import android.widget.ListView;
40import android.widget.PopupMenu;
41import android.widget.PopupMenu.OnMenuItemClickListener;
42import android.widget.Toast;
43
44public class ConversationActivity extends XmppActivity implements
45 OnAccountUpdate, OnConversationUpdate, OnRosterUpdate {
46
47 public static final String VIEW_CONVERSATION = "viewConversation";
48 public static final String CONVERSATION = "conversationUuid";
49 public static final String TEXT = "text";
50 public static final String PRESENCE = "eu.siacs.conversations.presence";
51
52 public static final int REQUEST_SEND_MESSAGE = 0x0201;
53 public static final int REQUEST_DECRYPT_PGP = 0x0202;
54 private static final int REQUEST_ATTACH_FILE_DIALOG = 0x0203;
55 private static final int REQUEST_IMAGE_CAPTURE = 0x0204;
56 private static final int REQUEST_RECORD_AUDIO = 0x0205;
57 private static final int REQUEST_SEND_PGP_IMAGE = 0x0206;
58 public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207;
59
60 private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301;
61 private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
62 private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0303;
63
64 protected SlidingPaneLayout spl;
65
66 private List<Conversation> conversationList = new ArrayList<Conversation>();
67 private Conversation selectedConversation = null;
68 private ListView listView;
69
70 private boolean paneShouldBeOpen = true;
71 private ArrayAdapter<Conversation> listAdapter;
72
73 protected ConversationActivity activity = this;
74 private Toast prepareImageToast;
75
76 private Uri pendingImageUri = null;
77
78 public List<Conversation> getConversationList() {
79 return this.conversationList;
80 }
81
82 public Conversation getSelectedConversation() {
83 return this.selectedConversation;
84 }
85
86 public void setSelectedConversation(Conversation conversation) {
87 this.selectedConversation = conversation;
88 }
89
90 public ListView getConversationListView() {
91 return this.listView;
92 }
93
94 public SlidingPaneLayout getSlidingPaneLayout() {
95 return this.spl;
96 }
97
98 public boolean shouldPaneBeOpen() {
99 return paneShouldBeOpen;
100 }
101
102 @Override
103 protected void onCreate(Bundle savedInstanceState) {
104 super.onCreate(savedInstanceState);
105
106 setContentView(R.layout.fragment_conversations_overview);
107
108 listView = (ListView) findViewById(R.id.list);
109
110 getActionBar().setDisplayHomeAsUpEnabled(false);
111 getActionBar().setHomeButtonEnabled(false);
112
113 this.listAdapter = new ConversationAdapter(this, conversationList);
114 listView.setAdapter(this.listAdapter);
115
116 listView.setOnItemClickListener(new OnItemClickListener() {
117
118 @Override
119 public void onItemClick(AdapterView<?> arg0, View clickedView,
120 int position, long arg3) {
121 paneShouldBeOpen = false;
122 if (getSelectedConversation() != conversationList.get(position)) {
123 setSelectedConversation(conversationList.get(position));
124 swapConversationFragment();
125 } else {
126 spl.closePane();
127 }
128 }
129 });
130 spl = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout);
131 spl.setParallaxDistance(150);
132 spl.setShadowResource(R.drawable.es_slidingpane_shadow);
133 spl.setSliderFadeColor(0);
134 spl.setPanelSlideListener(new PanelSlideListener() {
135
136 @Override
137 public void onPanelOpened(View arg0) {
138 paneShouldBeOpen = true;
139 ActionBar ab = getActionBar();
140 if (ab != null) {
141 ab.setDisplayHomeAsUpEnabled(false);
142 ab.setHomeButtonEnabled(false);
143 ab.setTitle(R.string.app_name);
144 }
145 invalidateOptionsMenu();
146 hideKeyboard();
147 }
148
149 @Override
150 public void onPanelClosed(View arg0) {
151 paneShouldBeOpen = false;
152 if ((conversationList.size() > 0)
153 && (getSelectedConversation() != null)) {
154 ActionBar ab = getActionBar();
155 if (ab != null) {
156 ab.setDisplayHomeAsUpEnabled(true);
157 ab.setHomeButtonEnabled(true);
158 if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE
159 || activity.useSubjectToIdentifyConference()) {
160 ab.setTitle(getSelectedConversation().getName());
161 } else {
162 ab.setTitle(getSelectedConversation()
163 .getContactJid().split("/")[0]);
164 }
165 }
166 invalidateOptionsMenu();
167 if (!getSelectedConversation().isRead()) {
168 xmppConnectionService
169 .markRead(getSelectedConversation());
170 UIHelper.updateNotification(getApplicationContext(),
171 getConversationList(), null, false);
172 listView.invalidateViews();
173 }
174 }
175 }
176
177 @Override
178 public void onPanelSlide(View arg0, float arg1) {
179 // TODO Auto-generated method stub
180
181 }
182 });
183 }
184
185 @Override
186 public boolean onCreateOptionsMenu(Menu menu) {
187 getMenuInflater().inflate(R.menu.conversations, menu);
188 MenuItem menuSecure = (MenuItem) menu.findItem(R.id.action_security);
189 MenuItem menuArchive = (MenuItem) menu.findItem(R.id.action_archive);
190 MenuItem menuMucDetails = (MenuItem) menu
191 .findItem(R.id.action_muc_details);
192 MenuItem menuContactDetails = (MenuItem) menu
193 .findItem(R.id.action_contact_details);
194 MenuItem menuAttach = (MenuItem) menu.findItem(R.id.action_attach_file);
195 MenuItem menuClearHistory = (MenuItem) menu
196 .findItem(R.id.action_clear_history);
197 MenuItem menuAdd = (MenuItem) menu.findItem(R.id.action_add);
198 MenuItem menuInviteContact = (MenuItem) menu
199 .findItem(R.id.action_invite);
200 MenuItem menuMute = (MenuItem) menu.findItem(R.id.action_mute);
201
202 if ((spl.isOpen() && (spl.isSlideable()))) {
203 menuArchive.setVisible(false);
204 menuMucDetails.setVisible(false);
205 menuContactDetails.setVisible(false);
206 menuSecure.setVisible(false);
207 menuInviteContact.setVisible(false);
208 menuAttach.setVisible(false);
209 menuClearHistory.setVisible(false);
210 menuMute.setVisible(false);
211 } else {
212 menuAdd.setVisible(!spl.isSlideable());
213 if (this.getSelectedConversation() != null) {
214 if (this.getSelectedConversation().getLatestMessage()
215 .getEncryption() != Message.ENCRYPTION_NONE) {
216 menuSecure.setIcon(R.drawable.ic_action_secure);
217 }
218 if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
219 menuContactDetails.setVisible(false);
220 menuAttach.setVisible(false);
221 } else {
222 menuMucDetails.setVisible(false);
223 menuInviteContact.setVisible(false);
224 }
225 }
226 }
227 return true;
228 }
229
230 private void selectPresenceToAttachFile(final int attachmentChoice) {
231 selectPresence(getSelectedConversation(), new OnPresenceSelected() {
232
233 @Override
234 public void onPresenceSelected() {
235 if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO) {
236 pendingImageUri = xmppConnectionService.getFileBackend()
237 .getTakePhotoUri();
238 Intent takePictureIntent = new Intent(
239 MediaStore.ACTION_IMAGE_CAPTURE);
240 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
241 pendingImageUri);
242 if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
243 startActivityForResult(takePictureIntent,
244 REQUEST_IMAGE_CAPTURE);
245 }
246 } else if (attachmentChoice == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
247 Intent attachFileIntent = new Intent();
248 attachFileIntent.setType("image/*");
249 attachFileIntent.setAction(Intent.ACTION_GET_CONTENT);
250 Intent chooser = Intent.createChooser(attachFileIntent,
251 getString(R.string.attach_file));
252 startActivityForResult(chooser, REQUEST_ATTACH_FILE_DIALOG);
253 } else if (attachmentChoice == ATTACHMENT_CHOICE_RECORD_VOICE) {
254 Intent intent = new Intent(
255 MediaStore.Audio.Media.RECORD_SOUND_ACTION);
256 startActivityForResult(intent, REQUEST_RECORD_AUDIO);
257 }
258 }
259 });
260 }
261
262 private void attachFile(final int attachmentChoice) {
263 final Conversation conversation = getSelectedConversation();
264 if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
265 if (hasPgp()) {
266 if (conversation.getContact().getPgpKeyId() != 0) {
267 xmppConnectionService.getPgpEngine().hasKey(
268 conversation.getContact(),
269 new UiCallback<Contact>() {
270
271 @Override
272 public void userInputRequried(PendingIntent pi,
273 Contact contact) {
274 ConversationActivity.this.runIntent(pi,
275 attachmentChoice);
276 }
277
278 @Override
279 public void success(Contact contact) {
280 selectPresenceToAttachFile(attachmentChoice);
281 }
282
283 @Override
284 public void error(int error, Contact contact) {
285 displayErrorDialog(error);
286 }
287 });
288 } else {
289 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
290 .findFragmentByTag("conversation");
291 if (fragment != null) {
292 fragment.showNoPGPKeyDialog(false,
293 new OnClickListener() {
294
295 @Override
296 public void onClick(DialogInterface dialog,
297 int which) {
298 conversation
299 .setNextEncryption(Message.ENCRYPTION_NONE);
300 xmppConnectionService.databaseBackend.updateConversation(conversation);
301 selectPresenceToAttachFile(attachmentChoice);
302 }
303 });
304 }
305 }
306 } else {
307 showInstallPgpDialog();
308 }
309 } else if (getSelectedConversation().getNextEncryption(
310 forceEncryption()) == Message.ENCRYPTION_NONE) {
311 selectPresenceToAttachFile(attachmentChoice);
312 } else {
313 selectPresenceToAttachFile(attachmentChoice);
314 }
315 }
316
317 @Override
318 public boolean onOptionsItemSelected(MenuItem item) {
319 if (item.getItemId() == android.R.id.home) {
320 spl.openPane();
321 return true;
322 } else if (item.getItemId() == R.id.action_add) {
323 startActivity(new Intent(this, StartConversationActivity.class));
324 return true;
325 } else if (getSelectedConversation() != null) {
326 switch (item.getItemId()) {
327 case R.id.action_attach_file:
328 attachFileDialog();
329 break;
330 case R.id.action_archive:
331 this.endConversation(getSelectedConversation());
332 break;
333 case R.id.action_contact_details:
334 Contact contact = this.getSelectedConversation().getContact();
335 if (contact.showInRoster()) {
336 switchToContactDetails(contact);
337 } else {
338 showAddToRosterDialog(getSelectedConversation());
339 }
340 break;
341 case R.id.action_muc_details:
342 Intent intent = new Intent(this,
343 ConferenceDetailsActivity.class);
344 intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
345 intent.putExtra("uuid", getSelectedConversation().getUuid());
346 startActivity(intent);
347 break;
348 case R.id.action_invite:
349 inviteToConversation(getSelectedConversation());
350 break;
351 case R.id.action_security:
352 selectEncryptionDialog(getSelectedConversation());
353 break;
354 case R.id.action_clear_history:
355 clearHistoryDialog(getSelectedConversation());
356 break;
357 case R.id.action_mute:
358 muteConversationDialog(getSelectedConversation());
359 break;
360 default:
361 break;
362 }
363 return super.onOptionsItemSelected(item);
364 } else {
365 return super.onOptionsItemSelected(item);
366 }
367 }
368
369 public void endConversation(Conversation conversation) {
370 conversation.setStatus(Conversation.STATUS_ARCHIVED);
371 paneShouldBeOpen = true;
372 spl.openPane();
373 xmppConnectionService.archiveConversation(conversation);
374 if (conversationList.size() > 0) {
375 setSelectedConversation(conversationList.get(0));
376 } else {
377 setSelectedConversation(null);
378 }
379 }
380
381 @SuppressLint("InflateParams")
382 protected void clearHistoryDialog(final Conversation conversation) {
383 AlertDialog.Builder builder = new AlertDialog.Builder(this);
384 builder.setTitle(getString(R.string.clear_conversation_history));
385 View dialogView = getLayoutInflater().inflate(
386 R.layout.dialog_clear_history, null);
387 final CheckBox endConversationCheckBox = (CheckBox) dialogView
388 .findViewById(R.id.end_conversation_checkbox);
389 builder.setView(dialogView);
390 builder.setNegativeButton(getString(R.string.cancel), null);
391 builder.setPositiveButton(getString(R.string.delete_messages),
392 new OnClickListener() {
393
394 @Override
395 public void onClick(DialogInterface dialog, int which) {
396 activity.xmppConnectionService
397 .clearConversationHistory(conversation);
398 if (endConversationCheckBox.isChecked()) {
399 endConversation(conversation);
400 }
401 }
402 });
403 builder.create().show();
404 }
405
406 protected void attachFileDialog() {
407 View menuAttachFile = findViewById(R.id.action_attach_file);
408 if (menuAttachFile == null) {
409 return;
410 }
411 PopupMenu attachFilePopup = new PopupMenu(this, menuAttachFile);
412 attachFilePopup.inflate(R.menu.attachment_choices);
413 attachFilePopup
414 .setOnMenuItemClickListener(new OnMenuItemClickListener() {
415
416 @Override
417 public boolean onMenuItemClick(MenuItem item) {
418 switch (item.getItemId()) {
419 case R.id.attach_choose_picture:
420 attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
421 break;
422 case R.id.attach_take_picture:
423 attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
424 break;
425 case R.id.attach_record_voice:
426 attachFile(ATTACHMENT_CHOICE_RECORD_VOICE);
427 break;
428 }
429 return false;
430 }
431 });
432 attachFilePopup.show();
433 }
434
435 protected void selectEncryptionDialog(final Conversation conversation) {
436 View menuItemView = findViewById(R.id.action_security);
437 if (menuItemView == null) {
438 return;
439 }
440 PopupMenu popup = new PopupMenu(this, menuItemView);
441 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
442 .findFragmentByTag("conversation");
443 if (fragment != null) {
444 popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
445
446 @Override
447 public boolean onMenuItemClick(MenuItem item) {
448 switch (item.getItemId()) {
449 case R.id.encryption_choice_none:
450 conversation.setNextEncryption(Message.ENCRYPTION_NONE);
451 item.setChecked(true);
452 break;
453 case R.id.encryption_choice_otr:
454 conversation.setNextEncryption(Message.ENCRYPTION_OTR);
455 item.setChecked(true);
456 break;
457 case R.id.encryption_choice_pgp:
458 if (hasPgp()) {
459 if (conversation.getAccount().getKeys()
460 .has("pgp_signature")) {
461 conversation
462 .setNextEncryption(Message.ENCRYPTION_PGP);
463 item.setChecked(true);
464 } else {
465 announcePgp(conversation.getAccount(),
466 conversation);
467 }
468 } else {
469 showInstallPgpDialog();
470 }
471 break;
472 default:
473 conversation.setNextEncryption(Message.ENCRYPTION_NONE);
474 break;
475 }
476 xmppConnectionService.databaseBackend.updateConversation(conversation);
477 fragment.updateChatMsgHint();
478 return true;
479 }
480 });
481 popup.inflate(R.menu.encryption_choices);
482 MenuItem otr = popup.getMenu().findItem(R.id.encryption_choice_otr);
483 MenuItem none = popup.getMenu().findItem(
484 R.id.encryption_choice_none);
485 if (conversation.getMode() == Conversation.MODE_MULTI) {
486 otr.setEnabled(false);
487 } else {
488 if (forceEncryption()) {
489 none.setVisible(false);
490 }
491 }
492 switch (conversation.getNextEncryption(forceEncryption())) {
493 case Message.ENCRYPTION_NONE:
494 none.setChecked(true);
495 break;
496 case Message.ENCRYPTION_OTR:
497 otr.setChecked(true);
498 break;
499 case Message.ENCRYPTION_PGP:
500 popup.getMenu().findItem(R.id.encryption_choice_pgp)
501 .setChecked(true);
502 break;
503 default:
504 popup.getMenu().findItem(R.id.encryption_choice_none)
505 .setChecked(true);
506 break;
507 }
508 popup.show();
509 }
510 }
511
512 protected void muteConversationDialog(final Conversation conversation) {
513 AlertDialog.Builder builder = new AlertDialog.Builder(this);
514 builder.setTitle(R.string.disable_notifications_for_this_conversation);
515 final int[] durations = getResources().getIntArray(
516 R.array.mute_options_durations);
517 builder.setItems(R.array.mute_options_descriptions,
518 new OnClickListener() {
519
520 @Override
521 public void onClick(DialogInterface dialog, int which) {
522 long till;
523 if (durations[which] == -1) {
524 till = Long.MAX_VALUE;
525 } else {
526 till = SystemClock.elapsedRealtime()
527 + (durations[which] * 1000);
528 }
529 conversation.setMutedTill(till);
530 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
531 .findFragmentByTag("conversation");
532 if (selectedFragment != null) {
533 selectedFragment.updateMessages();
534 }
535 }
536 });
537 builder.create().show();
538 }
539
540 protected ConversationFragment swapConversationFragment() {
541 ConversationFragment selectedFragment = new ConversationFragment();
542 if (!isFinishing()) {
543
544 FragmentTransaction transaction = getFragmentManager()
545 .beginTransaction();
546 transaction.replace(R.id.selected_conversation, selectedFragment,
547 "conversation");
548
549 transaction.commitAllowingStateLoss();
550 }
551 return selectedFragment;
552 }
553
554 @Override
555 public boolean onKeyDown(int keyCode, KeyEvent event) {
556 if (keyCode == KeyEvent.KEYCODE_BACK) {
557 if (!spl.isOpen()) {
558 spl.openPane();
559 return false;
560 }
561 }
562 return super.onKeyDown(keyCode, event);
563 }
564
565 @Override
566 protected void onNewIntent(Intent intent) {
567 if (xmppConnectionServiceBound) {
568 if ((Intent.ACTION_VIEW.equals(intent.getAction()) && (VIEW_CONVERSATION
569 .equals(intent.getType())))) {
570 String convToView = (String) intent.getExtras().get(
571 CONVERSATION);
572 updateConversationList();
573 for (int i = 0; i < conversationList.size(); ++i) {
574 if (conversationList.get(i).getUuid().equals(convToView)) {
575 setSelectedConversation(conversationList.get(i));
576 break;
577 }
578 }
579 paneShouldBeOpen = false;
580 String text = intent.getExtras().getString(TEXT, null);
581 swapConversationFragment().setText(text);
582 }
583 } else {
584 handledViewIntent = false;
585 setIntent(intent);
586 }
587 }
588
589 @Override
590 public void onStart() {
591 super.onStart();
592 if (this.xmppConnectionServiceBound) {
593 this.onBackendConnected();
594 }
595 if (conversationList.size() >= 1) {
596 this.onConversationUpdate();
597 }
598 }
599
600 @Override
601 protected void onStop() {
602 if (xmppConnectionServiceBound) {
603 xmppConnectionService.removeOnConversationListChangedListener();
604 xmppConnectionService.removeOnAccountListChangedListener();
605 xmppConnectionService.removeOnRosterUpdateListener();
606 }
607 super.onStop();
608 }
609
610 @Override
611 void onBackendConnected() {
612 this.registerListener();
613 if (conversationList.size() == 0) {
614 updateConversationList();
615 }
616
617 if (getSelectedConversation() != null && pendingImageUri != null) {
618 attachImageToConversation(getSelectedConversation(),
619 pendingImageUri);
620 pendingImageUri = null;
621 } else {
622 pendingImageUri = null;
623 }
624
625 if ((getIntent().getAction() != null)
626 && (getIntent().getAction().equals(Intent.ACTION_VIEW) && (!handledViewIntent))) {
627 if (getIntent().getType().equals(
628 ConversationActivity.VIEW_CONVERSATION)) {
629 handledViewIntent = true;
630
631 String convToView = (String) getIntent().getExtras().get(
632 CONVERSATION);
633
634 for (int i = 0; i < conversationList.size(); ++i) {
635 if (conversationList.get(i).getUuid().equals(convToView)) {
636 setSelectedConversation(conversationList.get(i));
637 }
638 }
639 paneShouldBeOpen = false;
640 String text = getIntent().getExtras().getString(TEXT, null);
641 swapConversationFragment().setText(text);
642 }
643 } else {
644 if (xmppConnectionService.getAccounts().size() == 0) {
645 startActivity(new Intent(this, EditAccountActivity.class));
646 } else if (conversationList.size() <= 0) {
647 // add no history
648 startActivity(new Intent(this, StartConversationActivity.class));
649 finish();
650 } else {
651 spl.openPane();
652 // find currently loaded fragment
653 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
654 .findFragmentByTag("conversation");
655 if (selectedFragment != null) {
656 selectedFragment.onBackendConnected();
657 } else {
658 setSelectedConversation(conversationList.get(0));
659 swapConversationFragment();
660 }
661 ExceptionHelper.checkForCrash(this, this.xmppConnectionService);
662 }
663 }
664 }
665
666 public void registerListener() {
667 if (xmppConnectionServiceBound) {
668 xmppConnectionService.setOnConversationListChangedListener(this);
669 xmppConnectionService.setOnAccountListChangedListener(this);
670 xmppConnectionService.setOnRosterUpdateListener(this);
671 }
672 }
673
674 @Override
675 protected void onActivityResult(int requestCode, int resultCode,
676 final Intent data) {
677 super.onActivityResult(requestCode, resultCode, data);
678 if (resultCode == RESULT_OK) {
679 if (requestCode == REQUEST_DECRYPT_PGP) {
680 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
681 .findFragmentByTag("conversation");
682 if (selectedFragment != null) {
683 selectedFragment.hideSnackbar();
684 }
685 } else if (requestCode == REQUEST_ATTACH_FILE_DIALOG) {
686 pendingImageUri = data.getData();
687 if (xmppConnectionServiceBound) {
688 attachImageToConversation(getSelectedConversation(),
689 pendingImageUri);
690 pendingImageUri = null;
691 }
692 } else if (requestCode == REQUEST_SEND_PGP_IMAGE) {
693
694 } else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
695 attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
696 } else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) {
697 attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
698 } else if (requestCode == REQUEST_ANNOUNCE_PGP) {
699 announcePgp(getSelectedConversation().getAccount(),
700 getSelectedConversation());
701 } else if (requestCode == REQUEST_ENCRYPT_MESSAGE) {
702 // encryptTextMessage();
703 } else if (requestCode == REQUEST_IMAGE_CAPTURE) {
704 if (xmppConnectionServiceBound) {
705 attachImageToConversation(getSelectedConversation(),
706 pendingImageUri);
707 pendingImageUri = null;
708 }
709 Intent intent = new Intent(
710 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
711 intent.setData(pendingImageUri);
712 sendBroadcast(intent);
713 } else if (requestCode == REQUEST_RECORD_AUDIO) {
714 attachAudioToConversation(getSelectedConversation(),
715 data.getData());
716 }
717 }
718 }
719
720 private void attachAudioToConversation(Conversation conversation, Uri uri) {
721
722 }
723
724 private void attachImageToConversation(Conversation conversation, Uri uri) {
725 prepareImageToast = Toast.makeText(getApplicationContext(),
726 getText(R.string.preparing_image), Toast.LENGTH_LONG);
727 prepareImageToast.show();
728 xmppConnectionService.attachImageToConversation(conversation, uri,
729 new UiCallback<Message>() {
730
731 @Override
732 public void userInputRequried(PendingIntent pi,
733 Message object) {
734 hidePrepareImageToast();
735 ConversationActivity.this.runIntent(pi,
736 ConversationActivity.REQUEST_SEND_PGP_IMAGE);
737 }
738
739 @Override
740 public void success(Message message) {
741 xmppConnectionService.sendMessage(message);
742 }
743
744 @Override
745 public void error(int error, Message message) {
746 hidePrepareImageToast();
747 displayErrorDialog(error);
748 }
749 });
750 }
751
752 private void hidePrepareImageToast() {
753 if (prepareImageToast != null) {
754 runOnUiThread(new Runnable() {
755
756 @Override
757 public void run() {
758 prepareImageToast.cancel();
759 }
760 });
761 }
762 }
763
764 public void updateConversationList() {
765 xmppConnectionService
766 .populateWithOrderedConversations(conversationList);
767 listAdapter.notifyDataSetChanged();
768 }
769
770 public void runIntent(PendingIntent pi, int requestCode) {
771 try {
772 this.startIntentSenderForResult(pi.getIntentSender(), requestCode,
773 null, 0, 0, 0);
774 } catch (SendIntentException e1) {
775 }
776 }
777
778 public void encryptTextMessage(Message message) {
779 xmppConnectionService.getPgpEngine().encrypt(message,
780 new UiCallback<Message>() {
781
782 @Override
783 public void userInputRequried(PendingIntent pi,
784 Message message) {
785 activity.runIntent(pi,
786 ConversationActivity.REQUEST_SEND_MESSAGE);
787 }
788
789 @Override
790 public void success(Message message) {
791 message.setEncryption(Message.ENCRYPTION_DECRYPTED);
792 xmppConnectionService.sendMessage(message);
793 }
794
795 @Override
796 public void error(int error, Message message) {
797
798 }
799 });
800 }
801
802 public boolean forceEncryption() {
803 return getPreferences().getBoolean("force_encryption", false);
804 }
805
806 public boolean useSendButtonToIndicateStatus() {
807 return getPreferences().getBoolean("send_button_status", false);
808 }
809
810 public boolean indicateReceived() {
811 return getPreferences().getBoolean("indicate_received", false);
812 }
813
814 @Override
815 public void onAccountUpdate() {
816 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
817 .findFragmentByTag("conversation");
818 if (fragment != null) {
819 runOnUiThread(new Runnable() {
820
821 @Override
822 public void run() {
823 fragment.updateMessages();
824 }
825 });
826 }
827 }
828
829 @Override
830 public void onConversationUpdate() {
831 runOnUiThread(new Runnable() {
832
833 @Override
834 public void run() {
835 updateConversationList();
836 if (paneShouldBeOpen) {
837 if (conversationList.size() >= 1) {
838 swapConversationFragment();
839 } else {
840 startActivity(new Intent(getApplicationContext(),
841 StartConversationActivity.class));
842 finish();
843 }
844 }
845 ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
846 .findFragmentByTag("conversation");
847 if (selectedFragment != null) {
848 selectedFragment.updateMessages();
849 }
850 }
851 });
852 }
853
854 @Override
855 public void onRosterUpdate() {
856 final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
857 .findFragmentByTag("conversation");
858 if (fragment != null) {
859 runOnUiThread(new Runnable() {
860
861 @Override
862 public void run() {
863 fragment.updateMessages();
864 }
865 });
866 }
867 }
868}