Added progress feedback to leave and block group actions and additional group v2 error handling.
parent
9a566e5559
commit
a33771b15d
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<RecipientId> newAdminIds) {
|
||||
@NonNull GroupChangeResult updateAdminsAndLeave(@NonNull GroupId.V2 groupId, @NonNull List<RecipientId> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<UpdateResult> consumer) {
|
||||
void updateAdminsAndLeave(@NonNull Consumer<GroupChangeResult> consumer) {
|
||||
//noinspection ConstantConditions
|
||||
List<RecipientId> recipientIds = Stream.of(selection.getValue()).map(entry -> entry.getMember().getId()).toList();
|
||||
SimpleTask.run(() -> repository.updateAdminsAndLeave(groupId, recipientIds), consumer::accept);
|
||||
|
|
|
@ -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<AlertDialog> 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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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<GroupMemberEntry.FullMember> filterMemberList(@NonNull List<GroupMemberEntry.FullMember> members,
|
||||
@NonNull CollapseState collapseState)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* Dismiss can be called on any thread.
|
||||
*/
|
||||
@AnyThread
|
||||
public static @NonNull DismissibleDialog showDelayed(@NonNull Context context, int delayMs) {
|
||||
AtomicReference<AlertDialog> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -234,7 +234,6 @@
|
|||
<string name="ConversationActivity_transport_insecure_mms">Insecure MMS</string>
|
||||
<string name="ConversationActivity_transport_signal">Signal</string>
|
||||
<string name="ConversationActivity_lets_switch_to_signal">Let\'s switch to Signal %1$s</string>
|
||||
<string name="ConversationActivity_error_leaving_group">Error leaving group</string>
|
||||
<string name="ConversationActivity_specify_recipient">Please choose a contact</string>
|
||||
<string name="ConversationActivity_unblock_this_contact_question">Unblock this contact?</string>
|
||||
<string name="ConversationActivity_unblock_this_group_question">Unblock this group?</string>
|
||||
|
@ -554,6 +553,8 @@
|
|||
<string name="ManageGroupActivity_not_capable">Someone you added does not support new groups and needs to update Signal</string>
|
||||
<string name="ManageGroupActivity_failed_to_update_the_group">Failed to update the group</string>
|
||||
<string name="ManageGroupActivity_youre_not_a_member_of_the_group">You\'re not a member of the group</string>
|
||||
<string name="ManageGroupActivity_failed_to_update_the_group_please_retry_later">Failed to update the group please retry later</string>
|
||||
<string name="ManageGroupActivity_failed_to_update_the_group_due_to_a_network_error_please_retry_later">Failed to update the group due to a network error, please retry later</string>
|
||||
|
||||
<string name="ManageGroupActivity_edit_name_and_picture">Edit name and picture</string>
|
||||
|
||||
|
|
Loading…
Reference in New Issue