diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index dc611809fd..81dc5a7f9f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -148,12 +148,10 @@ import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.events.ReminderUpdateEvent; import org.thoughtcrime.securesms.giph.ui.GiphyActivity; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; -import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason; +import org.thoughtcrime.securesms.groups.ui.GroupChangeResult; import org.thoughtcrime.securesms.groups.ui.GroupErrors; import org.thoughtcrime.securesms.groups.ui.LeaveGroupDialog; import org.thoughtcrime.securesms.groups.ui.managegroup.ManageGroupActivity; @@ -1003,26 +1001,20 @@ public class ConversationActivity extends PassphraseRequiredActivity if (activeGroup) { try { GroupManager.updateGroupTimer(ConversationActivity.this, getRecipient().requireGroupId().requirePush(), expirationTime); - } catch (GroupInsufficientRightsException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - return ConversationActivity.this.getString(R.string.ManageGroupActivity_you_dont_have_the_rights_to_do_this); - } catch (GroupNotAMemberException e) { - Log.w(TAG, e); - return ConversationActivity.this.getString(R.string.ManageGroupActivity_youre_not_a_member_of_the_group); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - return ConversationActivity.this.getString(R.string.ManageGroupActivity_failed_to_update_the_group); + return GroupChangeResult.failure(GroupChangeFailureReason.fromException(e)); } } else { DatabaseFactory.getRecipientDatabase(ConversationActivity.this).setExpireMessages(recipient.getId(), expirationTime); OutgoingExpirationUpdateMessage outgoingMessage = new OutgoingExpirationUpdateMessage(getRecipient(), System.currentTimeMillis(), expirationTime * 1000L); MessageSender.send(ConversationActivity.this, outgoingMessage, threadId, false, null); } - return null; + return GroupChangeResult.SUCCESS; }, - (errorString) -> { - if (errorString != null) { - Toast.makeText(ConversationActivity.this, errorString, Toast.LENGTH_SHORT).show(); + (changeResult) -> { + if (changeResult.isSuccess()) { + Toast.makeText(ConversationActivity.this, GroupErrors.getUserDisplayMessage(changeResult.getFailureReason()), Toast.LENGTH_SHORT).show(); } else { invalidateOptionsMenu(); if (fragment != null) fragment.setLastSeen(0); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeBusyException.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeBusyException.java index 100eb4a93a..f93204be41 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeBusyException.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeBusyException.java @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.groups; import androidx.annotation.NonNull; -public final class GroupChangeBusyException extends Exception { +public final class GroupChangeBusyException extends GroupChangeException { public GroupChangeBusyException(@NonNull Throwable throwable) { super(throwable); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeException.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeException.java new file mode 100644 index 0000000000..400415803f --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeException.java @@ -0,0 +1,17 @@ +package org.thoughtcrime.securesms.groups; + +import androidx.annotation.NonNull; + +public abstract class GroupChangeException extends Exception { + + GroupChangeException() { + } + + GroupChangeException(@NonNull Throwable throwable) { + super(throwable); + } + + GroupChangeException(@NonNull String message) { + super(message); + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeFailedException.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeFailedException.java index c054cac5f5..6d4566a8a3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeFailedException.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupChangeFailedException.java @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.groups; import androidx.annotation.NonNull; -public final class GroupChangeFailedException extends Exception { +public final class GroupChangeFailedException extends GroupChangeException { GroupChangeFailedException() { } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupInsufficientRightsException.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupInsufficientRightsException.java index 6e3a76bfb7..24554b4a65 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupInsufficientRightsException.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupInsufficientRightsException.java @@ -1,6 +1,6 @@ package org.thoughtcrime.securesms.groups; -public final class GroupInsufficientRightsException extends Exception { +public final class GroupInsufficientRightsException extends GroupChangeException { GroupInsufficientRightsException(Throwable throwable) { super(throwable); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupNotAMemberException.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupNotAMemberException.java index 70604af8a3..672bb6429c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupNotAMemberException.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupNotAMemberException.java @@ -1,6 +1,6 @@ package org.thoughtcrime.securesms.groups; -public final class GroupNotAMemberException extends Exception { +public final class GroupNotAMemberException extends GroupChangeException { public GroupNotAMemberException(Throwable throwable) { super(throwable); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupChangeFailureReason.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupChangeFailureReason.java index 895f003462..1cf6c919b7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupChangeFailureReason.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupChangeFailureReason.java @@ -1,8 +1,28 @@ package org.thoughtcrime.securesms.groups.ui; +import androidx.annotation.NonNull; + +import org.thoughtcrime.securesms.groups.GroupChangeBusyException; +import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; +import org.thoughtcrime.securesms.groups.GroupNotAMemberException; +import org.thoughtcrime.securesms.groups.MembershipNotSuitableForV2Exception; + +import java.io.IOException; + public enum GroupChangeFailureReason { NO_RIGHTS, NOT_CAPABLE, NOT_A_MEMBER, - OTHER + BUSY, + NETWORK, + OTHER; + + public static @NonNull GroupChangeFailureReason fromException(@NonNull Exception e) { + if (e instanceof MembershipNotSuitableForV2Exception) return GroupChangeFailureReason.NOT_CAPABLE; + if (e instanceof IOException) return GroupChangeFailureReason.NETWORK; + if (e instanceof GroupNotAMemberException) return GroupChangeFailureReason.NOT_A_MEMBER; + if (e instanceof GroupChangeBusyException) return GroupChangeFailureReason.BUSY; + if (e instanceof GroupInsufficientRightsException) return GroupChangeFailureReason.NO_RIGHTS; + return GroupChangeFailureReason.OTHER; + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupChangeResult.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupChangeResult.java new file mode 100644 index 0000000000..7ab9cd9747 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupChangeResult.java @@ -0,0 +1,31 @@ +package org.thoughtcrime.securesms.groups.ui; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public final class GroupChangeResult { + + public final static GroupChangeResult SUCCESS = new GroupChangeResult(null); + + private final @Nullable GroupChangeFailureReason failureReason; + + GroupChangeResult(@Nullable GroupChangeFailureReason failureReason) { + this.failureReason = failureReason; + } + + public static GroupChangeResult failure(@NonNull GroupChangeFailureReason failureReason) { + return new GroupChangeResult(failureReason); + } + + public boolean isSuccess() { + return failureReason == null; + } + + public @NonNull GroupChangeFailureReason getFailureReason() { + if (isSuccess()) { + throw new UnsupportedOperationException(); + } + + return failureReason; + } + } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupErrors.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupErrors.java index ff3ff46d67..7eca06efe2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupErrors.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupErrors.java @@ -14,6 +14,8 @@ public final class GroupErrors { case NO_RIGHTS : return R.string.ManageGroupActivity_you_dont_have_the_rights_to_do_this; case NOT_CAPABLE : return R.string.ManageGroupActivity_not_capable; case NOT_A_MEMBER: return R.string.ManageGroupActivity_youre_not_a_member_of_the_group; + case BUSY : return R.string.ManageGroupActivity_failed_to_update_the_group_please_retry_later; + case NETWORK : return R.string.ManageGroupActivity_failed_to_update_the_group_due_to_a_network_error_please_retry_later; default : return R.string.ManageGroupActivity_failed_to_update_the_group; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java index 50eb607a92..d22a63e3dd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/LeaveGroupDialog.java @@ -12,14 +12,14 @@ import com.annimon.stream.Stream; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupManager; import org.thoughtcrime.securesms.groups.ui.chooseadmin.ChooseNewAdminActivity; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; +import org.thoughtcrime.securesms.util.views.SimpleProgressDialog; import java.io.IOException; import java.util.List; @@ -90,26 +90,32 @@ public final class LeaveGroupDialog { .setIconAttribute(R.attr.dialog_info_icon) .setCancelable(true) .setMessage(R.string.ConversationActivity_are_you_sure_you_want_to_leave_this_group) - .setPositiveButton(R.string.yes, (dialog, which) -> SimpleTask.run(activity.getLifecycle(), this::leaveGroup, this::handleLeaveGroupResult)) + .setPositiveButton(R.string.yes, (dialog, which) -> { + SimpleProgressDialog.DismissibleDialog progressDialog = SimpleProgressDialog.showDelayed(activity); + SimpleTask.run(activity.getLifecycle(), this::leaveGroup, result -> { + progressDialog.dismiss(); + handleLeaveGroupResult(result); + }); + }) .setNegativeButton(R.string.no, null) .show(); } - private boolean leaveGroup() { + private @NonNull GroupChangeResult leaveGroup() { try { GroupManager.leaveGroup(activity, groupId); - return true; - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { + return GroupChangeResult.SUCCESS; + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - return false; + return GroupChangeResult.failure(GroupChangeFailureReason.fromException(e)); } } - private void handleLeaveGroupResult(boolean success) { - if (success) { + private void handleLeaveGroupResult(@NonNull GroupChangeResult result) { + if (result.isSuccess()) { if (onSuccess != null) onSuccess.run(); } else { - Toast.makeText(activity, R.string.ConversationActivity_error_leaving_group, Toast.LENGTH_LONG).show(); + Toast.makeText(activity, GroupErrors.getUserDisplayMessage(result.getFailureReason()), Toast.LENGTH_LONG).show(); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addtogroup/AddToGroupRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addtogroup/AddToGroupRepository.java index a9e9852624..14daaacd71 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addtogroup/AddToGroupRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/addtogroup/AddToGroupRepository.java @@ -5,12 +5,9 @@ import android.content.Context; import androidx.annotation.NonNull; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.groups.MembershipNotSuitableForV2Exception; import org.thoughtcrime.securesms.groups.ui.GroupChangeErrorCallback; import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason; @@ -44,15 +41,9 @@ final class AddToGroupRepository { GroupManager.addMembers(context, pushGroupId, Collections.singletonList(recipientId)); success.run(); - } catch (GroupInsufficientRightsException | GroupNotAMemberException e) { + } catch (GroupChangeException | MembershipNotSuitableForV2Exception | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); - } catch (MembershipNotSuitableForV2Exception e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NOT_CAPABLE); + error.onError(GroupChangeFailureReason.fromException(e)); } }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminActivity.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminActivity.java index 1746c51984..61f161f828 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminActivity.java @@ -20,10 +20,10 @@ import org.thoughtcrime.securesms.PassphraseRequiredActivity; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.groups.BadGroupIdException; import org.thoughtcrime.securesms.groups.GroupId; +import org.thoughtcrime.securesms.groups.ui.GroupChangeResult; import org.thoughtcrime.securesms.groups.ui.GroupErrors; import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; import org.thoughtcrime.securesms.groups.ui.GroupMemberListView; -import org.thoughtcrime.securesms.groups.ui.chooseadmin.ChooseNewAdminRepository.UpdateResult; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; @@ -108,7 +108,7 @@ public final class ChooseNewAdminActivity extends PassphraseRequiredActivity { viewModel.getSelection().observe(this, selection -> done.setVisibility(selection.isEmpty() ? View.GONE : View.VISIBLE)); } - private void handleUpdateAndLeaveResult(@NonNull UpdateResult updateResult) { + private void handleUpdateAndLeaveResult(@NonNull GroupChangeResult updateResult) { if (updateResult.isSuccess()) { String title = Recipient.externalGroup(this, groupId).getDisplayName(this); Toast.makeText(this, getString(R.string.ChooseNewAdminActivity_you_left, title), Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminRepository.java index 3ac88b92bb..4aa1659042 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminRepository.java @@ -3,60 +3,32 @@ package org.thoughtcrime.securesms.groups.ui.chooseadmin; import android.app.Application; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import androidx.core.util.Consumer; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason; +import org.thoughtcrime.securesms.groups.ui.GroupChangeResult; import org.thoughtcrime.securesms.recipients.RecipientId; import java.io.IOException; import java.util.List; public final class ChooseNewAdminRepository { - private Application context; + private final Application context; ChooseNewAdminRepository(@NonNull Application context) { this.context = context; } @WorkerThread - @NonNull UpdateResult updateAdminsAndLeave(@NonNull GroupId.V2 groupId, @NonNull List newAdminIds) { + @NonNull GroupChangeResult updateAdminsAndLeave(@NonNull GroupId.V2 groupId, @NonNull List newAdminIds) { try { GroupManager.addMemberAdminsAndLeaveGroup(context, groupId, newAdminIds); - return new UpdateResult(); - } catch (GroupInsufficientRightsException e) { - return new UpdateResult(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupNotAMemberException e) { - return new UpdateResult(GroupChangeFailureReason.NOT_A_MEMBER); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - return new UpdateResult(GroupChangeFailureReason.OTHER); - } - } - - static final class UpdateResult { - final @Nullable GroupChangeFailureReason failureReason; - - UpdateResult() { - this(null); - } - - UpdateResult(@Nullable GroupChangeFailureReason failureReason) { - this.failureReason = failureReason; - } - - boolean isSuccess() { - return failureReason == null; - } - - @Nullable GroupChangeFailureReason getFailureReason() { - return failureReason; + return GroupChangeResult.SUCCESS; + } catch (GroupChangeException | IOException e) { + return GroupChangeResult.failure(GroupChangeFailureReason.fromException(e)); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminViewModel.java index e365c20657..21ddda7a97 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/chooseadmin/ChooseNewAdminViewModel.java @@ -1,11 +1,9 @@ package org.thoughtcrime.securesms.groups.ui.chooseadmin; import androidx.annotation.NonNull; -import androidx.annotation.StringRes; import androidx.core.util.Consumer; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; @@ -14,13 +12,10 @@ import com.annimon.stream.Stream; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.LiveGroup; -import org.thoughtcrime.securesms.groups.ui.GroupErrors; +import org.thoughtcrime.securesms.groups.ui.GroupChangeResult; import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; -import org.thoughtcrime.securesms.groups.ui.chooseadmin.ChooseNewAdminRepository.UpdateResult; -import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; -import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import java.util.Collections; import java.util.List; @@ -53,7 +48,7 @@ final class ChooseNewAdminViewModel extends ViewModel { this.selection.setValue(selection); } - void updateAdminsAndLeave(@NonNull Consumer consumer) { + void updateAdminsAndLeave(@NonNull Consumer consumer) { //noinspection ConstantConditions List recipientIds = Stream.of(selection.getValue()).map(entry -> entry.getMember().getId()).toList(); SimpleTask.run(() -> repository.updateAdminsAndLeave(groupId, recipientIds), consumer::accept); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/CreateGroupActivity.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/CreateGroupActivity.java index 9c9bc9d1d8..0ebb3c8146 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/CreateGroupActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/CreateGroupActivity.java @@ -8,7 +8,6 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import com.annimon.stream.Stream; @@ -24,24 +23,14 @@ import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.FeatureFlags; -import org.thoughtcrime.securesms.util.ProfileUtil; import org.thoughtcrime.securesms.util.Stopwatch; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.concurrent.SimpleTask; import org.thoughtcrime.securesms.util.views.SimpleProgressDialog; import org.whispersystems.libsignal.util.guava.Optional; -import org.whispersystems.signalservice.api.profiles.ProfileAndCredential; -import org.whispersystems.signalservice.api.profiles.SignalServiceProfile; -import org.whispersystems.signalservice.internal.util.concurrent.ListenableFuture; import java.io.IOException; import java.util.List; -import java.util.Locale; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicReference; public class CreateGroupActivity extends ContactSelectionActivity { @@ -133,15 +122,8 @@ public class CreateGroupActivity extends ContactSelectionActivity { } private void handleNextPressed() { - Stopwatch stopwatch = new Stopwatch("Recipient Refresh"); - AtomicReference progressDialog = new AtomicReference<>(); - - Runnable showDialogRunnable = () -> { - Log.i(TAG, "Taking some time. Showing a progress dialog."); - progressDialog.set(SimpleProgressDialog.show(this)); - }; - - next.postDelayed(showDialogRunnable, 300); + Stopwatch stopwatch = new Stopwatch("Recipient Refresh"); + SimpleProgressDialog.DismissibleDialog dismissibleDialog = SimpleProgressDialog.showDelayed(this); SimpleTask.run(getLifecycle(), () -> { RecipientId[] ids = Stream.of(contactsFragment.getSelectedContacts()) @@ -182,11 +164,8 @@ public class CreateGroupActivity extends ContactSelectionActivity { return ids; }, ids -> { - if (progressDialog.get() != null) { - progressDialog.get().dismiss(); - } + dismissibleDialog.dismiss(); - next.removeCallbacks(showDialogRunnable); stopwatch.stop(TAG); startActivityForResult(AddGroupDetailsActivity.newIntent(this, ids), REQUEST_CODE_ADD_DETAILS); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsRepository.java index 5272fd6441..4409ea72ac 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsRepository.java @@ -9,7 +9,7 @@ import androidx.core.util.Consumer; import com.annimon.stream.Stream; import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupManager; import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; import org.thoughtcrime.securesms.recipients.Recipient; @@ -57,7 +57,7 @@ final class AddGroupDetailsRepository { resultConsumer.accept(GroupCreateResult.success(result)); } catch (GroupChangeBusyException e) { resultConsumer.accept(GroupCreateResult.error(GroupCreateResult.Error.Type.ERROR_BUSY)); - } catch (GroupChangeFailedException e) { + } catch (GroupChangeException e) { resultConsumer.accept(GroupCreateResult.error(GroupCreateResult.Error.Type.ERROR_FAILED)); } catch (IOException e) { resultConsumer.accept(GroupCreateResult.error(GroupCreateResult.Error.Type.ERROR_IO)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupRepository.java index caa52d1959..8f6f74ffcc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupRepository.java @@ -14,12 +14,9 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.groups.GroupAccessControl; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.groups.GroupProtoUtil; import org.thoughtcrime.securesms.groups.MembershipNotSuitableForV2Exception; import org.thoughtcrime.securesms.groups.ui.AddMembersResultCallback; @@ -89,15 +86,9 @@ final class ManageGroupRepository { SignalExecutors.UNBOUNDED.execute(() -> { try { GroupManager.updateGroupTimer(context, groupId.requirePush(), newExpirationTime); - } catch (GroupInsufficientRightsException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupNotAMemberException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NOT_A_MEMBER); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); } }); } @@ -106,12 +97,9 @@ final class ManageGroupRepository { SignalExecutors.UNBOUNDED.execute(() -> { try { GroupManager.applyMembershipAdditionRightsChange(context, groupId.requireV2(), newRights); - } catch (GroupInsufficientRightsException | GroupNotAMemberException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); } }); } @@ -120,12 +108,9 @@ final class ManageGroupRepository { SignalExecutors.UNBOUNDED.execute(() -> { try { GroupManager.applyAttributesRightsChange(context, groupId.requireV2(), newRights); - } catch (GroupInsufficientRightsException | GroupNotAMemberException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); } }); } @@ -148,26 +133,21 @@ final class ManageGroupRepository { try { GroupManager.GroupActionResult groupActionResult = GroupManager.addMembers(context, groupId.requirePush(), selected); addMembersResultCallback.onMembersAdded(groupActionResult.getAddedMemberCount(), groupActionResult.getInvitedMembers()); - } catch (GroupInsufficientRightsException | GroupNotAMemberException e) { + } catch (GroupChangeException | MembershipNotSuitableForV2Exception | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); - } catch (MembershipNotSuitableForV2Exception e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NOT_CAPABLE); + error.onError(GroupChangeFailureReason.fromException(e)); } }); } - void blockAndLeaveGroup(@NonNull GroupChangeErrorCallback error) { + void blockAndLeaveGroup(@NonNull GroupChangeErrorCallback error, @NonNull Runnable onSuccess) { SignalExecutors.UNBOUNDED.execute(() -> { try { RecipientUtil.block(context, Recipient.externalGroup(context, groupId)); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { + onSuccess.run(); + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); } }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupViewModel.java index 58cd6096f6..c0e1b0aade 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupViewModel.java @@ -40,6 +40,7 @@ import org.thoughtcrime.securesms.util.ExpirationUtil; import org.thoughtcrime.securesms.util.SingleLiveEvent; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; +import org.thoughtcrime.securesms.util.views.SimpleProgressDialog; import java.util.ArrayList; import java.util.List; @@ -213,7 +214,7 @@ public class ManageGroupViewModel extends ViewModel { manageGroupRepository.getRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity, activity.getLifecycle(), recipient, - () -> manageGroupRepository.blockAndLeaveGroup(this::showErrorToast))); + this::onBlockAndLeaveConfirmed)); } void unblock(@NonNull FragmentActivity activity) { @@ -237,6 +238,16 @@ public class ManageGroupViewModel extends ViewModel { memberListCollapseState.setValue(CollapseState.OPEN); } + private void onBlockAndLeaveConfirmed() { + SimpleProgressDialog.DismissibleDialog dismissibleDialog = SimpleProgressDialog.showDelayed(context); + + manageGroupRepository.blockAndLeaveGroup(e -> { + dismissibleDialog.dismiss(); + showErrorToast(e); + }, + dismissibleDialog::dismiss); + } + private static @NonNull List filterMemberList(@NonNull List members, @NonNull CollapseState collapseState) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/pendingmemberinvites/PendingMemberRepository.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/pendingmemberinvites/PendingMemberRepository.java index 54755b3510..1b8f048953 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/pendingmemberinvites/PendingMemberRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/pendingmemberinvites/PendingMemberRepository.java @@ -16,12 +16,9 @@ import org.signal.zkgroup.groups.UuidCiphertext; import org.signal.zkgroup.util.UUIDUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.groups.GroupProtoUtil; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.recipients.Recipient; @@ -105,7 +102,7 @@ final class PendingMemberRepository { try { GroupManager.cancelInvites(context, groupId, uuidCipherTexts); return true; - } catch (GroupChangeFailedException | GroupInsufficientRightsException | IOException | GroupNotAMemberException | GroupChangeBusyException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); return false; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java index 0f01c5d987..dcc400f683 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestRepository.java @@ -12,11 +12,8 @@ import org.thoughtcrime.securesms.database.MessagingDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase; 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.GroupInsufficientRightsException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.groups.ui.GroupChangeErrorCallback; import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason; import org.thoughtcrime.securesms.jobs.MultiDeviceMessageRequestResponseJob; @@ -101,12 +98,9 @@ final class MessageRequestRepository { recipientDatabase.setProfileSharing(liveRecipient.getId(), true); onMessageRequestAccepted.run(); - } catch (GroupInsufficientRightsException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupChangeBusyException | GroupChangeFailedException | GroupNotAMemberException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); } } else { RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); @@ -139,9 +133,9 @@ final class MessageRequestRepository { if (resolved.isGroup() && resolved.requireGroupId().isPush()) { try { GroupManager.leaveGroupFromBlockOrMessageRequest(context, resolved.requireGroupId().requirePush()); - } catch (GroupChangeBusyException | GroupChangeFailedException | IOException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); return; } } @@ -165,8 +159,9 @@ final class MessageRequestRepository { Recipient recipient = liveRecipient.resolve(); try { RecipientUtil.block(context, recipient); - } catch (GroupChangeBusyException | GroupChangeFailedException | IOException e) { - error.onError(GroupChangeFailureReason.OTHER); + } catch (GroupChangeException | IOException e) { + Log.w(TAG, e); + error.onError(GroupChangeFailureReason.fromException(e)); return; } liveRecipient.refresh(); @@ -188,8 +183,9 @@ final class MessageRequestRepository { Recipient recipient = liveRecipient.resolve(); try{ RecipientUtil.block(context, recipient); - } catch (GroupChangeBusyException | GroupChangeFailedException | IOException e) { - error.onError(GroupChangeFailureReason.OTHER); + } catch (GroupChangeException | IOException e) { + Log.w(TAG, e); + error.onError(GroupChangeFailureReason.fromException(e)); return; } liveRecipient.refresh(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditPushGroupProfileRepository.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditPushGroupProfileRepository.java index 30f1817b6f..e6c9e738e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditPushGroupProfileRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditPushGroupProfileRepository.java @@ -8,12 +8,9 @@ import androidx.annotation.WorkerThread; import androidx.core.util.Consumer; import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.profiles.AvatarHelper; import org.thoughtcrime.securesms.profiles.ProfileName; @@ -83,7 +80,7 @@ class EditPushGroupProfileRepository implements EditProfileRepository { GroupManager.updateGroupDetails(context, groupId, avatar, avatarChanged, displayName, displayNameChanged); return UploadResult.SUCCESS; - } catch (GroupChangeFailedException | GroupInsufficientRightsException | IOException | GroupNotAMemberException | GroupChangeBusyException e) { + } catch (GroupChangeException | IOException e) { return UploadResult.ERROR_IO; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index 7fafc1b8b4..41095f3fd0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -14,6 +14,7 @@ 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.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupChangeFailedException; import org.thoughtcrime.securesms.groups.GroupManager; import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob; @@ -77,7 +78,7 @@ public class RecipientUtil { try { block(context, recipient); - } catch (GroupChangeBusyException | IOException | GroupChangeFailedException e) { + } catch (GroupChangeException | IOException e) { throw new AssertionError(e); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java index f0e180a555..b5ff52bf7e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientDialogRepository.java @@ -10,12 +10,9 @@ import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.IdentityDatabase; -import org.thoughtcrime.securesms.groups.GroupChangeBusyException; -import org.thoughtcrime.securesms.groups.GroupChangeFailedException; +import org.thoughtcrime.securesms.groups.GroupChangeException; import org.thoughtcrime.securesms.groups.GroupId; -import org.thoughtcrime.securesms.groups.GroupInsufficientRightsException; import org.thoughtcrime.securesms.groups.GroupManager; -import org.thoughtcrime.securesms.groups.GroupNotAMemberException; import org.thoughtcrime.securesms.groups.ui.GroupChangeErrorCallback; import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason; import org.thoughtcrime.securesms.logging.Log; @@ -89,12 +86,9 @@ final class RecipientDialogRepository { try { GroupManager.ejectFromGroup(context, Objects.requireNonNull(groupId).requireV2(), Recipient.resolved(recipientId)); return true; - } catch (GroupInsufficientRightsException | GroupNotAMemberException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); } return false; }, @@ -107,12 +101,9 @@ final class RecipientDialogRepository { try { GroupManager.setMemberAdmin(context, Objects.requireNonNull(groupId).requireV2(), recipientId, admin); return true; - } catch (GroupInsufficientRightsException | GroupNotAMemberException e) { + } catch (GroupChangeException | IOException e) { Log.w(TAG, e); - error.onError(GroupChangeFailureReason.NO_RIGHTS); - } catch (GroupChangeFailedException | GroupChangeBusyException | IOException e) { - Log.w(TAG, e); - error.onError(GroupChangeFailureReason.OTHER); + error.onError(GroupChangeFailureReason.fromException(e)); } return false; }, diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/views/SimpleProgressDialog.java b/app/src/main/java/org/thoughtcrime/securesms/util/views/SimpleProgressDialog.java index 9c334fabff..7ec5bdace9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/views/SimpleProgressDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/views/SimpleProgressDialog.java @@ -2,18 +2,27 @@ package org.thoughtcrime.securesms.util.views; import android.content.Context; +import androidx.annotation.AnyThread; +import androidx.annotation.MainThread; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.logging.Log; +import org.thoughtcrime.securesms.util.Util; + +import java.util.concurrent.atomic.AtomicReference; /** * Helper class to show a fullscreen blocking indeterminate progress dialog. */ public final class SimpleProgressDialog { + private static final String TAG = Log.tag(SimpleProgressDialog.class); + private SimpleProgressDialog() {} + @MainThread public static @NonNull AlertDialog show(@NonNull Context context) { AlertDialog dialog = new AlertDialog.Builder(context) .setView(R.layout.progress_dialog) @@ -25,4 +34,44 @@ public final class SimpleProgressDialog { return dialog; } + + @AnyThread + public static @NonNull DismissibleDialog showDelayed(@NonNull Context context) { + return showDelayed(context, 300); + } + + /** + * Shows the dialog after {@param delayMs} ms. + *

+ * To dismiss, call {@link DismissibleDialog#dismiss()} on the result. If dismiss is called before + * the delay has elapsed, the dialog will not show at all. + *

+ * Dismiss can be called on any thread. + */ + @AnyThread + public static @NonNull DismissibleDialog showDelayed(@NonNull Context context, int delayMs) { + AtomicReference dialogAtomicReference = new AtomicReference<>(); + + Runnable showRunnable = () -> { + Log.i(TAG, "Taking some time. Showing a progress dialog."); + dialogAtomicReference.set(show(context)); + }; + + Util.runOnMainDelayed(showRunnable, delayMs); + + return () -> { + Util.cancelRunnableOnMain(showRunnable); + Util.runOnMain(() -> { + AlertDialog alertDialog = dialogAtomicReference.getAndSet(null); + if (alertDialog != null) { + alertDialog.dismiss(); + } + }); + }; + } + + public interface DismissibleDialog { + @AnyThread + void dismiss(); + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fe6850eeaa..3a256b9a92 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -234,7 +234,6 @@ Insecure MMS Signal Let\'s switch to Signal %1$s - Error leaving group Please choose a contact Unblock this contact? Unblock this group? @@ -554,6 +553,8 @@ Someone you added does not support new groups and needs to update Signal Failed to update the group You\'re not a member of the group + Failed to update the group please retry later + Failed to update the group due to a network error, please retry later Edit name and picture