Recreate fragment whenever we handle onNewIntent instead of restarting whole activity.
This commit is contained in:
parent
88b895f5ea
commit
8767f775e9
4 changed files with 79 additions and 108 deletions
|
@ -32,14 +32,27 @@ open class ConversationActivity : PassphraseRequiredActivity(), ConversationPare
|
|||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
setContentView(R.layout.conversation_parent_fragment_container)
|
||||
|
||||
fragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as ConversationParentFragment
|
||||
if (savedInstanceState == null) {
|
||||
replaceFragment(intent!!)
|
||||
} else {
|
||||
fragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as ConversationParentFragment
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
|
||||
finish()
|
||||
startActivity(intent)
|
||||
setIntent(intent)
|
||||
replaceFragment(intent!!)
|
||||
}
|
||||
|
||||
private fun replaceFragment(intent: Intent) {
|
||||
fragment = ConversationParentFragment.create(intent)
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, fragment)
|
||||
.disallowAddToBackStack()
|
||||
.commitNowAllowingStateLoss()
|
||||
}
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.conversation;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -35,6 +36,8 @@ public class ConversationIntents {
|
|||
private static final String EXTRA_FIRST_TIME_IN_SELF_CREATED_GROUP = "first_time_in_group";
|
||||
private static final String EXTRA_WITH_SEARCH_OPEN = "with_search_open";
|
||||
private static final String EXTRA_GIFT_BADGE = "gift_badge";
|
||||
private static final String INTENT_DATA = "intent_data";
|
||||
private static final String INTENT_TYPE = "intent_type";
|
||||
|
||||
private ConversationIntents() {
|
||||
}
|
||||
|
@ -51,16 +54,35 @@ public class ConversationIntents {
|
|||
return new Builder(context, BubbleConversationActivity.class, recipientId, threadId).build();
|
||||
}
|
||||
|
||||
static boolean isInvalid(@NonNull Intent intent) {
|
||||
if (isBubbleIntent(intent)) {
|
||||
return intent.getData().getQueryParameter(EXTRA_RECIPIENT) == null;
|
||||
static boolean isInvalid(@NonNull Bundle arguments) {
|
||||
Uri uri = getIntentData(arguments);
|
||||
if (isBubbleIntentUri(uri)) {
|
||||
return uri.getQueryParameter(EXTRA_RECIPIENT) == null;
|
||||
} else {
|
||||
return !intent.hasExtra(EXTRA_RECIPIENT);
|
||||
return !arguments.containsKey(EXTRA_RECIPIENT);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isBubbleIntent(@NonNull Intent intent) {
|
||||
return intent.getData() != null && Objects.equals(intent.getData().getAuthority(), BUBBLE_AUTHORITY);
|
||||
static @Nullable Uri getIntentData(@NonNull Bundle bundle) {
|
||||
return bundle.getParcelable(INTENT_DATA);
|
||||
}
|
||||
|
||||
static @Nullable String getIntentType(@NonNull Bundle bundle) {
|
||||
return bundle.getString(INTENT_TYPE);
|
||||
}
|
||||
|
||||
static @NonNull Bundle createParentFragmentArguments(@NonNull Intent intent) {
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putAll(intent.getExtras());
|
||||
bundle.putParcelable(INTENT_DATA, intent.getData());
|
||||
bundle.putString(INTENT_TYPE, intent.getType());
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
private static boolean isBubbleIntentUri(@Nullable Uri uri) {
|
||||
return uri != null && Objects.equals(uri.getAuthority(), BUBBLE_AUTHORITY);
|
||||
}
|
||||
|
||||
final static class Args {
|
||||
|
@ -76,10 +98,11 @@ public class ConversationIntents {
|
|||
private final boolean withSearchOpen;
|
||||
private final Badge giftBadge;
|
||||
|
||||
static Args from(@NonNull Intent intent) {
|
||||
if (isBubbleIntent(intent)) {
|
||||
return new Args(RecipientId.from(intent.getData().getQueryParameter(EXTRA_RECIPIENT)),
|
||||
Long.parseLong(intent.getData().getQueryParameter(EXTRA_THREAD_ID)),
|
||||
static Args from(@NonNull Bundle arguments) {
|
||||
Uri intentDataUri = getIntentData(arguments);
|
||||
if (isBubbleIntentUri(intentDataUri)) {
|
||||
return new Args(RecipientId.from(intentDataUri.getQueryParameter(EXTRA_RECIPIENT)),
|
||||
Long.parseLong(intentDataUri.getQueryParameter(EXTRA_THREAD_ID)),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
|
@ -91,17 +114,17 @@ public class ConversationIntents {
|
|||
null);
|
||||
}
|
||||
|
||||
return new Args(RecipientId.from(Objects.requireNonNull(intent.getStringExtra(EXTRA_RECIPIENT))),
|
||||
intent.getLongExtra(EXTRA_THREAD_ID, -1),
|
||||
intent.getStringExtra(EXTRA_TEXT),
|
||||
intent.getParcelableArrayListExtra(EXTRA_MEDIA),
|
||||
intent.getParcelableExtra(EXTRA_STICKER),
|
||||
intent.getBooleanExtra(EXTRA_BORDERLESS, false),
|
||||
intent.getIntExtra(EXTRA_DISTRIBUTION_TYPE, ThreadDatabase.DistributionTypes.DEFAULT),
|
||||
intent.getIntExtra(EXTRA_STARTING_POSITION, -1),
|
||||
intent.getBooleanExtra(EXTRA_FIRST_TIME_IN_SELF_CREATED_GROUP, false),
|
||||
intent.getBooleanExtra(EXTRA_WITH_SEARCH_OPEN, false),
|
||||
intent.getParcelableExtra(EXTRA_GIFT_BADGE));
|
||||
return new Args(RecipientId.from(Objects.requireNonNull(arguments.getString(EXTRA_RECIPIENT))),
|
||||
arguments.getLong(EXTRA_THREAD_ID, -1),
|
||||
arguments.getString(EXTRA_TEXT),
|
||||
arguments.getParcelableArrayList(EXTRA_MEDIA),
|
||||
arguments.getParcelable(EXTRA_STICKER),
|
||||
arguments.getBoolean(EXTRA_BORDERLESS, false),
|
||||
arguments.getInt(EXTRA_DISTRIBUTION_TYPE, ThreadDatabase.DistributionTypes.DEFAULT),
|
||||
arguments.getInt(EXTRA_STARTING_POSITION, -1),
|
||||
arguments.getBoolean(EXTRA_FIRST_TIME_IN_SELF_CREATED_GROUP, false),
|
||||
arguments.getBoolean(EXTRA_WITH_SEARCH_OPEN, false),
|
||||
arguments.getParcelable(EXTRA_GIFT_BADGE));
|
||||
}
|
||||
|
||||
private Args(@NonNull RecipientId recipientId,
|
||||
|
|
|
@ -369,6 +369,8 @@ public class ConversationParentFragment extends Fragment
|
|||
private static final String STATE_REACT_WITH_ANY_PAGE = "STATE_REACT_WITH_ANY_PAGE";
|
||||
private static final String STATE_IS_SEARCH_REQUESTED = "STATE_IS_SEARCH_REQUESTED";
|
||||
|
||||
private static final String ARG_INTENT_DATA = "arg.intent.data";
|
||||
|
||||
private static final int REQUEST_CODE_SETTINGS = 1000;
|
||||
|
||||
private static final int PICK_GALLERY = 1;
|
||||
|
@ -460,12 +462,20 @@ public class ConversationParentFragment extends Fragment
|
|||
private final LifecycleDisposable disposables = new LifecycleDisposable();
|
||||
private final Debouncer optionsMenuDebouncer = new Debouncer(50);
|
||||
|
||||
private volatile boolean screenInitialized = false;
|
||||
|
||||
private IdentityRecordList identityRecords = new IdentityRecordList(Collections.emptyList());
|
||||
private Callback callback;
|
||||
private RecentEmojiPageModel recentEmojis;
|
||||
|
||||
public static ConversationParentFragment create(Intent intent) {
|
||||
ConversationParentFragment fragment = new ConversationParentFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putAll(ConversationIntents.createParentFragmentArguments(intent));
|
||||
fragment.setArguments(bundle);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.conversation_activity, container, false);
|
||||
|
@ -484,7 +494,7 @@ public class ConversationParentFragment extends Fragment
|
|||
}
|
||||
|
||||
// TODO [alex] LargeScreenSupport -- This check will no longer be valid / necessary
|
||||
if (ConversationIntents.isInvalid(requireActivity().getIntent())) {
|
||||
if (ConversationIntents.isInvalid(requireArguments())) {
|
||||
Log.w(TAG, "[onCreate] Missing recipientId!");
|
||||
// TODO [greyson] Navigation
|
||||
startActivity(MainActivity.clearTop(requireContext()));
|
||||
|
@ -499,8 +509,7 @@ public class ConversationParentFragment extends Fragment
|
|||
// TODO [alex] LargeScreenSupport -- Should be removed once we move to multi-pane layout.
|
||||
new FullscreenHelper(requireActivity()).showSystemUI();
|
||||
|
||||
// TODO [alex] LargeScreenSupport -- This will need to be built from requireArguments()
|
||||
ConversationIntents.Args args = ConversationIntents.Args.from(requireActivity().getIntent());
|
||||
ConversationIntents.Args args = ConversationIntents.Args.from(requireArguments());
|
||||
if (savedInstanceState == null && args.getGiftBadge() != null) {
|
||||
GiftThanksSheet.show(getChildFragmentManager(), args.getRecipientId(), args.getGiftBadge());
|
||||
}
|
||||
|
@ -575,8 +584,6 @@ public class ConversationParentFragment extends Fragment
|
|||
composeText.addTextChangedListener(typingTextWatcher);
|
||||
}
|
||||
composeText.setSelection(composeText.length(), composeText.length());
|
||||
|
||||
screenInitialized = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -600,78 +607,6 @@ public class ConversationParentFragment extends Fragment
|
|||
sendButton.post(() -> sendButton.triggerSelectedChangedEvent());
|
||||
}
|
||||
|
||||
// TODO [alex] LargeScreenSupport -- This needs to be fed a stream of intents
|
||||
protected void onNewIntent(Intent intent) {
|
||||
Log.i(TAG, "onNewIntent()");
|
||||
|
||||
if (requireActivity().isFinishing()) {
|
||||
Log.w(TAG, "Activity is finishing...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!screenInitialized) {
|
||||
Log.w(TAG, "Activity is in the middle of initialization. Restarting.");
|
||||
requireActivity().finish();
|
||||
startActivity(intent);
|
||||
return;
|
||||
}
|
||||
|
||||
reactWithAnyEmojiStartPage = -1;
|
||||
if (!Util.isEmpty(composeText) || attachmentManager.isAttachmentPresent() || inputPanel.hasSaveableContent()) {
|
||||
saveDraft();
|
||||
attachmentManager.clear(glideRequests, false);
|
||||
inputPanel.clearQuote();
|
||||
silentlySetComposeText("");
|
||||
}
|
||||
|
||||
if (ConversationIntents.isInvalid(intent)) {
|
||||
Log.w(TAG, "[onNewIntent] Missing recipientId!");
|
||||
// TODO [greyson] Navigation
|
||||
startActivity(MainActivity.clearTop(requireContext()));
|
||||
requireActivity().finish();
|
||||
return;
|
||||
}
|
||||
|
||||
requireActivity().setIntent(intent);
|
||||
|
||||
ConversationIntents.Args args = ConversationIntents.Args.from(intent);
|
||||
// TODO [alex] LargeScreenSupport - Set arguments
|
||||
isSearchRequested = args.isWithSearchOpen();
|
||||
|
||||
viewModel.setArgs(args);
|
||||
setVisibleThread(args.getThreadId());
|
||||
|
||||
reportShortcutLaunch(viewModel.getArgs().getRecipientId());
|
||||
initializeResources(viewModel.getArgs());
|
||||
|
||||
initializeSecurity(recipient.get().isRegistered(), isDefaultSms).addListener(new AssertedSuccessListener<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
if (getContext() != null) {
|
||||
Log.d(TAG, "Initializing draft from new intent...");
|
||||
hasProcessedShareData = false;
|
||||
initializeDraft(viewModel.getArgs());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (fragment != null) {
|
||||
fragment.onNewIntent();
|
||||
}
|
||||
|
||||
searchNav.setVisibility(View.GONE);
|
||||
|
||||
if (args.isWithSearchOpen()) {
|
||||
if (searchViewItem != null && searchViewItem.expandActionView()) {
|
||||
searchViewModel.onSearchOpened();
|
||||
}
|
||||
} else {
|
||||
searchViewModel.onSearchClosed();
|
||||
viewModel.setSearchQuery(null);
|
||||
inputPanel.setHideForSearch(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -1598,9 +1533,10 @@ public class ConversationParentFragment extends Fragment
|
|||
private void handleManualMmsRequired() {
|
||||
Toast.makeText(requireContext(), R.string.MmsDownloader_error_reading_mms_settings, Toast.LENGTH_LONG).show();
|
||||
|
||||
Bundle extras = requireActivity().getIntent().getExtras();
|
||||
Bundle extras = requireArguments();
|
||||
Intent intent = new Intent(requireContext(), PromptMmsActivity.class);
|
||||
if (extras != null) intent.putExtras(extras);
|
||||
|
||||
intent.putExtras(extras);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
@ -1676,8 +1612,8 @@ public class ConversationParentFragment extends Fragment
|
|||
}
|
||||
|
||||
final CharSequence draftText = args.getDraftText();
|
||||
final Uri draftMedia = requireActivity().getIntent().getData();
|
||||
final String draftContentType = requireActivity().getIntent().getType();
|
||||
final Uri draftMedia = ConversationIntents.getIntentData(requireArguments());
|
||||
final String draftContentType = ConversationIntents.getIntentType(requireArguments());
|
||||
final MediaType draftMediaType = MediaType.from(draftContentType);
|
||||
final List<Media> mediaList = args.getMedia();
|
||||
final StickerLocator stickerLocator = args.getStickerLocator();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/fragment_container"
|
||||
android:name="org.thoughtcrime.securesms.conversation.ConversationParentFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
Loading…
Add table
Reference in a new issue