Groups V2 invite decline.

This commit is contained in:
Alan Evans
2020-07-15 15:40:13 -03:00
committed by Greyson Parrelli
parent 1ce36c1069
commit 644af87782
13 changed files with 245 additions and 87 deletions

View File

@@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.whispersystems.libsignal.util.guava.Optional;
@@ -57,8 +56,8 @@ final class MessageRequestRepository {
void getMemberCount(@NonNull RecipientId recipientId, @NonNull Consumer<GroupMemberCount> onMemberCountLoaded) {
executor.execute(() -> {
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
Optional<GroupDatabase.GroupRecord> groupRecord = groupDatabase.getGroup(recipientId);
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
Optional<GroupDatabase.GroupRecord> groupRecord = groupDatabase.getGroup(recipientId);
onMemberCountLoaded.accept(groupRecord.transform(record -> {
if (record.isV2Group()) {
DecryptedGroup decryptedGroup = record.requireV2GroupProperties().getDecryptedGroup();
@@ -90,9 +89,8 @@ final class MessageRequestRepository {
void acceptMessageRequest(@NonNull LiveRecipient liveRecipient,
long threadId,
@NonNull Runnable onMessageRequestAccepted,
@NonNull GroupChangeErrorCallback mainThreadError)
@NonNull GroupChangeErrorCallback error)
{
GroupChangeErrorCallback error = e -> Util.runOnMain(() -> mainThreadError.onError(e));
executor.execute(()-> {
if (liveRecipient.get().isPushV2Group()) {
try {
@@ -130,27 +128,47 @@ final class MessageRequestRepository {
});
}
void deleteMessageRequest(@NonNull LiveRecipient recipient, long threadId, @NonNull Runnable onMessageRequestDeleted) {
void deleteMessageRequest(@NonNull LiveRecipient recipient,
long threadId,
@NonNull Runnable onMessageRequestDeleted,
@NonNull GroupChangeErrorCallback error)
{
executor.execute(() -> {
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
threadDatabase.deleteConversation(threadId);
Recipient resolved = recipient.resolve();
if (recipient.resolve().isGroup()) {
RecipientUtil.leaveGroup(context, recipient.get());
if (resolved.isGroup() && resolved.requireGroupId().isPush()) {
try {
GroupManager.leaveGroupFromBlockOrMessageRequest(context, resolved.requireGroupId().requirePush());
} catch (GroupChangeBusyException | GroupChangeFailedException | IOException e) {
Log.w(TAG, e);
error.onError(GroupChangeFailureReason.OTHER);
return;
}
}
if (TextSecurePreferences.isMultiDevice(context)) {
ApplicationDependencies.getJobManager().add(MultiDeviceMessageRequestResponseJob.forDelete(recipient.getId()));
}
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
threadDatabase.deleteConversation(threadId);
onMessageRequestDeleted.run();
});
}
void blockMessageRequest(@NonNull LiveRecipient liveRecipient, @NonNull Runnable onMessageRequestBlocked) {
void blockMessageRequest(@NonNull LiveRecipient liveRecipient,
@NonNull Runnable onMessageRequestBlocked,
@NonNull GroupChangeErrorCallback error)
{
executor.execute(() -> {
Recipient recipient = liveRecipient.resolve();
RecipientUtil.block(context, recipient);
try {
RecipientUtil.block(context, recipient);
} catch (GroupChangeBusyException | GroupChangeFailedException | IOException e) {
error.onError(GroupChangeFailureReason.OTHER);
return;
}
liveRecipient.refresh();
if (TextSecurePreferences.isMultiDevice(context)) {
@@ -161,10 +179,19 @@ final class MessageRequestRepository {
});
}
void blockAndDeleteMessageRequest(@NonNull LiveRecipient liveRecipient, long threadId, @NonNull Runnable onMessageRequestBlocked) {
void blockAndDeleteMessageRequest(@NonNull LiveRecipient liveRecipient,
long threadId,
@NonNull Runnable onMessageRequestBlocked,
@NonNull GroupChangeErrorCallback error)
{
executor.execute(() -> {
Recipient recipient = liveRecipient.resolve();
RecipientUtil.block(context, recipient);
try{
RecipientUtil.block(context, recipient);
} catch (GroupChangeBusyException | GroupChangeFailedException | IOException e) {
error.onError(GroupChangeFailureReason.OTHER);
return;
}
liveRecipient.refresh();
DatabaseFactory.getThreadDatabase(context).deleteConversation(threadId);

View File

@@ -11,12 +11,11 @@ import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.groups.ui.GroupChangeErrorCallback;
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
import org.thoughtcrime.securesms.recipients.LiveRecipient;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.SingleLiveEvent;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.livedata.LiveDataTriple;
@@ -26,13 +25,14 @@ import java.util.List;
public class MessageRequestViewModel extends ViewModel {
private final SingleLiveEvent<Status> status = new SingleLiveEvent<>();
private final MutableLiveData<Recipient> recipient = new MutableLiveData<>();
private final MutableLiveData<List<String>> groups = new MutableLiveData<>(Collections.emptyList());
private final MutableLiveData<GroupMemberCount> memberCount = new MutableLiveData<>(GroupMemberCount.ZERO);
private final MutableLiveData<DisplayState> displayState = new MutableLiveData<>();
private final LiveData<RecipientInfo> recipientInfo = Transformations.map(new LiveDataTriple<>(recipient, memberCount, groups),
triple -> new RecipientInfo(triple.first(), triple.second(), triple.third()));
private final SingleLiveEvent<Status> status = new SingleLiveEvent<>();
private final SingleLiveEvent<GroupChangeFailureReason> failures = new SingleLiveEvent<>();
private final MutableLiveData<Recipient> recipient = new MutableLiveData<>();
private final MutableLiveData<List<String>> groups = new MutableLiveData<>(Collections.emptyList());
private final MutableLiveData<GroupMemberCount> memberCount = new MutableLiveData<>(GroupMemberCount.ZERO);
private final MutableLiveData<DisplayState> displayState = new MutableLiveData<>();
private final LiveData<RecipientInfo> recipientInfo = Transformations.map(new LiveDataTriple<>(recipient, memberCount, groups),
triple -> new RecipientInfo(triple.first(), triple.second(), triple.third()));
private final MessageRequestRepository repository;
@@ -85,44 +85,58 @@ public class MessageRequestViewModel extends ViewModel {
return status;
}
public LiveData<GroupChangeFailureReason> getFailures() {
return failures;
}
public boolean shouldShowMessageRequest() {
return displayState.getValue() == DisplayState.DISPLAY_MESSAGE_REQUEST;
}
@MainThread
public void onAccept(@NonNull GroupChangeErrorCallback error) {
repository.acceptMessageRequest(liveRecipient, threadId, () -> {
status.postValue(Status.ACCEPTED);
},
error);
public void onAccept() {
status.setValue(Status.ACCEPTING);
repository.acceptMessageRequest(liveRecipient,
threadId,
() -> status.postValue(Status.ACCEPTED),
this::onGroupChangeError);
}
@MainThread
public void onDelete() {
repository.deleteMessageRequest(liveRecipient, threadId, () -> {
status.postValue(Status.DELETED);
});
status.setValue(Status.DELETING);
repository.deleteMessageRequest(liveRecipient,
threadId,
() -> status.postValue(Status.DELETED),
this::onGroupChangeError);
}
@MainThread
public void onBlock() {
repository.blockMessageRequest(liveRecipient, () -> {
status.postValue(Status.BLOCKED);
});
status.setValue(Status.BLOCKING);
repository.blockMessageRequest(liveRecipient,
() -> status.postValue(Status.BLOCKED),
this::onGroupChangeError);
}
@MainThread
public void onUnblock() {
repository.unblockAndAccept(liveRecipient, threadId, () -> {
status.postValue(Status.ACCEPTED);
});
repository.unblockAndAccept(liveRecipient,
threadId,
() -> status.postValue(Status.ACCEPTED));
}
@MainThread
public void onBlockAndDelete() {
repository.blockAndDeleteMessageRequest(liveRecipient, threadId, () -> {
status.postValue(Status.BLOCKED);
});
repository.blockAndDeleteMessageRequest(liveRecipient,
threadId,
() -> status.postValue(Status.BLOCKED),
this::onGroupChangeError);
}
private void onGroupChangeError(@NonNull GroupChangeFailureReason error) {
status.postValue(Status.IDLE);
failures.postValue(error);
}
private void loadRecipient() {
@@ -191,8 +205,12 @@ public class MessageRequestViewModel extends ViewModel {
}
public enum Status {
IDLE,
BLOCKING,
BLOCKED,
DELETING,
DELETED,
ACCEPTING,
ACCEPTED
}

View File

@@ -12,19 +12,24 @@ import androidx.core.text.HtmlCompat;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Debouncer;
import org.thoughtcrime.securesms.util.HtmlUtil;
public class MessageRequestsBottomView extends ConstraintLayout {
private final Debouncer showProgressDebouncer = new Debouncer(250);
private TextView question;
private View accept;
private View block;
private View delete;
private View bigDelete;
private View bigUnblock;
private View busyIndicator;
private Group normalButtons;
private Group blockedButtons;
private Group activeGroup;
public MessageRequestsBottomView(Context context) {
super(context);
@@ -52,6 +57,7 @@ public class MessageRequestsBottomView extends ConstraintLayout {
bigUnblock = findViewById(R.id.message_request_big_unblock);
normalButtons = findViewById(R.id.message_request_normal_buttons);
blockedButtons = findViewById(R.id.message_request_blocked_buttons);
busyIndicator = findViewById(R.id.message_request_busy_indicator);
}
public void setRecipient(@NonNull Recipient recipient) {
@@ -62,8 +68,7 @@ public class MessageRequestsBottomView extends ConstraintLayout {
String name = recipient.getProfileName().isEmpty() ? recipient.getDisplayName(getContext()) : recipient.getProfileName().getGivenName();
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them, HtmlUtil.bold(name)), 0));
}
normalButtons.setVisibility(GONE);
blockedButtons.setVisibility(VISIBLE);
setActiveInactiveGroups(blockedButtons, normalButtons);
} else {
if (recipient.isGroup()) {
if (recipient.isPushV2Group()) {
@@ -75,8 +80,31 @@ public class MessageRequestsBottomView extends ConstraintLayout {
String name = recipient.getProfileName().isEmpty() ? recipient.getDisplayName(getContext()) : recipient.getProfileName().getGivenName();
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept, HtmlUtil.bold(name)), 0));
}
normalButtons.setVisibility(VISIBLE);
blockedButtons.setVisibility(GONE);
setActiveInactiveGroups(normalButtons, blockedButtons);
}
}
private void setActiveInactiveGroups(@NonNull Group activeGroup, @NonNull Group inActiveGroup) {
int initialVisibility = this.activeGroup != null ? this.activeGroup.getVisibility() : VISIBLE;
this.activeGroup = activeGroup;
inActiveGroup.setVisibility(GONE);
activeGroup.setVisibility(initialVisibility);
}
public void showBusy() {
showProgressDebouncer.publish(() -> busyIndicator.setVisibility(VISIBLE));
if (activeGroup != null) {
activeGroup.setVisibility(INVISIBLE);
}
}
public void hideBusy() {
showProgressDebouncer.clear();
busyIndicator.setVisibility(GONE);
if (activeGroup != null) {
activeGroup.setVisibility(VISIBLE);
}
}