StartConversationActivity: persist search across rotation

This commit is contained in:
Daniel Gultsch 2018-03-20 12:52:23 +01:00
parent 6d3be890b7
commit 3c61af88a1
1 changed files with 76 additions and 65 deletions

View File

@ -2,36 +2,27 @@ package eu.siacs.conversations.ui;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.res.TypedArray;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.graphics.drawable.Drawable;
import android.support.annotation.AttrRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.databinding.DataBindingUtil;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment; import android.support.v4.app.ListFragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.PagerAdapter; import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.Editable; import android.text.Editable;
import android.text.SpannableString; import android.text.SpannableString;
@ -50,11 +41,9 @@ import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.Checkable;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Spinner; import android.widget.Spinner;
@ -63,7 +52,6 @@ import android.widget.Toast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -78,11 +66,9 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Presence;
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.adapter.ListItemAdapter; import eu.siacs.conversations.ui.adapter.ListItemAdapter;
import eu.siacs.conversations.ui.interfaces.OnBackendConnected; import eu.siacs.conversations.ui.interfaces.OnBackendConnected;
import eu.siacs.conversations.ui.service.EmojiService; import eu.siacs.conversations.ui.service.EmojiService;
import eu.siacs.conversations.ui.util.DelayedHintHelper;
import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
import eu.siacs.conversations.ui.util.PendingItem; import eu.siacs.conversations.ui.util.PendingItem;
import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.utils.XmppUri;
@ -94,6 +80,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
private final int REQUEST_SYNC_CONTACTS = 0x28cf; private final int REQUEST_SYNC_CONTACTS = 0x28cf;
private final int REQUEST_CREATE_CONFERENCE = 0x39da; private final int REQUEST_CREATE_CONFERENCE = 0x39da;
private final PendingItem<Intent> pendingViewIntent = new PendingItem<>();
private final PendingItem<String> mInitialSearchValue = new PendingItem<>();
private final AtomicBoolean oneShotKeyboardSuppress = new AtomicBoolean();
public int conference_context_id; public int conference_context_id;
public int contact_context_id; public int contact_context_id;
private ListPagerAdapter mListPagerAdapter; private ListPagerAdapter mListPagerAdapter;
@ -102,7 +91,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
private List<ListItem> conferences = new ArrayList<>(); private List<ListItem> conferences = new ArrayList<>();
private ListItemAdapter mConferenceAdapter; private ListItemAdapter mConferenceAdapter;
private List<String> mActivatedAccounts = new ArrayList<>(); private List<String> mActivatedAccounts = new ArrayList<>();
private Invite mPendingInvite = null;
private EditText mSearchEditText; private EditText mSearchEditText;
private AtomicBoolean mRequestedContactsPermission = new AtomicBoolean(false); private AtomicBoolean mRequestedContactsPermission = new AtomicBoolean(false);
private boolean mHideOfflineContacts = false; private boolean mHideOfflineContacts = false;
@ -112,7 +100,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
public boolean onMenuItemActionExpand(MenuItem item) { public boolean onMenuItemActionExpand(MenuItem item) {
mSearchEditText.post(() -> { mSearchEditText.post(() -> {
mSearchEditText.requestFocus(); mSearchEditText.requestFocus();
if (oneShotKeyboardSuppress.compareAndSet(true,false)) { if (oneShotKeyboardSuppress.compareAndSet(true, false)) {
return; return;
} }
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -147,26 +135,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
public void onTextChanged(CharSequence s, int start, int before, int count) { public void onTextChanged(CharSequence s, int start, int before, int count) {
} }
}; };
private TextView.OnEditorActionListener mSearchDone = new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
int pos = binding.startConversationViewPager.getCurrentItem();
if (pos == 0) {
if (contacts.size() == 1) {
openConversationForContact((Contact) contacts.get(0));
return true;
}
} else {
if (conferences.size() == 1) {
openConversationsForBookmark((Bookmark) conferences.get(0));
return true;
}
}
hideKeyboard();
mListPagerAdapter.requestFocus(pos);
return true;
}
};
private MenuItem mMenuSearchView; private MenuItem mMenuSearchView;
private ListItemAdapter.OnTagClickedListener mOnTagClickedListener = new ListItemAdapter.OnTagClickedListener() { private ListItemAdapter.OnTagClickedListener mOnTagClickedListener = new ListItemAdapter.OnTagClickedListener() {
@Override @Override
@ -179,8 +147,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
} }
} }
}; };
private final PendingItem<String> mInitialSearchValue = new PendingItem<>();
private final AtomicBoolean oneShotKeyboardSuppress = new AtomicBoolean();
private Pair<Integer, Intent> mPostponedActivityResult; private Pair<Integer, Intent> mPostponedActivityResult;
private Toast mToast; private Toast mToast;
private UiCallback<Conversation> mAdhocConferenceCallback = new UiCallback<Conversation>() { private UiCallback<Conversation> mAdhocConferenceCallback = new UiCallback<Conversation>() {
@ -203,6 +169,26 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
} }
}; };
private ActivityStartConversationBinding binding; private ActivityStartConversationBinding binding;
private TextView.OnEditorActionListener mSearchDone = new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
int pos = binding.startConversationViewPager.getCurrentItem();
if (pos == 0) {
if (contacts.size() == 1) {
openConversationForContact((Contact) contacts.get(0));
return true;
}
} else {
if (conferences.size() == 1) {
openConversationsForBookmark((Bookmark) conferences.get(0));
return true;
}
}
hideKeyboard();
mListPagerAdapter.requestFocus(pos);
return true;
}
};
private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() { private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
@Override @Override
public void onPageSelected(int position) { public void onPageSelected(int position) {
@ -231,6 +217,17 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
context.startActivity(intent); context.startActivity(intent);
} }
private static Intent createLauncherIntent(Context context) {
final Intent intent = new Intent(context, StartConversationActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
return intent;
}
private static boolean isViewIntent(final Intent i) {
return i != null && (Intent.ACTION_VIEW.equals(i.getAction()) || Intent.ACTION_SENDTO.equals(i.getAction()));
}
protected void hideToast() { protected void hideToast() {
if (mToast != null) { if (mToast != null) {
mToast.cancel(); mToast.cancel();
@ -285,6 +282,31 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
mContactsAdapter.setOnTagClickedListener(this.mOnTagClickedListener); mContactsAdapter.setOnTagClickedListener(this.mOnTagClickedListener);
this.mHideOfflineContacts = getPreferences().getBoolean("hide_offline", false); this.mHideOfflineContacts = getPreferences().getBoolean("hide_offline", false);
final Intent intent;
if (savedInstanceState == null) {
intent = getIntent();
} else {
final String search = savedInstanceState.getString("search");
if (search != null) {
mInitialSearchValue.push(search);
}
intent = savedInstanceState.getParcelable("intent");
}
if (isViewIntent(intent)) {
pendingViewIntent.push(intent);
setIntent(createLauncherIntent(this));
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
Intent pendingIntent = pendingViewIntent.peek();
savedInstanceState.putParcelable("intent", pendingIntent != null ? pendingIntent : getIntent());
if (mMenuSearchView != null && mMenuSearchView.isActionViewExpanded()) {
savedInstanceState.putString("search", mSearchEditText != null ? mSearchEditText.getText().toString() : null);
}
super.onSaveInstanceState(savedInstanceState);
} }
@Override @Override
@ -304,12 +326,13 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
} }
@Override @Override
public void onNewIntent(Intent intent) { public void onNewIntent(final Intent intent) {
if (xmppConnectionServiceBound) { if (xmppConnectionServiceBound) {
handleIntent(intent); processViewIntent(intent);
} else { } else {
setIntent(intent); pendingViewIntent.push(intent);
} }
setIntent(createLauncherIntent(this));
} }
protected void openConversationForContact(int position) { protected void openConversationForContact(int position) {
@ -682,40 +705,31 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
} }
} }
} }
final Intent intent = getIntent();
final ActionBar ab = getSupportActionBar(); final ActionBar ab = getSupportActionBar();
boolean init = intent != null && intent.getBooleanExtra("init", false);
boolean noConversations = xmppConnectionService.getConversations().size() == 0; boolean noConversations = xmppConnectionService.getConversations().size() == 0;
if ((init || noConversations) && ab != null) { if (noConversations && ab != null) {
ab.setDisplayShowHomeEnabled(false); ab.setDisplayShowHomeEnabled(false);
ab.setDisplayHomeAsUpEnabled(false); ab.setDisplayHomeAsUpEnabled(false);
ab.setHomeButtonEnabled(false); ab.setHomeButtonEnabled(false);
} }
if (this.mPendingInvite != null) { Intent intent = pendingViewIntent.pop();
mPendingInvite.invite(); if (intent != null && processViewIntent(intent)) {
this.mPendingInvite = null;
filter(null); filter(null);
} else if (!handleIntent(getIntent())) { } else {
if (mSearchEditText != null) { if (mSearchEditText != null) {
filter(mSearchEditText.getText().toString()); filter(mSearchEditText.getText().toString());
} else { } else {
filter(null); filter(null);
} }
} else {
filter(null);
} }
setIntent(null);
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_DIALOG); Fragment fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_DIALOG);
if (fragment != null && fragment instanceof OnBackendConnected) { if (fragment != null && fragment instanceof OnBackendConnected) {
Log.d(Config.LOGTAG,"calling on backend connected on dialog"); Log.d(Config.LOGTAG, "calling on backend connected on dialog");
((OnBackendConnected) fragment).onBackendConnected(); ((OnBackendConnected) fragment).onBackendConnected();
} }
} }
protected boolean handleIntent(Intent intent) { protected boolean processViewIntent(Intent intent) {
if (intent == null) {
return false;
}
final String inviteUri = intent.getStringExtra(WelcomeActivity.EXTRA_INVITE_URI); final String inviteUri = intent.getStringExtra(WelcomeActivity.EXTRA_INVITE_URI);
if (inviteUri != null) { if (inviteUri != null) {
Invite invite = new Invite(inviteUri); Invite invite = new Invite(inviteUri);
@ -723,9 +737,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
return invite.invite(); return invite.invite();
} }
} }
if (intent.getAction() == null) {
return false;
}
switch (intent.getAction()) { switch (intent.getAction()) {
case Intent.ACTION_SENDTO: case Intent.ACTION_SENDTO:
case Intent.ACTION_VIEW: case Intent.ACTION_VIEW:
@ -876,7 +887,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
} }
@Override @Override
public void onCreateDialogPositiveClick(Spinner spinner,String subject) { public void onCreateDialogPositiveClick(Spinner spinner, String subject) {
if (!xmppConnectionServiceBound) { if (!xmppConnectionServiceBound) {
return; return;
} }