2014-02-28 12:46:01 -05:00
package eu.siacs.conversations.ui ;
2014-01-23 20:04:05 -05:00
2014-09-27 05:46:56 -04:00
import android.annotation.SuppressLint ;
2014-07-30 15:30:55 -04:00
import android.app.ActionBar ;
2014-02-20 11:00:50 -05:00
import android.app.AlertDialog ;
2014-01-23 20:04:05 -05:00
import android.app.FragmentTransaction ;
2014-05-06 15:34:30 -04:00
import android.app.PendingIntent ;
2016-04-29 07:58:37 -04:00
import android.content.ActivityNotFoundException ;
2015-04-11 08:53:10 -04:00
import android.content.ClipData ;
2014-02-20 11:00:50 -05:00
import android.content.DialogInterface ;
2014-04-16 12:16:23 -04:00
import android.content.DialogInterface.OnClickListener ;
2014-01-23 20:04:05 -05:00
import android.content.Intent ;
2014-11-03 14:00:20 -05:00
import android.content.IntentSender.SendIntentException ;
2015-12-06 12:23:59 -05:00
import android.content.pm.PackageManager ;
2014-11-03 14:00:20 -05:00
import android.net.Uri ;
2015-01-21 23:00:35 -05:00
import android.os.Build ;
2014-11-03 14:00:20 -05:00
import android.os.Bundle ;
2016-09-08 05:01:27 -04:00
import android.os.Handler ;
2014-11-03 14:00:20 -05:00
import android.provider.MediaStore ;
2016-01-11 05:17:45 -05:00
import android.provider.Settings ;
2014-01-23 20:04:05 -05:00
import android.support.v4.widget.SlidingPaneLayout ;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener ;
2015-06-25 11:01:42 -04:00
import android.util.Log ;
2015-12-01 08:18:07 -05:00
import android.util.Pair ;
2015-11-25 14:47:02 -05:00
import android.view.Gravity ;
2015-09-07 09:46:22 -04:00
import android.view.KeyEvent ;
2014-01-23 20:04:05 -05:00
import android.view.Menu ;
import android.view.MenuItem ;
2015-09-07 14:45:21 -04:00
import android.view.Surface ;
2014-01-23 20:04:05 -05:00
import android.view.View ;
import android.widget.AdapterView ;
import android.widget.AdapterView.OnItemClickListener ;
2014-01-24 17:58:51 -05:00
import android.widget.ArrayAdapter ;
2014-04-20 14:48:16 -04:00
import android.widget.CheckBox ;
2014-02-16 10:32:15 -05:00
import android.widget.PopupMenu ;
import android.widget.PopupMenu.OnMenuItemClickListener ;
2014-05-09 14:46:43 -04:00
import android.widget.Toast ;
2014-01-23 20:04:05 -05:00
2015-01-01 19:21:14 -05:00
import net.java.otr4j.session.SessionStatus ;
2016-01-11 05:17:45 -05:00
import org.openintents.openpgp.util.OpenPgpApi ;
2014-11-03 14:00:20 -05:00
import java.util.ArrayList ;
2015-04-11 08:53:10 -04:00
import java.util.Iterator ;
2014-11-03 14:00:20 -05:00
import java.util.List ;
2015-10-20 09:27:33 -04:00
import java.util.concurrent.atomic.AtomicBoolean ;
2014-11-03 14:00:20 -05:00
2015-07-20 08:26:29 -04:00
import de.timroes.android.listview.EnhancedListView ;
2015-06-25 11:01:42 -04:00
import eu.siacs.conversations.Config ;
2014-11-03 14:00:20 -05:00
import eu.siacs.conversations.R ;
2015-07-09 21:02:49 -04:00
import eu.siacs.conversations.crypto.axolotl.AxolotlService ;
2016-11-14 16:27:41 -05:00
import eu.siacs.conversations.crypto.axolotl.FingerprintStatus ;
2015-06-28 07:14:21 -04:00
import eu.siacs.conversations.entities.Account ;
2014-12-21 15:43:58 -05:00
import eu.siacs.conversations.entities.Blockable ;
2014-11-03 14:00:20 -05:00
import eu.siacs.conversations.entities.Contact ;
import eu.siacs.conversations.entities.Conversation ;
import eu.siacs.conversations.entities.Message ;
2015-12-06 12:23:59 -05:00
import eu.siacs.conversations.entities.Transferable ;
2016-03-31 18:03:14 -04:00
import eu.siacs.conversations.persistance.FileBackend ;
2015-07-10 07:28:50 -04:00
import eu.siacs.conversations.services.XmppConnectionService ;
2014-11-03 14:00:20 -05:00
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate ;
import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate ;
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate ;
import eu.siacs.conversations.ui.adapter.ConversationAdapter ;
import eu.siacs.conversations.utils.ExceptionHelper ;
2017-03-03 06:26:33 -05:00
import eu.siacs.conversations.utils.UIHelper ;
2014-12-21 15:43:58 -05:00
import eu.siacs.conversations.xmpp.OnUpdateBlocklist ;
2016-11-02 10:21:26 -04:00
import eu.siacs.conversations.xmpp.XmppConnection ;
2015-07-21 07:15:59 -04:00
import eu.siacs.conversations.xmpp.jid.InvalidJidException ;
import eu.siacs.conversations.xmpp.jid.Jid ;
2014-11-03 14:00:20 -05:00
2014-12-21 15:43:58 -05:00
public class ConversationActivity extends XmppActivity
2015-07-10 07:28:50 -04:00
implements OnAccountUpdate , OnConversationUpdate , OnRosterUpdate , OnUpdateBlocklist , XmppConnectionService . OnShowErrorToast {
2014-01-24 04:50:18 -05:00
2016-07-25 08:15:47 -04:00
public static final String ACTION_VIEW_CONVERSATION = " eu.siacs.conversations.action.VIEW " ;
2014-02-03 12:38:47 -05:00
public static final String CONVERSATION = " conversationUuid " ;
2016-07-25 08:15:47 -04:00
public static final String EXTRA_DOWNLOAD_UUID = " eu.siacs.conversations.download_uuid " ;
2014-03-13 16:37:27 -04:00
public static final String TEXT = " text " ;
2014-11-16 19:54:01 -05:00
public static final String NICK = " nick " ;
2015-07-21 07:15:59 -04:00
public static final String PRIVATE_MESSAGE = " pm " ;
2014-04-10 08:12:08 -04:00
2014-08-13 05:22:32 -04:00
public static final int REQUEST_SEND_MESSAGE = 0x0201 ;
public static final int REQUEST_DECRYPT_PGP = 0x0202 ;
2014-11-06 11:25:14 -05:00
public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207 ;
2015-07-19 12:36:28 -04:00
public static final int REQUEST_TRUST_KEYS_TEXT = 0x0208 ;
public static final int REQUEST_TRUST_KEYS_MENU = 0x0209 ;
2015-12-06 12:23:59 -05:00
public static final int REQUEST_START_DOWNLOAD = 0x0210 ;
2015-05-02 05:38:56 -04:00
public static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301 ;
public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302 ;
public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303 ;
public static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0304 ;
public static final int ATTACHMENT_CHOICE_LOCATION = 0x0305 ;
2015-07-19 12:36:28 -04:00
public static final int ATTACHMENT_CHOICE_INVALID = 0x0306 ;
2014-10-03 09:00:29 -04:00
private static final String STATE_OPEN_CONVERSATION = " state_open_conversation " ;
private static final String STATE_PANEL_OPEN = " state_panel_open " ;
2014-11-06 11:25:14 -05:00
private static final String STATE_PENDING_URI = " state_pending_uri " ;
2016-09-12 15:18:56 -04:00
private static final String STATE_FIRST_VISIBLE = " first_visible " ;
private static final String STATE_OFFSET_FROM_TOP = " offset_from_top " ;
2014-01-23 20:04:05 -05:00
2016-09-12 15:18:56 -04:00
private String mOpenConversation = null ;
2014-10-03 09:00:29 -04:00
private boolean mPanelOpen = true ;
2017-01-20 04:43:50 -05:00
private AtomicBoolean mShouldPanelBeOpen = new AtomicBoolean ( false ) ;
2016-09-12 15:18:56 -04:00
private Pair < Integer , Integer > mScrollPosition = null ;
2015-04-11 08:53:10 -04:00
final private List < Uri > mPendingImageUris = new ArrayList < > ( ) ;
final private List < Uri > mPendingFileUris = new ArrayList < > ( ) ;
2015-03-07 08:15:38 -05:00
private Uri mPendingGeoUri = null ;
2015-07-19 12:36:28 -04:00
private boolean forbidProcessingPendings = false ;
2015-12-06 12:23:59 -05:00
private Message mPendingDownloadableMessage = null ;
2014-10-03 09:00:29 -04:00
2015-09-07 09:46:22 -04:00
private boolean conversationWasSelectedByKeyboard = false ;
2014-10-03 09:00:29 -04:00
private View mContentView ;
2014-01-24 04:50:18 -05:00
2014-11-07 09:09:28 -05:00
private List < Conversation > conversationList = new ArrayList < > ( ) ;
2015-04-02 18:06:37 -04:00
private Conversation swipedConversation = null ;
2014-11-17 18:07:27 -05:00
private Conversation mSelectedConversation = null ;
2015-04-02 18:06:37 -04:00
private EnhancedListView listView ;
2014-11-07 09:38:20 -05:00
private ConversationFragment mConversationFragment ;
2014-06-06 05:39:17 -04:00
2014-02-01 09:07:20 -05:00
private ArrayAdapter < Conversation > listAdapter ;
2014-06-06 05:39:17 -04:00
2015-01-02 06:04:33 -05:00
private boolean mActivityPaused = false ;
2015-10-20 09:27:33 -04:00
private AtomicBoolean mRedirected = new AtomicBoolean ( false ) ;
2015-12-01 08:18:07 -05:00
private Pair < Integer , Intent > mPostponedActivityResult ;
2016-11-08 06:42:13 -05:00
private boolean mUnprocessedNewIntent = false ;
2015-01-02 06:04:33 -05:00
2014-02-06 20:57:36 -05:00
public Conversation getSelectedConversation ( ) {
2014-11-17 18:07:27 -05:00
return this . mSelectedConversation ;
2014-01-27 14:40:42 -05:00
}
2014-06-06 05:39:17 -04:00
2014-05-13 11:11:27 -04:00
public void setSelectedConversation ( Conversation conversation ) {
2014-11-17 18:07:27 -05:00
this . mSelectedConversation = conversation ;
2014-05-13 11:11:27 -04:00
}
2014-04-10 08:12:08 -04:00
2014-10-03 09:00:29 -04:00
public void showConversationsOverview ( ) {
if ( mContentView instanceof SlidingPaneLayout ) {
SlidingPaneLayout mSlidingPaneLayout = ( SlidingPaneLayout ) mContentView ;
2017-01-20 04:43:50 -05:00
mShouldPanelBeOpen . set ( true ) ;
2014-10-03 09:00:29 -04:00
mSlidingPaneLayout . openPane ( ) ;
}
}
2014-10-05 18:33:52 -04:00
2014-11-04 06:15:14 -05:00
@Override
protected String getShareableUri ( ) {
Conversation conversation = getSelectedConversation ( ) ;
2014-11-06 11:25:14 -05:00
if ( conversation ! = null ) {
2014-11-15 18:20:20 -05:00
return conversation . getAccount ( ) . getShareableUri ( ) ;
2014-11-04 06:15:14 -05:00
} else {
2014-11-04 11:10:35 -05:00
return " " ;
2014-11-04 06:15:14 -05:00
}
}
2014-10-03 09:00:29 -04:00
public void hideConversationsOverview ( ) {
if ( mContentView instanceof SlidingPaneLayout ) {
SlidingPaneLayout mSlidingPaneLayout = ( SlidingPaneLayout ) mContentView ;
2017-01-20 04:43:50 -05:00
mShouldPanelBeOpen . set ( false ) ;
2014-10-03 09:00:29 -04:00
mSlidingPaneLayout . closePane ( ) ;
}
}
2014-10-05 18:33:52 -04:00
2014-10-03 09:00:29 -04:00
public boolean isConversationsOverviewHideable ( ) {
2016-10-03 04:13:45 -04:00
return mContentView instanceof SlidingPaneLayout ;
2014-10-03 09:00:29 -04:00
}
2014-10-05 18:33:52 -04:00
2014-10-03 09:00:29 -04:00
public boolean isConversationsOverviewVisable ( ) {
if ( mContentView instanceof SlidingPaneLayout ) {
2017-01-20 04:43:50 -05:00
return mShouldPanelBeOpen . get ( ) ;
2014-10-03 09:00:29 -04:00
} else {
return true ;
}
}
2014-04-10 08:12:08 -04:00
2014-01-23 20:04:05 -05:00
@Override
2015-01-14 15:28:27 -05:00
protected void onCreate ( final Bundle savedInstanceState ) {
2014-01-25 13:33:12 -05:00
super . onCreate ( savedInstanceState ) ;
2015-04-11 08:53:10 -04:00
if ( savedInstanceState ! = null ) {
2016-09-12 15:18:56 -04:00
mOpenConversation = savedInstanceState . getString ( STATE_OPEN_CONVERSATION , null ) ;
2015-04-11 08:53:10 -04:00
mPanelOpen = savedInstanceState . getBoolean ( STATE_PANEL_OPEN , true ) ;
2016-09-12 15:18:56 -04:00
int pos = savedInstanceState . getInt ( STATE_FIRST_VISIBLE , - 1 ) ;
int offset = savedInstanceState . getInt ( STATE_OFFSET_FROM_TOP , 1 ) ;
if ( pos > = 0 & & offset < = 0 ) {
Log . d ( Config . LOGTAG , " retrieved scroll position from instanceState " + pos + " : " + offset ) ;
mScrollPosition = new Pair < > ( pos , offset ) ;
} else {
mScrollPosition = null ;
}
2015-04-11 08:53:10 -04:00
String pending = savedInstanceState . getString ( STATE_PENDING_URI , null ) ;
if ( pending ! = null ) {
2016-10-03 05:13:04 -04:00
Log . d ( Config . LOGTAG , " ConversationsActivity.onCreate() - restoring pending image uri " ) ;
2015-04-11 08:53:10 -04:00
mPendingImageUris . clear ( ) ;
mPendingImageUris . add ( Uri . parse ( pending ) ) ;
}
2014-10-03 09:00:29 -04:00
}
2014-01-24 17:58:51 -05:00
setContentView ( R . layout . fragment_conversations_overview ) ;
2014-01-24 04:50:18 -05:00
2014-11-07 09:38:20 -05:00
this . mConversationFragment = new ConversationFragment ( ) ;
FragmentTransaction transaction = getFragmentManager ( ) . beginTransaction ( ) ;
transaction . replace ( R . id . selected_conversation , this . mConversationFragment , " conversation " ) ;
transaction . commit ( ) ;
2015-04-02 18:06:37 -04:00
listView = ( EnhancedListView ) findViewById ( R . id . list ) ;
2014-11-07 15:49:31 -05:00
this . listAdapter = new ConversationAdapter ( this , conversationList ) ;
listView . setAdapter ( this . listAdapter ) ;
2014-08-31 10:28:21 -04:00
2017-02-18 12:08:37 -05:00
final ActionBar actionBar = getActionBar ( ) ;
if ( actionBar ! = null ) {
actionBar . setDisplayOptions ( ActionBar . DISPLAY_SHOW_TITLE ) ;
2014-11-07 09:09:28 -05:00
}
2014-01-25 13:33:12 -05:00
2014-01-23 20:04:05 -05:00
listView . setOnItemClickListener ( new OnItemClickListener ( ) {
@Override
2014-01-24 04:50:18 -05:00
public void onItemClick ( AdapterView < ? > arg0 , View clickedView ,
2016-01-11 05:17:45 -05:00
int position , long arg3 ) {
2014-05-13 11:11:27 -04:00
if ( getSelectedConversation ( ) ! = conversationList . get ( position ) ) {
setSelectedConversation ( conversationList . get ( position ) ) ;
2014-11-07 09:38:20 -05:00
ConversationActivity . this . mConversationFragment . reInit ( getSelectedConversation ( ) ) ;
2015-09-07 09:46:22 -04:00
conversationWasSelectedByKeyboard = false ;
2014-01-27 14:40:42 -05:00
}
2014-11-07 09:38:20 -05:00
hideConversationsOverview ( ) ;
2015-01-09 16:24:50 -05:00
openConversation ( ) ;
2014-01-23 20:04:05 -05:00
}
} ) ;
2015-04-02 18:06:37 -04:00
listView . setDismissCallback ( new EnhancedListView . OnDismissCallback ( ) {
@Override
public EnhancedListView . Undoable onDismiss ( final EnhancedListView enhancedListView , final int position ) {
final int index = listView . getFirstVisiblePosition ( ) ;
View v = listView . getChildAt ( 0 ) ;
final int top = ( v = = null ) ? 0 : ( v . getTop ( ) - listView . getPaddingTop ( ) ) ;
2015-09-17 08:02:28 -04:00
try {
swipedConversation = listAdapter . getItem ( position ) ;
} catch ( IndexOutOfBoundsException e ) {
return null ;
}
2015-04-02 18:06:37 -04:00
listAdapter . remove ( swipedConversation ) ;
2015-10-14 15:18:34 -04:00
xmppConnectionService . markRead ( swipedConversation ) ;
2015-04-02 18:06:37 -04:00
final boolean formerlySelected = ( getSelectedConversation ( ) = = swipedConversation ) ;
if ( position = = 0 & & listAdapter . getCount ( ) = = 0 ) {
endConversation ( swipedConversation , false , true ) ;
return null ;
} else if ( formerlySelected ) {
setSelectedConversation ( listAdapter . getItem ( 0 ) ) ;
ConversationActivity . this . mConversationFragment
. reInit ( getSelectedConversation ( ) ) ;
}
return new EnhancedListView . Undoable ( ) {
@Override
public void undo ( ) {
listAdapter . insert ( swipedConversation , position ) ;
if ( formerlySelected ) {
setSelectedConversation ( swipedConversation ) ;
ConversationActivity . this . mConversationFragment
. reInit ( getSelectedConversation ( ) ) ;
}
swipedConversation = null ;
listView . setSelectionFromTop ( index + ( listView . getChildCount ( ) < position ? 1 : 0 ) , top ) ;
}
@Override
public void discard ( ) {
if ( ! swipedConversation . isRead ( )
& & swipedConversation . getMode ( ) = = Conversation . MODE_SINGLE ) {
swipedConversation = null ;
return ;
}
endConversation ( swipedConversation , false , false ) ;
swipedConversation = null ;
}
@Override
public String getTitle ( ) {
if ( swipedConversation . getMode ( ) = = Conversation . MODE_MULTI ) {
return getResources ( ) . getString ( R . string . title_undo_swipe_out_muc ) ;
} else {
return getResources ( ) . getString ( R . string . title_undo_swipe_out_conversation ) ;
}
}
} ;
}
} ) ;
listView . enableSwipeToDismiss ( ) ;
listView . setSwipingLayout ( R . id . swipeable_item ) ;
listView . setUndoStyle ( EnhancedListView . UndoStyle . SINGLE_POPUP ) ;
2015-04-28 03:25:58 -04:00
listView . setUndoHideDelay ( 5000 ) ;
2015-04-02 18:06:37 -04:00
listView . setRequireTouchBeforeDismiss ( false ) ;
2014-10-03 09:00:29 -04:00
mContentView = findViewById ( R . id . content_view_spl ) ;
2014-10-05 18:33:52 -04:00
if ( mContentView = = null ) {
2014-10-03 09:00:29 -04:00
mContentView = findViewById ( R . id . content_view_ll ) ;
}
if ( mContentView instanceof SlidingPaneLayout ) {
SlidingPaneLayout mSlidingPaneLayout = ( SlidingPaneLayout ) mContentView ;
2016-12-25 12:57:30 -05:00
mSlidingPaneLayout . setShadowResource ( R . drawable . es_slidingpane_shadow ) ;
2014-10-03 09:00:29 -04:00
mSlidingPaneLayout . setSliderFadeColor ( 0 ) ;
mSlidingPaneLayout . setPanelSlideListener ( new PanelSlideListener ( ) {
2014-01-24 04:50:18 -05:00
2014-10-03 09:00:29 -04:00
@Override
public void onPanelOpened ( View arg0 ) {
2017-01-20 07:44:29 -05:00
mShouldPanelBeOpen . set ( true ) ;
2014-11-21 14:02:13 -05:00
updateActionBarTitle ( ) ;
2014-10-03 09:00:29 -04:00
invalidateOptionsMenu ( ) ;
hideKeyboard ( ) ;
if ( xmppConnectionServiceBound ) {
2017-01-20 07:44:29 -05:00
xmppConnectionService . getNotificationService ( ) . setOpenConversation ( null ) ;
2014-10-03 09:00:29 -04:00
}
2014-10-23 15:27:41 -04:00
closeContextMenu ( ) ;
2014-09-29 12:28:13 -04:00
}
2014-01-24 04:50:18 -05:00
2014-10-03 09:00:29 -04:00
@Override
public void onPanelClosed ( View arg0 ) {
2017-01-20 07:44:29 -05:00
mShouldPanelBeOpen . set ( false ) ;
2015-04-02 18:06:37 -04:00
listView . discardUndo ( ) ;
2014-11-07 15:49:31 -05:00
openConversation ( ) ;
2014-01-24 04:50:18 -05:00
}
2014-01-23 20:04:05 -05:00
2014-10-03 09:00:29 -04:00
@Override
public void onPanelSlide ( View arg0 , float arg1 ) {
// TODO Auto-generated method stub
2014-01-24 04:50:18 -05:00
2014-10-03 09:00:29 -04:00
}
} ) ;
}
2014-01-23 20:04:05 -05:00
}
2014-10-03 09:00:29 -04:00
2014-11-20 12:20:42 -05:00
@Override
public void switchToConversation ( Conversation conversation ) {
setSelectedConversation ( conversation ) ;
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
ConversationActivity . this . mConversationFragment . reInit ( getSelectedConversation ( ) ) ;
openConversation ( ) ;
}
} ) ;
}
2014-11-21 14:02:13 -05:00
private void updateActionBarTitle ( ) {
updateActionBarTitle ( isConversationsOverviewHideable ( ) & & ! isConversationsOverviewVisable ( ) ) ;
}
private void updateActionBarTitle ( boolean titleShouldBeName ) {
2014-11-27 04:30:06 -05:00
final ActionBar ab = getActionBar ( ) ;
final Conversation conversation = getSelectedConversation ( ) ;
2014-09-29 12:28:13 -04:00
if ( ab ! = null ) {
2014-11-27 04:30:06 -05:00
if ( titleShouldBeName & & conversation ! = null ) {
2017-02-18 12:08:37 -05:00
if ( ( ab . getDisplayOptions ( ) & ActionBar . DISPLAY_HOME_AS_UP ) ! = ActionBar . DISPLAY_HOME_AS_UP ) {
ab . setDisplayOptions ( ActionBar . DISPLAY_HOME_AS_UP | ActionBar . DISPLAY_SHOW_TITLE ) ;
}
2014-11-27 04:30:06 -05:00
if ( conversation . getMode ( ) = = Conversation . MODE_SINGLE | | useSubjectToIdentifyConference ( ) ) {
ab . setTitle ( conversation . getName ( ) ) ;
2014-11-21 14:02:13 -05:00
} else {
2014-12-21 15:43:58 -05:00
ab . setTitle ( conversation . getJid ( ) . toBareJid ( ) . toString ( ) ) ;
2014-11-21 14:02:13 -05:00
}
2014-09-29 12:28:13 -04:00
} else {
2017-02-18 12:08:37 -05:00
if ( ( ab . getDisplayOptions ( ) & ActionBar . DISPLAY_HOME_AS_UP ) = = ActionBar . DISPLAY_HOME_AS_UP ) {
ab . setDisplayOptions ( ActionBar . DISPLAY_SHOW_TITLE ) ;
}
2014-11-21 14:02:13 -05:00
ab . setTitle ( R . string . app_name ) ;
2014-09-29 12:28:13 -04:00
}
}
2014-11-21 14:02:13 -05:00
}
private void openConversation ( ) {
this . updateActionBarTitle ( ) ;
this . invalidateOptionsMenu ( ) ;
2014-09-29 12:28:13 -04:00
if ( xmppConnectionServiceBound ) {
2015-01-02 06:04:33 -05:00
final Conversation conversation = getSelectedConversation ( ) ;
xmppConnectionService . getNotificationService ( ) . setOpenConversation ( conversation ) ;
sendReadMarkerIfNecessary ( conversation ) ;
}
2015-01-09 16:24:50 -05:00
listAdapter . notifyDataSetChanged ( ) ;
2015-01-02 06:04:33 -05:00
}
public void sendReadMarkerIfNecessary ( final Conversation conversation ) {
2016-11-08 06:42:13 -05:00
if ( ! mActivityPaused & & ! mUnprocessedNewIntent & & conversation ! = null ) {
2016-02-15 17:09:42 -05:00
xmppConnectionService . sendReadMarker ( conversation ) ;
2014-09-29 12:28:13 -04:00
}
}
2014-01-24 04:50:18 -05:00
2014-01-23 20:04:05 -05:00
@Override
public boolean onCreateOptionsMenu ( Menu menu ) {
getMenuInflater ( ) . inflate ( R . menu . conversations , menu ) ;
2014-12-21 15:43:58 -05:00
final MenuItem menuSecure = menu . findItem ( R . id . action_security ) ;
final MenuItem menuArchive = menu . findItem ( R . id . action_archive ) ;
final MenuItem menuMucDetails = menu . findItem ( R . id . action_muc_details ) ;
final MenuItem menuContactDetails = menu . findItem ( R . id . action_contact_details ) ;
final MenuItem menuAttach = menu . findItem ( R . id . action_attach_file ) ;
final MenuItem menuClearHistory = menu . findItem ( R . id . action_clear_history ) ;
final MenuItem menuAdd = menu . findItem ( R . id . action_add ) ;
final MenuItem menuInviteContact = menu . findItem ( R . id . action_invite ) ;
final MenuItem menuMute = menu . findItem ( R . id . action_mute ) ;
final MenuItem menuUnmute = menu . findItem ( R . id . action_unmute ) ;
2014-04-10 08:12:08 -04:00
2015-01-07 12:34:24 -05:00
if ( isConversationsOverviewVisable ( ) & & isConversationsOverviewHideable ( ) ) {
2014-02-28 12:46:01 -05:00
menuArchive . setVisible ( false ) ;
menuMucDetails . setVisible ( false ) ;
menuContactDetails . setVisible ( false ) ;
2014-02-13 17:40:08 -05:00
menuSecure . setVisible ( false ) ;
2014-07-16 18:03:37 -04:00
menuInviteContact . setVisible ( false ) ;
2014-04-05 06:49:43 -04:00
menuAttach . setVisible ( false ) ;
2014-04-16 12:16:23 -04:00
menuClearHistory . setVisible ( false ) ;
2014-09-03 06:36:54 -04:00
menuMute . setVisible ( false ) ;
2014-11-18 07:51:04 -05:00
menuUnmute . setVisible ( false ) ;
2014-01-23 20:04:05 -05:00
} else {
2014-10-03 09:00:29 -04:00
menuAdd . setVisible ( ! isConversationsOverviewHideable ( ) ) ;
2014-04-10 08:12:08 -04:00
if ( this . getSelectedConversation ( ) ! = null ) {
2015-07-30 18:52:46 -04:00
if ( this . getSelectedConversation ( ) . getNextEncryption ( ) ! = Message . ENCRYPTION_NONE ) {
2015-01-21 23:00:35 -05:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . LOLLIPOP ) {
2015-04-28 08:28:51 -04:00
menuSecure . setIcon ( R . drawable . ic_lock_white_24dp ) ;
2015-01-21 23:00:35 -05:00
} else {
menuSecure . setIcon ( R . drawable . ic_action_secure ) ;
}
}
2014-02-06 20:57:36 -05:00
if ( this . getSelectedConversation ( ) . getMode ( ) = = Conversation . MODE_MULTI ) {
2014-02-28 12:46:01 -05:00
menuContactDetails . setVisible ( false ) ;
2015-09-13 11:13:46 -04:00
menuAttach . setVisible ( getSelectedConversation ( ) . getAccount ( ) . httpUploadAvailable ( ) & & getSelectedConversation ( ) . getMucOptions ( ) . participating ( ) ) ;
2015-01-07 12:34:24 -05:00
menuInviteContact . setVisible ( getSelectedConversation ( ) . getMucOptions ( ) . canInvite ( ) ) ;
2016-02-29 07:18:07 -05:00
menuSecure . setVisible ( ( Config . supportOpenPgp ( ) | | Config . supportOmemo ( ) ) & & Config . multipleEncryptionChoices ( ) ) ; //only if pgp is supported we have a choice
2014-02-13 17:40:08 -05:00
} else {
2016-04-09 04:59:54 -04:00
menuContactDetails . setVisible ( ! this . getSelectedConversation ( ) . withSelf ( ) ) ;
2014-02-28 12:46:01 -05:00
menuMucDetails . setVisible ( false ) ;
2016-02-24 08:47:49 -05:00
menuSecure . setVisible ( Config . multipleEncryptionChoices ( ) ) ;
2017-02-13 11:32:26 -05:00
menuInviteContact . setVisible ( xmppConnectionService ! = null & & xmppConnectionService . findConferenceServer ( getSelectedConversation ( ) . getAccount ( ) ) ! = null ) ;
2014-02-06 20:57:36 -05:00
}
2014-11-18 07:51:04 -05:00
if ( this . getSelectedConversation ( ) . isMuted ( ) ) {
menuMute . setVisible ( false ) ;
} else {
menuUnmute . setVisible ( false ) ;
}
2014-02-06 20:57:36 -05:00
}
2014-01-23 20:04:05 -05:00
}
2016-09-08 05:01:27 -04:00
if ( Config . supportOmemo ( ) ) {
new Handler ( ) . post ( new Runnable ( ) {
@Override
public void run ( ) {
View view = findViewById ( R . id . action_security ) ;
if ( view ! = null ) {
view . setOnLongClickListener ( new View . OnLongClickListener ( ) {
@Override
public boolean onLongClick ( View v ) {
return quickOmemoDebugger ( getSelectedConversation ( ) ) ;
}
} ) ;
}
}
} ) ;
}
2016-02-27 04:25:31 -05:00
return super . onCreateOptionsMenu ( menu ) ;
2014-01-23 20:04:05 -05:00
}
2014-06-06 05:39:17 -04:00
2016-09-08 05:01:27 -04:00
private boolean quickOmemoDebugger ( Conversation c ) {
if ( c ! = null ) {
2016-10-03 15:04:10 -04:00
boolean single = c . getMode ( ) = = Conversation . MODE_SINGLE ;
2016-09-08 05:01:27 -04:00
AxolotlService axolotlService = c . getAccount ( ) . getAxolotlService ( ) ;
Pair < AxolotlService . AxolotlCapability , Jid > capabilityJidPair = axolotlService . isConversationAxolotlCapableDetailed ( c ) ;
switch ( capabilityJidPair . first ) {
case MISSING_PRESENCE :
2016-10-03 15:04:10 -04:00
Toast . makeText ( ConversationActivity . this , single ? getString ( R . string . missing_presence_subscription ) : getString ( R . string . missing_presence_subscription_with_x , capabilityJidPair . second . toBareJid ( ) . toString ( ) ) , Toast . LENGTH_SHORT ) . show ( ) ;
2016-09-08 05:01:27 -04:00
return true ;
case MISSING_KEYS :
2016-10-03 15:04:10 -04:00
Toast . makeText ( ConversationActivity . this , single ? getString ( R . string . missing_omemo_keys ) : getString ( R . string . missing_keys_from_x , capabilityJidPair . second . toBareJid ( ) . toString ( ) ) , Toast . LENGTH_SHORT ) . show ( ) ;
2016-09-08 05:01:27 -04:00
return true ;
case WRONG_CONFIGURATION :
Toast . makeText ( ConversationActivity . this , R . string . wrong_conference_configuration , Toast . LENGTH_SHORT ) . show ( ) ;
return true ;
case NO_MEMBERS :
Toast . makeText ( ConversationActivity . this , R . string . this_conference_has_no_members , Toast . LENGTH_SHORT ) . show ( ) ;
return true ;
}
}
return false ;
}
2015-07-19 12:36:28 -04:00
protected void selectPresenceToAttachFile ( final int attachmentChoice , final int encryption ) {
2015-06-28 07:14:21 -04:00
final Conversation conversation = getSelectedConversation ( ) ;
final Account account = conversation . getAccount ( ) ;
2015-05-04 03:54:10 -04:00
final OnPresenceSelected callback = new OnPresenceSelected ( ) {
2014-06-06 05:39:17 -04:00
2015-05-04 03:54:10 -04:00
@Override
public void onPresenceSelected ( ) {
Intent intent = new Intent ( ) ;
boolean chooser = false ;
String fallbackPackageId = null ;
switch ( attachmentChoice ) {
case ATTACHMENT_CHOICE_CHOOSE_IMAGE :
intent . setAction ( Intent . ACTION_GET_CONTENT ) ;
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . JELLY_BEAN_MR2 ) {
2016-01-11 05:17:45 -05:00
intent . putExtra ( Intent . EXTRA_ALLOW_MULTIPLE , true ) ;
2015-03-07 08:15:38 -05:00
}
2015-05-04 03:54:10 -04:00
intent . setType ( " image/* " ) ;
chooser = true ;
break ;
case ATTACHMENT_CHOICE_TAKE_PHOTO :
Uri uri = xmppConnectionService . getFileBackend ( ) . getTakePhotoUri ( ) ;
2016-08-30 07:14:38 -04:00
intent . addFlags ( Intent . FLAG_GRANT_WRITE_URI_PERMISSION ) ;
2016-11-08 05:45:20 -05:00
intent . addFlags ( Intent . FLAG_GRANT_READ_URI_PERMISSION ) ;
2015-05-04 03:54:10 -04:00
intent . setAction ( MediaStore . ACTION_IMAGE_CAPTURE ) ;
intent . putExtra ( MediaStore . EXTRA_OUTPUT , uri ) ;
mPendingImageUris . clear ( ) ;
mPendingImageUris . add ( uri ) ;
break ;
case ATTACHMENT_CHOICE_CHOOSE_FILE :
chooser = true ;
intent . setType ( " */* " ) ;
intent . addCategory ( Intent . CATEGORY_OPENABLE ) ;
intent . setAction ( Intent . ACTION_GET_CONTENT ) ;
break ;
case ATTACHMENT_CHOICE_RECORD_VOICE :
intent . setAction ( MediaStore . Audio . Media . RECORD_SOUND_ACTION ) ;
2015-05-19 21:27:52 -04:00
fallbackPackageId = " eu.siacs.conversations.voicerecorder " ;
2015-05-04 03:54:10 -04:00
break ;
case ATTACHMENT_CHOICE_LOCATION :
intent . setAction ( " eu.siacs.conversations.location.request " ) ;
fallbackPackageId = " eu.siacs.conversations.sharelocation " ;
break ;
}
if ( intent . resolveActivity ( getPackageManager ( ) ) ! = null ) {
if ( chooser ) {
startActivityForResult (
Intent . createChooser ( intent , getString ( R . string . perform_action_with ) ) ,
attachmentChoice ) ;
} else {
startActivityForResult ( intent , attachmentChoice ) ;
2014-05-13 11:42:23 -04:00
}
2015-05-04 03:54:10 -04:00
} else if ( fallbackPackageId ! = null ) {
startActivity ( getInstallApkIntent ( fallbackPackageId ) ) ;
2014-05-13 11:42:23 -04:00
}
2015-05-04 03:54:10 -04:00
}
} ;
2015-06-28 07:14:21 -04:00
if ( ( account . httpUploadAvailable ( ) | | attachmentChoice = = ATTACHMENT_CHOICE_LOCATION ) & & encryption ! = Message . ENCRYPTION_OTR ) {
conversation . setNextCounterpart ( null ) ;
2015-05-04 03:54:10 -04:00
callback . onPresenceSelected ( ) ;
} else {
2015-07-21 07:15:59 -04:00
selectPresence ( conversation , callback ) ;
2015-03-07 08:15:38 -05:00
}
2014-05-13 09:25:04 -04:00
}
2014-01-24 04:50:18 -05:00
2015-05-03 22:38:12 -04:00
private Intent getInstallApkIntent ( final String packageId ) {
Intent intent = new Intent ( Intent . ACTION_VIEW ) ;
2015-09-07 09:46:22 -04:00
intent . setData ( Uri . parse ( " market://details?id= " + packageId ) ) ;
2015-05-03 22:38:12 -04:00
if ( intent . resolveActivity ( getPackageManager ( ) ) ! = null ) {
return intent ;
} else {
2015-07-21 07:15:59 -04:00
intent . setData ( Uri . parse ( " http://play.google.com/store/apps/details?id= " + packageId ) ) ;
2015-05-03 22:38:12 -04:00
return intent ;
}
}
2015-05-02 05:38:56 -04:00
public void attachFile ( final int attachmentChoice ) {
2015-12-06 12:23:59 -05:00
if ( attachmentChoice ! = ATTACHMENT_CHOICE_LOCATION ) {
2016-12-02 05:25:14 -05:00
if ( ! Config . ONLY_INTERNAL_STORAGE & & ! hasStoragePermission ( attachmentChoice ) ) {
2015-12-06 12:23:59 -05:00
return ;
}
}
2015-05-02 05:38:56 -04:00
switch ( attachmentChoice ) {
case ATTACHMENT_CHOICE_LOCATION :
2016-01-11 05:17:45 -05:00
getPreferences ( ) . edit ( ) . putString ( " recently_used_quick_action " , " location " ) . apply ( ) ;
2015-05-02 05:38:56 -04:00
break ;
case ATTACHMENT_CHOICE_RECORD_VOICE :
2016-01-11 05:17:45 -05:00
getPreferences ( ) . edit ( ) . putString ( " recently_used_quick_action " , " voice " ) . apply ( ) ;
2015-05-02 05:38:56 -04:00
break ;
case ATTACHMENT_CHOICE_TAKE_PHOTO :
2016-01-11 05:17:45 -05:00
getPreferences ( ) . edit ( ) . putString ( " recently_used_quick_action " , " photo " ) . apply ( ) ;
2015-05-02 05:38:56 -04:00
break ;
2015-05-25 23:34:58 -04:00
case ATTACHMENT_CHOICE_CHOOSE_IMAGE :
2016-01-11 05:17:45 -05:00
getPreferences ( ) . edit ( ) . putString ( " recently_used_quick_action " , " picture " ) . apply ( ) ;
2015-05-25 23:34:58 -04:00
break ;
2015-05-02 05:38:56 -04:00
}
2014-05-08 08:23:09 -04:00
final Conversation conversation = getSelectedConversation ( ) ;
2015-07-30 18:52:46 -04:00
final int encryption = conversation . getNextEncryption ( ) ;
2015-11-25 14:47:02 -05:00
final int mode = conversation . getMode ( ) ;
2015-03-07 08:15:38 -05:00
if ( encryption = = Message . ENCRYPTION_PGP ) {
2014-05-07 06:33:55 -04:00
if ( hasPgp ( ) ) {
2015-11-25 14:47:02 -05:00
if ( mode = = Conversation . MODE_SINGLE & & conversation . getContact ( ) . getPgpKeyId ( ) ! = 0 ) {
2014-06-06 05:39:17 -04:00
xmppConnectionService . getPgpEngine ( ) . hasKey (
2014-06-07 07:25:27 -04:00
conversation . getContact ( ) ,
new UiCallback < Contact > ( ) {
2014-06-06 05:39:17 -04:00
@Override
2015-11-25 14:47:02 -05:00
public void userInputRequried ( PendingIntent pi , Contact contact ) {
ConversationActivity . this . runIntent ( pi , attachmentChoice ) ;
2014-06-06 05:39:17 -04:00
}
@Override
2014-06-07 07:25:27 -04:00
public void success ( Contact contact ) {
2015-11-25 14:47:02 -05:00
selectPresenceToAttachFile ( attachmentChoice , encryption ) ;
2014-06-06 05:39:17 -04:00
}
@Override
2014-06-07 07:25:27 -04:00
public void error ( int error , Contact contact ) {
2016-06-19 05:08:17 -04:00
replaceToast ( getString ( error ) ) ;
2014-06-06 05:39:17 -04:00
}
} ) ;
2015-11-25 14:47:02 -05:00
} else if ( mode = = Conversation . MODE_MULTI & & conversation . getMucOptions ( ) . pgpKeysInUse ( ) ) {
if ( ! conversation . getMucOptions ( ) . everybodyHasKeys ( ) ) {
Toast warning = Toast
. makeText ( this ,
R . string . missing_public_keys ,
Toast . LENGTH_LONG ) ;
warning . setGravity ( Gravity . CENTER_VERTICAL , 0 , 0 ) ;
warning . show ( ) ;
}
selectPresenceToAttachFile ( attachmentChoice , encryption ) ;
2014-05-08 08:23:09 -04:00
} else {
final ConversationFragment fragment = ( ConversationFragment ) getFragmentManager ( )
2016-01-11 05:17:45 -05:00
. findFragmentByTag ( " conversation " ) ;
2014-05-08 08:23:09 -04:00
if ( fragment ! = null ) {
2014-06-06 05:39:17 -04:00
fragment . showNoPGPKeyDialog ( false ,
new OnClickListener ( ) {
@Override
public void onClick ( DialogInterface dialog ,
2016-01-11 05:17:45 -05:00
int which ) {
2016-10-18 07:06:24 -04:00
conversation . setNextEncryption ( Message . ENCRYPTION_NONE ) ;
xmppConnectionService . updateConversation ( conversation ) ;
2016-01-11 05:17:45 -05:00
selectPresenceToAttachFile ( attachmentChoice , Message . ENCRYPTION_NONE ) ;
2014-06-06 05:39:17 -04:00
}
} ) ;
2014-05-07 06:33:55 -04:00
}
2014-05-08 08:23:09 -04:00
}
2014-06-09 15:25:01 -04:00
} else {
showInstallPgpDialog ( ) ;
2014-05-07 06:33:55 -04:00
}
2014-05-09 15:20:34 -04:00
} else {
2015-07-19 12:36:28 -04:00
if ( encryption ! = Message . ENCRYPTION_AXOLOTL | | ! trustKeysIfNeeded ( REQUEST_TRUST_KEYS_MENU , attachmentChoice ) ) {
selectPresenceToAttachFile ( attachmentChoice , encryption ) ;
}
2014-05-07 06:33:55 -04:00
}
}
2014-06-06 05:39:17 -04:00
2014-01-23 20:04:05 -05:00
@Override
2015-12-06 12:23:59 -05:00
public void onRequestPermissionsResult ( int requestCode , String permissions [ ] , int [ ] grantResults ) {
if ( grantResults . length > 0 )
if ( grantResults [ 0 ] = = PackageManager . PERMISSION_GRANTED ) {
if ( requestCode = = REQUEST_START_DOWNLOAD ) {
if ( this . mPendingDownloadableMessage ! = null ) {
startDownloadable ( this . mPendingDownloadableMessage ) ;
}
} else {
attachFile ( requestCode ) ;
}
} else {
2016-01-11 05:17:45 -05:00
Toast . makeText ( this , R . string . no_storage_permission , Toast . LENGTH_SHORT ) . show ( ) ;
}
2015-12-06 12:23:59 -05:00
}
public void startDownloadable ( Message message ) {
2016-12-02 05:25:14 -05:00
if ( ! Config . ONLY_INTERNAL_STORAGE & & ! hasStoragePermission ( ConversationActivity . REQUEST_START_DOWNLOAD ) ) {
2015-12-06 12:23:59 -05:00
this . mPendingDownloadableMessage = message ;
return ;
}
Transferable transferable = message . getTransferable ( ) ;
if ( transferable ! = null ) {
if ( ! transferable . start ( ) ) {
2016-01-11 05:17:45 -05:00
Toast . makeText ( this , R . string . not_connected_try_again , Toast . LENGTH_SHORT ) . show ( ) ;
2015-12-06 12:23:59 -05:00
}
2017-04-05 16:32:02 -04:00
} else if ( message . treatAsDownloadable ( ) ) {
2015-12-06 12:23:59 -05:00
xmppConnectionService . getHttpConnectionManager ( ) . createNewDownloadConnection ( message , true ) ;
}
}
2016-01-11 05:17:45 -05:00
@Override
2014-12-21 15:43:58 -05:00
public boolean onOptionsItemSelected ( final MenuItem item ) {
2014-09-23 09:06:49 -04:00
if ( item . getItemId ( ) = = android . R . id . home ) {
2014-10-03 09:00:29 -04:00
showConversationsOverview ( ) ;
2014-08-15 07:18:15 -04:00
return true ;
2014-09-23 09:06:49 -04:00
} else if ( item . getItemId ( ) = = R . id . action_add ) {
2014-07-16 18:03:37 -04:00
startActivity ( new Intent ( this , StartConversationActivity . class ) ) ;
2014-09-23 09:06:49 -04:00
return true ;
} else if ( getSelectedConversation ( ) ! = null ) {
switch ( item . getItemId ( ) ) {
2014-11-03 14:00:20 -05:00
case R . id . action_attach_file :
attachFileDialog ( ) ;
break ;
case R . id . action_archive :
this . endConversation ( getSelectedConversation ( ) ) ;
break ;
case R . id . action_contact_details :
2015-01-21 09:31:40 -05:00
switchToContactDetails ( getSelectedConversation ( ) . getContact ( ) ) ;
2014-11-03 14:00:20 -05:00
break ;
case R . id . action_muc_details :
Intent intent = new Intent ( this ,
ConferenceDetailsActivity . class ) ;
intent . setAction ( ConferenceDetailsActivity . ACTION_VIEW_MUC ) ;
intent . putExtra ( " uuid " , getSelectedConversation ( ) . getUuid ( ) ) ;
startActivity ( intent ) ;
break ;
case R . id . action_invite :
inviteToConversation ( getSelectedConversation ( ) ) ;
break ;
case R . id . action_security :
selectEncryptionDialog ( getSelectedConversation ( ) ) ;
break ;
case R . id . action_clear_history :
clearHistoryDialog ( getSelectedConversation ( ) ) ;
break ;
case R . id . action_mute :
muteConversationDialog ( getSelectedConversation ( ) ) ;
break ;
2014-11-18 07:51:04 -05:00
case R . id . action_unmute :
unmuteConversation ( getSelectedConversation ( ) ) ;
break ;
2014-12-21 15:43:58 -05:00
case R . id . action_block :
2017-03-06 10:53:54 -05:00
BlockContactDialog . show ( this , getSelectedConversation ( ) ) ;
2014-12-21 15:43:58 -05:00
break ;
case R . id . action_unblock :
2017-03-06 10:53:54 -05:00
BlockContactDialog . show ( this , getSelectedConversation ( ) ) ;
2014-12-21 15:43:58 -05:00
break ;
2014-11-03 14:00:20 -05:00
default :
break ;
2014-04-10 08:12:08 -04:00
}
2014-09-23 09:06:49 -04:00
return super . onOptionsItemSelected ( item ) ;
} else {
return super . onOptionsItemSelected ( item ) ;
2014-01-23 20:04:05 -05:00
}
}
2014-06-06 05:39:17 -04:00
2014-07-18 06:44:33 -04:00
public void endConversation ( Conversation conversation ) {
2015-04-02 18:06:37 -04:00
endConversation ( conversation , true , true ) ;
}
public void endConversation ( Conversation conversation , boolean showOverview , boolean reinit ) {
if ( showOverview ) {
showConversationsOverview ( ) ;
}
2014-04-20 14:48:16 -04:00
xmppConnectionService . archiveConversation ( conversation ) ;
2015-04-02 18:06:37 -04:00
if ( reinit ) {
if ( conversationList . size ( ) > 0 ) {
setSelectedConversation ( conversationList . get ( 0 ) ) ;
this . mConversationFragment . reInit ( getSelectedConversation ( ) ) ;
} else {
setSelectedConversation ( null ) ;
2016-01-11 05:17:45 -05:00
if ( mRedirected . compareAndSet ( false , true ) ) {
2015-10-20 09:27:33 -04:00
Intent intent = new Intent ( this , StartConversationActivity . class ) ;
2016-01-11 05:17:45 -05:00
intent . putExtra ( " init " , true ) ;
2015-10-20 09:27:33 -04:00
startActivity ( intent ) ;
finish ( ) ;
}
2015-04-02 18:06:37 -04:00
}
2014-04-20 14:48:16 -04:00
}
}
2014-09-27 05:46:56 -04:00
@SuppressLint ( " InflateParams " )
2014-04-20 14:48:16 -04:00
protected void clearHistoryDialog ( final Conversation conversation ) {
2014-04-16 12:16:23 -04:00
AlertDialog . Builder builder = new AlertDialog . Builder ( this ) ;
builder . setTitle ( getString ( R . string . clear_conversation_history ) ) ;
2014-06-06 05:39:17 -04:00
View dialogView = getLayoutInflater ( ) . inflate (
R . layout . dialog_clear_history , null ) ;
final CheckBox endConversationCheckBox = ( CheckBox ) dialogView
2016-01-11 05:17:45 -05:00
. findViewById ( R . id . end_conversation_checkbox ) ;
2014-04-16 12:16:23 -04:00
builder . setView ( dialogView ) ;
builder . setNegativeButton ( getString ( R . string . cancel ) , null ) ;
2014-06-06 05:39:17 -04:00
builder . setPositiveButton ( getString ( R . string . delete_messages ) ,
new OnClickListener ( ) {
@Override
public void onClick ( DialogInterface dialog , int which ) {
2014-12-15 11:14:27 -05:00
ConversationActivity . this . xmppConnectionService . clearConversationHistory ( conversation ) ;
2014-06-06 05:39:17 -04:00
if ( endConversationCheckBox . isChecked ( ) ) {
endConversation ( conversation ) ;
2014-12-14 12:10:46 -05:00
} else {
updateConversationList ( ) ;
ConversationActivity . this . mConversationFragment . updateMessages ( ) ;
2014-06-06 05:39:17 -04:00
}
}
} ) ;
2014-04-16 12:16:23 -04:00
builder . create ( ) . show ( ) ;
}
2014-09-28 09:21:56 -04:00
2014-09-23 09:06:49 -04:00
protected void attachFileDialog ( ) {
View menuAttachFile = findViewById ( R . id . action_attach_file ) ;
if ( menuAttachFile = = null ) {
return ;
}
PopupMenu attachFilePopup = new PopupMenu ( this , menuAttachFile ) ;
attachFilePopup . inflate ( R . menu . attachment_choices ) ;
2015-01-03 10:06:59 -05:00
if ( new Intent ( MediaStore . Audio . Media . RECORD_SOUND_ACTION ) . resolveActivity ( getPackageManager ( ) ) = = null ) {
attachFilePopup . getMenu ( ) . findItem ( R . id . attach_record_voice ) . setVisible ( false ) ;
}
2015-03-07 08:15:38 -05:00
if ( new Intent ( " eu.siacs.conversations.location.request " ) . resolveActivity ( getPackageManager ( ) ) = = null ) {
attachFilePopup . getMenu ( ) . findItem ( R . id . attach_location ) . setVisible ( false ) ;
}
2015-01-03 10:06:59 -05:00
attachFilePopup . setOnMenuItemClickListener ( new OnMenuItemClickListener ( ) {
2014-09-23 09:06:49 -04:00
2015-01-14 15:28:27 -05:00
@Override
public boolean onMenuItemClick ( MenuItem item ) {
switch ( item . getItemId ( ) ) {
case R . id . attach_choose_picture :
attachFile ( ATTACHMENT_CHOICE_CHOOSE_IMAGE ) ;
break ;
case R . id . attach_take_picture :
attachFile ( ATTACHMENT_CHOICE_TAKE_PHOTO ) ;
break ;
case R . id . attach_choose_file :
attachFile ( ATTACHMENT_CHOICE_CHOOSE_FILE ) ;
break ;
case R . id . attach_record_voice :
attachFile ( ATTACHMENT_CHOICE_RECORD_VOICE ) ;
break ;
2015-03-07 08:15:38 -05:00
case R . id . attach_location :
attachFile ( ATTACHMENT_CHOICE_LOCATION ) ;
break ;
2014-12-21 15:43:58 -05:00
}
2015-01-14 15:28:27 -05:00
return false ;
}
} ) ;
2017-03-03 06:26:33 -05:00
UIHelper . showIconsInPopup ( attachFilePopup ) ;
2014-09-23 09:06:49 -04:00
attachFilePopup . show ( ) ;
}
2015-01-01 19:21:14 -05:00
public void verifyOtrSessionDialog ( final Conversation conversation , View view ) {
if ( ! conversation . hasValidOtrSession ( ) | | conversation . getOtrSession ( ) . getSessionStatus ( ) ! = SessionStatus . ENCRYPTED ) {
Toast . makeText ( this , R . string . otr_session_not_started , Toast . LENGTH_LONG ) . show ( ) ;
return ;
}
if ( view = = null ) {
return ;
}
PopupMenu popup = new PopupMenu ( this , view ) ;
popup . inflate ( R . menu . verification_choices ) ;
popup . setOnMenuItemClickListener ( new OnMenuItemClickListener ( ) {
@Override
public boolean onMenuItemClick ( MenuItem menuItem ) {
Intent intent = new Intent ( ConversationActivity . this , VerifyOTRActivity . class ) ;
intent . setAction ( VerifyOTRActivity . ACTION_VERIFY_CONTACT ) ;
intent . putExtra ( " contact " , conversation . getContact ( ) . getJid ( ) . toBareJid ( ) . toString ( ) ) ;
2016-01-22 14:46:24 -05:00
intent . putExtra ( EXTRA_ACCOUNT , conversation . getAccount ( ) . getJid ( ) . toBareJid ( ) . toString ( ) ) ;
2015-01-01 19:21:14 -05:00
switch ( menuItem . getItemId ( ) ) {
case R . id . scan_fingerprint :
2015-09-07 09:46:22 -04:00
intent . putExtra ( " mode " , VerifyOTRActivity . MODE_SCAN_FINGERPRINT ) ;
2015-01-01 19:21:14 -05:00
break ;
case R . id . ask_question :
2015-09-07 09:46:22 -04:00
intent . putExtra ( " mode " , VerifyOTRActivity . MODE_ASK_QUESTION ) ;
2015-01-01 19:21:14 -05:00
break ;
case R . id . manual_verification :
2015-09-07 09:46:22 -04:00
intent . putExtra ( " mode " , VerifyOTRActivity . MODE_MANUAL_VERIFICATION ) ;
2015-01-01 19:21:14 -05:00
break ;
}
startActivity ( intent ) ;
return true ;
}
} ) ;
popup . show ( ) ;
}
2014-09-23 09:06:49 -04:00
protected void selectEncryptionDialog ( final Conversation conversation ) {
View menuItemView = findViewById ( R . id . action_security ) ;
if ( menuItemView = = null ) {
return ;
}
PopupMenu popup = new PopupMenu ( this , menuItemView ) ;
final ConversationFragment fragment = ( ConversationFragment ) getFragmentManager ( )
2016-01-11 05:17:45 -05:00
. findFragmentByTag ( " conversation " ) ;
2014-09-23 09:06:49 -04:00
if ( fragment ! = null ) {
popup . setOnMenuItemClickListener ( new OnMenuItemClickListener ( ) {
@Override
public boolean onMenuItemClick ( MenuItem item ) {
switch ( item . getItemId ( ) ) {
2014-11-03 14:00:20 -05:00
case R . id . encryption_choice_none :
conversation . setNextEncryption ( Message . ENCRYPTION_NONE ) ;
item . setChecked ( true ) ;
break ;
case R . id . encryption_choice_otr :
conversation . setNextEncryption ( Message . ENCRYPTION_OTR ) ;
item . setChecked ( true ) ;
break ;
case R . id . encryption_choice_pgp :
if ( hasPgp ( ) ) {
2015-10-29 09:03:41 -04:00
if ( conversation . getAccount ( ) . getPgpSignature ( ) ! = null ) {
2015-07-12 11:59:22 -04:00
conversation . setNextEncryption ( Message . ENCRYPTION_PGP ) ;
2014-11-03 14:00:20 -05:00
item . setChecked ( true ) ;
} else {
2016-05-05 07:17:04 -04:00
announcePgp ( conversation . getAccount ( ) , conversation , onOpenPGPKeyPublished ) ;
2014-11-03 14:00:20 -05:00
}
2014-09-23 09:06:49 -04:00
} else {
2014-11-03 14:00:20 -05:00
showInstallPgpDialog ( ) ;
2014-09-23 09:06:49 -04:00
}
2014-11-03 14:00:20 -05:00
break ;
2015-06-25 11:01:42 -04:00
case R . id . encryption_choice_axolotl :
2015-07-09 21:02:49 -04:00
Log . d ( Config . LOGTAG , AxolotlService . getLogprefix ( conversation . getAccount ( ) )
+ " Enabled axolotl for Contact " + conversation . getContact ( ) . getJid ( ) ) ;
conversation . setNextEncryption ( Message . ENCRYPTION_AXOLOTL ) ;
item . setChecked ( true ) ;
2015-06-26 09:41:02 -04:00
break ;
2014-11-03 14:00:20 -05:00
default :
conversation . setNextEncryption ( Message . ENCRYPTION_NONE ) ;
break ;
2014-09-23 09:06:49 -04:00
}
2016-10-18 07:06:24 -04:00
xmppConnectionService . updateConversation ( conversation ) ;
2014-09-23 09:06:49 -04:00
fragment . updateChatMsgHint ( ) ;
2015-07-12 11:59:22 -04:00
invalidateOptionsMenu ( ) ;
2015-07-29 14:10:21 -04:00
refreshUi ( ) ;
2014-09-23 09:06:49 -04:00
return true ;
}
} ) ;
popup . inflate ( R . menu . encryption_choices ) ;
MenuItem otr = popup . getMenu ( ) . findItem ( R . id . encryption_choice_otr ) ;
2015-07-12 11:59:22 -04:00
MenuItem none = popup . getMenu ( ) . findItem ( R . id . encryption_choice_none ) ;
MenuItem pgp = popup . getMenu ( ) . findItem ( R . id . encryption_choice_pgp ) ;
2015-07-09 21:02:49 -04:00
MenuItem axolotl = popup . getMenu ( ) . findItem ( R . id . encryption_choice_axolotl ) ;
2016-02-24 08:47:49 -05:00
pgp . setVisible ( Config . supportOpenPgp ( ) ) ;
none . setVisible ( Config . supportUnencrypted ( ) | | conversation . getMode ( ) = = Conversation . MODE_MULTI ) ;
otr . setVisible ( Config . supportOtr ( ) ) ;
axolotl . setVisible ( Config . supportOmemo ( ) ) ;
2014-09-23 09:06:49 -04:00
if ( conversation . getMode ( ) = = Conversation . MODE_MULTI ) {
2015-08-06 07:09:53 -04:00
otr . setVisible ( false ) ;
2016-02-29 07:18:07 -05:00
}
if ( ! conversation . getAccount ( ) . getAxolotlService ( ) . isConversationAxolotlCapable ( conversation ) ) {
2015-07-09 21:02:49 -04:00
axolotl . setEnabled ( false ) ;
}
2015-07-30 18:52:46 -04:00
switch ( conversation . getNextEncryption ( ) ) {
2014-11-03 14:00:20 -05:00
case Message . ENCRYPTION_NONE :
none . setChecked ( true ) ;
break ;
case Message . ENCRYPTION_OTR :
otr . setChecked ( true ) ;
break ;
case Message . ENCRYPTION_PGP :
2015-07-12 11:59:22 -04:00
pgp . setChecked ( true ) ;
2014-11-03 14:00:20 -05:00
break ;
2015-06-25 11:01:42 -04:00
case Message . ENCRYPTION_AXOLOTL :
2015-07-30 18:52:46 -04:00
axolotl . setChecked ( true ) ;
2015-06-25 11:01:42 -04:00
break ;
2014-11-03 14:00:20 -05:00
default :
2015-07-12 11:59:22 -04:00
none . setChecked ( true ) ;
2014-11-03 14:00:20 -05:00
break ;
2014-09-23 09:06:49 -04:00
}
popup . show ( ) ;
}
}
2014-09-08 07:37:22 -04:00
2014-09-03 06:36:54 -04:00
protected void muteConversationDialog ( final Conversation conversation ) {
AlertDialog . Builder builder = new AlertDialog . Builder ( this ) ;
2014-11-17 18:07:27 -05:00
builder . setTitle ( R . string . disable_notifications ) ;
2015-07-30 18:52:46 -04:00
final int [ ] durations = getResources ( ) . getIntArray ( R . array . mute_options_durations ) ;
2014-09-08 07:37:22 -04:00
builder . setItems ( R . array . mute_options_descriptions ,
new OnClickListener ( ) {
@Override
2014-12-21 15:43:58 -05:00
public void onClick ( final DialogInterface dialog , final int which ) {
final long till ;
2014-09-08 07:37:22 -04:00
if ( durations [ which ] = = - 1 ) {
till = Long . MAX_VALUE ;
} else {
2015-02-12 12:52:10 -05:00
till = System . currentTimeMillis ( ) + ( durations [ which ] * 1000 ) ;
2014-09-08 07:37:22 -04:00
}
conversation . setMutedTill ( till ) ;
2016-10-18 07:06:24 -04:00
ConversationActivity . this . xmppConnectionService . updateConversation ( conversation ) ;
2014-11-17 18:07:27 -05:00
updateConversationList ( ) ;
ConversationActivity . this . mConversationFragment . updateMessages ( ) ;
2014-11-18 07:51:04 -05:00
invalidateOptionsMenu ( ) ;
2014-09-08 07:37:22 -04:00
}
} ) ;
2014-09-03 06:36:54 -04:00
builder . create ( ) . show ( ) ;
}
2014-01-23 20:04:05 -05:00
2014-11-18 07:51:04 -05:00
public void unmuteConversation ( final Conversation conversation ) {
conversation . setMutedTill ( 0 ) ;
2016-10-18 07:06:24 -04:00
this . xmppConnectionService . updateConversation ( conversation ) ;
2014-11-18 07:51:04 -05:00
updateConversationList ( ) ;
ConversationActivity . this . mConversationFragment . updateMessages ( ) ;
invalidateOptionsMenu ( ) ;
}
2014-01-24 04:50:18 -05:00
@Override
2014-11-21 12:57:27 -05:00
public void onBackPressed ( ) {
if ( ! isConversationsOverviewVisable ( ) ) {
showConversationsOverview ( ) ;
} else {
2017-01-22 12:26:47 -05:00
super . onBackPressed ( ) ;
2014-01-24 04:50:18 -05:00
}
}
2014-04-10 08:12:08 -04:00
2015-09-07 09:46:22 -04:00
@Override
public boolean onKeyUp ( int key , KeyEvent event ) {
2015-09-07 14:45:21 -04:00
int rotation = getWindowManager ( ) . getDefaultDisplay ( ) . getRotation ( ) ;
final int upKey ;
final int downKey ;
2016-01-11 05:17:45 -05:00
switch ( rotation ) {
2015-09-07 14:45:21 -04:00
case Surface . ROTATION_90 :
upKey = KeyEvent . KEYCODE_DPAD_LEFT ;
downKey = KeyEvent . KEYCODE_DPAD_RIGHT ;
break ;
case Surface . ROTATION_180 :
upKey = KeyEvent . KEYCODE_DPAD_DOWN ;
downKey = KeyEvent . KEYCODE_DPAD_UP ;
break ;
case Surface . ROTATION_270 :
upKey = KeyEvent . KEYCODE_DPAD_RIGHT ;
downKey = KeyEvent . KEYCODE_DPAD_LEFT ;
break ;
2017-01-22 12:26:47 -05:00
case Surface . ROTATION_0 :
2015-09-07 14:45:21 -04:00
default :
upKey = KeyEvent . KEYCODE_DPAD_UP ;
downKey = KeyEvent . KEYCODE_DPAD_DOWN ;
}
2016-06-05 14:21:44 -04:00
final boolean modifier = event . isCtrlPressed ( ) | | ( event . getMetaState ( ) & KeyEvent . META_ALT_LEFT_ON ) ! = 0 ;
2015-09-07 09:46:22 -04:00
if ( modifier & & key = = KeyEvent . KEYCODE_TAB & & isConversationsOverviewHideable ( ) ) {
toggleConversationsOverview ( ) ;
return true ;
2016-05-12 12:49:54 -04:00
} else if ( modifier & & key = = KeyEvent . KEYCODE_SPACE ) {
startActivity ( new Intent ( this , StartConversationActivity . class ) ) ;
return true ;
2015-09-07 14:45:21 -04:00
} else if ( modifier & & key = = downKey ) {
2015-09-07 09:46:22 -04:00
if ( isConversationsOverviewHideable ( ) & & ! isConversationsOverviewVisable ( ) ) {
2016-01-11 05:17:45 -05:00
showConversationsOverview ( ) ;
;
2015-09-07 09:46:22 -04:00
}
2015-09-09 17:28:37 -04:00
return selectDownConversation ( ) ;
2015-09-07 14:45:21 -04:00
} else if ( modifier & & key = = upKey ) {
2015-09-07 09:46:22 -04:00
if ( isConversationsOverviewHideable ( ) & & ! isConversationsOverviewVisable ( ) ) {
2015-09-09 17:28:37 -04:00
showConversationsOverview ( ) ;
2015-09-07 09:46:22 -04:00
}
2015-09-09 17:28:37 -04:00
return selectUpConversation ( ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_1 ) {
return openConversationByIndex ( 0 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_2 ) {
return openConversationByIndex ( 1 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_3 ) {
return openConversationByIndex ( 2 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_4 ) {
return openConversationByIndex ( 3 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_5 ) {
return openConversationByIndex ( 4 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_6 ) {
return openConversationByIndex ( 5 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_7 ) {
return openConversationByIndex ( 6 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_8 ) {
return openConversationByIndex ( 7 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_9 ) {
return openConversationByIndex ( 8 ) ;
} else if ( modifier & & key = = KeyEvent . KEYCODE_0 ) {
return openConversationByIndex ( 9 ) ;
2015-09-07 09:46:22 -04:00
} else {
return super . onKeyUp ( key , event ) ;
}
}
private void toggleConversationsOverview ( ) {
if ( isConversationsOverviewVisable ( ) ) {
hideConversationsOverview ( ) ;
if ( mConversationFragment ! = null ) {
mConversationFragment . setFocusOnInputField ( ) ;
}
} else {
showConversationsOverview ( ) ;
}
}
2015-09-09 17:28:37 -04:00
private boolean selectUpConversation ( ) {
2015-09-07 09:46:22 -04:00
if ( this . mSelectedConversation ! = null ) {
int index = this . conversationList . indexOf ( this . mSelectedConversation ) ;
if ( index > 0 ) {
2015-09-09 17:28:37 -04:00
return openConversationByIndex ( index - 1 ) ;
2015-09-07 09:46:22 -04:00
}
}
2015-09-09 17:28:37 -04:00
return false ;
2015-09-07 09:46:22 -04:00
}
2015-09-09 17:28:37 -04:00
private boolean selectDownConversation ( ) {
2015-09-07 09:46:22 -04:00
if ( this . mSelectedConversation ! = null ) {
int index = this . conversationList . indexOf ( this . mSelectedConversation ) ;
if ( index ! = - 1 & & index < this . conversationList . size ( ) - 1 ) {
2015-09-09 17:28:37 -04:00
return openConversationByIndex ( index + 1 ) ;
2015-09-07 09:46:22 -04:00
}
}
2015-09-09 17:28:37 -04:00
return false ;
}
private boolean openConversationByIndex ( int index ) {
try {
this . conversationWasSelectedByKeyboard = true ;
setSelectedConversation ( this . conversationList . get ( index ) ) ;
this . mConversationFragment . reInit ( getSelectedConversation ( ) ) ;
if ( index > listView . getLastVisiblePosition ( ) - 1 | | index < listView . getFirstVisiblePosition ( ) + 1 ) {
this . listView . setSelection ( index ) ;
}
openConversation ( ) ;
return true ;
} catch ( IndexOutOfBoundsException e ) {
return false ;
}
2015-09-07 09:46:22 -04:00
}
2014-05-21 10:43:19 -04:00
@Override
2014-11-07 09:09:28 -05:00
protected void onNewIntent ( final Intent intent ) {
2016-07-25 08:15:47 -04:00
if ( intent ! = null & & ACTION_VIEW_CONVERSATION . equals ( intent . getAction ( ) ) ) {
2016-09-12 15:18:56 -04:00
mOpenConversation = null ;
2016-11-08 06:42:13 -05:00
mUnprocessedNewIntent = true ;
2016-07-25 08:15:47 -04:00
if ( xmppConnectionServiceBound ) {
2014-10-24 08:34:46 -04:00
handleViewConversationIntent ( intent ) ;
2016-07-25 08:15:47 -04:00
intent . setAction ( Intent . ACTION_MAIN ) ;
} else {
setIntent ( intent ) ;
2014-05-21 10:43:19 -04:00
}
}
}
2014-06-06 05:39:17 -04:00
2014-03-28 07:22:09 -04:00
@Override
2014-02-04 16:26:46 -05:00
public void onStart ( ) {
super . onStart ( ) ;
2015-10-20 09:27:33 -04:00
this . mRedirected . set ( false ) ;
2014-03-28 07:22:09 -04:00
if ( this . xmppConnectionServiceBound ) {
this . onBackendConnected ( ) ;
}
2014-04-10 08:12:08 -04:00
if ( conversationList . size ( ) > = 1 ) {
2014-09-10 11:59:57 -04:00
this . onConversationUpdate ( ) ;
2014-02-05 16:33:39 -05:00
}
2014-02-04 16:26:46 -05:00
}
2014-04-10 08:12:08 -04:00
2015-01-02 06:04:33 -05:00
@Override
public void onPause ( ) {
2015-04-02 18:06:37 -04:00
listView . discardUndo ( ) ;
2015-01-02 06:04:33 -05:00
super . onPause ( ) ;
this . mActivityPaused = true ;
}
2014-12-09 14:22:21 -05:00
@Override
public void onResume ( ) {
super . onResume ( ) ;
2015-01-14 15:28:27 -05:00
final int theme = findTheme ( ) ;
final boolean usingEnterKey = usingEnterKey ( ) ;
if ( this . mTheme ! = theme | | usingEnterKey ! = mUsingEnterKey ) {
2014-12-09 14:22:21 -05:00
recreate ( ) ;
}
2015-01-02 06:04:33 -05:00
this . mActivityPaused = false ;
2015-01-29 07:20:18 -05:00
2016-11-08 06:42:13 -05:00
2015-01-15 10:32:24 -05:00
if ( ! isConversationsOverviewVisable ( ) | | ! isConversationsOverviewHideable ( ) ) {
sendReadMarkerIfNecessary ( getSelectedConversation ( ) ) ;
}
2015-01-29 07:20:18 -05:00
2014-12-09 14:22:21 -05:00
}
2014-10-03 09:00:29 -04:00
@Override
2014-11-07 09:09:28 -05:00
public void onSaveInstanceState ( final Bundle savedInstanceState ) {
2014-10-06 13:27:58 -04:00
Conversation conversation = getSelectedConversation ( ) ;
2014-10-06 16:03:01 -04:00
if ( conversation ! = null ) {
2016-01-11 05:17:45 -05:00
savedInstanceState . putString ( STATE_OPEN_CONVERSATION , conversation . getUuid ( ) ) ;
2016-09-12 15:18:56 -04:00
Pair < Integer , Integer > scrollPosition = mConversationFragment . getScrollPosition ( ) ;
if ( scrollPosition ! = null ) {
savedInstanceState . putInt ( STATE_FIRST_VISIBLE , scrollPosition . first ) ;
savedInstanceState . putInt ( STATE_OFFSET_FROM_TOP , scrollPosition . second ) ;
}
2015-12-05 13:02:57 -05:00
} else {
savedInstanceState . remove ( STATE_OPEN_CONVERSATION ) ;
2014-10-06 13:27:58 -04:00
}
2016-01-11 05:17:45 -05:00
savedInstanceState . putBoolean ( STATE_PANEL_OPEN , isConversationsOverviewVisable ( ) ) ;
2015-04-11 08:53:10 -04:00
if ( this . mPendingImageUris . size ( ) > = 1 ) {
2016-10-03 05:13:04 -04:00
Log . d ( Config . LOGTAG , " ConversationsActivity.onSaveInstanceState() - saving pending image uri " ) ;
2015-04-11 08:53:10 -04:00
savedInstanceState . putString ( STATE_PENDING_URI , this . mPendingImageUris . get ( 0 ) . toString ( ) ) ;
2015-12-05 13:02:57 -05:00
} else {
savedInstanceState . remove ( STATE_PENDING_URI ) ;
2014-11-06 11:25:14 -05:00
}
2014-10-03 09:00:29 -04:00
super . onSaveInstanceState ( savedInstanceState ) ;
}
2015-12-05 13:02:57 -05:00
private void clearPending ( ) {
mPendingImageUris . clear ( ) ;
mPendingFileUris . clear ( ) ;
mPendingGeoUri = null ;
mPostponedActivityResult = null ;
}
2017-03-06 10:53:54 -05:00
private void redirectToStartConversationActivity ( ) {
Account pendingAccount = xmppConnectionService . getPendingAccount ( ) ;
if ( pendingAccount = = null ) {
Intent startConversationActivity = new Intent ( this , StartConversationActivity . class ) ;
startConversationActivity . putExtra ( " init " , true ) ;
startActivity ( startConversationActivity ) ;
} else {
switchToAccount ( pendingAccount , true ) ;
}
finish ( ) ;
}
2014-01-25 13:33:12 -05:00
@Override
2014-01-27 14:40:42 -05:00
void onBackendConnected ( ) {
2015-01-02 06:04:33 -05:00
this . xmppConnectionService . getNotificationService ( ) . setIsInForeground ( true ) ;
2014-10-03 09:00:29 -04:00
updateConversationList ( ) ;
2015-05-11 22:33:04 -04:00
if ( mPendingConferenceInvite ! = null ) {
2016-06-28 04:34:43 -04:00
if ( mPendingConferenceInvite . execute ( this ) ) {
mToast = Toast . makeText ( this , R . string . creating_conference , Toast . LENGTH_LONG ) ;
mToast . show ( ) ;
}
2015-05-11 22:33:04 -04:00
mPendingConferenceInvite = null ;
}
2016-07-25 08:15:47 -04:00
final Intent intent = getIntent ( ) ;
2014-10-03 09:00:29 -04:00
if ( xmppConnectionService . getAccounts ( ) . size ( ) = = 0 ) {
2016-01-11 05:17:45 -05:00
if ( mRedirected . compareAndSet ( false , true ) ) {
2015-10-20 09:27:33 -04:00
if ( Config . X509_VERIFICATION ) {
startActivity ( new Intent ( this , ManageAccountActivity . class ) ) ;
2016-04-19 12:03:24 -04:00
} else if ( Config . MAGIC_CREATE_DOMAIN ! = null ) {
startActivity ( new Intent ( this , WelcomeActivity . class ) ) ;
2015-10-20 09:27:33 -04:00
} else {
2016-08-26 03:10:59 -04:00
Intent editAccount = new Intent ( this , EditAccountActivity . class ) ;
editAccount . putExtra ( " init " , true ) ;
startActivity ( editAccount ) ;
2015-10-20 09:27:33 -04:00
}
2015-02-22 07:24:29 -05:00
finish ( ) ;
}
2014-10-03 09:00:29 -04:00
} else if ( conversationList . size ( ) < = 0 ) {
2016-01-11 05:17:45 -05:00
if ( mRedirected . compareAndSet ( false , true ) ) {
2017-03-06 10:53:54 -05:00
redirectToStartConversationActivity ( ) ;
2015-02-22 07:24:29 -05:00
}
2016-09-12 15:18:56 -04:00
} else if ( selectConversationByUuid ( mOpenConversation ) ) {
2014-11-07 09:38:20 -05:00
if ( mPanelOpen ) {
2014-10-03 09:00:29 -04:00
showConversationsOverview ( ) ;
2014-11-07 15:49:31 -05:00
} else {
if ( isConversationsOverviewHideable ( ) ) {
openConversation ( ) ;
2016-01-16 15:18:59 -05:00
updateActionBarTitle ( true ) ;
2014-11-07 15:49:31 -05:00
}
2014-10-03 09:00:29 -04:00
}
2016-09-12 15:18:56 -04:00
if ( this . mConversationFragment . reInit ( getSelectedConversation ( ) ) ) {
Log . d ( Config . LOGTAG , " setting scroll position on fragment " ) ;
this . mConversationFragment . setScrollPosition ( mScrollPosition ) ;
}
mOpenConversation = null ;
2016-07-25 08:15:47 -04:00
} else if ( intent ! = null & & ACTION_VIEW_CONVERSATION . equals ( intent . getAction ( ) ) ) {
clearPending ( ) ;
handleViewConversationIntent ( intent ) ;
intent . setAction ( Intent . ACTION_MAIN ) ;
2015-05-11 21:56:13 -04:00
} else if ( getSelectedConversation ( ) = = null ) {
2017-03-06 10:53:54 -05:00
reInitLatestConversation ( ) ;
2015-08-24 14:56:25 -04:00
} else {
this . mConversationFragment . messageListAdapter . updatePreferences ( ) ;
this . mConversationFragment . messagesView . invalidateViews ( ) ;
2015-09-04 08:48:00 -04:00
this . mConversationFragment . setupIme ( ) ;
2014-01-27 14:40:42 -05:00
}
2014-08-31 10:28:21 -04:00
2015-12-01 08:18:07 -05:00
if ( this . mPostponedActivityResult ! = null ) {
this . onActivityResult ( mPostponedActivityResult . first , RESULT_OK , mPostponedActivityResult . second ) ;
}
2017-03-06 10:53:54 -05:00
final boolean stopping = isStopping ( ) ;
2016-10-03 05:13:04 -04:00
2016-01-11 05:17:45 -05:00
if ( ! forbidProcessingPendings ) {
2015-07-19 12:36:28 -04:00
for ( Iterator < Uri > i = mPendingImageUris . iterator ( ) ; i . hasNext ( ) ; i . remove ( ) ) {
Uri foo = i . next ( ) ;
2016-10-03 05:13:04 -04:00
Log . d ( Config . LOGTAG , " ConversationsActivity.onBackendConnected() - attaching image to conversations. stopping= " + Boolean . toString ( stopping ) ) ;
2015-07-19 12:36:28 -04:00
attachImageToConversation ( getSelectedConversation ( ) , foo ) ;
}
2015-04-11 08:53:10 -04:00
2015-07-19 12:36:28 -04:00
for ( Iterator < Uri > i = mPendingFileUris . iterator ( ) ; i . hasNext ( ) ; i . remove ( ) ) {
2016-10-03 05:13:04 -04:00
Log . d ( Config . LOGTAG , " ConversationsActivity.onBackendConnected() - attaching file to conversations. stopping= " + Boolean . toString ( stopping ) ) ;
2015-07-19 12:36:28 -04:00
attachFileToConversation ( getSelectedConversation ( ) , i . next ( ) ) ;
}
2015-04-11 08:53:10 -04:00
2015-07-19 12:36:28 -04:00
if ( mPendingGeoUri ! = null ) {
attachLocationToConversation ( getSelectedConversation ( ) , mPendingGeoUri ) ;
mPendingGeoUri = null ;
}
2014-08-21 03:19:18 -04:00
}
2015-07-19 12:36:28 -04:00
forbidProcessingPendings = false ;
2016-01-11 05:17:45 -05:00
if ( ! ExceptionHelper . checkForCrash ( this , this . xmppConnectionService ) ) {
openBatteryOptimizationDialogIfNeeded ( ) ;
}
2017-01-20 07:44:29 -05:00
if ( isConversationsOverviewVisable ( ) & & isConversationsOverviewHideable ( ) ) {
xmppConnectionService . getNotificationService ( ) . setOpenConversation ( null ) ;
2017-01-22 07:08:21 -05:00
} else {
xmppConnectionService . getNotificationService ( ) . setOpenConversation ( getSelectedConversation ( ) ) ;
2017-01-20 07:44:29 -05:00
}
2014-10-03 09:00:29 -04:00
}
2014-10-29 04:57:03 -04:00
2017-03-06 10:53:54 -05:00
private boolean isStopping ( ) {
if ( Build . VERSION . SDK_INT > = 17 ) {
return isFinishing ( ) | | isDestroyed ( ) ;
} else {
return isFinishing ( ) ;
}
}
private void reInitLatestConversation ( ) {
showConversationsOverview ( ) ;
clearPending ( ) ;
setSelectedConversation ( conversationList . get ( 0 ) ) ;
this . mConversationFragment . reInit ( getSelectedConversation ( ) ) ;
}
2015-01-16 00:36:11 -05:00
private void handleViewConversationIntent ( final Intent intent ) {
2015-04-19 13:11:32 -04:00
final String uuid = intent . getStringExtra ( CONVERSATION ) ;
2016-07-25 08:15:47 -04:00
final String downloadUuid = intent . getStringExtra ( EXTRA_DOWNLOAD_UUID ) ;
2015-04-19 13:11:32 -04:00
final String text = intent . getStringExtra ( TEXT ) ;
final String nick = intent . getStringExtra ( NICK ) ;
2016-01-11 05:17:45 -05:00
final boolean pm = intent . getBooleanExtra ( PRIVATE_MESSAGE , false ) ;
2015-01-10 13:43:23 -05:00
if ( selectConversationByUuid ( uuid ) ) {
this . mConversationFragment . reInit ( getSelectedConversation ( ) ) ;
if ( nick ! = null ) {
2015-07-21 07:15:59 -04:00
if ( pm ) {
Jid jid = getSelectedConversation ( ) . getJid ( ) ;
try {
2016-01-11 05:17:45 -05:00
Jid next = Jid . fromParts ( jid . getLocalpart ( ) , jid . getDomainpart ( ) , nick ) ;
2015-07-21 07:15:59 -04:00
this . mConversationFragment . privateMessageWith ( next ) ;
} catch ( final InvalidJidException ignored ) {
//do nothing
}
} else {
this . mConversationFragment . highlightInConference ( nick ) ;
}
2015-01-10 13:43:23 -05:00
} else {
this . mConversationFragment . appendText ( text ) ;
}
hideConversationsOverview ( ) ;
2016-11-08 06:42:13 -05:00
mUnprocessedNewIntent = false ;
2015-01-10 13:43:23 -05:00
openConversation ( ) ;
if ( mContentView instanceof SlidingPaneLayout ) {
updateActionBarTitle ( true ) ; //fixes bug where slp isn't properly closed yet
}
2015-01-16 00:36:11 -05:00
if ( downloadUuid ! = null ) {
final Message message = mSelectedConversation . findMessageWithFileAndUuid ( downloadUuid ) ;
if ( message ! = null ) {
2015-12-06 12:23:59 -05:00
startDownloadable ( message ) ;
2015-01-16 00:36:11 -05:00
}
}
2016-11-08 06:42:13 -05:00
} else {
mUnprocessedNewIntent = false ;
2014-11-07 15:49:31 -05:00
}
2014-10-24 08:34:46 -04:00
}
2014-01-25 13:33:12 -05:00
2015-01-10 13:43:23 -05:00
private boolean selectConversationByUuid ( String uuid ) {
if ( uuid = = null ) {
return false ;
}
2014-12-21 15:43:58 -05:00
for ( Conversation aConversationList : conversationList ) {
if ( aConversationList . getUuid ( ) . equals ( uuid ) ) {
setSelectedConversation ( aConversationList ) ;
2015-01-10 13:43:23 -05:00
return true ;
2014-12-21 15:43:58 -05:00
}
}
2015-01-10 13:43:23 -05:00
return false ;
2014-01-25 13:33:12 -05:00
}
2014-04-10 08:12:08 -04:00
2014-11-11 11:39:28 -05:00
@Override
protected void unregisterListeners ( ) {
super . unregisterListeners ( ) ;
xmppConnectionService . getNotificationService ( ) . setOpenConversation ( null ) ;
2014-03-10 16:52:58 -04:00
}
2015-04-13 11:35:20 -04:00
@SuppressLint ( " NewApi " )
2015-04-11 08:53:10 -04:00
private static List < Uri > extractUriFromIntent ( final Intent intent ) {
List < Uri > uris = new ArrayList < > ( ) ;
2016-01-15 17:47:55 -05:00
if ( intent = = null ) {
return uris ;
}
2015-04-11 08:53:10 -04:00
Uri uri = intent . getData ( ) ;
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . JELLY_BEAN_MR2 & & uri = = null ) {
2016-08-19 15:46:47 -04:00
final ClipData clipData = intent . getClipData ( ) ;
if ( clipData ! = null ) {
for ( int i = 0 ; i < clipData . getItemCount ( ) ; + + i ) {
uris . add ( clipData . getItemAt ( i ) . getUri ( ) ) ;
}
2015-04-11 08:53:10 -04:00
}
} else {
uris . add ( uri ) ;
}
return uris ;
}
2014-03-10 16:52:58 -04:00
@Override
2016-01-11 05:17:45 -05:00
protected void onActivityResult ( int requestCode , int resultCode , final Intent data ) {
2014-04-10 08:12:08 -04:00
super . onActivityResult ( requestCode , resultCode , data ) ;
if ( resultCode = = RESULT_OK ) {
2014-02-27 20:58:15 -05:00
if ( requestCode = = REQUEST_DECRYPT_PGP ) {
2015-10-15 18:21:47 -04:00
mConversationFragment . onActivityResult ( requestCode , resultCode , data ) ;
2015-10-29 09:03:41 -04:00
} else if ( requestCode = = REQUEST_CHOOSE_PGP_ID ) {
2016-01-15 16:54:29 -05:00
// the user chose OpenPGP for encryption and selected his key in the PGP provider
2015-12-01 08:18:07 -05:00
if ( xmppConnectionServiceBound ) {
if ( data . getExtras ( ) . containsKey ( OpenPgpApi . EXTRA_SIGN_KEY_ID ) ) {
2016-01-15 16:54:29 -05:00
// associate selected PGP keyId with the account
2015-12-01 08:18:07 -05:00
mSelectedConversation . getAccount ( ) . setPgpSignId ( data . getExtras ( ) . getLong ( OpenPgpApi . EXTRA_SIGN_KEY_ID ) ) ;
2016-01-15 16:54:29 -05:00
// we need to announce the key as described in XEP-027
2016-05-05 07:17:04 -04:00
announcePgp ( mSelectedConversation . getAccount ( ) , null , onOpenPGPKeyPublished ) ;
2015-12-01 08:18:07 -05:00
} else {
choosePgpSignId ( mSelectedConversation . getAccount ( ) ) ;
}
this . mPostponedActivityResult = null ;
2015-10-29 09:03:41 -04:00
} else {
2015-12-01 08:18:07 -05:00
this . mPostponedActivityResult = new Pair < > ( requestCode , data ) ;
2015-10-29 09:03:41 -04:00
}
} else if ( requestCode = = REQUEST_ANNOUNCE_PGP ) {
2015-12-01 08:18:07 -05:00
if ( xmppConnectionServiceBound ) {
2016-05-05 07:17:04 -04:00
announcePgp ( mSelectedConversation . getAccount ( ) , mSelectedConversation , onOpenPGPKeyPublished ) ;
2015-12-01 08:18:07 -05:00
this . mPostponedActivityResult = null ;
} else {
this . mPostponedActivityResult = new Pair < > ( requestCode , data ) ;
}
2015-01-03 10:06:59 -05:00
} else if ( requestCode = = ATTACHMENT_CHOICE_CHOOSE_IMAGE ) {
2015-04-11 08:53:10 -04:00
mPendingImageUris . clear ( ) ;
mPendingImageUris . addAll ( extractUriFromIntent ( data ) ) ;
2014-08-21 03:19:18 -04:00
if ( xmppConnectionServiceBound ) {
2016-01-11 05:17:45 -05:00
for ( Iterator < Uri > i = mPendingImageUris . iterator ( ) ; i . hasNext ( ) ; i . remove ( ) ) {
2016-10-03 05:13:04 -04:00
Log . d ( Config . LOGTAG , " ConversationsActivity.onActivityResult() - attaching image to conversations. CHOOSE_IMAGE " ) ;
2016-01-11 05:17:45 -05:00
attachImageToConversation ( getSelectedConversation ( ) , i . next ( ) ) ;
2015-04-11 08:53:10 -04:00
}
2014-08-21 03:19:18 -04:00
}
2015-01-03 10:06:59 -05:00
} else if ( requestCode = = ATTACHMENT_CHOICE_CHOOSE_FILE | | requestCode = = ATTACHMENT_CHOICE_RECORD_VOICE ) {
2016-03-31 18:03:14 -04:00
final List < Uri > uris = extractUriFromIntent ( data ) ;
final Conversation c = getSelectedConversation ( ) ;
final OnPresenceSelected callback = new OnPresenceSelected ( ) {
@Override
public void onPresenceSelected ( ) {
mPendingFileUris . clear ( ) ;
mPendingFileUris . addAll ( uris ) ;
if ( xmppConnectionServiceBound ) {
for ( Iterator < Uri > i = mPendingFileUris . iterator ( ) ; i . hasNext ( ) ; i . remove ( ) ) {
2016-10-03 05:13:04 -04:00
Log . d ( Config . LOGTAG , " ConversationsActivity.onActivityResult() - attaching file to conversations. CHOOSE_FILE/RECORD_VOICE " ) ;
2016-03-31 18:03:14 -04:00
attachFileToConversation ( c , i . next ( ) ) ;
}
}
2015-04-11 08:53:10 -04:00
}
2016-03-31 18:03:14 -04:00
} ;
2016-04-07 13:20:45 -04:00
if ( c = = null | | c . getMode ( ) = = Conversation . MODE_MULTI
| | FileBackend . allFilesUnderSize ( this , uris , getMaxHttpUploadSize ( c ) )
2016-03-31 18:03:14 -04:00
| | c . getNextEncryption ( ) = = Message . ENCRYPTION_OTR ) {
callback . onPresenceSelected ( ) ;
} else {
selectPresence ( c , callback ) ;
2014-11-13 15:04:05 -05:00
}
2015-04-11 08:53:10 -04:00
} else if ( requestCode = = ATTACHMENT_CHOICE_TAKE_PHOTO ) {
if ( mPendingImageUris . size ( ) = = 1 ) {
2016-10-03 12:26:11 -04:00
Uri uri = FileBackend . getIndexableTakePhotoUri ( mPendingImageUris . get ( 0 ) ) ;
mPendingImageUris . set ( 0 , uri ) ;
2015-04-11 08:53:10 -04:00
if ( xmppConnectionServiceBound ) {
2016-10-03 05:13:04 -04:00
Log . d ( Config . LOGTAG , " ConversationsActivity.onActivityResult() - attaching image to conversations. TAKE_PHOTO " ) ;
2015-04-11 08:53:10 -04:00
attachImageToConversation ( getSelectedConversation ( ) , uri ) ;
mPendingImageUris . clear ( ) ;
}
2016-11-08 05:45:20 -05:00
if ( ! Config . ONLY_INTERNAL_STORAGE ) {
Intent intent = new Intent ( Intent . ACTION_MEDIA_SCANNER_SCAN_FILE ) ;
intent . setData ( uri ) ;
sendBroadcast ( intent ) ;
}
2015-04-11 08:53:10 -04:00
} else {
mPendingImageUris . clear ( ) ;
2014-08-21 03:19:18 -04:00
}
2015-03-07 08:15:38 -05:00
} else if ( requestCode = = ATTACHMENT_CHOICE_LOCATION ) {
2016-01-11 05:17:45 -05:00
double latitude = data . getDoubleExtra ( " latitude " , 0 ) ;
double longitude = data . getDoubleExtra ( " longitude " , 0 ) ;
this . mPendingGeoUri = Uri . parse ( " geo: " + String . valueOf ( latitude ) + " , " + String . valueOf ( longitude ) ) ;
2015-03-07 08:15:38 -05:00
if ( xmppConnectionServiceBound ) {
attachLocationToConversation ( getSelectedConversation ( ) , mPendingGeoUri ) ;
this . mPendingGeoUri = null ;
}
2015-07-19 12:36:28 -04:00
} else if ( requestCode = = REQUEST_TRUST_KEYS_TEXT | | requestCode = = REQUEST_TRUST_KEYS_MENU ) {
this . forbidProcessingPendings = ! xmppConnectionServiceBound ;
2016-01-16 15:18:59 -05:00
if ( xmppConnectionServiceBound ) {
mConversationFragment . onActivityResult ( requestCode , resultCode , data ) ;
this . mPostponedActivityResult = null ;
} else {
this . mPostponedActivityResult = new Pair < > ( requestCode , data ) ;
}
2014-02-27 20:58:15 -05:00
}
2015-04-27 06:18:27 -04:00
} else {
mPendingImageUris . clear ( ) ;
mPendingFileUris . clear ( ) ;
2015-10-15 18:21:47 -04:00
if ( requestCode = = ConversationActivity . REQUEST_DECRYPT_PGP ) {
mConversationFragment . onActivityResult ( requestCode , resultCode , data ) ;
}
2016-01-11 05:17:45 -05:00
if ( requestCode = = REQUEST_BATTERY_OP ) {
setNeverAskForBatteryOptimizationsAgain ( ) ;
}
}
}
2016-04-07 13:20:45 -04:00
private long getMaxHttpUploadSize ( Conversation conversation ) {
2016-11-02 10:21:26 -04:00
final XmppConnection connection = conversation . getAccount ( ) . getXmppConnection ( ) ;
return connection = = null ? - 1 : connection . getFeatures ( ) . getMaxHttpUploadSize ( ) ;
2016-04-07 13:20:45 -04:00
}
2016-01-11 05:17:45 -05:00
private void setNeverAskForBatteryOptimizationsAgain ( ) {
2017-03-28 12:44:05 -04:00
getPreferences ( ) . edit ( ) . putBoolean ( " show_battery_optimization " , false ) . apply ( ) ;
2016-01-11 05:17:45 -05:00
}
private void openBatteryOptimizationDialogIfNeeded ( ) {
2016-03-06 09:53:49 -05:00
if ( hasAccountWithoutPush ( )
& & isOptimizingBattery ( )
& & getPreferences ( ) . getBoolean ( " show_battery_optimization " , true ) ) {
2016-01-11 05:17:45 -05:00
AlertDialog . Builder builder = new AlertDialog . Builder ( this ) ;
builder . setTitle ( R . string . battery_optimizations_enabled ) ;
builder . setMessage ( R . string . battery_optimizations_enabled_dialog ) ;
builder . setPositiveButton ( R . string . next , new OnClickListener ( ) {
@Override
public void onClick ( DialogInterface dialog , int which ) {
Intent intent = new Intent ( Settings . ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS ) ;
Uri uri = Uri . parse ( " package: " + getPackageName ( ) ) ;
intent . setData ( uri ) ;
2016-04-29 07:58:37 -04:00
try {
startActivityForResult ( intent , REQUEST_BATTERY_OP ) ;
} catch ( ActivityNotFoundException e ) {
Toast . makeText ( ConversationActivity . this , R . string . device_does_not_support_battery_op , Toast . LENGTH_SHORT ) . show ( ) ;
}
2016-01-11 05:17:45 -05:00
}
} ) ;
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . JELLY_BEAN_MR2 ) {
builder . setOnDismissListener ( new DialogInterface . OnDismissListener ( ) {
@Override
public void onDismiss ( DialogInterface dialog ) {
setNeverAskForBatteryOptimizationsAgain ( ) ;
}
} ) ;
}
2017-06-03 18:05:02 -04:00
AlertDialog dialog = builder . create ( ) ;
dialog . setCanceledOnTouchOutside ( false ) ;
dialog . show ( ) ;
2014-04-10 08:12:08 -04:00
}
}
2014-06-06 05:39:17 -04:00
2016-03-06 09:53:49 -05:00
private boolean hasAccountWithoutPush ( ) {
for ( Account account : xmppConnectionService . getAccounts ( ) ) {
if ( account . getStatus ( ) ! = Account . State . DISABLED
2017-01-12 17:22:02 -05:00
& & ! xmppConnectionService . getPushManagementService ( ) . availableAndUseful ( account ) ) {
2016-03-06 09:53:49 -05:00
return true ;
}
}
return false ;
}
2015-03-07 08:15:38 -05:00
private void attachLocationToConversation ( Conversation conversation , Uri uri ) {
2015-07-16 07:14:51 -04:00
if ( conversation = = null ) {
return ;
}
2015-03-07 08:15:38 -05:00
xmppConnectionService . attachLocationToConversation ( conversation , uri , new UiCallback < Message > ( ) {
@Override
public void success ( Message message ) {
xmppConnectionService . sendMessage ( message ) ;
}
@Override
public void error ( int errorCode , Message object ) {
}
@Override
public void userInputRequried ( PendingIntent pi , Message object ) {
}
} ) ;
}
2014-11-13 15:04:05 -05:00
private void attachFileToConversation ( Conversation conversation , Uri uri ) {
2015-07-16 07:14:51 -04:00
if ( conversation = = null ) {
return ;
}
2016-01-15 17:47:55 -05:00
final Toast prepareFileToast = Toast . makeText ( getApplicationContext ( ) , getText ( R . string . preparing_file ) , Toast . LENGTH_LONG ) ;
2014-11-14 06:31:57 -05:00
prepareFileToast . show ( ) ;
2017-01-24 14:17:36 -05:00
xmppConnectionService . attachFileToConversation ( conversation , uri , new UiInformableCallback < Message > ( ) {
@Override
public void inform ( final String text ) {
hidePrepareFileToast ( prepareFileToast ) ;
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
replaceToast ( text ) ;
}
} ) ;
}
2014-11-13 18:28:39 -05:00
@Override
public void success ( Message message ) {
2017-01-24 14:17:36 -05:00
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
hideToast ( ) ;
}
} ) ;
2016-01-15 17:47:55 -05:00
hidePrepareFileToast ( prepareFileToast ) ;
2014-11-13 18:28:39 -05:00
xmppConnectionService . sendMessage ( message ) ;
}
@Override
2016-06-24 07:36:06 -04:00
public void error ( final int errorCode , Message message ) {
hidePrepareFileToast ( prepareFileToast ) ;
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
replaceToast ( getString ( errorCode ) ) ;
}
} ) ;
2014-11-13 18:28:39 -05:00
}
@Override
public void userInputRequried ( PendingIntent pi , Message message ) {
2016-06-24 07:36:06 -04:00
hidePrepareFileToast ( prepareFileToast ) ;
2014-11-13 18:28:39 -05:00
}
} ) ;
2014-05-18 11:32:20 -04:00
}
2016-12-30 15:48:39 -05:00
public void attachImageToConversation ( Uri uri ) {
this . attachImageToConversation ( getSelectedConversation ( ) , uri ) ;
}
2014-05-14 05:49:43 -04:00
private void attachImageToConversation ( Conversation conversation , Uri uri ) {
2015-07-16 07:14:51 -04:00
if ( conversation = = null ) {
return ;
}
2016-01-15 17:47:55 -05:00
final Toast prepareFileToast = Toast . makeText ( getApplicationContext ( ) , getText ( R . string . preparing_image ) , Toast . LENGTH_LONG ) ;
2014-11-14 06:31:57 -05:00
prepareFileToast . show ( ) ;
2014-06-07 07:25:27 -04:00
xmppConnectionService . attachImageToConversation ( conversation , uri ,
new UiCallback < Message > ( ) {
2014-06-06 05:39:17 -04:00
@Override
2016-01-15 17:47:55 -05:00
public void userInputRequried ( PendingIntent pi , Message object ) {
hidePrepareFileToast ( prepareFileToast ) ;
2014-06-06 05:39:17 -04:00
}
@Override
2014-06-07 07:25:27 -04:00
public void success ( Message message ) {
2016-01-15 17:47:55 -05:00
hidePrepareFileToast ( prepareFileToast ) ;
2014-06-11 15:53:25 -04:00
xmppConnectionService . sendMessage ( message ) ;
2014-06-06 05:39:17 -04:00
}
@Override
2016-06-24 07:36:06 -04:00
public void error ( final int error , Message message ) {
hidePrepareFileToast ( prepareFileToast ) ;
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
replaceToast ( getString ( error ) ) ;
}
} ) ;
2014-06-06 05:39:17 -04:00
}
} ) ;
2014-05-08 10:52:19 -04:00
}
2014-06-06 05:39:17 -04:00
2016-01-15 17:47:55 -05:00
private void hidePrepareFileToast ( final Toast prepareFileToast ) {
2014-11-14 06:31:57 -05:00
if ( prepareFileToast ! = null ) {
2014-05-14 12:43:58 -04:00
runOnUiThread ( new Runnable ( ) {
2014-06-06 05:39:17 -04:00
2014-05-14 12:43:58 -04:00
@Override
public void run ( ) {
2014-11-14 06:31:57 -05:00
prepareFileToast . cancel ( ) ;
2014-05-14 12:43:58 -04:00
}
} ) ;
}
}
2014-03-19 11:16:40 -04:00
public void updateConversationList ( ) {
2017-03-06 10:53:54 -05:00
xmppConnectionService . populateWithOrderedConversations ( conversationList ) ;
if ( ! conversationList . contains ( mSelectedConversation ) ) {
mSelectedConversation = null ;
}
2015-04-02 18:06:37 -04:00
if ( swipedConversation ! = null ) {
if ( swipedConversation . isRead ( ) ) {
conversationList . remove ( swipedConversation ) ;
} else {
listView . discardUndo ( ) ;
}
}
2014-09-08 06:46:48 -04:00
listAdapter . notifyDataSetChanged ( ) ;
2014-03-19 11:16:40 -04:00
}
2014-06-06 05:39:17 -04:00
2014-05-07 06:33:55 -04:00
public void runIntent ( PendingIntent pi , int requestCode ) {
try {
2014-06-06 05:39:17 -04:00
this . startIntentSenderForResult ( pi . getIntentSender ( ) , requestCode ,
null , 0 , 0 , 0 ) ;
2014-11-07 09:09:28 -05:00
} catch ( final SendIntentException ignored ) {
2014-08-31 10:28:21 -04:00
}
2014-05-07 06:33:55 -04:00
}
2014-06-06 05:39:17 -04:00
2014-06-07 07:25:27 -04:00
public void encryptTextMessage ( Message message ) {
xmppConnectionService . getPgpEngine ( ) . encrypt ( message ,
new UiCallback < Message > ( ) {
2014-05-08 11:31:53 -04:00
@Override
2016-06-15 07:53:34 -04:00
public void userInputRequried ( PendingIntent pi , Message message ) {
ConversationActivity . this . runIntent ( pi , ConversationActivity . REQUEST_SEND_MESSAGE ) ;
2014-05-08 11:31:53 -04:00
}
@Override
2014-06-07 07:25:27 -04:00
public void success ( Message message ) {
2014-06-22 11:24:47 -04:00
message . setEncryption ( Message . ENCRYPTION_DECRYPTED ) ;
2014-06-11 15:53:25 -04:00
xmppConnectionService . sendMessage ( message ) ;
2017-03-19 15:15:07 -04:00
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
mConversationFragment . messageSent ( ) ;
}
} ) ;
2014-05-08 11:31:53 -04:00
}
@Override
2016-06-15 07:53:34 -04:00
public void error ( final int error , Message message ) {
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
2017-03-19 15:15:07 -04:00
mConversationFragment . doneSendingPgpMessage ( ) ;
2016-06-15 07:53:34 -04:00
Toast . makeText ( ConversationActivity . this ,
R . string . unable_to_connect_to_keychain ,
Toast . LENGTH_SHORT
) . show ( ) ;
}
} ) ;
2017-03-19 15:15:07 -04:00
2014-05-08 11:31:53 -04:00
}
} ) ;
}
2014-09-08 07:37:22 -04:00
2014-09-10 11:59:57 -04:00
public boolean useSendButtonToIndicateStatus ( ) {
return getPreferences ( ) . getBoolean ( " send_button_status " , false ) ;
}
2014-09-20 09:49:25 -04:00
public boolean indicateReceived ( ) {
return getPreferences ( ) . getBoolean ( " indicate_received " , false ) ;
}
Dark theme, theme switch, icons, style, strings
added some white icons,
changed hardcoded icons to theme attributes,
changed icon_edit_dark to icon_edit_body to reflect icons position,
grey message bubbles in dark theme,
misc
purged ic_action_chat as it wasn't used
preference use_white_background changed to use_green_background, default true
grey chat bubbles darker, text white
replaced all grey600 with black icons and 0.54 alpha attribute
highlightColor in dark grey chat bubble now darker than background
2016-05-12 14:00:18 -04:00
public boolean useGreenBackground ( ) {
return getPreferences ( ) . getBoolean ( " use_green_background " , true ) ;
2015-08-24 14:56:25 -04:00
}
2015-07-19 12:36:28 -04:00
protected boolean trustKeysIfNeeded ( int requestCode ) {
return trustKeysIfNeeded ( requestCode , ATTACHMENT_CHOICE_INVALID ) ;
}
protected boolean trustKeysIfNeeded ( int requestCode , int attachmentChoice ) {
AxolotlService axolotlService = mSelectedConversation . getAccount ( ) . getAxolotlService ( ) ;
2016-02-29 07:18:07 -05:00
final List < Jid > targets = axolotlService . getCryptoTargets ( mSelectedConversation ) ;
2016-03-01 05:26:59 -05:00
boolean hasUnaccepted = ! mSelectedConversation . getAcceptedCryptoTargets ( ) . containsAll ( targets ) ;
2016-11-14 16:27:41 -05:00
boolean hasUndecidedOwn = ! axolotlService . getKeysWithTrust ( FingerprintStatus . createActiveUndecided ( ) ) . isEmpty ( ) ;
boolean hasUndecidedContacts = ! axolotlService . getKeysWithTrust ( FingerprintStatus . createActiveUndecided ( ) , targets ) . isEmpty ( ) ;
2016-01-04 06:11:58 -05:00
boolean hasPendingKeys = ! axolotlService . findDevicesWithoutSession ( mSelectedConversation ) . isEmpty ( ) ;
2016-02-29 07:18:07 -05:00
boolean hasNoTrustedKeys = axolotlService . anyTargetHasNoTrustedKeys ( targets ) ;
2016-03-01 05:26:59 -05:00
if ( hasUndecidedOwn | | hasUndecidedContacts | | hasPendingKeys | | hasNoTrustedKeys | | hasUnaccepted ) {
2015-07-31 15:12:34 -04:00
axolotlService . createSessionsIfNeeded ( mSelectedConversation ) ;
2015-07-19 12:36:28 -04:00
Intent intent = new Intent ( getApplicationContext ( ) , TrustKeysActivity . class ) ;
2016-02-29 07:18:07 -05:00
String [ ] contacts = new String [ targets . size ( ) ] ;
for ( int i = 0 ; i < contacts . length ; + + i ) {
contacts [ i ] = targets . get ( i ) . toString ( ) ;
}
intent . putExtra ( " contacts " , contacts ) ;
2016-01-22 14:46:24 -05:00
intent . putExtra ( EXTRA_ACCOUNT , mSelectedConversation . getAccount ( ) . getJid ( ) . toBareJid ( ) . toString ( ) ) ;
2015-07-19 12:36:28 -04:00
intent . putExtra ( " choice " , attachmentChoice ) ;
2016-03-01 05:26:59 -05:00
intent . putExtra ( " conversation " , mSelectedConversation . getUuid ( ) ) ;
2015-07-19 12:36:28 -04:00
startActivityForResult ( intent , requestCode ) ;
return true ;
} else {
return false ;
}
}
2014-09-10 11:59:57 -04:00
@Override
2015-02-17 08:18:35 -05:00
protected void refreshUiReal ( ) {
updateConversationList ( ) ;
2015-10-20 09:27:33 -04:00
if ( conversationList . size ( ) > 0 ) {
2016-03-13 12:41:38 -04:00
if ( ! this . mConversationFragment . isAdded ( ) ) {
Log . d ( Config . LOGTAG , " fragment NOT added to activity. detached= " + Boolean . toString ( mConversationFragment . isDetached ( ) ) ) ;
}
2017-03-06 10:53:54 -05:00
if ( getSelectedConversation ( ) = = null ) {
reInitLatestConversation ( ) ;
} else {
ConversationActivity . this . mConversationFragment . updateMessages ( ) ;
updateActionBarTitle ( ) ;
invalidateOptionsMenu ( ) ;
}
2016-03-13 12:41:38 -04:00
} else {
2017-03-06 10:53:54 -05:00
if ( ! isStopping ( ) & & mRedirected . compareAndSet ( false , true ) ) {
redirectToStartConversationActivity ( ) ;
}
2016-03-13 12:41:38 -04:00
Log . d ( Config . LOGTAG , " not updating conversations fragment because conversations list size was 0 " ) ;
2015-02-17 08:18:35 -05:00
}
}
2014-09-10 11:59:57 -04:00
2015-02-17 08:18:35 -05:00
@Override
public void onAccountUpdate ( ) {
this . refreshUi ( ) ;
2014-09-10 11:59:57 -04:00
}
@Override
public void onConversationUpdate ( ) {
2015-02-17 08:18:35 -05:00
this . refreshUi ( ) ;
2014-09-10 11:59:57 -04:00
}
@Override
public void onRosterUpdate ( ) {
2015-02-17 08:18:35 -05:00
this . refreshUi ( ) ;
2014-12-21 15:43:58 -05:00
}
@Override
public void OnUpdateBlocklist ( Status status ) {
2015-02-17 08:18:35 -05:00
this . refreshUi ( ) ;
2014-12-21 15:43:58 -05:00
}
public void unblockConversation ( final Blockable conversation ) {
xmppConnectionService . sendUnblockRequest ( conversation ) ;
}
2015-01-09 13:23:26 -05:00
public boolean enterIsSend ( ) {
2017-03-02 07:03:30 -05:00
return getPreferences ( ) . getBoolean ( " enter_is_send " , getResources ( ) . getBoolean ( R . bool . enter_is_send ) ) ;
2015-01-09 13:23:26 -05:00
}
2015-07-10 07:28:50 -04:00
@Override
public void onShowErrorToast ( final int resId ) {
runOnUiThread ( new Runnable ( ) {
@Override
public void run ( ) {
Toast . makeText ( ConversationActivity . this , resId , Toast . LENGTH_SHORT ) . show ( ) ;
}
} ) ;
}
2015-09-07 09:46:22 -04:00
public boolean highlightSelectedConversations ( ) {
return ! isConversationsOverviewHideable ( ) | | this . conversationWasSelectedByKeyboard ;
}
2014-01-23 20:04:05 -05:00
}