Move group resolution for conversations to background LiveData.

This commit is contained in:
Cody Henthorne 2020-06-06 19:26:21 -04:00 committed by Greyson Parrelli
parent 18c7bc2b5b
commit 5b4d74b7fe
2 changed files with 111 additions and 18 deletions

View file

@ -126,6 +126,7 @@ import org.thoughtcrime.securesms.contactshare.Contact;
import org.thoughtcrime.securesms.contactshare.ContactShareEditActivity; import org.thoughtcrime.securesms.contactshare.ContactShareEditActivity;
import org.thoughtcrime.securesms.contactshare.ContactUtil; import org.thoughtcrime.securesms.contactshare.ContactUtil;
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher; import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher;
import org.thoughtcrime.securesms.conversation.ConversationGroupViewModel.GroupActiveState;
import org.thoughtcrime.securesms.conversationlist.model.MessageResult; import org.thoughtcrime.securesms.conversationlist.model.MessageResult;
import org.thoughtcrime.securesms.crypto.SecurityEvent; import org.thoughtcrime.securesms.crypto.SecurityEvent;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
@ -339,6 +340,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private ConversationStickerViewModel stickerViewModel; private ConversationStickerViewModel stickerViewModel;
private ConversationViewModel viewModel; private ConversationViewModel viewModel;
private InviteReminderModel inviteReminderModel; private InviteReminderModel inviteReminderModel;
private ConversationGroupViewModel groupViewModel;
private LiveRecipient recipient; private LiveRecipient recipient;
private long threadId; private long threadId;
@ -406,6 +408,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
initializeSearchObserver(); initializeSearchObserver();
initializeStickerObserver(); initializeStickerObserver();
initializeViewModel(); initializeViewModel();
initializeGroupViewModel();
initializeEnabledCheck();
initializeSecurity(recipient.get().isRegistered(), isDefaultSms).addListener(new AssertedSuccessListener<Boolean>() { initializeSecurity(recipient.get().isRegistered(), isDefaultSms).addListener(new AssertedSuccessListener<Boolean>() {
@Override @Override
public void onSuccess(Boolean result) { public void onSuccess(Boolean result) {
@ -485,7 +489,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
dynamicLanguage.onResume(this); dynamicLanguage.onResume(this);
EventBus.getDefault().register(this); EventBus.getDefault().register(this);
initializeEnabledCheck();
initializeMmsEnabledCheck(); initializeMmsEnabledCheck();
initializeIdentityRecords(); initializeIdentityRecords();
composeText.setTransport(sendButton.getSelectedTransport()); composeText.setTransport(sendButton.getSelectedTransport());
@ -704,8 +707,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
MenuInflater inflater = this.getMenuInflater(); MenuInflater inflater = this.getMenuInflater();
menu.clear(); menu.clear();
GroupActiveState groupActiveState = groupViewModel.getGroupActiveState().getValue();
boolean isActiveGroup = groupActiveState != null && groupActiveState.isActiveGroup();
boolean isActiveV2Group = groupActiveState != null && groupActiveState.isActiveV2Group();
if (isInMessageRequest()) { if (isInMessageRequest()) {
if (isActiveGroup()) { if (isActiveGroup) {
inflater.inflate(R.menu.conversation_message_requests_group, menu); inflater.inflate(R.menu.conversation_message_requests_group, menu);
} }
@ -741,9 +748,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else { } else {
menu.findItem(R.id.menu_distribution_conversation).setChecked(true); menu.findItem(R.id.menu_distribution_conversation).setChecked(true);
} }
} else if (isActiveV2Group() || isActiveGroup() && FeatureFlags.newGroupUI()) { } else if (isActiveV2Group || isActiveGroup && FeatureFlags.newGroupUI()) {
inflater.inflate(R.menu.conversation_push_group_v2_options, menu); inflater.inflate(R.menu.conversation_push_group_v2_options, menu);
} else if (isActiveGroup()) { } else if (isActiveGroup) {
inflater.inflate(R.menu.conversation_push_group_options, menu); inflater.inflate(R.menu.conversation_push_group_options, menu);
} }
} }
@ -789,10 +796,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
hideMenuItem(menu, R.id.menu_mute_notifications); hideMenuItem(menu, R.id.menu_mute_notifications);
} }
if (isActiveV2Group()) { if (isActiveV2Group) {
hideMenuItem(menu, R.id.menu_mute_notifications); hideMenuItem(menu, R.id.menu_mute_notifications);
hideMenuItem(menu, R.id.menu_conversation_settings); hideMenuItem(menu, R.id.menu_conversation_settings);
} else if (isActiveGroup()) { } else if (isActiveGroup) {
hideMenuItem(menu, R.id.menu_conversation_settings); hideMenuItem(menu, R.id.menu_conversation_settings);
} }
@ -1187,7 +1194,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
LeaveGroupDialog.handleLeavePushGroup(ConversationActivity.this, LeaveGroupDialog.handleLeavePushGroup(ConversationActivity.this,
getLifecycle(), getLifecycle(),
getRecipient().requireGroupId().requirePush(), getRecipient().requireGroupId().requirePush(),
this::initializeEnabledCheck); null);
} }
private void handleEditPushGroupV1() { private void handleEditPushGroupV1() {
@ -1417,10 +1424,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} }
private void initializeEnabledCheck() { private void initializeEnabledCheck() {
boolean enabled = !(isPushGroupConversation() && !isActiveGroup()); groupViewModel.getGroupActiveState().observe(this, state -> {
inputPanel.setEnabled(enabled); boolean enabled = state == null || !(isPushGroupConversation() && !state.isActiveGroup());
sendButton.setEnabled(enabled); inputPanel.setEnabled(enabled);
attachButton.setEnabled(enabled); sendButton.setEnabled(enabled);
attachButton.setEnabled(enabled);
});
} }
private ListenableFuture<Boolean> initializeDraftFromDatabase() { private ListenableFuture<Boolean> initializeDraftFromDatabase() {
@ -1851,6 +1860,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
this.viewModel = ViewModelProviders.of(this, new ConversationViewModel.Factory()).get(ConversationViewModel.class); this.viewModel = ViewModelProviders.of(this, new ConversationViewModel.Factory()).get(ConversationViewModel.class);
} }
private void initializeGroupViewModel() {
groupViewModel = ViewModelProviders.of(this, new ConversationGroupViewModel.Factory()).get(ConversationGroupViewModel.class);
recipient.observe(this, groupViewModel::onRecipientChange);
groupViewModel.getGroupActiveState().observe(this, unused -> invalidateOptionsMenu());
}
private void showStickerIntroductionTooltip() { private void showStickerIntroductionTooltip() {
TextSecurePreferences.setMediaKeyboardMode(this, MediaKeyboardMode.STICKER); TextSecurePreferences.setMediaKeyboardMode(this, MediaKeyboardMode.STICKER);
inputPanel.setMediaKeyboardToggleMode(true); inputPanel.setMediaKeyboardToggleMode(true);
@ -1948,6 +1963,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (searchViewItem == null || !searchViewItem.isActionViewExpanded()) { if (searchViewItem == null || !searchViewItem.isActionViewExpanded()) {
invalidateOptionsMenu(); invalidateOptionsMenu();
} }
if (groupViewModel != null) {
groupViewModel.onRecipientChange(recipient);
}
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
@ -2205,13 +2224,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
return record.isPresent() && record.get().isActive(); return record.isPresent() && record.get().isActive();
} }
private boolean isActiveV2Group() {
if (!isGroupConversation()) return false;
Optional<GroupRecord> record = DatabaseFactory.getGroupDatabase(this).getGroup(getRecipient().getId());
return record.isPresent() && record.get().isActive() && record.get().isV2Group();
}
@SuppressWarnings("SimplifiableIfStatement") @SuppressWarnings("SimplifiableIfStatement")
private boolean isSelfConversation() { private boolean isSelfConversation() {
if (!TextSecurePreferences.isPushRegistered(this)) return false; if (!TextSecurePreferences.isPushRegistered(this)) return false;

View file

@ -0,0 +1,81 @@
package org.thoughtcrime.securesms.conversation;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
class ConversationGroupViewModel extends ViewModel {
private final MutableLiveData<Recipient> liveRecipient;
private final LiveData<GroupActiveState> groupActiveState;
private ConversationGroupViewModel() {
liveRecipient = new MutableLiveData<>();
LiveData<GroupRecord> groupRecord = LiveDataUtil.mapAsync(liveRecipient, this::getGroupRecordForRecipient);
groupActiveState = Transformations.distinctUntilChanged(Transformations.map(groupRecord, this::mapToGroupActiveState));
}
void onRecipientChange(Recipient recipient) {
liveRecipient.setValue(recipient);
}
LiveData<GroupActiveState> getGroupActiveState() {
return groupActiveState;
}
private GroupRecord getGroupRecordForRecipient(Recipient recipient) {
if (recipient != null && recipient.isGroup()) {
Application context = ApplicationDependencies.getApplication();
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
return groupDatabase.getGroup(recipient.getId()).orNull();
} else {
return null;
}
}
private GroupActiveState mapToGroupActiveState(@Nullable GroupRecord record) {
if (record == null) {
return null;
}
return new GroupActiveState(record.isActive(), record.isV2Group());
}
static final class GroupActiveState {
private final boolean isActive;
private final boolean isActiveV2;
public GroupActiveState(boolean isActive, boolean isV2) {
this.isActive = isActive;
this.isActiveV2 = isActive && isV2;
}
public boolean isActiveGroup() {
return isActive;
}
public boolean isActiveV2Group() {
return isActiveV2;
}
}
static class Factory extends ViewModelProvider.NewInstanceFactory {
@Override
public @NonNull <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//noinspection ConstantConditions
return modelClass.cast(new ConversationGroupViewModel());
}
}
}