Groups V2 invite decline.
parent
1ce36c1069
commit
644af87782
|
@ -2847,25 +2847,44 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
|||
|
||||
@Override
|
||||
public void onMessageRequest(@NonNull MessageRequestViewModel viewModel) {
|
||||
messageRequestBottomView.setAcceptOnClickListener(v -> viewModel.onAccept(this::showGroupChangeErrorToast));
|
||||
messageRequestBottomView.setAcceptOnClickListener(v -> viewModel.onAccept());
|
||||
messageRequestBottomView.setDeleteOnClickListener(v -> onMessageRequestDeleteClicked(viewModel));
|
||||
messageRequestBottomView.setBlockOnClickListener(v -> onMessageRequestBlockClicked(viewModel));
|
||||
messageRequestBottomView.setUnblockOnClickListener(v -> onMessageRequestUnblockClicked(viewModel));
|
||||
|
||||
viewModel.getRecipient().observe(this, this::presentMessageRequestBottomViewTo);
|
||||
viewModel.getMessageRequestDisplayState().observe(this, this::presentMessageRequestDisplayState);
|
||||
viewModel.getFailures().observe(this, this::showGroupChangeErrorToast);
|
||||
viewModel.getMessageRequestStatus().observe(this, status -> {
|
||||
switch (status) {
|
||||
case IDLE:
|
||||
hideMessageRequestBusy();
|
||||
break;
|
||||
case ACCEPTING:
|
||||
case BLOCKING:
|
||||
case DELETING:
|
||||
showMessageRequestBusy();
|
||||
break;
|
||||
case ACCEPTED:
|
||||
hideMessageRequestBusy();
|
||||
messageRequestBottomView.setVisibility(View.GONE);
|
||||
return;
|
||||
break;
|
||||
case DELETED:
|
||||
case BLOCKED:
|
||||
hideMessageRequestBusy();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showMessageRequestBusy() {
|
||||
messageRequestBottomView.showBusy();
|
||||
}
|
||||
|
||||
private void hideMessageRequestBusy() {
|
||||
messageRequestBottomView.hideBusy();
|
||||
}
|
||||
|
||||
private void showGroupChangeErrorToast(@NonNull GroupChangeFailureReason e) {
|
||||
Toast.makeText(this, GroupErrors.getUserDisplayMessage(e), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
|
|
@ -127,11 +127,15 @@ public final class GroupManager {
|
|||
}
|
||||
|
||||
@WorkerThread
|
||||
public static boolean silentLeaveGroup(@NonNull Context context, @NonNull GroupId.Push groupId) {
|
||||
public static void leaveGroupFromBlockOrMessageRequest(@NonNull Context context, @NonNull GroupId.Push groupId)
|
||||
throws IOException, GroupChangeBusyException, GroupChangeFailedException
|
||||
{
|
||||
if (groupId.isV2()) {
|
||||
throw new AssertionError("NYI"); // TODO [Alan] GV2 support silent leave for block and leave operations on GV2
|
||||
leaveGroup(context, groupId.requireV2());
|
||||
} else {
|
||||
return GroupManagerV1.silentLeaveGroup(context, groupId.requireV1());
|
||||
if (!GroupManagerV1.silentLeaveGroup(context, groupId.requireV1())) {
|
||||
throw new GroupChangeFailedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ import org.signal.storageservice.protos.groups.Member;
|
|||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.VerificationFailedException;
|
||||
import org.signal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.zkgroup.groups.GroupSecretParams;
|
||||
|
@ -54,6 +56,7 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -268,7 +271,20 @@ final class GroupManagerV2 {
|
|||
@NonNull GroupManager.GroupActionResult leaveGroup()
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
return ejectMember(Recipient.self().getId());
|
||||
Recipient self = Recipient.self();
|
||||
GroupDatabase.GroupRecord groupRecord = groupDatabase.getGroup(groupId).get();
|
||||
List<DecryptedPendingMember> pendingMembersList = groupRecord.requireV2GroupProperties().getDecryptedGroup().getPendingMembersList();
|
||||
Optional<DecryptedPendingMember> selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfUuid);
|
||||
|
||||
if (selfPendingMember.isPresent()) {
|
||||
try {
|
||||
return cancelInvites(Collections.singleton(new UuidCiphertext(selfPendingMember.get().getUuidCipherText().toByteArray())));
|
||||
} catch (InvalidInputException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
} else {
|
||||
return ejectMember(self.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
|||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
|
@ -160,6 +161,17 @@ final class ManageGroupRepository {
|
|||
});
|
||||
}
|
||||
|
||||
void blockAndLeaveGroup(@NonNull GroupChangeErrorCallback error) {
|
||||
SignalExecutors.UNBOUNDED.execute(() -> {
|
||||
try {
|
||||
RecipientUtil.block(context, Recipient.externalGroup(context, groupId));
|
||||
} catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) {
|
||||
Log.w(TAG, e);
|
||||
error.onError(GroupChangeFailureReason.OTHER);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static final class GroupStateResult {
|
||||
|
||||
private final long threadId;
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.thoughtcrime.securesms.database.MediaDatabase;
|
|||
import org.thoughtcrime.securesms.database.loaders.MediaLoader;
|
||||
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
|
||||
import org.thoughtcrime.securesms.groups.GroupAccessControl;
|
||||
import org.thoughtcrime.securesms.groups.GroupChangeBusyException;
|
||||
import org.thoughtcrime.securesms.groups.GroupChangeFailedException;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.LiveGroup;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
||||
|
@ -41,6 +43,7 @@ import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
|||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -205,8 +208,10 @@ public class ManageGroupViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
void blockAndLeave(@NonNull FragmentActivity activity) {
|
||||
manageGroupRepository.getRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity, activity.getLifecycle(), recipient,
|
||||
() -> RecipientUtil.block(context, recipient)));
|
||||
manageGroupRepository.getRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity,
|
||||
activity.getLifecycle(),
|
||||
recipient,
|
||||
() -> manageGroupRepository.blockAndLeaveGroup(this::showErrorToast)));
|
||||
}
|
||||
|
||||
void unblock(@NonNull FragmentActivity activity) {
|
||||
|
|
|
@ -103,6 +103,11 @@ public class SendReadReceiptJob extends BaseJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if (recipient.isGroup()) {
|
||||
Log.w(TAG, "Refusing to send receipts to group");
|
||||
return;
|
||||
}
|
||||
|
||||
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
|
||||
SignalServiceAddress remoteAddress = RecipientUtil.toSignalServiceAddress(context, recipient);
|
||||
SignalServiceReceiptMessage receiptMessage = new SignalServiceReceiptMessage(SignalServiceReceiptMessage.Type.READ, messageIds, timestamp);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.thoughtcrime.securesms.recipients;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -9,12 +8,13 @@ import androidx.annotation.WorkerThread;
|
|||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupChangeBusyException;
|
||||
import org.thoughtcrime.securesms.groups.GroupChangeFailedException;
|
||||
import org.thoughtcrime.securesms.groups.GroupManager;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
|
@ -66,8 +66,32 @@ public class RecipientUtil {
|
|||
return resolved.isPushGroup() || resolved.hasServiceIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* You can call this for non-groups and not have to handle any network errors.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void block(@NonNull Context context, @NonNull Recipient recipient) {
|
||||
public static void blockNonGroup(@NonNull Context context, @NonNull Recipient recipient) {
|
||||
if (recipient.isGroup()) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
try {
|
||||
block(context, recipient);
|
||||
} catch (GroupChangeBusyException | IOException | GroupChangeFailedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* You can call this for any type of recipient but must handle network errors that can occur from
|
||||
* GV2.
|
||||
* <p>
|
||||
* GV2 operations can also take longer due to the network.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void block(@NonNull Context context, @NonNull Recipient recipient)
|
||||
throws GroupChangeBusyException, IOException, GroupChangeFailedException
|
||||
{
|
||||
if (!isBlockable(recipient)) {
|
||||
throw new AssertionError("Recipient is not blockable!");
|
||||
}
|
||||
|
@ -76,8 +100,8 @@ public class RecipientUtil {
|
|||
|
||||
DatabaseFactory.getRecipientDatabase(context).setBlocked(resolved.getId(), true);
|
||||
|
||||
if (resolved.isGroup()) {
|
||||
leaveGroup(context, recipient);
|
||||
if (resolved.isGroup() && recipient.getGroupId().get().isPush()) {
|
||||
GroupManager.leaveGroupFromBlockOrMessageRequest(context, recipient.getGroupId().get().requirePush());
|
||||
}
|
||||
|
||||
if (resolved.isSystemContact() || resolved.isProfileSharing() || isProfileSharedViaGroup(context,resolved)) {
|
||||
|
@ -101,20 +125,6 @@ public class RecipientUtil {
|
|||
ApplicationDependencies.getJobManager().add(MultiDeviceMessageRequestResponseJob.forAccept(recipient.getId()));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static void leaveGroup(@NonNull Context context, @NonNull Recipient recipient) {
|
||||
Recipient resolved = recipient.resolve();
|
||||
|
||||
if (!resolved.isGroup()) {
|
||||
throw new AssertionError("Not a group!");
|
||||
}
|
||||
|
||||
if (!GroupManager.silentLeaveGroup(context, resolved.requireGroupId().requirePush())) {
|
||||
Log.w(TAG, "Failed to leave group.");
|
||||
Toast.makeText(context, R.string.RecipientPreferenceActivity_error_leaving_group, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, the new message request UI does not need to be shown, and it's safe to send read
|
||||
* receipts.
|
||||
|
|
|
@ -120,7 +120,7 @@ final class RecipientDialogViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
void onBlockClicked(@NonNull FragmentActivity activity) {
|
||||
recipientDialogRepository.getRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity, activity.getLifecycle(), recipient, () -> RecipientUtil.block(context, recipient)));
|
||||
recipientDialogRepository.getRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity, activity.getLifecycle(), recipient, () -> RecipientUtil.blockNonGroup(context, recipient)));
|
||||
}
|
||||
|
||||
void onUnblockClicked(@NonNull FragmentActivity activity) {
|
||||
|
|
|
@ -210,7 +210,7 @@ public final class ManageRecipientViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
void onBlockClicked(@NonNull FragmentActivity activity) {
|
||||
withRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity, activity.getLifecycle(), recipient, () -> RecipientUtil.block(context, recipient)));
|
||||
withRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity, activity.getLifecycle(), recipient, () -> RecipientUtil.blockNonGroup(context, recipient)));
|
||||
}
|
||||
|
||||
void onUnblockClicked(@NonNull FragmentActivity activity) {
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="11dp"
|
||||
android:textAppearance="@style/Signal.Text.MessageRequest.Description"
|
||||
android:paddingTop="16dp"
|
||||
android:textAppearance="@style/Signal.Text.MessageRequest.Description"
|
||||
app:layout_constraintBottom_toTopOf="@id/message_request_button_barrier"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -20,12 +20,12 @@
|
|||
|
||||
<Button
|
||||
android:id="@+id/message_request_block"
|
||||
style="@style/Signal.MessageRequest.Button.Deny"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
style="@style/Signal.MessageRequest.Button.Deny"
|
||||
android:text="@string/MessageRequestBottomView_block"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/message_request_delete"
|
||||
|
@ -34,10 +34,10 @@
|
|||
|
||||
<Button
|
||||
android:id="@+id/message_request_delete"
|
||||
style="@style/Signal.MessageRequest.Button.Deny"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
style="@style/Signal.MessageRequest.Button.Deny"
|
||||
android:text="@string/MessageRequestBottomView_delete"
|
||||
app:layout_constraintBottom_toBottomOf="@id/message_request_block"
|
||||
app:layout_constraintEnd_toStartOf="@+id/message_request_accept"
|
||||
|
@ -47,10 +47,10 @@
|
|||
|
||||
<Button
|
||||
android:id="@+id/message_request_accept"
|
||||
style="@style/Signal.MessageRequest.Button.Accept"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
style="@style/Signal.MessageRequest.Button.Accept"
|
||||
android:text="@string/MessageRequestBottomView_accept"
|
||||
app:layout_constraintBottom_toBottomOf="@id/message_request_block"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
@ -60,35 +60,35 @@
|
|||
|
||||
<Button
|
||||
android:id="@+id/message_request_big_delete"
|
||||
style="@style/Signal.MessageRequest.Button.Deny"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
style="@style/Signal.MessageRequest.Button.Deny"
|
||||
android:text="@string/MessageRequestBottomView_delete"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/message_request_big_unblock"/>
|
||||
app:layout_constraintEnd_toStartOf="@id/message_request_big_unblock"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/message_request_big_unblock"
|
||||
style="@style/Signal.MessageRequest.Button.Accept"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
style="@style/Signal.MessageRequest.Button.Accept"
|
||||
android:text="@string/MessageRequestBottomView_unblock"
|
||||
app:layout_constraintTop_toTopOf="@id/message_request_big_delete"
|
||||
app:layout_constraintStart_toEndOf="@id/message_request_big_delete"
|
||||
app:layout_constraintBottom_toBottomOf="@id/message_request_big_delete"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/message_request_big_delete"/>
|
||||
app:layout_constraintStart_toEndOf="@id/message_request_big_delete"
|
||||
app:layout_constraintTop_toTopOf="@id/message_request_big_delete" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/message_request_button_barrier"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="message_request_block,message_request_big_delete"/>
|
||||
app:constraint_referenced_ids="message_request_block,message_request_big_delete" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/message_request_normal_buttons"
|
||||
|
@ -102,6 +102,20 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
app:constraint_referenced_ids="message_request_big_delete,message_request_big_unblock" />
|
||||
app:constraint_referenced_ids="message_request_big_delete,message_request_big_unblock"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/message_request_busy_indicator"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/message_request_question"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</merge>
|
Loading…
Reference in New Issue