Add support for announcement groups.

This commit is contained in:
Greyson Parrelli
2021-07-23 16:22:08 -04:00
parent 1a56924a56
commit 25234496bf
74 changed files with 1109 additions and 208 deletions

View File

@@ -56,6 +56,7 @@ import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.LifecycleDisposable;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
@@ -69,6 +70,9 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;
/**
* Entry point for sharing content into the app.
*
@@ -104,6 +108,8 @@ public class ShareActivity extends PassphraseRequiredActivity
private ShareIntents.Args args;
private ShareViewModel viewModel;
private final LifecycleDisposable disposables = new LifecycleDisposable();
@Override
protected void onPreCreate() {
dynamicTheme.onCreate(this);
@@ -114,6 +120,8 @@ public class ShareActivity extends PassphraseRequiredActivity
protected void onCreate(Bundle icicle, boolean ready) {
setContentView(R.layout.share_activity);
disposables.bindTo(getLifecycle());
initializeArgs();
initializeViewModel();
initializeMedia();
@@ -176,12 +184,28 @@ public class ShareActivity extends PassphraseRequiredActivity
}
@Override
public boolean onBeforeContactSelected(Optional<RecipientId> recipientId, String number) {
public void onBeforeContactSelected(Optional<RecipientId> recipientId, String number, java.util.function.Consumer<Boolean> callback) {
if (disallowMultiShare) {
Toast.makeText(this, R.string.ShareActivity__sharing_to_multiple_chats_is, Toast.LENGTH_LONG).show();
return false;
callback.accept(false);
} else {
return viewModel.onContactSelected(new ShareContact(recipientId, number));
disposables.add(viewModel.onContactSelected(new ShareContact(recipientId, number))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
switch (result) {
case TRUE:
callback.accept(true);
break;
case FALSE:
callback.accept(false);
break;
case FALSE_AND_SHOW_PERMISSION_TOAST:
Toast.makeText(this, R.string.ShareActivity_you_do_not_have_permission_to_send_to_this_group, Toast.LENGTH_SHORT).show();
callback.accept(false);
break;
}
}));
}
}

View File

@@ -14,6 +14,8 @@ import androidx.lifecycle.ViewModelProvider;
import com.annimon.stream.Stream;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.providers.BlobProvider;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -26,6 +28,8 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import io.reactivex.rxjava3.core.Single;
public class ShareViewModel extends ViewModel {
private static final String TAG = Log.tag(ShareViewModel.class);
@@ -61,14 +65,28 @@ public class ShareViewModel extends ViewModel {
return selectedContacts.getValue().size() > 1;
}
boolean onContactSelected(@NonNull ShareContact selectedContact) {
Set<ShareContact> contacts = new LinkedHashSet<>(selectedContacts.getValue());
if (contacts.add(selectedContact)) {
selectedContacts.setValue(contacts);
return true;
} else {
return false;
}
@NonNull Single<ContactSelectResult> onContactSelected(@NonNull ShareContact selectedContact) {
return Single.fromCallable(() -> {
if (selectedContact.getRecipientId().isPresent()) {
Recipient recipient = Recipient.resolved(selectedContact.getRecipientId().get());
if (recipient.isPushV2Group()) {
Optional<GroupDatabase.GroupRecord> record = DatabaseFactory.getGroupDatabase(context).getGroup(recipient.requireGroupId());
if (record.isPresent() && record.get().isAnnouncementGroup() && !record.get().isAdmin(Recipient.self())) {
return ContactSelectResult.FALSE_AND_SHOW_PERMISSION_TOAST;
}
}
}
Set<ShareContact> contacts = new LinkedHashSet<>(selectedContacts.getValue());
if (contacts.add(selectedContact)) {
selectedContacts.postValue(contacts);
return ContactSelectResult.TRUE;
} else {
return ContactSelectResult.FALSE;
}
});
}
void onContactDeselected(@NonNull ShareContact selectedContact) {
@@ -141,12 +159,8 @@ public class ShareViewModel extends ViewModel {
}
}
public static class Factory extends ViewModelProvider.NewInstanceFactory {
@Override
public @NonNull<T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//noinspection ConstantConditions
return modelClass.cast(new ShareViewModel());
}
enum ContactSelectResult {
TRUE, FALSE, FALSE_AND_SHOW_PERMISSION_TOAST
}
enum SmsShareRestriction {
@@ -154,4 +168,12 @@ public class ShareViewModel extends ViewModel {
DISALLOW_SMS_CONTACTS,
DISALLOW_MULTI_SHARE
}
public static class Factory extends ViewModelProvider.NewInstanceFactory {
@Override
public @NonNull<T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//noinspection ConstantConditions
return modelClass.cast(new ShareViewModel());
}
}
}