conversations-classic/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java

910 lines
30 KiB
Java
Raw Normal View History

2014-02-28 17:46:01 +00:00
package eu.siacs.conversations.ui;
2014-01-24 01:04:05 +00:00
import android.annotation.SuppressLint;
2018-02-16 12:29:38 +00:00
import android.support.v7.app.AlertDialog;
2014-01-24 01:04:05 +00:00
import android.app.FragmentTransaction;
2014-05-06 19:34:30 +00:00
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
2014-01-24 01:04:05 +00:00
import android.content.Intent;
2014-11-03 19:00:20 +00:00
import android.content.IntentSender.SendIntentException;
import android.net.Uri;
2015-01-22 04:00:35 +00:00
import android.os.Build;
2014-11-03 19:00:20 +00:00
import android.os.Bundle;
import android.provider.Settings;
2014-01-24 01:04:05 +00:00
import android.support.v4.widget.SlidingPaneLayout;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
2018-02-16 11:06:05 +00:00
import android.support.v7.app.ActionBar;
2015-06-25 15:01:42 +00:00
import android.util.Log;
import android.util.Pair;
import android.view.KeyEvent;
2014-01-24 01:04:05 +00:00
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
2014-01-24 01:04:05 +00:00
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Toast;
2014-01-24 01:04:05 +00:00
2014-11-03 19:00:20 +00:00
import java.util.ArrayList;
import java.util.Iterator;
2014-11-03 19:00:20 +00:00
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
2014-11-03 19:00:20 +00:00
2015-07-20 12:26:29 +00:00
import de.timroes.android.listview.EnhancedListView;
2015-06-25 15:01:42 +00:00
import eu.siacs.conversations.Config;
2014-11-03 19:00:20 +00:00
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.axolotl.FingerprintStatus;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Blockable;
2014-11-03 19:00:20 +00:00
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.XmppConnectionService;
2014-11-03 19:00:20 +00: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;
2017-09-29 17:44:30 +00:00
import eu.siacs.conversations.ui.service.EmojiService;
2014-11-03 19:00:20 +00:00
import eu.siacs.conversations.utils.ExceptionHelper;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.XmppConnection;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
2014-11-03 19:00:20 +00:00
public class ConversationActivity extends XmppActivity
implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast {
2014-01-24 09:50:18 +00:00
public static final String ACTION_VIEW_CONVERSATION = "eu.siacs.conversations.action.VIEW";
2014-02-03 17:38:47 +00:00
public static final String CONVERSATION = "conversationUuid";
public static final String EXTRA_DOWNLOAD_UUID = "eu.siacs.conversations.download_uuid";
2014-03-13 20:37:27 +00:00
public static final String TEXT = "text";
public static final String NICK = "nick";
public static final String PRIVATE_MESSAGE = "pm";
2014-10-03 13:00:29 +00:00
private static final String STATE_OPEN_CONVERSATION = "state_open_conversation";
private static final String STATE_PANEL_OPEN = "state_panel_open";
2014-11-06 16:25:14 +00:00
private static final String STATE_PENDING_URI = "state_pending_uri";
private static final String STATE_FIRST_VISIBLE = "first_visible";
private static final String STATE_OFFSET_FROM_TOP = "offset_from_top";
2014-01-24 01:04:05 +00:00
private String mOpenConversation = null;
2014-10-03 13:00:29 +00:00
private boolean mPanelOpen = true;
private AtomicBoolean mShouldPanelBeOpen = new AtomicBoolean(false);
private Pair<Integer, Integer> mScrollPosition = null;
private boolean forbidProcessingPendings = false;
2014-10-03 13:00:29 +00:00
private boolean conversationWasSelectedByKeyboard = false;
2014-10-03 13:00:29 +00:00
private View mContentView;
2014-01-24 09:50:18 +00:00
2014-11-07 14:09:28 +00:00
private List<Conversation> conversationList = new ArrayList<>();
private Conversation swipedConversation = null;
private Conversation mSelectedConversation = null;
private EnhancedListView listView;
2014-11-07 14:38:20 +00:00
private ConversationFragment mConversationFragment;
2014-02-01 14:07:20 +00:00
private ArrayAdapter<Conversation> listAdapter;
private boolean mActivityPaused = false;
private AtomicBoolean mRedirected = new AtomicBoolean(false);
private boolean mUnprocessedNewIntent = false;
2014-02-07 01:57:36 +00:00
public Conversation getSelectedConversation() {
return this.mSelectedConversation;
}
2014-05-13 15:11:27 +00:00
public void setSelectedConversation(Conversation conversation) {
this.mSelectedConversation = conversation;
2014-05-13 15:11:27 +00:00
}
2014-10-03 13:00:29 +00:00
public void showConversationsOverview() {
if (mConversationFragment != null) {
mConversationFragment.stopScrolling();
}
2014-10-03 13:00:29 +00:00
if (mContentView instanceof SlidingPaneLayout) {
SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
mShouldPanelBeOpen.set(true);
2014-10-03 13:00:29 +00:00
mSlidingPaneLayout.openPane();
}
}
@Override
protected String getShareableUri() {
Conversation conversation = getSelectedConversation();
2014-11-06 16:25:14 +00:00
if (conversation != null) {
return conversation.getAccount().getShareableUri();
} else {
return "";
}
}
2014-10-03 13:00:29 +00:00
public void hideConversationsOverview() {
if (mContentView instanceof SlidingPaneLayout) {
SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
mShouldPanelBeOpen.set(false);
2014-10-03 13:00:29 +00:00
mSlidingPaneLayout.closePane();
}
}
2014-10-03 13:00:29 +00:00
public boolean isConversationsOverviewHideable() {
return mContentView instanceof SlidingPaneLayout;
2014-10-03 13:00:29 +00:00
}
2014-10-03 13:00:29 +00:00
public boolean isConversationsOverviewVisable() {
if (mContentView instanceof SlidingPaneLayout) {
return mShouldPanelBeOpen.get();
2014-10-03 13:00:29 +00:00
} else {
return true;
}
}
2014-01-24 01:04:05 +00:00
@Override
2015-01-14 20:28:27 +00:00
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
2017-09-29 17:44:30 +00:00
new EmojiService(this).init();
if (savedInstanceState != null) {
mOpenConversation = savedInstanceState.getString(STATE_OPEN_CONVERSATION, null);
mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true);
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;
}
2014-10-03 13:00:29 +00:00
}
setContentView(R.layout.fragment_conversations_overview);
2014-01-24 09:50:18 +00:00
2014-11-07 14:38:20 +00:00
this.mConversationFragment = new ConversationFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.selected_conversation, this.mConversationFragment, "conversation");
transaction.commit();
this.listView = findViewById(R.id.list);
this.listAdapter = new ConversationAdapter(this, conversationList);
this.listView.setAdapter(this.listAdapter);
this.listView.setSwipeDirection(EnhancedListView.SwipeDirection.END);
2014-08-31 14:28:21 +00:00
2018-02-16 11:06:05 +00:00
final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE);
2014-11-07 14:09:28 +00:00
}
2014-01-24 01:04:05 +00:00
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
2014-01-24 09:50:18 +00:00
public void onItemClick(AdapterView<?> arg0, View clickedView,
int position, long arg3) {
2014-05-13 15:11:27 +00:00
if (getSelectedConversation() != conversationList.get(position)) {
ConversationActivity.this.mConversationFragment.stopScrolling();
2014-05-13 15:11:27 +00:00
setSelectedConversation(conversationList.get(position));
2014-11-07 14:38:20 +00:00
ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
conversationWasSelectedByKeyboard = false;
}
2014-11-07 14:38:20 +00:00
hideConversationsOverview();
2015-01-09 21:24:50 +00:00
openConversation();
2014-01-24 01:04:05 +00: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());
try {
swipedConversation = listAdapter.getItem(position);
} catch (IndexOutOfBoundsException e) {
return null;
}
listAdapter.remove(swipedConversation);
xmppConnectionService.markRead(swipedConversation);
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);
listView.setUndoHideDelay(5000);
listView.setRequireTouchBeforeDismiss(false);
2014-10-03 13:00:29 +00:00
mContentView = findViewById(R.id.content_view_spl);
if (mContentView == null) {
2014-10-03 13:00:29 +00:00
mContentView = findViewById(R.id.content_view_ll);
}
if (mContentView instanceof SlidingPaneLayout) {
SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
mSlidingPaneLayout.setShadowResource(R.drawable.es_slidingpane_shadow);
2014-10-03 13:00:29 +00:00
mSlidingPaneLayout.setSliderFadeColor(0);
mSlidingPaneLayout.setPanelSlideListener(new PanelSlideListener() {
2014-01-24 09:50:18 +00:00
2014-10-03 13:00:29 +00:00
@Override
public void onPanelOpened(View arg0) {
mShouldPanelBeOpen.set(true);
updateActionBarTitle();
2014-10-03 13:00:29 +00:00
invalidateOptionsMenu();
hideKeyboard();
if (xmppConnectionServiceBound) {
xmppConnectionService.getNotificationService().setOpenConversation(null);
2014-10-03 13:00:29 +00:00
}
closeContextMenu();
2014-09-29 16:28:13 +00:00
}
2014-01-24 09:50:18 +00:00
2014-10-03 13:00:29 +00:00
@Override
public void onPanelClosed(View arg0) {
mShouldPanelBeOpen.set(false);
listView.discardUndo();
openConversation();
2014-01-24 09:50:18 +00:00
}
2014-01-24 01:04:05 +00:00
2014-10-03 13:00:29 +00:00
@Override
public void onPanelSlide(View arg0, float arg1) {
// TODO Auto-generated method stub
2014-01-24 09:50:18 +00:00
2014-10-03 13:00:29 +00:00
}
});
}
2014-01-24 01:04:05 +00:00
}
2014-10-03 13:00:29 +00:00
@Override
public void switchToConversation(Conversation conversation) {
setSelectedConversation(conversation);
runOnUiThread(() -> {
ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
openConversation();
});
}
private void updateActionBarTitle() {
updateActionBarTitle(isConversationsOverviewHideable() && !isConversationsOverviewVisable());
}
private void updateActionBarTitle(boolean titleShouldBeName) {
2018-02-16 11:06:05 +00:00
final ActionBar ab = getSupportActionBar();
2014-11-27 09:30:06 +00:00
final Conversation conversation = getSelectedConversation();
2014-09-29 16:28:13 +00:00
if (ab != null) {
2014-11-27 09:30:06 +00:00
if (titleShouldBeName && conversation != null) {
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 09:30:06 +00:00
if (conversation.getMode() == Conversation.MODE_SINGLE || useSubjectToIdentifyConference()) {
ab.setTitle(conversation.getName());
} else {
ab.setTitle(conversation.getJid().toBareJid().toString());
}
2014-09-29 16:28:13 +00:00
} else {
if ((ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) == ActionBar.DISPLAY_HOME_AS_UP) {
ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE);
}
ab.setTitle(R.string.app_name);
2014-09-29 16:28:13 +00:00
}
}
}
private void openConversation() {
this.updateActionBarTitle();
this.invalidateOptionsMenu();
2014-09-29 16:28:13 +00:00
if (xmppConnectionServiceBound) {
final Conversation conversation = getSelectedConversation();
xmppConnectionService.getNotificationService().setOpenConversation(conversation);
sendReadMarkerIfNecessary(conversation);
}
2015-01-09 21:24:50 +00:00
listAdapter.notifyDataSetChanged();
}
public void sendReadMarkerIfNecessary(final Conversation conversation) {
if (!mActivityPaused && !mUnprocessedNewIntent && conversation != null) {
xmppConnectionService.sendReadMarker(conversation);
2014-09-29 16:28:13 +00:00
}
}
2014-01-24 09:50:18 +00:00
2014-01-24 01:04:05 +00:00
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_conversations, menu);
return super.onCreateOptionsMenu(menu);
2014-01-24 01:04:05 +00:00
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
2014-09-23 13:06:49 +00:00
if (item.getItemId() == android.R.id.home) {
2014-10-03 13:00:29 +00:00
showConversationsOverview();
return true;
2014-09-23 13:06:49 +00:00
} else if (item.getItemId() == R.id.action_add) {
startActivity(new Intent(this, StartConversationActivity.class));
2014-09-23 13:06:49 +00:00
return true;
} else {
return super.onOptionsItemSelected(item);
2014-01-24 01:04:05 +00:00
}
}
public void endConversation(Conversation conversation) {
endConversation(conversation, true, true);
}
public void endConversation(Conversation conversation, boolean showOverview, boolean reinit) {
if (showOverview) {
showConversationsOverview();
}
2014-04-20 18:48:16 +00:00
xmppConnectionService.archiveConversation(conversation);
if (reinit) {
if (conversationList.size() > 0) {
setSelectedConversation(conversationList.get(0));
this.mConversationFragment.reInit(getSelectedConversation());
} else {
setSelectedConversation(null);
if (mRedirected.compareAndSet(false, true)) {
Intent intent = new Intent(this, StartConversationActivity.class);
intent.putExtra("init", true);
startActivity(intent);
finish();
}
}
2014-04-20 18:48:16 +00:00
}
}
2014-01-24 09:50:18 +00:00
@Override
public void onBackPressed() {
if (!isConversationsOverviewVisable()) {
showConversationsOverview();
} else {
super.onBackPressed();
2014-01-24 09:50:18 +00:00
}
}
@Override
public boolean onKeyUp(int key, KeyEvent event) {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
final int upKey;
final int downKey;
switch (rotation) {
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;
case Surface.ROTATION_0:
default:
upKey = KeyEvent.KEYCODE_DPAD_UP;
downKey = KeyEvent.KEYCODE_DPAD_DOWN;
}
final boolean modifier = event.isCtrlPressed() || (event.getMetaState() & KeyEvent.META_ALT_LEFT_ON) != 0;
if (modifier && key == KeyEvent.KEYCODE_TAB && isConversationsOverviewHideable()) {
toggleConversationsOverview();
return true;
} else if (modifier && key == KeyEvent.KEYCODE_SPACE) {
startActivity(new Intent(this, StartConversationActivity.class));
return true;
} else if (modifier && key == downKey) {
if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) {
showConversationsOverview();
;
}
return selectDownConversation();
} else if (modifier && key == upKey) {
if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) {
showConversationsOverview();
}
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);
} else {
return super.onKeyUp(key, event);
}
}
private void toggleConversationsOverview() {
if (isConversationsOverviewVisable()) {
hideConversationsOverview();
if (mConversationFragment != null) {
mConversationFragment.setFocusOnInputField();
}
} else {
showConversationsOverview();
}
}
private boolean selectUpConversation() {
if (this.mSelectedConversation != null) {
int index = this.conversationList.indexOf(this.mSelectedConversation);
if (index > 0) {
return openConversationByIndex(index - 1);
}
}
return false;
}
private boolean selectDownConversation() {
if (this.mSelectedConversation != null) {
int index = this.conversationList.indexOf(this.mSelectedConversation);
if (index != -1 && index < this.conversationList.size() - 1) {
return openConversationByIndex(index + 1);
}
}
return false;
}
private boolean openConversationByIndex(int index) {
try {
this.conversationWasSelectedByKeyboard = true;
this.mConversationFragment.stopScrolling();
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;
}
}
2014-05-21 14:43:19 +00:00
@Override
2014-11-07 14:09:28 +00:00
protected void onNewIntent(final Intent intent) {
if (intent != null && ACTION_VIEW_CONVERSATION.equals(intent.getAction())) {
mOpenConversation = null;
mUnprocessedNewIntent = true;
if (xmppConnectionServiceBound) {
handleViewConversationIntent(intent);
intent.setAction(Intent.ACTION_MAIN);
} else {
setIntent(intent);
2014-05-21 14:43:19 +00:00
}
}
}
@Override
public void onStart() {
super.onStart();
this.mRedirected.set(false);
if (this.xmppConnectionServiceBound) {
this.onBackendConnected();
}
if (conversationList.size() >= 1) {
2014-09-10 15:59:57 +00:00
this.onConversationUpdate();
}
}
@Override
public void onPause() {
listView.discardUndo();
super.onPause();
this.mActivityPaused = true;
}
@Override
public void onResume() {
super.onResume();
2015-01-14 20:28:27 +00:00
final int theme = findTheme();
final boolean usingEnterKey = usingEnterKey();
if (this.mTheme != theme || usingEnterKey != mUsingEnterKey) {
recreate();
}
this.mActivityPaused = false;
if (!isConversationsOverviewVisable() || !isConversationsOverviewHideable()) {
sendReadMarkerIfNecessary(getSelectedConversation());
}
}
2014-10-03 13:00:29 +00:00
@Override
2014-11-07 14:09:28 +00:00
public void onSaveInstanceState(final Bundle savedInstanceState) {
2014-10-06 17:27:58 +00:00
Conversation conversation = getSelectedConversation();
2014-10-06 20:03:01 +00:00
if (conversation != null) {
savedInstanceState.putString(STATE_OPEN_CONVERSATION, conversation.getUuid());
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 18:02:57 +00:00
} else {
savedInstanceState.remove(STATE_OPEN_CONVERSATION);
2014-10-06 17:27:58 +00:00
}
savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable());
/*if (this.mPendingImageUris.size() >= 1) {
Log.d(Config.LOGTAG, "ConversationsActivity.onSaveInstanceState() - saving pending image uri");
savedInstanceState.putString(STATE_PENDING_URI, this.mPendingImageUris.get(0).toString());
2015-12-05 18:02:57 +00:00
} else {
savedInstanceState.remove(STATE_PENDING_URI);
}*/
2014-10-03 13:00:29 +00:00
super.onSaveInstanceState(savedInstanceState);
}
2015-12-05 18:02:57 +00:00
private void clearPending() {
mConversationFragment.clearPending();
2015-12-05 18:02:57 +00:00
}
2018-02-09 21:19:13 +00:00
private void redirectToStartConversationActivity(boolean noAnimation) {
Account pendingAccount = xmppConnectionService.getPendingAccount();
if (pendingAccount == null) {
Intent startConversationActivity = new Intent(this, StartConversationActivity.class);
2018-02-09 21:19:13 +00:00
startConversationActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
if (noAnimation) {
startConversationActivity.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
}
startConversationActivity.putExtra("init", true);
startActivity(startConversationActivity);
2018-02-09 21:19:13 +00:00
if (noAnimation) {
overridePendingTransition(0, 0);
2018-02-09 21:19:13 +00:00
}
} else {
switchToAccount(pendingAccount, true);
}
}
@Override
void onBackendConnected() {
this.xmppConnectionService.getNotificationService().setIsInForeground(true);
2014-10-03 13:00:29 +00:00
updateConversationList();
if (mPendingConferenceInvite != null) {
if (mPendingConferenceInvite.execute(this)) {
mToast = Toast.makeText(this, R.string.creating_conference, Toast.LENGTH_LONG);
mToast.show();
}
mPendingConferenceInvite = null;
}
final Intent intent = getIntent();
2014-10-03 13:00:29 +00:00
if (xmppConnectionService.getAccounts().size() == 0) {
if (mRedirected.compareAndSet(false, true)) {
if (Config.X509_VERIFICATION) {
Intent redirectionIntent = new Intent(this, ManageAccountActivity.class);
redirectionIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(redirectionIntent);
overridePendingTransition(0, 0);
2016-04-19 16:03:24 +00:00
} else if (Config.MAGIC_CREATE_DOMAIN != null) {
WelcomeActivity.launch(this);
} else {
2016-08-26 07:10:59 +00:00
Intent editAccount = new Intent(this, EditAccountActivity.class);
editAccount.putExtra("init", true);
editAccount.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
2016-08-26 07:10:59 +00:00
startActivity(editAccount);
overridePendingTransition(0, 0);
}
}
2014-10-03 13:00:29 +00:00
} else if (conversationList.size() <= 0) {
if (mRedirected.compareAndSet(false, true)) {
2018-02-09 21:19:13 +00:00
redirectToStartConversationActivity(true);
}
} else if (selectConversationByUuid(mOpenConversation)) {
2014-11-07 14:38:20 +00:00
if (mPanelOpen) {
2014-10-03 13:00:29 +00:00
showConversationsOverview();
} else {
if (isConversationsOverviewHideable()) {
openConversation();
updateActionBarTitle(true);
}
2014-10-03 13:00:29 +00:00
}
if (this.mConversationFragment.reInit(getSelectedConversation())) {
Log.d(Config.LOGTAG, "setting scroll position on fragment");
this.mConversationFragment.setScrollPosition(mScrollPosition);
}
mOpenConversation = null;
} else if (intent != null && ACTION_VIEW_CONVERSATION.equals(intent.getAction())) {
clearPending();
handleViewConversationIntent(intent);
intent.setAction(Intent.ACTION_MAIN);
} else if (getSelectedConversation() == null) {
reInitLatestConversation();
} else {
this.mConversationFragment.messageListAdapter.updatePreferences();
this.mConversationFragment.messagesView.invalidateViews();
this.mConversationFragment.setupIme();
}
2014-08-31 14:28:21 +00:00
mConversationFragment.onBackendConnected();
if (!ExceptionHelper.checkForCrash(this, this.xmppConnectionService) && !mRedirected.get()) {
openBatteryOptimizationDialogIfNeeded();
}
if (isConversationsOverviewVisable() && isConversationsOverviewHideable()) {
xmppConnectionService.getNotificationService().setOpenConversation(null);
} else {
xmppConnectionService.getNotificationService().setOpenConversation(getSelectedConversation());
}
2014-10-03 13:00:29 +00:00
}
2014-10-29 08:57:03 +00: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());
}
private void handleViewConversationIntent(final Intent intent) {
final String uuid = intent.getStringExtra(CONVERSATION);
final String downloadUuid = intent.getStringExtra(EXTRA_DOWNLOAD_UUID);
final String text = intent.getStringExtra(TEXT);
final String nick = intent.getStringExtra(NICK);
final boolean pm = intent.getBooleanExtra(PRIVATE_MESSAGE, false);
this.mConversationFragment.stopScrolling();
if (selectConversationByUuid(uuid)) {
this.mConversationFragment.reInit(getSelectedConversation());
if (nick != null) {
if (pm) {
Jid jid = getSelectedConversation().getJid();
try {
Jid next = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), nick);
this.mConversationFragment.privateMessageWith(next);
} catch (final InvalidJidException ignored) {
//do nothing
}
} else {
this.mConversationFragment.highlightInConference(nick);
}
} else {
this.mConversationFragment.appendText(text);
}
hideConversationsOverview();
mUnprocessedNewIntent = false;
openConversation();
if (mContentView instanceof SlidingPaneLayout) {
updateActionBarTitle(true); //fixes bug where slp isn't properly closed yet
}
if (downloadUuid != null) {
final Message message = mSelectedConversation.findMessageWithFileAndUuid(downloadUuid);
if (message != null) {
//startDownloadable(message);
}
}
} else {
mUnprocessedNewIntent = false;
}
}
private boolean selectConversationByUuid(String uuid) {
if (uuid == null) {
return false;
}
for (Conversation aConversationList : conversationList) {
if (aConversationList.getUuid().equals(uuid)) {
setSelectedConversation(aConversationList);
return true;
}
}
return false;
}
2014-11-11 16:39:28 +00:00
@Override
protected void unregisterListeners() {
super.unregisterListeners();
xmppConnectionService.getNotificationService().setOpenConversation(null);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) {
if (requestCode == REQUEST_BATTERY_OP) {
setNeverAskForBatteryOptimizationsAgain();
}
}
}
public long getMaxHttpUploadSize(Conversation conversation) {
final XmppConnection connection = conversation.getAccount().getXmppConnection();
return connection == null ? -1 : connection.getFeatures().getMaxHttpUploadSize();
}
2017-12-06 15:57:43 +00:00
private String getBatteryOptimizationPreferenceKey() {
@SuppressLint("HardwareIds") String device = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
return "show_battery_optimization" + (device == null ? "" : device);
2017-12-06 15:57:43 +00:00
}
private void setNeverAskForBatteryOptimizationsAgain() {
2017-12-06 15:57:43 +00:00
getPreferences().edit().putBoolean(getBatteryOptimizationPreferenceKey(), false).apply();
}
private void openBatteryOptimizationDialogIfNeeded() {
if (hasAccountWithoutPush()
&& isOptimizingBattery()
2017-12-06 15:57:43 +00:00
&& getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.battery_optimizations_enabled);
builder.setMessage(R.string.battery_optimizations_enabled_dialog);
2018-02-19 14:00:42 +00:00
builder.setPositiveButton(R.string.next, (dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
Uri uri = Uri.parse("package:" + getPackageName());
intent.setData(uri);
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();
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
2018-02-19 14:00:42 +00:00
builder.setOnDismissListener(dialog -> setNeverAskForBatteryOptimizationsAgain());
}
2017-06-03 22:05:02 +00:00
AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
}
private boolean hasAccountWithoutPush() {
for (Account account : xmppConnectionService.getAccounts()) {
2017-12-06 15:57:43 +00:00
if (account.getStatus() == Account.State.ONLINE && !xmppConnectionService.getPushManagementService().available(account)) {
return true;
}
}
return false;
}
public void updateConversationList() {
xmppConnectionService.populateWithOrderedConversations(conversationList);
if (!conversationList.contains(mSelectedConversation)) {
mSelectedConversation = null;
}
if (swipedConversation != null) {
if (swipedConversation.isRead()) {
conversationList.remove(swipedConversation);
} else {
listView.discardUndo();
}
}
2014-09-08 10:46:48 +00:00
listAdapter.notifyDataSetChanged();
}
2014-05-07 10:33:55 +00:00
public void runIntent(PendingIntent pi, int requestCode) {
try {
this.startIntentSenderForResult(pi.getIntentSender(), requestCode,
null, 0, 0, 0);
2014-11-07 14:09:28 +00:00
} catch (final SendIntentException ignored) {
2014-08-31 14:28:21 +00:00
}
2014-05-07 10:33:55 +00:00
}
2014-09-10 15:59:57 +00:00
public boolean useSendButtonToIndicateStatus() {
return getPreferences().getBoolean("send_button_status", getResources().getBoolean(R.bool.send_button_status));
2014-09-10 15:59:57 +00:00
}
public boolean indicateReceived() {
return getPreferences().getBoolean("indicate_received", getResources().getBoolean(R.bool.indicate_received));
}
public boolean useGreenBackground() {
return getPreferences().getBoolean("use_green_background", getResources().getBoolean(R.bool.use_green_background));
}
2014-09-10 15:59:57 +00:00
@Override
2015-02-17 13:18:35 +00:00
protected void refreshUiReal() {
updateConversationList();
if (conversationList.size() > 0) {
if (!this.mConversationFragment.isAdded()) {
Log.d(Config.LOGTAG, "fragment NOT added to activity. detached=" + Boolean.toString(mConversationFragment.isDetached()));
}
if (getSelectedConversation() == null) {
reInitLatestConversation();
} else {
ConversationActivity.this.mConversationFragment.updateMessages();
updateActionBarTitle();
invalidateOptionsMenu();
}
} else {
if (!isStopping() && mRedirected.compareAndSet(false, true)) {
2018-02-09 21:19:13 +00:00
redirectToStartConversationActivity(false);
}
Log.d(Config.LOGTAG, "not updating conversations fragment because conversations list size was 0");
2015-02-17 13:18:35 +00:00
}
}
2014-09-10 15:59:57 +00:00
2015-02-17 13:18:35 +00:00
@Override
public void onAccountUpdate() {
this.refreshUi();
2014-09-10 15:59:57 +00:00
}
@Override
public void onConversationUpdate() {
2015-02-17 13:18:35 +00:00
this.refreshUi();
2014-09-10 15:59:57 +00:00
}
@Override
public void onRosterUpdate() {
2015-02-17 13:18:35 +00:00
this.refreshUi();
}
@Override
public void OnUpdateBlocklist(Status status) {
2015-02-17 13:18:35 +00:00
this.refreshUi();
}
public boolean enterIsSend() {
return getPreferences().getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send));
}
@Override
public void onShowErrorToast(final int resId) {
runOnUiThread(() -> Toast.makeText(ConversationActivity.this, resId, Toast.LENGTH_SHORT).show());
}
public boolean highlightSelectedConversations() {
return !isConversationsOverviewHideable() || this.conversationWasSelectedByKeyboard;
}
2014-01-24 01:04:05 +00:00
}