diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f4b586b994..b5d5ce3e91 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -421,9 +421,8 @@ android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/> + android:theme="@style/TextSecure.LightRegistrationTheme" + android:windowSoftInputMode="adjustResize" /> { - if (recipientClickListener != null) { + if (recipient.equals(Recipient.self())) { + this.itemView.setEnabled(false); + return; + } + + this.itemView.setEnabled(true); + this.itemView.setOnClickListener(v -> { + if (recipientClickListener != null && getAdapterPosition() != RecyclerView.NO_POSITION) { recipientClickListener.onClick(recipient); } - }; - this.avatar.setOnClickListener(onClickListener); - this.recipient.setOnClickListener(onClickListener); + }); } void bind(@NonNull GroupMemberEntry memberEntry) { @@ -151,8 +156,7 @@ final class GroupMemberListAdapter extends LifecycleRecyclerAdapter { busyProgress.setVisibility(busy ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java index cd2f62c2c3..0dd2ae2f7d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListView.java @@ -34,7 +34,10 @@ public final class GroupMemberListView extends RecyclerView { } private void initialize(@NonNull Context context, @Nullable AttributeSet attrs) { - setHasFixedSize(true); + if (maxHeight > 0) { + setHasFixedSize(true); + } + setLayoutManager(new LinearLayoutManager(context)); setAdapter(membersAdapter); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupFragment.java index 6cae0a0dc2..c60a5f2211 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/ManageGroupFragment.java @@ -10,14 +10,12 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import android.widget.CompoundButton; import android.widget.Switch; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.constraintlayout.widget.Group; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; @@ -31,6 +29,8 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.ThreadPhotoRailView; import org.thoughtcrime.securesms.contacts.ContactsCursorLoader; +import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto; +import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto; import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.ui.GroupMemberListView; import org.thoughtcrime.securesms.groups.ui.LeaveGroupDialog; @@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.mediaoverview.MediaOverviewActivity; import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.profiles.edit.EditProfileActivity; +import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment; import org.thoughtcrime.securesms.util.DateUtils; @@ -71,16 +72,28 @@ public class ManageGroupFragment extends Fragment { private View pendingMembersCard; private ManageGroupViewModel.CursorFactory cursorFactory; private View photoRailLabel; - private Button editGroupAccessValue; - private Button editGroupMembershipValue; - private Button disappearingMessages; - private Button blockGroup; - private Button leaveGroup; - private Button addMembers; + private View editGroupAccessRow; + private TextView editGroupAccessValue; + private View editGroupMembershipRow; + private TextView editGroupMembershipValue; + private View disappearingMessagesRow; + private TextView disappearingMessages; + private TextView blockGroup; + private TextView leaveGroup; + private TextView addMembers; private Switch muteNotificationsSwitch; + private View muteNotificationsRow; private TextView muteNotificationsUntilLabel; private TextView customNotificationsButton; - private Group customNotificationsControls; + private View customNotificationsRow; + private View toggleAllMembers; + + private final Recipient.FallbackPhotoProvider fallbackPhotoProvider = new Recipient.FallbackPhotoProvider() { + @Override + public @NonNull FallbackContactPhoto getPhotoForGroup() { + return new ResourceContactPhoto(R.drawable.ic_group_80); + } + }; static ManageGroupFragment newInstance(@NonNull String groupId) { ManageGroupFragment fragment = new ManageGroupFragment(); @@ -116,16 +129,21 @@ public class ManageGroupFragment extends Fragment { accessControlCard = view.findViewById(R.id.group_access_control_card); pendingMembersCard = view.findViewById(R.id.group_pending_card); photoRailLabel = view.findViewById(R.id.rail_label); + editGroupAccessRow = view.findViewById(R.id.edit_group_access_row); editGroupAccessValue = view.findViewById(R.id.edit_group_access_value); + editGroupMembershipRow = view.findViewById(R.id.edit_group_membership_row); editGroupMembershipValue = view.findViewById(R.id.edit_group_membership_value); + disappearingMessagesRow = view.findViewById(R.id.disappearing_messages_row); disappearingMessages = view.findViewById(R.id.disappearing_messages); blockGroup = view.findViewById(R.id.blockGroup); leaveGroup = view.findViewById(R.id.leaveGroup); addMembers = view.findViewById(R.id.add_members); muteNotificationsUntilLabel = view.findViewById(R.id.group_mute_notifications_until); muteNotificationsSwitch = view.findViewById(R.id.group_mute_notifications_switch); + muteNotificationsRow = view.findViewById(R.id.group_mute_notifications_row); customNotificationsButton = view.findViewById(R.id.group_custom_notifications_button); - customNotificationsControls = view.findViewById(R.id.group_custom_notifications_controls); + customNotificationsRow = view.findViewById(R.id.group_custom_notifications_row); + toggleAllMembers = view.findViewById(R.id.toggle_all_members); return view; } @@ -142,6 +160,15 @@ public class ManageGroupFragment extends Fragment { viewModel.getMembers().observe(getViewLifecycleOwner(), members -> groupMemberList.setMembers(members)); + viewModel.getCanCollapseMemberList().observe(getViewLifecycleOwner(), canCollapseMemberList -> { + if (canCollapseMemberList) { + toggleAllMembers.setVisibility(View.VISIBLE); + toggleAllMembers.setOnClickListener(v -> viewModel.revealCollapsedMembers()); + } else { + toggleAllMembers.setVisibility(View.GONE); + } + }); + viewModel.getPendingMemberCount().observe(getViewLifecycleOwner(), members -> { if (members > 0) { @@ -156,6 +183,8 @@ public class ManageGroupFragment extends Fragment { } }); + avatar.setFallbackPhotoProvider(fallbackPhotoProvider); + viewModel.getTitle().observe(getViewLifecycleOwner(), groupTitle::setText); viewModel.getMemberCountSummary().observe(getViewLifecycleOwner(), memberCountUnderAvatar::setText); viewModel.getFullMemberCountSummary().observe(getViewLifecycleOwner(), memberCountAboveList::setText); @@ -173,7 +202,6 @@ public class ManageGroupFragment extends Fragment { ViewCompat.getLayoutDirection(threadPhotoRailView) == ViewCompat.LAYOUT_DIRECTION_LTR), RETURN_FROM_MEDIA)); - accessControlCard.setVisibility(vs.getGroupRecipient().requireGroupId().isV2() ? View.VISIBLE : View.GONE); pendingMembersCard.setVisibility(vs.getGroupRecipient().requireGroupId().isV2() ? View.VISIBLE : View.GONE); }); @@ -185,7 +213,7 @@ public class ManageGroupFragment extends Fragment { viewModel.getDisappearingMessageTimer().observe(getViewLifecycleOwner(), string -> disappearingMessages.setText(string)); - disappearingMessages.setOnClickListener(v -> viewModel.handleExpirationSelection()); + disappearingMessagesRow.setOnClickListener(v -> viewModel.handleExpirationSelection()); blockGroup.setOnClickListener(v -> viewModel.blockAndLeave(requireActivity())); addMembers.setOnClickListener(v -> { @@ -197,7 +225,7 @@ public class ManageGroupFragment extends Fragment { viewModel.getMembershipRights().observe(getViewLifecycleOwner(), r -> { if (r != null) { editGroupMembershipValue.setText(r.getString()); - editGroupMembershipValue.setOnClickListener(v -> new GroupRightsDialog(context, GroupRightsDialog.Type.MEMBERSHIP, r, (from, to) -> viewModel.applyMembershipRightsChange(to)).show()); + editGroupMembershipRow.setOnClickListener(v -> new GroupRightsDialog(context, GroupRightsDialog.Type.MEMBERSHIP, r, (from, to) -> viewModel.applyMembershipRightsChange(to)).show()); } } ); @@ -205,13 +233,16 @@ public class ManageGroupFragment extends Fragment { viewModel.getEditGroupAttributesRights().observe(getViewLifecycleOwner(), r -> { if (r != null) { editGroupAccessValue.setText(r.getString()); - editGroupAccessValue.setOnClickListener(v -> new GroupRightsDialog(context, GroupRightsDialog.Type.ATTRIBUTES, r, (from, to) -> viewModel.applyAttributesRightsChange(to)).show()); + editGroupAccessRow.setOnClickListener(v -> new GroupRightsDialog(context, GroupRightsDialog.Type.ATTRIBUTES, r, (from, to) -> viewModel.applyAttributesRightsChange(to)).show()); } } ); viewModel.getIsAdmin().observe(getViewLifecycleOwner(), admin -> { + accessControlCard.setVisibility(admin ? View.VISIBLE : View.GONE); + editGroupMembershipRow.setEnabled(admin); editGroupMembershipValue.setEnabled(admin); + editGroupAccessRow.setEnabled(admin); editGroupAccessValue.setEnabled(admin); }); @@ -228,6 +259,12 @@ public class ManageGroupFragment extends Fragment { } }; + muteNotificationsRow.setOnClickListener(v -> { + if (muteNotificationsSwitch.isEnabled()) { + muteNotificationsSwitch.toggle(); + } + }); + viewModel.getMuteState().observe(getViewLifecycleOwner(), muteState -> { if (muteNotificationsSwitch.isChecked() != muteState.isMuted()) { muteNotificationsSwitch.setOnCheckedChangeListener(null); @@ -247,10 +284,10 @@ public class ManageGroupFragment extends Fragment { }); if (NotificationChannels.supported()) { - customNotificationsControls.setVisibility(View.VISIBLE); + customNotificationsRow.setVisibility(View.VISIBLE); - customNotificationsButton.setOnClickListener(v -> CustomNotificationsDialogFragment.create(groupId) - .show(requireFragmentManager(), "CUSTOM_NOTIFICATIONS")); + customNotificationsRow.setOnClickListener(v -> CustomNotificationsDialogFragment.create(groupId) + .show(requireFragmentManager(), "CUSTOM_NOTIFICATIONS")); //noinspection CodeBlock2Expr viewModel.hasCustomNotifications().observe(getViewLifecycleOwner(), hasCustomNotifications -> { @@ -258,7 +295,7 @@ public class ManageGroupFragment extends Fragment { : R.string.ManageGroupActivity_off); }); } else { - customNotificationsControls.setVisibility(View.GONE); + customNotificationsRow.setVisibility(View.GONE); } } @@ -308,7 +345,7 @@ public class ManageGroupFragment extends Fragment { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RETURN_FROM_MEDIA) { applyMediaCursorFactory(); - } else if (requestCode == PICK_CONTACT) { + } else if (requestCode == PICK_CONTACT && data != null) { List selected = data.getParcelableArrayListExtra(PushContactSelectionActivity.KEY_SELECTED_RECIPIENTS); viewModel.onAddMembers(selected); } 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 7bb87744d0..20b1ed88f9 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 @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.groups.ui.managegroup; import android.content.Context; -import android.content.Intent; import android.database.Cursor; import android.widget.Toast; @@ -15,11 +14,7 @@ import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import org.thoughtcrime.securesms.BlockUnblockDialog; -import org.thoughtcrime.securesms.ContactSelectionListFragment; import org.thoughtcrime.securesms.ExpirationDialog; -import org.thoughtcrime.securesms.GroupCreateActivity; -import org.thoughtcrime.securesms.PushContactSelectionActivity; -import org.thoughtcrime.securesms.contacts.ContactsCursorLoader; import org.thoughtcrime.securesms.database.MediaDatabase; import org.thoughtcrime.securesms.database.loaders.MediaLoader; import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader; @@ -30,13 +25,17 @@ import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.recipients.RecipientUtil; +import org.thoughtcrime.securesms.util.DefaultValueLiveData; import org.thoughtcrime.securesms.util.ExpirationUtil; import org.thoughtcrime.securesms.util.Util; +import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import java.util.List; public class ManageGroupViewModel extends ViewModel { + private static final int MAX_COLLAPSED_MEMBERS = 5; + private final Context context; private final ManageGroupRepository manageGroupRepository; private final LiveData title; @@ -54,6 +53,8 @@ public class ManageGroupViewModel extends ViewModel { private final MutableLiveData groupViewState = new MutableLiveData<>(null); private final LiveData muteState; private final LiveData hasCustomNotifications; + private final LiveData canCollapseMemberList; + private final DefaultValueLiveData memberListCollapseState = new DefaultValueLiveData<>(CollapseState.COLLAPSED); private ManageGroupViewModel(@NonNull Context context, @NonNull ManageGroupRepository manageGroupRepository) { this.context = context; @@ -65,7 +66,12 @@ public class ManageGroupViewModel extends ViewModel { this.title = liveGroup.getTitle(); this.isAdmin = liveGroup.isSelfAdmin(); - this.members = liveGroup.getFullMembers(); + this.canCollapseMemberList = LiveDataUtil.combineLatest(memberListCollapseState, + Transformations.map(liveGroup.getFullMembers(), m -> m.size() > MAX_COLLAPSED_MEMBERS), + (state, hasEnoughMembers) -> state != CollapseState.OPEN && hasEnoughMembers); + this.members = LiveDataUtil.combineLatest(liveGroup.getFullMembers(), + memberListCollapseState, + this::filterMemberList); this.pendingMemberCount = liveGroup.getPendingMemberCount(); this.memberCountSummary = liveGroup.getMembershipCountDescription(context.getResources()); this.fullMemberCountSummary = liveGroup.getFullMembershipCountDescription(context.getResources()); @@ -148,6 +154,10 @@ public class ManageGroupViewModel extends ViewModel { return hasCustomNotifications; } + public LiveData getCanCollapseMemberList() { + return canCollapseMemberList; + } + void handleExpirationSelection() { manageGroupRepository.getRecipient(groupRecipient -> ExpirationDialog.show(context, @@ -180,6 +190,20 @@ public class ManageGroupViewModel extends ViewModel { manageGroupRepository.setMuteUntil(0); } + void revealCollapsedMembers() { + memberListCollapseState.setValue(CollapseState.OPEN); + } + + private @NonNull List filterMemberList(@NonNull List members, + @NonNull CollapseState collapseState) + { + if (collapseState == CollapseState.COLLAPSED && members.size() > MAX_COLLAPSED_MEMBERS) { + return members.subList(0, MAX_COLLAPSED_MEMBERS); + } else { + return members; + } + } + @WorkerThread private void showErrorToast(@NonNull ManageGroupRepository.FailureReason e) { Util.runOnMain(() -> Toast.makeText(context, e.getToastMessage(), Toast.LENGTH_LONG).show()); @@ -230,6 +254,11 @@ public class ManageGroupViewModel extends ViewModel { } } + private enum CollapseState { + OPEN, + COLLAPSED + } + interface CursorFactory { Cursor create(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/ProfileName.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/ProfileName.java index 2a7526c683..d2816a0969 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/ProfileName.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/ProfileName.java @@ -9,16 +9,14 @@ import androidx.annotation.VisibleForTesting; import com.annimon.stream.Stream; +import org.thoughtcrime.securesms.util.StringUtil; import org.thoughtcrime.securesms.util.cjkv.CJKVUtil; import org.whispersystems.signalservice.api.crypto.ProfileCipher; -import java.nio.charset.StandardCharsets; - public final class ProfileName implements Parcelable { - public static final ProfileName EMPTY = new ProfileName("", ""); - - private static final int MAX_PART_LENGTH = (ProfileCipher.NAME_PADDED_LENGTH - 1) / 2; + public static final ProfileName EMPTY = new ProfileName("", ""); + public static final int MAX_PART_LENGTH = (ProfileCipher.NAME_PADDED_LENGTH - 1) / 2; private final String givenName; private final String familyName; @@ -94,31 +92,12 @@ public final class ProfileName implements Parcelable { givenName = givenName == null ? "" : givenName; familyName = familyName == null ? "" : familyName; - givenName = trimToFit(givenName .trim()); - familyName = trimToFit(familyName.trim()); + givenName = StringUtil.trimToFit(givenName.trim(), ProfileName.MAX_PART_LENGTH); + familyName = StringUtil.trimToFit(familyName.trim(), ProfileName.MAX_PART_LENGTH); return new ProfileName(givenName, familyName); } - /** - * Trims a name string to fit into the byte length requirement. - */ - public static @NonNull String trimToFit(@Nullable String name) { - if (name == null) return ""; - - // At least one byte per char, so shorten string to reduce loop - if (name.length() > ProfileName.MAX_PART_LENGTH) { - name = name.substring(0, ProfileName.MAX_PART_LENGTH); - } - - // Remove one char at a time until fits in byte allowance - while (name.getBytes(StandardCharsets.UTF_8).length > ProfileName.MAX_PART_LENGTH) { - name = name.substring(0, name.length() - 1); - } - - return name; - } - private static @NonNull String getJoinedName(@NonNull String givenName, @NonNull String familyName) { if (givenName.isEmpty() && familyName.isEmpty()) return ""; else if (givenName.isEmpty()) return familyName; diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java index c8963aaed8..ed9e320958 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java @@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.profiles.ProfileName; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.registration.RegistrationUtil; 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.whispersystems.libsignal.util.guava.Optional; @@ -66,6 +67,7 @@ public class EditProfileFragment extends Fragment { private static final String TAG = Log.tag(EditProfileFragment.class); private static final String AVATAR_STATE = "avatar"; private static final short REQUEST_CODE_SELECT_AVATAR = 31726; + private static final int MAX_GROUP_NAME_LENGTH = 32; private Toolbar toolbar; private View title; @@ -130,7 +132,9 @@ public class EditProfileFragment extends Fragment { initializeProfileName(); initializeUsername(); - requireActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); + if (groupId == null) { + requireActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); + } } @Override @@ -234,7 +238,7 @@ public class EditProfileFragment extends Fragment { .execute()); this.givenName .addTextChangedListener(new AfterTextChanged(s -> { - trimInPlace(s); + trimInPlace(s, isEditingGroup); viewModel.setGivenName(s.toString()); })); @@ -248,7 +252,7 @@ public class EditProfileFragment extends Fragment { view.findViewById(R.id.avatar_placeholder).setImageResource(R.drawable.ic_group_outline_40); } else { this.familyName.addTextChangedListener(new AfterTextChanged(s -> { - trimInPlace(s); + trimInPlace(s, false); viewModel.setFamilyName(s.toString()); })); } @@ -389,8 +393,10 @@ public class EditProfileFragment extends Fragment { animation.start(); } - private static void trimInPlace(Editable s) { - int trimmedLength = ProfileName.trimToFit(s.toString()).length(); + private static void trimInPlace(Editable s, boolean isGroup) { + int trimmedLength = isGroup ? StringUtil.trimToFit(s.toString(), MAX_GROUP_NAME_LENGTH).length() + : StringUtil.trimToFit(s.toString(), ProfileName.MAX_PART_LENGTH).length(); + if (s.length() > trimmedLength) { s.delete(trimmedLength, s.length()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/StringUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/StringUtil.java new file mode 100644 index 0000000000..b12cb581c8 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/util/StringUtil.java @@ -0,0 +1,31 @@ +package org.thoughtcrime.securesms.util; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.nio.charset.StandardCharsets; + +public final class StringUtil { + + private StringUtil() { + } + + /** + * Trims a name string to fit into the byte length requirement. + */ + public static @NonNull String trimToFit(@Nullable String name, int maxLength) { + if (name == null) return ""; + + // At least one byte per char, so shorten string to reduce loop + if (name.length() > maxLength) { + name = name.substring(0, maxLength); + } + + // Remove one char at a time until fits in byte allowance + while (name.getBytes(StandardCharsets.UTF_8).length > maxLength) { + name = name.substring(0, name.length() - 1); + } + + return name; + } +} diff --git a/app/src/main/res/drawable/ic_add_members_20.xml b/app/src/main/res/drawable/ic_add_members_20.xml new file mode 100644 index 0000000000..88cf2df945 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_members_20.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_members_circle_dark.xml b/app/src/main/res/drawable/ic_add_members_circle_dark.xml index 3721f6ab4f..9ec11afa49 100644 --- a/app/src/main/res/drawable/ic_add_members_circle_dark.xml +++ b/app/src/main/res/drawable/ic_add_members_circle_dark.xml @@ -7,7 +7,7 @@ diff --git a/app/src/main/res/drawable/ic_add_members_circle_light.xml b/app/src/main/res/drawable/ic_add_members_circle_light.xml index 95d9af5f76..50991a9380 100644 --- a/app/src/main/res/drawable/ic_add_members_circle_light.xml +++ b/app/src/main/res/drawable/ic_add_members_circle_light.xml @@ -7,7 +7,7 @@ diff --git a/app/src/main/res/drawable/ic_plus_24_ultramarine.xml b/app/src/main/res/drawable/ic_plus_24_ultramarine.xml deleted file mode 100644 index b3a3e6c356..0000000000 --- a/app/src/main/res/drawable/ic_plus_24_ultramarine.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_view_all_20.xml b/app/src/main/res/drawable/ic_view_all_20.xml new file mode 100644 index 0000000000..47f54f4566 --- /dev/null +++ b/app/src/main/res/drawable/ic_view_all_20.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_view_all_circle_dark.xml b/app/src/main/res/drawable/ic_view_all_circle_dark.xml new file mode 100644 index 0000000000..fb46989d4d --- /dev/null +++ b/app/src/main/res/drawable/ic_view_all_circle_dark.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_view_all_circle_light.xml b/app/src/main/res/drawable/ic_view_all_circle_light.xml new file mode 100644 index 0000000000..820436cf27 --- /dev/null +++ b/app/src/main/res/drawable/ic_view_all_circle_light.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/group_manage_fragment.xml b/app/src/main/res/layout/group_manage_fragment.xml index 401715c424..2e01a5e5c5 100644 --- a/app/src/main/res/layout/group_manage_fragment.xml +++ b/app/src/main/res/layout/group_manage_fragment.xml @@ -27,13 +27,13 @@ @@ -56,28 +57,37 @@ android:id="@+id/group_disappearing_messages_card" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="16dp" + android:layout_marginTop="@dimen/group_manage_fragment_card_vertical_padding" app:cardBackgroundColor="?android:attr/windowBackground" app:layout_constraintTop_toBottomOf="@id/group_title_card"> + android:layout_height="@dimen/group_manage_fragment_row_height" + android:background="?selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:orientation="horizontal" + android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding" + android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"> -