mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 00:29:11 +01:00
Add support for Group V2 description field.
This commit is contained in:
committed by
Greyson Parrelli
parent
b3aec58e69
commit
8c9df8d3be
@@ -78,17 +78,34 @@ class EditGroupProfileRepository implements EditProfileRepository {
|
||||
}, nameConsumer::accept);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCurrentDescription(@NonNull Consumer<String> descriptionConsumer) {
|
||||
SimpleTask.run(() -> {
|
||||
RecipientId recipientId = getRecipientId();
|
||||
|
||||
return DatabaseFactory.getGroupDatabase(context)
|
||||
.getGroup(recipientId)
|
||||
.transform(groupRecord -> {
|
||||
String description = groupRecord.getDescription();
|
||||
return description == null ? "" : description;
|
||||
})
|
||||
.or("");
|
||||
}, descriptionConsumer::accept);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadProfile(@NonNull ProfileName profileName,
|
||||
@NonNull String displayName,
|
||||
boolean displayNameChanged,
|
||||
@NonNull String description,
|
||||
boolean descriptionChanged,
|
||||
@Nullable byte[] avatar,
|
||||
boolean avatarChanged,
|
||||
@NonNull Consumer<UploadResult> uploadResultConsumer)
|
||||
{
|
||||
SimpleTask.run(() -> {
|
||||
try {
|
||||
GroupManager.updateGroupDetails(context, groupId, avatar, avatarChanged, displayName, displayNameChanged);
|
||||
GroupManager.updateGroupDetails(context, groupId, avatar, avatarChanged, displayName, displayNameChanged, description, descriptionChanged);
|
||||
|
||||
return UploadResult.SUCCESS;
|
||||
} catch (GroupChangeException | IOException e) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
@@ -35,22 +35,20 @@ import org.thoughtcrime.securesms.mediasend.AvatarSelectionActivity;
|
||||
import org.thoughtcrime.securesms.mediasend.AvatarSelectionBottomSheetDialogFragment;
|
||||
import org.thoughtcrime.securesms.mediasend.Media;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.profiles.manage.EditProfileNameFragment;
|
||||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||
import org.thoughtcrime.securesms.registration.RegistrationUtil;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.StringUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
import org.thoughtcrime.securesms.util.views.LearnMoreTextView;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static org.thoughtcrime.securesms.groups.v2.GroupDescriptionUtil.MAX_DESCRIPTION_LENGTH;
|
||||
import static org.thoughtcrime.securesms.profiles.edit.EditProfileActivity.EXCLUDE_SYSTEM;
|
||||
import static org.thoughtcrime.securesms.profiles.edit.EditProfileActivity.GROUP_ID;
|
||||
import static org.thoughtcrime.securesms.profiles.edit.EditProfileActivity.NEXT_BUTTON_TEXT;
|
||||
@@ -61,6 +59,8 @@ public class EditProfileFragment extends LoggingFragment {
|
||||
|
||||
private static final String TAG = Log.tag(EditProfileFragment.class);
|
||||
private static final short REQUEST_CODE_SELECT_AVATAR = 31726;
|
||||
private static final int MAX_DESCRIPTION_GLYPHS = 480;
|
||||
private static final int MAX_DESCRIPTION_BYTES = 8192;
|
||||
|
||||
private Toolbar toolbar;
|
||||
private View title;
|
||||
@@ -97,8 +97,8 @@ public class EditProfileFragment extends LoggingFragment {
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
GroupId groupId = GroupId.parseNullableOrThrow(requireArguments().getString(GROUP_ID, null));
|
||||
|
||||
initializeResources(view, groupId);
|
||||
initializeViewModel(requireArguments().getBoolean(EXCLUDE_SYSTEM, false), groupId, savedInstanceState != null);
|
||||
initializeResources(view, groupId);
|
||||
initializeProfileAvatar();
|
||||
initializeProfileName();
|
||||
}
|
||||
@@ -183,9 +183,25 @@ public class EditProfileFragment extends LoggingFragment {
|
||||
givenName.requestFocus();
|
||||
toolbar.setTitle(R.string.EditProfileFragment__edit_group_name_and_photo);
|
||||
preview.setVisibility(View.GONE);
|
||||
familyName.setVisibility(View.GONE);
|
||||
familyName.setEnabled(false);
|
||||
view.findViewById(R.id.description_text).setVisibility(View.GONE);
|
||||
|
||||
if (FeatureFlags.groupsV2Description()) {
|
||||
EditTextUtil.addGraphemeClusterLimitFilter(familyName, MAX_DESCRIPTION_GLYPHS);
|
||||
familyName.addTextChangedListener(new AfterTextChanged(s -> {
|
||||
EditProfileNameFragment.trimFieldToMaxByteLength(s, MAX_DESCRIPTION_BYTES);
|
||||
viewModel.setFamilyName(s.toString());
|
||||
}));
|
||||
familyName.setHint(R.string.EditProfileFragment__group_description);
|
||||
familyName.setSingleLine(false);
|
||||
familyName.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
|
||||
|
||||
LearnMoreTextView descriptionText = view.findViewById(R.id.description_text);
|
||||
descriptionText.setLearnMoreVisible(false);
|
||||
descriptionText.setText(R.string.CreateProfileActivity_group_descriptions_will_be_visible_to_members_of_this_group_and_people_who_have_been_invited);
|
||||
} else {
|
||||
familyName.setVisibility(View.GONE);
|
||||
familyName.setEnabled(false);
|
||||
view.findViewById(R.id.description_text).setVisibility(View.GONE);
|
||||
}
|
||||
view.<ImageView>findViewById(R.id.avatar_placeholder).setImageResource(R.drawable.ic_group_outline_40);
|
||||
} else {
|
||||
EditTextUtil.addGraphemeClusterLimitFilter(givenName, EditProfileNameFragment.NAME_MAX_GLYPHS);
|
||||
|
||||
@@ -17,9 +17,13 @@ interface EditProfileRepository {
|
||||
|
||||
void getCurrentName(@NonNull Consumer<String> nameConsumer);
|
||||
|
||||
void getCurrentDescription(@NonNull Consumer<String> descriptionConsumer);
|
||||
|
||||
void uploadProfile(@NonNull ProfileName profileName,
|
||||
@NonNull String displayName,
|
||||
boolean displayNameChanged,
|
||||
@NonNull String description,
|
||||
boolean descriptionChanged,
|
||||
@Nullable byte[] avatar,
|
||||
boolean avatarChanged,
|
||||
@NonNull Consumer<UploadResult> uploadResultConsumer);
|
||||
|
||||
@@ -13,24 +13,24 @@ import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.util.StringUtil;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
class EditProfileViewModel extends ViewModel {
|
||||
|
||||
private final MutableLiveData<String> givenName = new MutableLiveData<>();
|
||||
private final MutableLiveData<String> familyName = new MutableLiveData<>();
|
||||
private final LiveData<String> trimmedGivenName = Transformations.map(givenName, StringUtil::trimToVisualBounds);
|
||||
private final LiveData<String> trimmedFamilyName = Transformations.map(familyName, StringUtil::trimToVisualBounds);
|
||||
private final LiveData<ProfileName> internalProfileName = LiveDataUtil.combineLatest(trimmedGivenName, trimmedFamilyName, ProfileName::fromParts);
|
||||
private final MutableLiveData<byte[]> internalAvatar = new MutableLiveData<>();
|
||||
private final MutableLiveData<byte[]> originalAvatar = new MutableLiveData<>();
|
||||
private final MutableLiveData<String> originalDisplayName = new MutableLiveData<>();
|
||||
private final LiveData<Boolean> isFormValid;
|
||||
private final EditProfileRepository repository;
|
||||
private final GroupId groupId;
|
||||
private final MutableLiveData<String> givenName = new MutableLiveData<>();
|
||||
private final MutableLiveData<String> familyName = new MutableLiveData<>();
|
||||
private final LiveData<String> trimmedGivenName = Transformations.map(givenName, StringUtil::trimToVisualBounds);
|
||||
private final LiveData<String> trimmedFamilyName = Transformations.map(familyName, StringUtil::trimToVisualBounds);
|
||||
private final LiveData<ProfileName> internalProfileName = LiveDataUtil.combineLatest(trimmedGivenName, trimmedFamilyName, ProfileName::fromParts);
|
||||
private final MutableLiveData<byte[]> internalAvatar = new MutableLiveData<>();
|
||||
private final MutableLiveData<byte[]> originalAvatar = new MutableLiveData<>();
|
||||
private final MutableLiveData<String> originalDisplayName = new MutableLiveData<>();
|
||||
private final LiveData<Boolean> isFormValid;
|
||||
private final EditProfileRepository repository;
|
||||
private final GroupId groupId;
|
||||
private String originalDescription;
|
||||
|
||||
private EditProfileViewModel(@NonNull EditProfileRepository repository, boolean hasInstanceState, @Nullable GroupId groupId) {
|
||||
this.repository = repository;
|
||||
@@ -42,6 +42,10 @@ class EditProfileViewModel extends ViewModel {
|
||||
if (groupId != null) {
|
||||
repository.getCurrentDisplayName(originalDisplayName::setValue);
|
||||
repository.getCurrentName(givenName::setValue);
|
||||
repository.getCurrentDescription(d -> {
|
||||
originalDescription = d;
|
||||
familyName.setValue(d);
|
||||
});
|
||||
} else {
|
||||
repository.getCurrentProfileName(name -> {
|
||||
givenName.setValue(name.getGivenName());
|
||||
@@ -103,6 +107,7 @@ class EditProfileViewModel extends ViewModel {
|
||||
public void submitProfile(Consumer<EditProfileRepository.UploadResult> uploadResultConsumer) {
|
||||
ProfileName profileName = isGroup() ? ProfileName.EMPTY : internalProfileName.getValue();
|
||||
String displayName = isGroup() ? givenName.getValue() : "";
|
||||
String description = isGroup() ? familyName.getValue() : "";
|
||||
|
||||
if (profileName == null || displayName == null) {
|
||||
return;
|
||||
@@ -111,10 +116,13 @@ class EditProfileViewModel extends ViewModel {
|
||||
byte[] oldAvatar = originalAvatar.getValue();
|
||||
byte[] newAvatar = internalAvatar.getValue();
|
||||
String oldDisplayName = isGroup() ? originalDisplayName.getValue() : null;
|
||||
String oldDescription = isGroup() ? originalDescription : null;
|
||||
|
||||
repository.uploadProfile(profileName,
|
||||
displayName,
|
||||
!Objects.equals(StringUtil.stripBidiProtection(oldDisplayName), displayName),
|
||||
description,
|
||||
!Objects.equals(StringUtil.stripBidiProtection(oldDescription), description),
|
||||
newAvatar,
|
||||
!Arrays.equals(oldAvatar, newAvatar),
|
||||
uploadResultConsumer);
|
||||
|
||||
@@ -107,10 +107,16 @@ public class EditSelfProfileRepository implements EditProfileRepository {
|
||||
nameConsumer.accept("");
|
||||
}
|
||||
|
||||
@Override public void getCurrentDescription(@NonNull Consumer<String> descriptionConsumer) {
|
||||
descriptionConsumer.accept("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadProfile(@NonNull ProfileName profileName,
|
||||
@NonNull String displayName,
|
||||
boolean displayNameChanged,
|
||||
@NonNull String description,
|
||||
boolean descriptionChanged,
|
||||
@Nullable byte[] avatar,
|
||||
boolean avatarChanged,
|
||||
@NonNull Consumer<UploadResult> uploadResultConsumer)
|
||||
|
||||
@@ -104,7 +104,11 @@ public class EditProfileNameFragment extends Fragment {
|
||||
}
|
||||
|
||||
public static void trimFieldToMaxByteLength(Editable s) {
|
||||
int trimmedLength = StringUtil.trimToFit(s.toString(), ProfileName.MAX_PART_LENGTH).length();
|
||||
trimFieldToMaxByteLength(s, ProfileName.MAX_PART_LENGTH);
|
||||
}
|
||||
|
||||
public static void trimFieldToMaxByteLength(Editable s, int length) {
|
||||
int trimmedLength = StringUtil.trimToFit(s.toString(), length).length();
|
||||
|
||||
if (s.length() > trimmedLength) {
|
||||
s.delete(trimmedLength, s.length());
|
||||
|
||||
Reference in New Issue
Block a user