diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java index eeddee0012..8181b6a1a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java @@ -815,8 +815,9 @@ public class ConversationParentFragment extends Fragment private void onInitialSecurityConfigurationLoaded() { Log.d(TAG, "Initial security configuration loaded."); - if (isDetached()) { - Log.w(TAG, "Fragment has become detached. Ignoring configuration call."); + if (getContext() == null) { + Log.w(TAG, "Fragment has become detached from context. Ignoring configuration call."); + return; } initializeProfiles(); @@ -826,6 +827,12 @@ public class ConversationParentFragment extends Fragment initializeDraft(viewModel.getArgs()).addListener(new AssertedSuccessListener() { @Override public void onSuccess(Boolean loadedDraft) { + Log.d(TAG, "Initial security configuration loaded."); + if (getContext() == null) { + Log.w(TAG, "Fragment has become detached from context. Ignoring draft load."); + return; + } + if (loadedDraft != null && loadedDraft) { Log.i(TAG, "Finished loading draft"); ThreadUtil.runOnMain(() -> { @@ -837,7 +844,7 @@ public class ConversationParentFragment extends Fragment }); } - if (TextSecurePreferences.isTypingIndicatorsEnabled(requireContext())) { + if (TextSecurePreferences.isTypingIndicatorsEnabled(ApplicationDependencies.getApplication())) { composeText.addTextChangedListener(typingTextWatcher); } composeText.setSelection(composeText.length(), composeText.length()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java index 53edeff21a..bc638c33ea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationRepository.java @@ -133,8 +133,22 @@ class ConversationRepository { return Single.fromCallable(() -> Util.isMmsCapable(context)).subscribeOn(Schedulers.io()); } - @NonNull Observable getSecurityInfo(RecipientId recipientId) { - return Recipient.observable(recipientId).map(recipient -> { + /** + * Watchest the given recipient id for changes, and gets the security info for the recipient + * whenever a change occurs. + * + * @param recipientId The recipient id we are interested in + * + * @return The recipient's security info. + */ + @NonNull Observable getSecurityInfo(@NonNull RecipientId recipientId) { + return Recipient.observable(recipientId) + .switchMapSingle(this::getSecurityInfo) + .subscribeOn(Schedulers.io()); + } + + private @NonNull Single getSecurityInfo(@NonNull Recipient recipient) { + return Single.fromCallable(() -> { Log.i(TAG, "Resolving registered state..."); RecipientDatabase.RegisteredState registeredState; @@ -159,22 +173,22 @@ class ConversationRepository { } Log.i(TAG, "Returning registered state..."); - return new ConversationSecurityInfo(recipientId, + return new ConversationSecurityInfo(recipient.getId(), registeredState == RecipientDatabase.RegisteredState.REGISTERED && signalEnabled, Util.isDefaultSmsProvider(context), true); - }).subscribeOn(Schedulers.io()); + }); } - Observable getThreadRecord(long threadId) { + Observable> getThreadRecord(long threadId) { if (threadId == -1L) { - return Observable.empty(); + return Observable.just(Optional.empty()); } - return Observable.create(emitter -> { + return Observable.> create(emitter -> { DatabaseObserver.Observer listener = () -> { - emitter.onNext(SignalDatabase.threads().getThreadRecord(threadId)); + emitter.onNext(Optional.ofNullable(SignalDatabase.threads().getThreadRecord(threadId))); }; ApplicationDependencies.getDatabaseObserver().registerConversationObserver(threadId, listener); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationViewModel.java index dad0e6601c..3e4fc9c33b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationViewModel.java @@ -139,7 +139,7 @@ public class ConversationViewModel extends ViewModel { disposables.add(threadCountStore.update( threadId.switchMap(conversationRepository::getThreadRecord).toFlowable(BackpressureStrategy.BUFFER), - (record, count) -> count.updateWith(record) + (record, count) -> record.map(count::updateWith).orElse(count) )); conversationStateStore.update(Observable.combineLatest(recipientId, conversationStateTick, (id, tick) -> id) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index f77ad067b6..aadd97c997 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -688,7 +688,10 @@ public class ConversationListFragment extends MainFragment implements ActionMode AppStartup.getInstance().onCriticalRenderEventEnd(); startupStopwatch.split("first-render"); startupStopwatch.stop(TAG); - ConversationFragment.prepare(requireContext()); + + if (getContext() != null) { + ConversationFragment.prepare(getContext()); + } }); } });