Skip to content

Commit

Permalink
Move group resolution for conversations to background LiveData.
Browse files Browse the repository at this point in the history
  • Loading branch information
cody-signal authored and greyson-signal committed Jun 7, 2020
1 parent 18c7bc2 commit 5b4d74b
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 18 deletions.
Expand Up @@ -126,6 +126,7 @@
import org.thoughtcrime.securesms.contactshare.ContactShareEditActivity;
import org.thoughtcrime.securesms.contactshare.ContactUtil;
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher;
import org.thoughtcrime.securesms.conversation.ConversationGroupViewModel.GroupActiveState;
import org.thoughtcrime.securesms.conversationlist.model.MessageResult;
import org.thoughtcrime.securesms.crypto.SecurityEvent;
import org.thoughtcrime.securesms.database.DatabaseFactory;
Expand Down Expand Up @@ -339,6 +340,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private ConversationStickerViewModel stickerViewModel;
private ConversationViewModel viewModel;
private InviteReminderModel inviteReminderModel;
private ConversationGroupViewModel groupViewModel;

private LiveRecipient recipient;
private long threadId;
Expand Down Expand Up @@ -406,6 +408,8 @@ protected void onCreate(Bundle state, boolean ready) {
initializeSearchObserver();
initializeStickerObserver();
initializeViewModel();
initializeGroupViewModel();
initializeEnabledCheck();
initializeSecurity(recipient.get().isRegistered(), isDefaultSms).addListener(new AssertedSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean result) {
Expand Down Expand Up @@ -485,7 +489,6 @@ protected void onResume() {
dynamicLanguage.onResume(this);

EventBus.getDefault().register(this);
initializeEnabledCheck();
initializeMmsEnabledCheck();
initializeIdentityRecords();
composeText.setTransport(sendButton.getSelectedTransport());
Expand Down Expand Up @@ -704,8 +707,12 @@ public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = this.getMenuInflater();
menu.clear();

GroupActiveState groupActiveState = groupViewModel.getGroupActiveState().getValue();
boolean isActiveGroup = groupActiveState != null && groupActiveState.isActiveGroup();
boolean isActiveV2Group = groupActiveState != null && groupActiveState.isActiveV2Group();

if (isInMessageRequest()) {
if (isActiveGroup()) {
if (isActiveGroup) {
inflater.inflate(R.menu.conversation_message_requests_group, menu);
}

Expand Down Expand Up @@ -741,9 +748,9 @@ public boolean onPrepareOptionsMenu(Menu menu) {
} else {
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);
} else if (isActiveGroup()) {
} else if (isActiveGroup) {
inflater.inflate(R.menu.conversation_push_group_options, menu);
}
}
Expand Down Expand Up @@ -789,10 +796,10 @@ public boolean onPrepareOptionsMenu(Menu menu) {
hideMenuItem(menu, R.id.menu_mute_notifications);
}

if (isActiveV2Group()) {
if (isActiveV2Group) {
hideMenuItem(menu, R.id.menu_mute_notifications);
hideMenuItem(menu, R.id.menu_conversation_settings);
} else if (isActiveGroup()) {
} else if (isActiveGroup) {
hideMenuItem(menu, R.id.menu_conversation_settings);
}

Expand Down Expand Up @@ -1187,7 +1194,7 @@ private void handleLeavePushGroup() {
LeaveGroupDialog.handleLeavePushGroup(ConversationActivity.this,
getLifecycle(),
getRecipient().requireGroupId().requirePush(),
this::initializeEnabledCheck);
null);
}

private void handleEditPushGroupV1() {
Expand Down Expand Up @@ -1417,10 +1424,12 @@ private ListenableFuture<Boolean> initializeDraft() {
}

private void initializeEnabledCheck() {
boolean enabled = !(isPushGroupConversation() && !isActiveGroup());
inputPanel.setEnabled(enabled);
sendButton.setEnabled(enabled);
attachButton.setEnabled(enabled);
groupViewModel.getGroupActiveState().observe(this, state -> {
boolean enabled = state == null || !(isPushGroupConversation() && !state.isActiveGroup());
inputPanel.setEnabled(enabled);
sendButton.setEnabled(enabled);
attachButton.setEnabled(enabled);
});
}

private ListenableFuture<Boolean> initializeDraftFromDatabase() {
Expand Down Expand Up @@ -1851,6 +1860,12 @@ private void initializeViewModel() {
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() {
TextSecurePreferences.setMediaKeyboardMode(this, MediaKeyboardMode.STICKER);
inputPanel.setMediaKeyboardToggleMode(true);
Expand Down Expand Up @@ -1948,6 +1963,10 @@ private void onRecipientChanged(@NonNull Recipient recipient) {
if (searchViewItem == null || !searchViewItem.isActionViewExpanded()) {
invalidateOptionsMenu();
}

if (groupViewModel != null) {
groupViewModel.onRecipientChange(recipient);
}
}

@Subscribe(threadMode = ThreadMode.MAIN)
Expand Down Expand Up @@ -2205,13 +2224,6 @@ private boolean isActiveGroup() {
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")
private boolean isSelfConversation() {
if (!TextSecurePreferences.isPushRegistered(this)) return false;
Expand Down
@@ -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());
}
}
}

0 comments on commit 5b4d74b

Please sign in to comment.