Manage recipient activity.
parent
d9641128a8
commit
b53827f32b
|
@ -267,6 +267,10 @@
|
|||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".recipients.ui.managerecipient.ManageRecipientActivity"
|
||||
android:windowSoftInputMode="stateAlwaysHidden"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".DatabaseMigrationActivity"
|
||||
android:theme="@style/NoAnimation.Theme.AppCompat.Light.DarkActionBar"
|
||||
android:launchMode="singleTask"
|
||||
|
|
|
@ -272,12 +272,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
|
|||
private class ProfileClickListener implements Preference.OnPreferenceClickListener {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
Intent intent = new Intent(preference.getContext(), EditProfileActivity.class);
|
||||
intent.putExtra(EditProfileActivity.EXCLUDE_SYSTEM, true);
|
||||
intent.putExtra(EditProfileActivity.DISPLAY_USERNAME, true);
|
||||
intent.putExtra(EditProfileActivity.NEXT_BUTTON_TEXT, R.string.save);
|
||||
|
||||
requireActivity().startActivity(intent);
|
||||
requireActivity().startActivity(EditProfileActivity.getIntentForUserProfileEdit(preference.getContext()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.recipients.ui.managerecipient.ManageRecipientActivity;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.DynamicDarkToolbarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
@ -117,6 +118,15 @@ public class RecipientPreferenceActivity extends PassphraseRequiredActionBarActi
|
|||
private CollapsingToolbarLayout toolbarLayout;
|
||||
|
||||
public static @NonNull Intent getLaunchIntent(@NonNull Context context, @NonNull RecipientId id) {
|
||||
if (FeatureFlags.newGroupUI()) {
|
||||
return ManageRecipientActivity.newIntent(context, id);
|
||||
}
|
||||
|
||||
return getOldLaunchIntent(context, id);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Intent getOldLaunchIntent(@NonNull Context context, @NonNull RecipientId id) {
|
||||
Intent intent = new Intent(context, RecipientPreferenceActivity.class);
|
||||
intent.putExtra(RecipientPreferenceActivity.RECIPIENT_ID, id);
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.thoughtcrime.securesms.color;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
@ -52,7 +54,7 @@ public class MaterialColors {
|
|||
return null;
|
||||
}
|
||||
|
||||
public int[] asConversationColorArray(@NonNull Context context) {
|
||||
public @ColorInt int[] asConversationColorArray(@NonNull Context context) {
|
||||
int[] results = new int[colors.size()];
|
||||
int index = 0;
|
||||
|
||||
|
|
|
@ -2,13 +2,11 @@ package org.thoughtcrime.securesms.contacts.avatars;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
@ -18,7 +16,16 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class GroupFallbackPhoto80 implements FallbackContactPhoto {
|
||||
public final class FallbackPhoto80dp implements FallbackContactPhoto {
|
||||
|
||||
@DrawableRes private final int drawable80dp;
|
||||
private final MaterialColor backgroundColor;
|
||||
|
||||
public FallbackPhoto80dp(@DrawableRes int drawable80dp, @NonNull MaterialColor backgroundColor) {
|
||||
this.drawable80dp = drawable80dp;
|
||||
this.backgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable asDrawable(Context context, int color) {
|
||||
return buildDrawable(context);
|
||||
|
@ -41,12 +48,12 @@ public final class GroupFallbackPhoto80 implements FallbackContactPhoto {
|
|||
|
||||
private @NonNull Drawable buildDrawable(@NonNull Context context) {
|
||||
Drawable background = DrawableCompat.wrap(Objects.requireNonNull(AppCompatResources.getDrawable(context, R.drawable.circle_tintable)));
|
||||
Drawable foreground = AppCompatResources.getDrawable(context, R.drawable.ic_group_80);
|
||||
Drawable foreground = AppCompatResources.getDrawable(context, drawable80dp);
|
||||
Drawable gradient = ThemeUtil.getThemedDrawable(context, R.attr.resource_placeholder_gradient);
|
||||
LayerDrawable drawable = new LayerDrawable(new Drawable[]{background, foreground, gradient});
|
||||
int foregroundInset = ViewUtil.dpToPx(24);
|
||||
|
||||
DrawableCompat.setTint(background, MaterialColor.ULTRAMARINE.toAvatarColor(context));
|
||||
DrawableCompat.setTint(background, backgroundColor.toAvatarColor(context));
|
||||
|
||||
drawable.setLayerInset(1, foregroundInset, foregroundInset, foregroundInset, foregroundInset);
|
||||
|
|
@ -91,7 +91,7 @@ public class AddGroupDetailsFragment extends Fragment {
|
|||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
create = view.findViewById(R.id.create);
|
||||
name = view.findViewById(R.id.group_name);
|
||||
name = view.findViewById(R.id.name);
|
||||
toolbar = view.findViewById(R.id.toolbar);
|
||||
|
||||
setCreateEnabled(false, false);
|
||||
|
|
|
@ -27,10 +27,11 @@ import org.thoughtcrime.securesms.MediaPreviewActivity;
|
|||
import org.thoughtcrime.securesms.MuteDialog;
|
||||
import org.thoughtcrime.securesms.PushContactSelectionActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.ThreadPhotoRailView;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.GroupFallbackPhoto80;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackPhoto80dp;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberListView;
|
||||
import org.thoughtcrime.securesms.groups.ui.LeaveGroupDialog;
|
||||
|
@ -97,7 +98,7 @@ public class ManageGroupFragment extends Fragment {
|
|||
private final Recipient.FallbackPhotoProvider fallbackPhotoProvider = new Recipient.FallbackPhotoProvider() {
|
||||
@Override
|
||||
public @NonNull FallbackContactPhoto getPhotoForGroup() {
|
||||
return new GroupFallbackPhoto80();
|
||||
return new FallbackPhoto80dp(R.drawable.ic_group_80, MaterialColor.ULTRAMARINE);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -120,7 +121,7 @@ public class ManageGroupFragment extends Fragment {
|
|||
|
||||
avatar = view.findViewById(R.id.group_avatar);
|
||||
toolbar = view.findViewById(R.id.toolbar);
|
||||
groupName = view.findViewById(R.id.group_name);
|
||||
groupName = view.findViewById(R.id.name);
|
||||
memberCountUnderAvatar = view.findViewById(R.id.member_count);
|
||||
memberCountAboveList = view.findViewById(R.id.member_count_2);
|
||||
groupMemberList = view.findViewById(R.id.group_members);
|
||||
|
|
|
@ -13,7 +13,6 @@ import androidx.navigation.Navigation;
|
|||
import org.thoughtcrime.securesms.BaseActionBarActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.DynamicRegistrationTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
|
@ -35,6 +34,14 @@ public class EditProfileActivity extends BaseActionBarActivity implements EditPr
|
|||
return intent;
|
||||
}
|
||||
|
||||
public static @NonNull Intent getIntentForUserProfileEdit(@NonNull Context context) {
|
||||
Intent intent = new Intent(context, EditProfileActivity.class);
|
||||
intent.putExtra(EditProfileActivity.EXCLUDE_SYSTEM, true);
|
||||
intent.putExtra(EditProfileActivity.DISPLAY_USERNAME, true);
|
||||
intent.putExtra(EditProfileActivity.NEXT_BUTTON_TEXT, R.string.save);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static @NonNull Intent getIntentForGroupProfile(@NonNull Context context, @NonNull GroupId.Push groupId) {
|
||||
Intent intent = new Intent(context, EditProfileActivity.class);
|
||||
intent.putExtra(EditProfileActivity.SHOW_TOOLBAR, true);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.thoughtcrime.securesms.groups.ui.creategroup;
|
||||
package org.thoughtcrime.securesms.recipients.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
|
@ -19,17 +19,17 @@ import org.thoughtcrime.securesms.R;
|
|||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public final class GroupSettingsCoordinatorLayoutBehavior extends CoordinatorLayout.Behavior<View> {
|
||||
public final class RecipientSettingsCoordinatorLayoutBehavior extends CoordinatorLayout.Behavior<View> {
|
||||
|
||||
private static final Interpolator INTERPOLATOR = new DecelerateInterpolator();
|
||||
|
||||
private final ViewRef avatarTargetRef = new ViewRef(R.id.avatar_target);
|
||||
private final ViewRef groupNameRef = new ViewRef(R.id.group_name);
|
||||
private final ViewRef groupNameTargetRef = new ViewRef(R.id.group_name_target);
|
||||
private final Rect targetRect = new Rect();
|
||||
private final Rect childRect = new Rect();
|
||||
private final ViewReference avatarTargetRef = new ViewReference(R.id.avatar_target);
|
||||
private final ViewReference nameRef = new ViewReference(R.id.name);
|
||||
private final ViewReference nameTargetRef = new ViewReference(R.id.name_target);
|
||||
private final Rect targetRect = new Rect();
|
||||
private final Rect childRect = new Rect();
|
||||
|
||||
public GroupSettingsCoordinatorLayoutBehavior(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
public RecipientSettingsCoordinatorLayoutBehavior(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,8 +71,8 @@ public final class GroupSettingsCoordinatorLayoutBehavior extends CoordinatorLay
|
|||
}
|
||||
|
||||
private void updateNamePosition(@NonNull CoordinatorLayout parent, float factor) {
|
||||
TextView child = (TextView) groupNameRef.require(parent);
|
||||
View target = groupNameTargetRef.require(parent);
|
||||
TextView child = (TextView) nameRef.require(parent);
|
||||
View target = nameTargetRef.require(parent);
|
||||
|
||||
targetRect.set(target.getLeft(), target.getTop(), target.getRight(), target.getBottom());
|
||||
childRect.set(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());
|
||||
|
@ -95,13 +95,13 @@ public final class GroupSettingsCoordinatorLayoutBehavior extends CoordinatorLay
|
|||
return parent.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR ? rect.left : rect.right;
|
||||
}
|
||||
|
||||
private static final class ViewRef {
|
||||
private static final class ViewReference {
|
||||
|
||||
private WeakReference<View> ref = new WeakReference<>(null);
|
||||
|
||||
private final @IdRes int idRes;
|
||||
|
||||
private ViewRef(@IdRes int idRes) {
|
||||
private ViewReference(@IdRes int idRes) {
|
||||
this.idRes = idRes;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package org.thoughtcrime.securesms.recipients.ui.managerecipient;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
public class ManageRecipientActivity extends PassphraseRequiredActionBarActivity {
|
||||
|
||||
private static final String RECIPIENT_ID = "RECIPIENT_ID";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
|
||||
public static Intent newIntent(@NonNull Context context, @NonNull RecipientId recipientId) {
|
||||
Intent intent = new Intent(context, ManageRecipientActivity.class);
|
||||
intent.putExtra(RECIPIENT_ID, recipientId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static @Nullable Bundle createTransitionBundle(@NonNull Context activityContext, @NonNull View from) {
|
||||
if (activityContext instanceof Activity) {
|
||||
return ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) activityContext, from, "avatar").toBundle();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
||||
super.onCreate(savedInstanceState, ready);
|
||||
setContentView(R.layout.recipient_manage_activity);
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.container, ManageRecipientFragment.newInstance(getIntent().getParcelableExtra(RECIPIENT_ID)))
|
||||
.commitNow();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,349 @@
|
|||
package org.thoughtcrime.securesms.recipients.ui.managerecipient;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.takisoft.colorpicker.ColorPickerDialog;
|
||||
import com.takisoft.colorpicker.ColorStateDrawable;
|
||||
|
||||
import org.thoughtcrime.securesms.AvatarPreviewActivity;
|
||||
import org.thoughtcrime.securesms.MediaPreviewActivity;
|
||||
import org.thoughtcrime.securesms.MuteDialog;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.color.MaterialColors;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.ThreadPhotoRailView;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackPhoto80dp;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberListView;
|
||||
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.notifications.CustomNotificationsDialogFragment;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.LifecycleCursorWrapper;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ManageRecipientFragment extends Fragment {
|
||||
private static final String RECIPIENT_ID = "RECIPIENT_ID";
|
||||
|
||||
private static final int RETURN_FROM_MEDIA = 405;
|
||||
|
||||
private ManageRecipientViewModel viewModel;
|
||||
private GroupMemberListView sharedGroupList;
|
||||
private Toolbar toolbar;
|
||||
private TextView name;
|
||||
private TextView usernameNumber;
|
||||
private AvatarImageView avatar;
|
||||
private ThreadPhotoRailView threadPhotoRailView;
|
||||
private View mediaCard;
|
||||
private ManageRecipientViewModel.CursorFactory cursorFactory;
|
||||
private View sharedMediaRow;
|
||||
private View disappearingMessagesCard;
|
||||
private View disappearingMessagesRow;
|
||||
private TextView disappearingMessages;
|
||||
private View colorRow;
|
||||
private ImageView colorChip;
|
||||
private TextView block;
|
||||
private TextView unblock;
|
||||
private TextView addToAGroup;
|
||||
private SwitchCompat muteNotificationsSwitch;
|
||||
private View muteNotificationsRow;
|
||||
private TextView muteNotificationsUntilLabel;
|
||||
private TextView customNotificationsButton;
|
||||
private View customNotificationsRow;
|
||||
private View toggleAllGroups;
|
||||
private View viewSafetyNumber;
|
||||
private TextView groupsInCommonCount;
|
||||
private View messageButton;
|
||||
private View secureCallButton;
|
||||
private View secureVideoCallButton;
|
||||
|
||||
static ManageRecipientFragment newInstance(@NonNull RecipientId recipientId) {
|
||||
ManageRecipientFragment fragment = new ManageRecipientFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
args.putParcelable(RECIPIENT_ID, recipientId);
|
||||
fragment.setArguments(args);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
View view = inflater.inflate(R.layout.recipient_manage_fragment, container, false);
|
||||
|
||||
avatar = view.findViewById(R.id.recipient_avatar);
|
||||
toolbar = view.findViewById(R.id.toolbar);
|
||||
name = view.findViewById(R.id.name);
|
||||
usernameNumber = view.findViewById(R.id.username_number);
|
||||
sharedGroupList = view.findViewById(R.id.shared_group_list);
|
||||
groupsInCommonCount = view.findViewById(R.id.groups_in_common_count);
|
||||
threadPhotoRailView = view.findViewById(R.id.recent_photos);
|
||||
mediaCard = view.findViewById(R.id.recipient_media_card);
|
||||
sharedMediaRow = view.findViewById(R.id.shared_media_row);
|
||||
disappearingMessagesCard = view.findViewById(R.id.recipient_disappearing_messages_card);
|
||||
disappearingMessagesRow = view.findViewById(R.id.disappearing_messages_row);
|
||||
disappearingMessages = view.findViewById(R.id.disappearing_messages);
|
||||
colorRow = view.findViewById(R.id.color_row);
|
||||
colorChip = view.findViewById(R.id.color_chip);
|
||||
block = view.findViewById(R.id.block);
|
||||
unblock = view.findViewById(R.id.unblock);
|
||||
viewSafetyNumber = view.findViewById(R.id.view_safety_number);
|
||||
addToAGroup = view.findViewById(R.id.add_to_a_group);
|
||||
muteNotificationsUntilLabel = view.findViewById(R.id.recipient_mute_notifications_until);
|
||||
muteNotificationsSwitch = view.findViewById(R.id.recipient_mute_notifications_switch);
|
||||
muteNotificationsRow = view.findViewById(R.id.recipient_mute_notifications_row);
|
||||
customNotificationsButton = view.findViewById(R.id.recipient_custom_notifications_button);
|
||||
customNotificationsRow = view.findViewById(R.id.recipient_custom_notifications_row);
|
||||
toggleAllGroups = view.findViewById(R.id.toggle_all_groups);
|
||||
messageButton = view.findViewById(R.id.recipient_message);
|
||||
secureCallButton = view.findViewById(R.id.recipient_voice_call);
|
||||
secureVideoCallButton = view.findViewById(R.id.recipient_video_call);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
RecipientId recipientId = Objects.requireNonNull(requireArguments().getParcelable(RECIPIENT_ID));
|
||||
ManageRecipientViewModel.Factory factory = new ManageRecipientViewModel.Factory(recipientId);
|
||||
|
||||
viewModel = ViewModelProviders.of(requireActivity(), factory).get(ManageRecipientViewModel.class);
|
||||
|
||||
viewModel.getVisibleSharedGroups().observe(getViewLifecycleOwner(), members -> sharedGroupList.setMembers(members));
|
||||
viewModel.getSharedGroupsCountSummary().observe(getViewLifecycleOwner(), members -> groupsInCommonCount.setText(members));
|
||||
|
||||
viewModel.getCanCollapseMemberList().observe(getViewLifecycleOwner(), canCollapseMemberList -> {
|
||||
if (canCollapseMemberList) {
|
||||
toggleAllGroups.setVisibility(View.VISIBLE);
|
||||
toggleAllGroups.setOnClickListener(v -> viewModel.revealCollapsedMembers());
|
||||
} else {
|
||||
toggleAllGroups.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
viewModel.getIdentity().observe(getViewLifecycleOwner(), identityRecord -> {
|
||||
viewSafetyNumber.setVisibility(identityRecord != null ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (identityRecord != null) {
|
||||
viewSafetyNumber.setOnClickListener(view -> viewModel.onViewSafetyNumberClicked(requireActivity(), identityRecord));
|
||||
}
|
||||
});
|
||||
|
||||
toolbar.setNavigationOnClickListener(v -> requireActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this::onMenuItemSelected);
|
||||
toolbar.inflateMenu(R.menu.manage_recipient_fragment);
|
||||
|
||||
if (recipientId.equals(Recipient.self().getId())) {
|
||||
toolbar.getMenu().findItem(R.id.action_edit).setVisible(true);
|
||||
}
|
||||
|
||||
viewModel.getName().observe(getViewLifecycleOwner(), name::setText);
|
||||
viewModel.getDisappearingMessageTimer().observe(getViewLifecycleOwner(), string -> disappearingMessages.setText(string));
|
||||
viewModel.getRecipient().observe(getViewLifecycleOwner(), this::presentRecipient);
|
||||
viewModel.getMediaCursor().observe(getViewLifecycleOwner(), this::presentMediaCursor);
|
||||
viewModel.getMuteState().observe(getViewLifecycleOwner(), this::presentMuteState);
|
||||
|
||||
disappearingMessagesRow.setOnClickListener(v -> viewModel.handleExpirationSelection(requireContext()));
|
||||
block.setOnClickListener(v -> viewModel.onBlockClicked(requireActivity()));
|
||||
unblock.setOnClickListener(v -> viewModel.onUnblockClicked(requireActivity()));
|
||||
|
||||
addToAGroup.setOnClickListener(v -> viewModel.onAddToGroupButton(requireActivity()));
|
||||
|
||||
sharedGroupList.setRecipientClickListener(recipient -> viewModel.onGroupClicked(requireActivity(), recipient));
|
||||
sharedGroupList.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||
|
||||
muteNotificationsRow.setOnClickListener(v -> {
|
||||
if (muteNotificationsSwitch.isEnabled()) {
|
||||
muteNotificationsSwitch.toggle();
|
||||
}
|
||||
});
|
||||
|
||||
customNotificationsRow.setVisibility(View.VISIBLE);
|
||||
customNotificationsRow.setOnClickListener(v -> CustomNotificationsDialogFragment.create(recipientId)
|
||||
.show(requireFragmentManager(), "CUSTOM_NOTIFICATIONS"));
|
||||
|
||||
//noinspection CodeBlock2Expr
|
||||
if (NotificationChannels.supported()) {
|
||||
viewModel.hasCustomNotifications().observe(getViewLifecycleOwner(), hasCustomNotifications -> {
|
||||
customNotificationsButton.setText(hasCustomNotifications ? R.string.ManageRecipientActivity_on
|
||||
: R.string.ManageRecipientActivity_off);
|
||||
});
|
||||
}
|
||||
|
||||
viewModel.getCanBlock().observe(getViewLifecycleOwner(), canBlock -> {
|
||||
block.setVisibility(canBlock ? View.VISIBLE : View.GONE);
|
||||
unblock.setVisibility(canBlock ? View.GONE : View.VISIBLE);
|
||||
});
|
||||
|
||||
messageButton.setOnClickListener(v -> viewModel.onMessage(requireActivity()));
|
||||
secureCallButton.setOnClickListener(v -> viewModel.onSecureCall(requireActivity()));
|
||||
secureVideoCallButton.setOnClickListener(v -> viewModel.onSecureVideoCall(requireActivity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == RETURN_FROM_MEDIA) {
|
||||
applyMediaCursorFactory();
|
||||
}
|
||||
}
|
||||
|
||||
private void presentRecipient(@NonNull Recipient recipient) {
|
||||
disappearingMessagesCard.setVisibility(recipient.isRegistered() ? View.VISIBLE : View.GONE);
|
||||
addToAGroup.setVisibility(recipient.isRegistered() ? View.VISIBLE : View.GONE);
|
||||
|
||||
MaterialColor recipientColor = recipient.getColor();
|
||||
avatar.setFallbackPhotoProvider(new Recipient.FallbackPhotoProvider() {
|
||||
@Override
|
||||
public @NonNull FallbackContactPhoto getPhotoForRecipientWithoutName() {
|
||||
return new FallbackPhoto80dp(R.drawable.ic_profile_80, recipientColor);
|
||||
}
|
||||
});
|
||||
avatar.setRecipient(recipient);
|
||||
avatar.setOnClickListener(v -> {
|
||||
FragmentActivity activity = requireActivity();
|
||||
activity.startActivity(AvatarPreviewActivity.intentFromRecipientId(activity, recipient.getId()),
|
||||
AvatarPreviewActivity.createTransitionBundle(activity, avatar));
|
||||
});
|
||||
|
||||
@ColorInt int color = recipientColor.toActionBarColor(requireContext());
|
||||
Drawable[] colorDrawable = new Drawable[]{ContextCompat.getDrawable(requireContext(), R.drawable.colorpickerpreference_pref_swatch)};
|
||||
colorChip.setImageDrawable(new ColorStateDrawable(colorDrawable, color));
|
||||
colorRow.setOnClickListener(v -> handleColorSelection(color));
|
||||
|
||||
String usernameNumberString = String.format("%s %s", recipient.getUsername().or(""), recipient.getSmsAddress().or(""))
|
||||
.trim();
|
||||
usernameNumber.setText(usernameNumberString);
|
||||
usernameNumber.setVisibility(TextUtils.isEmpty(usernameNumberString) ? View.GONE : View.VISIBLE);
|
||||
usernameNumber.setOnLongClickListener(v -> {
|
||||
Util.copyToClipboard(v.getContext(), usernameNumber.getText().toString());
|
||||
ServiceUtil.getVibrator(v.getContext()).vibrate(250);
|
||||
Toast.makeText(v.getContext(), R.string.RecipientBottomSheet_copied_to_clipboard, Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
});
|
||||
|
||||
secureCallButton.setVisibility(recipient.isRegistered() ? View.VISIBLE : View.GONE);
|
||||
secureVideoCallButton.setVisibility(recipient.isRegistered() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void presentMediaCursor(ManageRecipientViewModel.MediaCursor mediaCursor) {
|
||||
if (mediaCursor == null) return;
|
||||
sharedMediaRow.setOnClickListener(v -> startActivity(MediaOverviewActivity.forThread(requireContext(), mediaCursor.getThreadId())));
|
||||
|
||||
setMediaCursorFactory(mediaCursor.getMediaCursorFactory());
|
||||
|
||||
threadPhotoRailView.setListener(mediaRecord ->
|
||||
startActivityForResult(MediaPreviewActivity.intentFromMediaRecord(requireContext(),
|
||||
mediaRecord,
|
||||
ViewCompat.getLayoutDirection(threadPhotoRailView) == ViewCompat.LAYOUT_DIRECTION_LTR),
|
||||
RETURN_FROM_MEDIA));
|
||||
}
|
||||
|
||||
private void presentMuteState(@NonNull ManageRecipientViewModel.MuteState muteState) {
|
||||
if (muteNotificationsSwitch.isChecked() != muteState.isMuted()) {
|
||||
muteNotificationsSwitch.setOnCheckedChangeListener(null);
|
||||
muteNotificationsSwitch.setChecked(muteState.isMuted());
|
||||
}
|
||||
|
||||
muteNotificationsSwitch.setEnabled(true);
|
||||
muteNotificationsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (isChecked) {
|
||||
MuteDialog.show(requireContext(), viewModel::setMuteUntil, () -> muteNotificationsSwitch.setChecked(false));
|
||||
} else {
|
||||
viewModel.clearMuteUntil();
|
||||
}
|
||||
});
|
||||
muteNotificationsUntilLabel.setVisibility(muteState.isMuted() ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (muteState.isMuted()) {
|
||||
muteNotificationsUntilLabel.setText(getString(R.string.ManageRecipientActivity_until_s,
|
||||
DateUtils.getTimeString(requireContext(),
|
||||
Locale.getDefault(),
|
||||
muteState.getMutedUntil())));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleColorSelection(@ColorInt int currentColor) {
|
||||
@ColorInt int[] colors = MaterialColors.CONVERSATION_PALETTE.asConversationColorArray(requireContext());
|
||||
|
||||
ColorPickerDialog.Params params = new ColorPickerDialog.Params.Builder(requireContext())
|
||||
.setSelectedColor(currentColor)
|
||||
.setColors(colors)
|
||||
.setSize(ColorPickerDialog.SIZE_SMALL)
|
||||
.setSortColors(false)
|
||||
.setColumns(3)
|
||||
.build();
|
||||
|
||||
ColorPickerDialog dialog = new ColorPickerDialog(requireActivity(), color -> viewModel.onSelectColor(color), params);
|
||||
dialog.setTitle(R.string.ManageRecipientActivity_chat_color);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public boolean onMenuItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_edit) {
|
||||
startActivity(EditProfileActivity.getIntentForUserProfileEdit(requireActivity()));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setMediaCursorFactory(@Nullable ManageRecipientViewModel.CursorFactory cursorFactory) {
|
||||
if (this.cursorFactory != cursorFactory) {
|
||||
this.cursorFactory = cursorFactory;
|
||||
applyMediaCursorFactory();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyMediaCursorFactory() {
|
||||
Context context = getContext();
|
||||
if (context == null) return;
|
||||
if (cursorFactory != null) {
|
||||
Cursor cursor = cursorFactory.create();
|
||||
getViewLifecycleOwner().getLifecycle().addObserver(new LifecycleCursorWrapper(cursor));
|
||||
|
||||
threadPhotoRailView.setCursor(GlideApp.with(context), cursor);
|
||||
mediaCard.setVisibility(cursor.getCount() > 0 ? View.VISIBLE : View.GONE);
|
||||
} else {
|
||||
threadPhotoRailView.setCursor(GlideApp.with(context), null);
|
||||
mediaCard.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package org.thoughtcrime.securesms.recipients.ui.managerecipient;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.core.util.Consumer;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.color.MaterialColors;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
final class ManageRecipientRepository {
|
||||
|
||||
private final Context context;
|
||||
private final RecipientId recipientId;
|
||||
|
||||
ManageRecipientRepository(@NonNull Context context, @NonNull RecipientId recipientId) {
|
||||
this.context = context;
|
||||
this.recipientId = recipientId;
|
||||
}
|
||||
|
||||
public RecipientId getRecipientId() {
|
||||
return recipientId;
|
||||
}
|
||||
|
||||
void getThreadId(@NonNull Consumer<Long> onGetThreadId) {
|
||||
SignalExecutors.BOUNDED.execute(() -> onGetThreadId.accept(getThreadId()));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private long getThreadId() {
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
Recipient groupRecipient = Recipient.resolved(recipientId);
|
||||
|
||||
return threadDatabase.getThreadIdFor(groupRecipient);
|
||||
}
|
||||
|
||||
void getIdentity(@NonNull Consumer<IdentityDatabase.IdentityRecord> callback) {
|
||||
SignalExecutors.BOUNDED.execute(() -> callback.accept(DatabaseFactory.getIdentityDatabase(context)
|
||||
.getIdentity(recipientId)
|
||||
.orNull()));
|
||||
}
|
||||
|
||||
void setExpiration(int newExpirationTime) {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipientId, newExpirationTime);
|
||||
OutgoingExpirationUpdateMessage outgoingMessage = new OutgoingExpirationUpdateMessage(Recipient.resolved(recipientId), System.currentTimeMillis(), newExpirationTime * 1000L);
|
||||
MessageSender.send(context, outgoingMessage, getThreadId(), false, null);
|
||||
});
|
||||
}
|
||||
|
||||
void getGroupMembership(@NonNull Consumer<List<RecipientId>> onComplete) {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
List<GroupDatabase.GroupRecord> groupRecords = groupDatabase.getPushGroupsContainingMember(recipientId);
|
||||
ArrayList<RecipientId> groupRecipients = new ArrayList<>(groupRecords.size());
|
||||
|
||||
for (GroupDatabase.GroupRecord groupRecord : groupRecords) {
|
||||
groupRecipients.add(groupRecord.getRecipientId());
|
||||
}
|
||||
|
||||
onComplete.accept(groupRecipients);
|
||||
});
|
||||
}
|
||||
|
||||
public void getRecipient(@NonNull Consumer<Recipient> recipientCallback) {
|
||||
SignalExecutors.BOUNDED.execute(() -> recipientCallback.accept(Recipient.resolved(recipientId)));
|
||||
}
|
||||
|
||||
void setMuteUntil(long until) {
|
||||
SignalExecutors.BOUNDED.execute(() -> DatabaseFactory.getRecipientDatabase(context).setMuted(recipientId, until));
|
||||
}
|
||||
|
||||
void setColor(int color) {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
MaterialColor selectedColor = MaterialColors.CONVERSATION_PALETTE.getByColor(context, color);
|
||||
if (selectedColor != null) {
|
||||
DatabaseFactory.getRecipientDatabase(context).setColor(recipientId, selectedColor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@NonNull List<Recipient> getSharedGroups(@NonNull RecipientId recipientId) {
|
||||
return Stream.of(DatabaseFactory.getGroupDatabase(context)
|
||||
.getPushGroupsContainingMember(recipientId))
|
||||
.filter(g -> g.getMembers().contains(Recipient.self().getId()))
|
||||
.map(GroupDatabase.GroupRecord::getRecipientId)
|
||||
.map(Recipient::resolved)
|
||||
.sortBy(gr -> gr.getDisplayName(context))
|
||||
.toList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
package org.thoughtcrime.securesms.recipients.ui.managerecipient;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.core.util.Consumer;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Transformations;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.BlockUnblockDialog;
|
||||
import org.thoughtcrime.securesms.ExpirationDialog;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.VerifyIdentityActivity;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||
import org.thoughtcrime.securesms.database.MediaDatabase;
|
||||
import org.thoughtcrime.securesms.database.loaders.MediaLoader;
|
||||
import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry;
|
||||
import org.thoughtcrime.securesms.groups.ui.addtogroup.AddToGroupsActivity;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
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 final class ManageRecipientViewModel extends ViewModel {
|
||||
|
||||
private static final int MAX_COLLAPSED_GROUPS = 5;
|
||||
|
||||
private final Context context;
|
||||
private final ManageRecipientRepository manageRecipientRepository;
|
||||
private final LiveData<String> name;
|
||||
private final LiveData<String> disappearingMessageTimer;
|
||||
private final MutableLiveData<IdentityDatabase.IdentityRecord> identity;
|
||||
private final LiveData<Recipient> recipient;
|
||||
private final MutableLiveData<MediaCursor> mediaCursor = new MutableLiveData<>(null);
|
||||
private final LiveData<MuteState> muteState;
|
||||
private final LiveData<Boolean> hasCustomNotifications;
|
||||
private final LiveData<Boolean> canCollapseMemberList;
|
||||
private final DefaultValueLiveData<CollapseState> groupListCollapseState = new DefaultValueLiveData<>(CollapseState.COLLAPSED);
|
||||
private final LiveData<Boolean> canBlock;
|
||||
private final LiveData<List<GroupMemberEntry.FullMember>> visibleSharedGroups;
|
||||
private final LiveData<String> sharedGroupsCountSummary;
|
||||
|
||||
private ManageRecipientViewModel(@NonNull Context context, @NonNull ManageRecipientRepository manageRecipientRepository) {
|
||||
this.context = context;
|
||||
this.manageRecipientRepository = manageRecipientRepository;
|
||||
|
||||
manageRecipientRepository.getThreadId(this::onThreadIdLoaded);
|
||||
|
||||
this.recipient = Recipient.live(manageRecipientRepository.getRecipientId()).getLiveData();
|
||||
this.name = Transformations.map(recipient, r -> r.getDisplayName(context));
|
||||
this.identity = new MutableLiveData<>();
|
||||
|
||||
LiveData<List<Recipient>> allSharedGroups = LiveDataUtil.mapAsync(this.recipient, r -> manageRecipientRepository.getSharedGroups(r.getId()));
|
||||
|
||||
this.sharedGroupsCountSummary = Transformations.map(allSharedGroups, list -> {
|
||||
int size = list.size();
|
||||
return size == 0 ? context.getString(R.string.ManageRecipientActivity_no_groups_in_common)
|
||||
: context.getResources().getQuantityString(R.plurals.ManageRecipientActivity_d_groups_in_common, size, size);
|
||||
});
|
||||
|
||||
this.canCollapseMemberList = LiveDataUtil.combineLatest(this.groupListCollapseState,
|
||||
Transformations.map(allSharedGroups, m -> m.size() > MAX_COLLAPSED_GROUPS),
|
||||
(state, hasEnoughMembers) -> state != CollapseState.OPEN && hasEnoughMembers);
|
||||
this.visibleSharedGroups = Transformations.map(LiveDataUtil.combineLatest(allSharedGroups,
|
||||
this.groupListCollapseState,
|
||||
ManageRecipientViewModel::filterSharedGroupList),
|
||||
recipients -> Stream.of(recipients).map(r -> new GroupMemberEntry.FullMember(r, false)).toList());
|
||||
|
||||
this.disappearingMessageTimer = Transformations.map(this.recipient, r -> ExpirationUtil.getExpirationDisplayValue(context, r.getExpireMessages()));
|
||||
this.muteState = Transformations.map(this.recipient, r -> new MuteState(r.getMuteUntil(), r.isMuted()));
|
||||
this.hasCustomNotifications = Transformations.map(this.recipient, r -> r.getNotificationChannel() != null || !NotificationChannels.supported());
|
||||
this.canBlock = Transformations.map(this.recipient, r -> !r.isBlocked());
|
||||
|
||||
boolean isSelf = manageRecipientRepository.getRecipientId().equals(Recipient.self().getId());
|
||||
if (!isSelf) {
|
||||
manageRecipientRepository.getIdentity(identity::postValue);
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private void onThreadIdLoaded(long threadId) {
|
||||
mediaCursor.postValue(new MediaCursor(threadId,
|
||||
() -> new ThreadMediaLoader(context, threadId, MediaLoader.MediaType.GALLERY, MediaDatabase.Sorting.Newest).getCursor()));
|
||||
}
|
||||
|
||||
public LiveData<String> getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public LiveData<Recipient> getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
LiveData<MediaCursor> getMediaCursor() {
|
||||
return mediaCursor;
|
||||
}
|
||||
|
||||
LiveData<MuteState> getMuteState() {
|
||||
return muteState;
|
||||
}
|
||||
|
||||
LiveData<String> getDisappearingMessageTimer() {
|
||||
return disappearingMessageTimer;
|
||||
}
|
||||
|
||||
LiveData<Boolean> hasCustomNotifications() {
|
||||
return hasCustomNotifications;
|
||||
}
|
||||
|
||||
LiveData<Boolean> getCanCollapseMemberList() {
|
||||
return canCollapseMemberList;
|
||||
}
|
||||
|
||||
LiveData<Boolean> getCanBlock() {
|
||||
return canBlock;
|
||||
}
|
||||
|
||||
void handleExpirationSelection(@NonNull Context context) {
|
||||
withRecipient(recipient ->
|
||||
ExpirationDialog.show(context,
|
||||
recipient.getExpireMessages(),
|
||||
manageRecipientRepository::setExpiration));
|
||||
}
|
||||
|
||||
void setMuteUntil(long muteUntil) {
|
||||
manageRecipientRepository.setMuteUntil(muteUntil);
|
||||
}
|
||||
|
||||
void clearMuteUntil() {
|
||||
manageRecipientRepository.setMuteUntil(0);
|
||||
}
|
||||
|
||||
void revealCollapsedMembers() {
|
||||
groupListCollapseState.setValue(CollapseState.OPEN);
|
||||
}
|
||||
|
||||
void onAddToGroupButton(@NonNull Activity activity) {
|
||||
manageRecipientRepository.getGroupMembership(existingGroups -> Util.runOnMain(() -> activity.startActivity(AddToGroupsActivity.newIntent(activity, manageRecipientRepository.getRecipientId(), existingGroups))));
|
||||
}
|
||||
|
||||
private void withRecipient(@NonNull Consumer<Recipient> mainThreadRecipientCallback) {
|
||||
manageRecipientRepository.getRecipient(recipient -> Util.runOnMain(() -> mainThreadRecipientCallback.accept(recipient)));
|
||||
}
|
||||
|
||||
private static @NonNull List<Recipient> filterSharedGroupList(@NonNull List<Recipient> groups,
|
||||
@NonNull CollapseState collapseState)
|
||||
{
|
||||
if (collapseState == CollapseState.COLLAPSED && groups.size() > MAX_COLLAPSED_GROUPS) {
|
||||
return groups.subList(0, MAX_COLLAPSED_GROUPS);
|
||||
} else {
|
||||
return groups;
|
||||
}
|
||||
}
|
||||
|
||||
LiveData<IdentityDatabase.IdentityRecord> getIdentity() {
|
||||
return identity;
|
||||
}
|
||||
|
||||
void onBlockClicked(@NonNull FragmentActivity activity) {
|
||||
withRecipient(recipient -> BlockUnblockDialog.showBlockFor(activity, activity.getLifecycle(), recipient, () -> RecipientUtil.block(context, recipient)));
|
||||
}
|
||||
|
||||
void onUnblockClicked(@NonNull FragmentActivity activity) {
|
||||
withRecipient(recipient -> BlockUnblockDialog.showUnblockFor(activity, activity.getLifecycle(), recipient, () -> RecipientUtil.unblock(context, recipient)));
|
||||
}
|
||||
|
||||
void onViewSafetyNumberClicked(@NonNull Activity activity, @NonNull IdentityDatabase.IdentityRecord identityRecord) {
|
||||
activity.startActivity(VerifyIdentityActivity.newIntent(activity, identityRecord));
|
||||
}
|
||||
|
||||
LiveData<List<GroupMemberEntry.FullMember>> getVisibleSharedGroups() {
|
||||
return visibleSharedGroups;
|
||||
}
|
||||
|
||||
LiveData<String> getSharedGroupsCountSummary() {
|
||||
return sharedGroupsCountSummary;
|
||||
}
|
||||
|
||||
void onSelectColor(int color) {
|
||||
manageRecipientRepository.setColor(color);
|
||||
}
|
||||
|
||||
void onGroupClicked(@NonNull Activity activity, @NonNull Recipient recipient) {
|
||||
CommunicationActions.startConversation(activity, recipient, null);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
void onMessage(@NonNull FragmentActivity activity) {
|
||||
withRecipient(r -> {
|
||||
CommunicationActions.startConversation(activity, r, null);
|
||||
activity.finish();
|
||||
});
|
||||
}
|
||||
|
||||
void onSecureCall(@NonNull FragmentActivity activity) {
|
||||
withRecipient(r -> CommunicationActions.startVoiceCall(activity, r));
|
||||
}
|
||||
|
||||
void onSecureVideoCall(@NonNull FragmentActivity activity) {
|
||||
withRecipient(r -> CommunicationActions.startVideoCall(activity, r));
|
||||
}
|
||||
|
||||
static final class MediaCursor {
|
||||
private final long threadId;
|
||||
@NonNull private final CursorFactory mediaCursorFactory;
|
||||
|
||||
private MediaCursor(long threadId,
|
||||
@NonNull CursorFactory mediaCursorFactory)
|
||||
{
|
||||
this.threadId = threadId;
|
||||
this.mediaCursorFactory = mediaCursorFactory;
|
||||
}
|
||||
|
||||
long getThreadId() {
|
||||
return threadId;
|
||||
}
|
||||
|
||||
@NonNull CursorFactory getMediaCursorFactory() {
|
||||
return mediaCursorFactory;
|
||||
}
|
||||
}
|
||||
|
||||
static final class MuteState {
|
||||
private final long mutedUntil;
|
||||
private final boolean isMuted;
|
||||
|
||||
MuteState(long mutedUntil, boolean isMuted) {
|
||||
this.mutedUntil = mutedUntil;
|
||||
this.isMuted = isMuted;
|
||||
}
|
||||
|
||||
long getMutedUntil() {
|
||||
return mutedUntil;
|
||||
}
|
||||
|
||||
public boolean isMuted() {
|
||||
return isMuted;
|
||||
}
|
||||
}
|
||||
|
||||
private enum CollapseState {
|
||||
OPEN,
|
||||
COLLAPSED
|
||||
}
|
||||
|
||||
interface CursorFactory {
|
||||
Cursor create();
|
||||
}
|
||||
|
||||
public static class Factory implements ViewModelProvider.Factory {
|
||||
private final Context context;
|
||||
private final RecipientId recipientId;
|
||||
|
||||
public Factory(@NonNull RecipientId recipientId) {
|
||||
this.context = ApplicationDependencies.getApplication();
|
||||
this.recipientId = recipientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
|
||||
//noinspection unchecked
|
||||
return (T) new ManageRecipientViewModel(context, new ManageRecipientRepository(context, recipientId));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ import android.widget.TextView;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
@ -25,21 +26,31 @@ import org.thoughtcrime.securesms.R;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class CustomNotificationsDialogFragment extends DialogFragment {
|
||||
|
||||
private static final short RINGTONE_PICKER_REQUEST_CODE = 13562;
|
||||
private static final short MESSAGE_RINGTONE_PICKER_REQUEST_CODE = 13562;
|
||||
private static final short CALL_RINGTONE_PICKER_REQUEST_CODE = 23621;
|
||||
|
||||
private static final String ARG_RECIPIENT_ID = "recipient_id";
|
||||
|
||||
private View customNotificationsRow;
|
||||
private SwitchCompat customNotificationsSwitch;
|
||||
private View soundRow;
|
||||
private View soundLabel;
|
||||
private TextView soundSelector;
|
||||
private View vibrateRow;
|
||||
private View vibrateLabel;
|
||||
private SwitchCompat vibrateSwitch;
|
||||
private View callHeading;
|
||||
private View ringtoneRow;
|
||||
private TextView ringtoneSelector;
|
||||
private View callVibrateRow;
|
||||
private TextView callVibrateSelector;
|
||||
|
||||
private CustomNotificationsViewModel viewModel;
|
||||
|
||||
|
@ -79,10 +90,13 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
|||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
if (requestCode == RINGTONE_PICKER_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
|
||||
viewModel.setMessageSound(uri);
|
||||
if (requestCode == MESSAGE_RINGTONE_PICKER_REQUEST_CODE) {
|
||||
viewModel.setMessageSound(uri);
|
||||
} else if (requestCode == CALL_RINGTONE_PICKER_REQUEST_CODE) {
|
||||
viewModel.setCallSound(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,11 +110,19 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
|||
}
|
||||
|
||||
private void initializeViews(@NonNull View view) {
|
||||
customNotificationsRow = view.findViewById(R.id.custom_notifications_row);
|
||||
customNotificationsSwitch = view.findViewById(R.id.custom_notifications_enable_switch);
|
||||
soundRow = view.findViewById(R.id.custom_notifications_sound_row);
|
||||
soundLabel = view.findViewById(R.id.custom_notifications_sound_label);
|
||||
soundSelector = view.findViewById(R.id.custom_notifications_sound_selection);
|
||||
vibrateRow = view.findViewById(R.id.custom_notifications_vibrate_row);
|
||||
vibrateLabel = view.findViewById(R.id.custom_notifications_vibrate_label);
|
||||
vibrateSwitch = view.findViewById(R.id.custom_notifications_vibrate_switch);
|
||||
callHeading = view.findViewById(R.id.custom_notifications_call_settings_section_header);
|
||||
ringtoneRow = view.findViewById(R.id.custom_notifications_ringtone_row);
|
||||
ringtoneSelector = view.findViewById(R.id.custom_notifications_ringtone_selection);
|
||||
callVibrateRow = view.findViewById(R.id.custom_notifications_call_vibrate_row);
|
||||
callVibrateSelector = view.findViewById(R.id.custom_notifications_call_vibrate_selection);
|
||||
|
||||
Toolbar toolbar = view.findViewById(R.id.custom_notifications_toolbar);
|
||||
|
||||
|
@ -119,8 +141,11 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
|||
}
|
||||
|
||||
customNotificationsSwitch.setOnCheckedChangeListener(onCustomNotificationsSwitchCheckChangedListener);
|
||||
customNotificationsRow.setOnClickListener(v -> customNotificationsSwitch.toggle());
|
||||
|
||||
soundRow.setEnabled(hasCustomNotifications);
|
||||
soundLabel.setEnabled(hasCustomNotifications);
|
||||
vibrateRow.setEnabled(hasCustomNotifications);
|
||||
vibrateLabel.setEnabled(hasCustomNotifications);
|
||||
soundSelector.setVisibility(hasCustomNotifications ? View.VISIBLE : View.GONE);
|
||||
vibrateSwitch.setVisibility(hasCustomNotifications ? View.VISIBLE : View.GONE);
|
||||
|
@ -145,18 +170,42 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
|||
|
||||
vibrateSwitch.setOnCheckedChangeListener(onVibrateSwitchCheckChangedListener);
|
||||
});
|
||||
vibrateRow.setOnClickListener(v -> vibrateSwitch.toggle());
|
||||
|
||||
viewModel.getNotificationSound().observe(getViewLifecycleOwner(), sound -> {
|
||||
soundSelector.setText(getRingtoneSummary(requireContext(), sound));
|
||||
soundSelector.setTag(sound);
|
||||
soundRow.setOnClickListener(v -> launchSoundSelector(sound, false));
|
||||
});
|
||||
|
||||
soundSelector.setOnClickListener(v -> launchSoundSelector(viewModel.getNotificationSound().getValue()));
|
||||
viewModel.getShowCallingOptions().observe(getViewLifecycleOwner(), showCalling -> {
|
||||
callHeading.setVisibility(showCalling ? View.VISIBLE : View.GONE);
|
||||
ringtoneRow.setVisibility(showCalling ? View.VISIBLE : View.GONE);
|
||||
callVibrateRow.setVisibility(showCalling ? View.VISIBLE : View.GONE);
|
||||
});
|
||||
|
||||
viewModel.getRingtone().observe(getViewLifecycleOwner(), sound -> {
|
||||
ringtoneSelector.setText(getRingtoneSummary(requireContext(), sound));
|
||||
ringtoneSelector.setTag(sound);
|
||||
ringtoneRow.setOnClickListener(v -> launchSoundSelector(sound, true));
|
||||
});
|
||||
|
||||
viewModel.getCallingVibrateState().observe(getViewLifecycleOwner(), vibrateState -> {
|
||||
String vibrateSummary = getVibrateSummary(requireContext(), vibrateState);
|
||||
callVibrateSelector.setText(vibrateSummary);
|
||||
callVibrateRow.setOnClickListener(v -> new AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.CustomNotificationsDialogFragment__vibrate)
|
||||
.setSingleChoiceItems(R.array.recipient_vibrate_entries, vibrateState.ordinal(), ((dialog, which) -> {
|
||||
viewModel.setCallingVibrate(RecipientDatabase.VibrateState.fromId(which));
|
||||
dialog.dismiss();
|
||||
})).setNegativeButton(android.R.string.cancel, null)
|
||||
.show());
|
||||
});
|
||||
}
|
||||
|
||||
private @NonNull String getRingtoneSummary(@NonNull Context context, @Nullable Uri ringtone) {
|
||||
if (ringtone == null) {
|
||||
return context.getString(R.string.preferences__default);
|
||||
return context.getString(R.string.CustomNotificationsDialogFragment__default);
|
||||
} else if (ringtone.toString().isEmpty()) {
|
||||
return context.getString(R.string.preferences__silent);
|
||||
} else {
|
||||
|
@ -167,18 +216,38 @@ public class CustomNotificationsDialogFragment extends DialogFragment {
|
|||
}
|
||||
}
|
||||
|
||||
return context.getString(R.string.preferences__default);
|
||||
return context.getString(R.string.CustomNotificationsDialogFragment__default);
|
||||
}
|
||||
|
||||
private void launchSoundSelector(@Nullable Uri current) {
|
||||
private void launchSoundSelector(@Nullable Uri current, boolean calls) {
|
||||
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
||||
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, Settings.System.DEFAULT_NOTIFICATION_URI);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, current);
|
||||
if (current == null) current = calls ? Settings.System.DEFAULT_RINGTONE_URI : Settings.System.DEFAULT_NOTIFICATION_URI;
|
||||
else if (current.toString().isEmpty()) current = null;
|
||||
|
||||
startActivityForResult(intent, RINGTONE_PICKER_REQUEST_CODE);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, calls ? RingtoneManager.TYPE_RINGTONE : RingtoneManager.TYPE_NOTIFICATION);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, current);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, defaultSound(calls));
|
||||
|
||||
startActivityForResult(intent, calls ? CALL_RINGTONE_PICKER_REQUEST_CODE : MESSAGE_RINGTONE_PICKER_REQUEST_CODE);
|
||||
}
|
||||
|
||||
private Uri defaultSound(boolean calls) {
|
||||
Uri defaultValue;
|
||||
|
||||
if (calls) defaultValue = TextSecurePreferences.getCallNotificationRingtone(requireContext());
|
||||
else defaultValue = TextSecurePreferences.getNotificationRingtone(requireContext());
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static @NonNull String getVibrateSummary(@NonNull Context context, @NonNull RecipientDatabase.VibrateState vibrateState) {
|
||||
switch (vibrateState) {
|
||||
case DEFAULT : return context.getString(R.string.CustomNotificationsDialogFragment__default);
|
||||
case ENABLED : return context.getString(R.string.CustomNotificationsDialogFragment__enabled);
|
||||
case DISABLED : return context.getString(R.string.CustomNotificationsDialogFragment__disabled);
|
||||
default : throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,10 @@ class CustomNotificationsRepository {
|
|||
});
|
||||
}
|
||||
|
||||
void setCallingVibrate(final RecipientDatabase.VibrateState vibrateState) {
|
||||
SignalExecutors.SERIAL.execute(() -> DatabaseFactory.getRecipientDatabase(context).setCallVibrate(recipientId, vibrateState));
|
||||
}
|
||||
|
||||
void setMessageSound(@Nullable Uri sound) {
|
||||
SignalExecutors.SERIAL.execute(() -> {
|
||||
Recipient recipient = getRecipient();
|
||||
|
@ -76,6 +80,19 @@ class CustomNotificationsRepository {
|
|||
});
|
||||
}
|
||||
|
||||
void setCallSound(@Nullable Uri sound) {
|
||||
SignalExecutors.SERIAL.execute(() -> {
|
||||
Uri defaultValue = TextSecurePreferences.getCallNotificationRingtone(context);
|
||||
Uri newValue;
|
||||
|
||||
if (defaultValue.equals(sound)) newValue = null;
|
||||
else if (sound == null) newValue = Uri.EMPTY;
|
||||
else newValue = sound;
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).setCallRingtone(recipientId, newValue);
|
||||
});
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private void createCustomNotificationChannel() {
|
||||
Recipient recipient = getRecipient();
|
||||
|
|
|
@ -22,14 +22,20 @@ public final class CustomNotificationsViewModel extends ViewModel {
|
|||
private final LiveData<Uri> notificationSound;
|
||||
private final CustomNotificationsRepository repository;
|
||||
private final MutableLiveData<Boolean> isInitialLoadComplete = new MutableLiveData<>();
|
||||
private final LiveData<Boolean> showCallingOptions;
|
||||
private final LiveData<Uri> ringtone;
|
||||
private final LiveData<RecipientDatabase.VibrateState> isCallingVibrateEnabled;
|
||||
|
||||
private CustomNotificationsViewModel(@NonNull RecipientId recipientId, @NonNull CustomNotificationsRepository repository) {
|
||||
LiveData<Recipient> recipient = Recipient.live(recipientId).getLiveData();
|
||||
|
||||
this.repository = repository;
|
||||
this.hasCustomNotifications = Transformations.map(recipient, r -> r.getNotificationChannel() != null || !NotificationChannels.supported());
|
||||
this.isVibrateEnabled = Transformations.map(recipient, Recipient::getMessageVibrate);
|
||||
this.notificationSound = Transformations.map(recipient, Recipient::getMessageRingtone);
|
||||
this.repository = repository;
|
||||
this.hasCustomNotifications = Transformations.map(recipient, r -> r.getNotificationChannel() != null || !NotificationChannels.supported());
|
||||
this.isVibrateEnabled = Transformations.map(recipient, Recipient::getMessageVibrate);
|
||||
this.notificationSound = Transformations.map(recipient, Recipient::getMessageRingtone);
|
||||
this.showCallingOptions = Transformations.map(recipient, r -> !r.isGroup() && r.isRegistered());
|
||||
this.ringtone = Transformations.map(recipient, Recipient::getCallRingtone);
|
||||
this.isCallingVibrateEnabled = Transformations.map(recipient, Recipient::getCallVibrate);
|
||||
|
||||
repository.onLoad(() -> isInitialLoadComplete.postValue(true));
|
||||
}
|
||||
|
@ -62,6 +68,26 @@ public final class CustomNotificationsViewModel extends ViewModel {
|
|||
repository.setMessageSound(sound);
|
||||
}
|
||||
|
||||
public void setCallSound(@Nullable Uri sound) {
|
||||
repository.setCallSound(sound);
|
||||
}
|
||||
|
||||
public LiveData<Boolean> getShowCallingOptions() {
|
||||
return showCallingOptions;
|
||||
}
|
||||
|
||||
public LiveData<Uri> getRingtone() {
|
||||
return ringtone;
|
||||
}
|
||||
|
||||
public LiveData<RecipientDatabase.VibrateState> getCallingVibrateState() {
|
||||
return isCallingVibrateEnabled;
|
||||
}
|
||||
|
||||
public void setCallingVibrate(@NonNull RecipientDatabase.VibrateState vibrateState) {
|
||||
repository.setCallingVibrate(vibrateState);
|
||||
}
|
||||
|
||||
public static final class Factory implements ViewModelProvider.Factory {
|
||||
|
||||
private final RecipientId recipientId;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/core_ultramarine"
|
||||
android:pathData="M12,4c4.963,0 9,3.364 9,7.5S16.963,19 12,19a10.536,10.536 0,0 1,-3.19 -0.5l-0.465,-0.148 -0.464,0.155L4.739,19.556l0.394,-2.365 0.118,-0.707 -0.477,-0.536A6.651,6.651 0,0 1,3 11.5C3,7.364 7.037,4 12,4m0,-1.5c-5.8,0 -10.5,4.029 -10.5,9a8.164,8.164 0,0 0,2.153 5.445l-0.639,3.836c-0.073,0.438 0.144,0.719 0.505,0.719a0.9,0.9 0,0 0,0.279 -0.049l4.558,-1.519A12.019,12.019 0,0 0,12 20.5c5.8,0 10.5,-4.029 10.5,-9s-4.773,-9 -10.5,-9Z" />
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/core_ultramarine_light"
|
||||
android:pathData="M12,2.5c-5.8,0 -10.5,4.029 -10.5,9a8.164,8.164 0,0 0,2.153 5.445l-0.639,3.836c-0.09,0.542 0.263,0.844 0.784,0.67l4.558,-1.519A12.019,12.019 0,0 0,12 20.5c5.8,0 10.5,-4.029 10.5,-9S17.727,2.5 12,2.5Z" />
|
||||
</vector>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/core_ultramarine"
|
||||
android:pathData="M22,6.56a1.06,1.06 0,0 0,-0.42 0.09L18,8.31L18,6.5a3,3 0,0 0,-3 -3L4,3.5a3,3 0,0 0,-3 3v11a3,3 0,0 0,3 3L15,20.5a3,3 0,0 0,3 -3L18,15.69l3.58,1.66a1.06,1.06 0,0 0,0.42 0.09,1 1,0 0,0 1,-1L23,7.56A1,1 0,0 0,22 6.56ZM16.5,17.5A1.5,1.5 0,0 1,15 19L4,19a1.5,1.5 0,0 1,-1.5 -1.5L2.5,6.5A1.5,1.5 0,0 1,4 5L15,5a1.5,1.5 0,0 1,1.5 1.5ZM21.5,8.34L21.5,16l-1,-0.81L18,14L18,10l2.48,-1.15 1,-0.81Z" />
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/core_ultramarine_light"
|
||||
android:pathData="M23,8.563v6.874a1,1 0,0 1,-1.419 0.908L18.5,14.923V9.077l3.081,-1.422A1,1 0,0 1,23 8.563ZM2.535,4.876A2.639,2.639 0,0 0,1.4 5.939,3.854 3.854,0 0,0 1,8.105V15.9a3.854,3.854 0,0 0,0.4 2.166,2.639 2.639,0 0,0 1.134,1.063 4.6,4.6 0,0 0,2.311 0.376h8.308a4.6,4.6 0,0 0,2.311 -0.376A2.639,2.639 0,0 0,16.6 18.061,3.854 3.854,0 0,0 17,15.9V8.105a3.854,3.854 0,0 0,-0.4 -2.166,2.639 2.639,0 0,0 -1.134,-1.063A4.6,4.6 0,0 0,13.154 4.5H4.846A4.6,4.6 0,0 0,2.535 4.876Z"/>
|
||||
</vector>
|
|
@ -25,7 +25,7 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiEditText
|
||||
android:id="@+id/group_name"
|
||||
android:id="@+id/name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
|
|
|
@ -23,73 +23,212 @@
|
|||
android:layout_marginTop="16dp"
|
||||
android:text="@string/CustomNotificationsDialogFragment__messages"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||
android:textColor="@color/ultramarine_text_button"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_toolbar" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_enable_label"
|
||||
style="@style/Widget.Signal.Button.TextButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/CustomNotificationsDialogFragment__use_custom_notifications"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_message_section_header" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_sound_label"
|
||||
style="@style/Widget.Signal.Button.TextButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_notifications_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/CustomNotificationsDialogFragment__notification_sound"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_enable_label" />
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_message_section_header">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_vibrate_label"
|
||||
style="@style/Widget.Signal.Button.TextButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:text="@string/CustomNotificationsDialogFragment__vibrate"
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_enable_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:text="@string/CustomNotificationsDialogFragment__use_custom_notifications"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/custom_notifications_enable_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"
|
||||
app:layout_constraintBottom_toBottomOf="@id/custom_notifications_enable_label"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/custom_notifications_enable_label"
|
||||
app:layout_constraintTop_toTopOf="@id/custom_notifications_enable_label" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_notifications_sound_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/CustomNotificationsDialogFragment__notification_sound"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_sound_label" />
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_row">
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/custom_notifications_enable_switch"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:enabled="false"
|
||||
app:layout_constraintBottom_toBottomOf="@id/custom_notifications_enable_label"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/custom_notifications_enable_label"
|
||||
app:layout_constraintTop_toTopOf="@id/custom_notifications_enable_label" />
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_sound_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:enabled="false"
|
||||
android:gravity="center_vertical|start"
|
||||
android:text="@string/CustomNotificationsDialogFragment__notification_sound"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_sound_selection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:visibility="gone"
|
||||
tools:text="Default (Popcorn)"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_notifications_vibrate_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/CustomNotificationsDialogFragment__notification_sound"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_sound_row">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_vibrate_label"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:enabled="false"
|
||||
android:gravity="center_vertical|start"
|
||||
android:text="@string/CustomNotificationsDialogFragment__vibrate"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/custom_notifications_vibrate_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_sound_selection"
|
||||
style="@style/Widget.Signal.Button.TextButton.Ultramarine"
|
||||
android:id="@+id/custom_notifications_call_settings_section_header"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="36dp"
|
||||
android:text="@string/CustomNotificationsDialogFragment__call_settings"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
android:gravity="end"
|
||||
app:layout_constraintBottom_toBottomOf="@id/custom_notifications_sound_label"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/custom_notifications_sound_label"
|
||||
app:layout_constraintTop_toTopOf="@id/custom_notifications_sound_label"
|
||||
tools:visibility="visible"
|
||||
tools:text="Default (Popcorn)" />
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_vibrate_row"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/custom_notifications_vibrate_switch"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_notifications_ringtone_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/CustomNotificationsDialogFragment__notification_sound"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/custom_notifications_vibrate_label"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/custom_notifications_vibrate_label"
|
||||
app:layout_constraintTop_toTopOf="@id/custom_notifications_vibrate_label" />
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_call_settings_section_header"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:text="@string/CustomNotificationsDialogFragment__ringtone"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_ringtone_selection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"
|
||||
android:textColor="?attr/colorAccent"
|
||||
tools:text="Default" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/custom_notifications_call_vibrate_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:text="@string/CustomNotificationsDialogFragment__notification_sound"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/custom_notifications_ringtone_row"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:text="@string/CustomNotificationsDialogFragment__vibrate"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/custom_notifications_call_vibrate_selection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"
|
||||
android:textColor="?attr/colorAccent"
|
||||
tools:text="Default" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -70,7 +70,7 @@
|
|||
android:layout_marginEnd="10dp" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/group_name_target"
|
||||
android:id="@+id/name_target"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
|
@ -93,10 +93,10 @@
|
|||
android:layout_marginTop="16dp"
|
||||
android:elevation="8dp"
|
||||
android:transitionName="avatar"
|
||||
app:layout_behavior=".groups.ui.creategroup.GroupSettingsCoordinatorLayoutBehavior" />
|
||||
app:layout_behavior=".recipients.ui.RecipientSettingsCoordinatorLayoutBehavior" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/group_name"
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".recipients.ui.managerecipient.ManageRecipientActivity">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
|
@ -0,0 +1,546 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".recipients.ui.managerecipient.ManageRecipientFragment"
|
||||
tools:theme="@style/TextSecure.LightNoActionBar">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
app:contentScrim="?android:attr/windowBackground"
|
||||
app:expandedTitleGravity="center_horizontal"
|
||||
app:expandedTitleMarginTop="156dp"
|
||||
app:expandedTitleTextAppearance="@style/TextAppearance.Signal.Body1.Bold"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
||||
app:scrimAnimationDuration="200">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<Space
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="14dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/username_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="?title_text_color_secondary"
|
||||
tools:text="\@spidergwen +1 555-654-6657" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/recipient_message"
|
||||
style="@style/Widget.Signal.Button.Icon.Circular"
|
||||
android:contentDescription="@string/ManageRecipientActivity_message_description"
|
||||
app:backgroundTint="?recipient_contact_button_color"
|
||||
app:icon="?recipient_message_circle_icon"
|
||||
app:rippleColor="@color/core_ultramarine" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/recipient_voice_call"
|
||||
style="@style/Widget.Signal.Button.Icon.Circular"
|
||||
android:layout_marginStart="36dp"
|
||||
android:contentDescription="@string/ManageRecipientActivity_voice_call_description"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="?recipient_contact_button_color"
|
||||
app:icon="?recipient_call_circle_icon"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/recipient_video_call"
|
||||
style="@style/Widget.Signal.Button.Icon.Circular"
|
||||
android:layout_marginStart="36dp"
|
||||
android:contentDescription="@string/ManageRecipientActivity_video_call_description"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="?recipient_contact_button_color"
|
||||
app:icon="?recipient_video_call_circle_icon"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:contentInsetStartWithNavigation="0dp"
|
||||
app:layout_collapseMode="pin"
|
||||
app:navigationIcon="@drawable/ic_arrow_left_24">
|
||||
|
||||
<Space
|
||||
android:id="@+id/avatar_target"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:layout_marginEnd="10dp" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/name_target"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold" />
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.components.AvatarImageView
|
||||
android:id="@+id/recipient_avatar"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:elevation="8dp"
|
||||
android:transitionName="avatar"
|
||||
app:layout_behavior=".recipients.ui.RecipientSettingsCoordinatorLayoutBehavior" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="158dp"
|
||||
android:elevation="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold"
|
||||
tools:text="Rob Aneesh" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?pref_divider"
|
||||
android:fillViewport="true"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/recipient_disappearing_messages_card"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/group_manage_fragment_card_vertical_padding"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/disappearing_messages_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_disappearing_messages"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/disappearing_messages"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:minWidth="48dp"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="@color/ultramarine_text_button"
|
||||
tools:text="Off" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/recipient_notifications_card"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/group_manage_fragment_card_vertical_padding"
|
||||
app:layout_constraintTop_toBottomOf="@id/recipient_disappearing_messages_card"
|
||||
app:layout_goneMarginTop="0dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/recipient_mute_notifications_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recipient_mute_notifications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:gravity="center_vertical|start"
|
||||
android:text="@string/ManageRecipientActivity_mute_notifications"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
app:layout_constraintBottom_toTopOf="@id/recipient_mute_notifications_until"
|
||||
app:layout_constraintEnd_toStartOf="@id/recipient_mute_notifications_switch"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recipient_mute_notifications_until"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:textAppearance="@style/TextSecure.SubtitleTextStyle"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/recipient_mute_notifications"
|
||||
tools:text="Until 12:42 PM"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/recipient_mute_notifications_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="false"
|
||||
android:enabled="false"
|
||||
android:minWidth="48dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/recipient_mute_notifications"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/recipient_custom_notifications_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recipient_custom_notifications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_custom_notifications"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/recipient_mute_notifications_switch"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recipient_custom_notifications_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical|end"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="@color/ultramarine_text_button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/recipient_custom_notifications"
|
||||
app:layout_constraintTop_toBottomOf="@id/recipient_mute_notifications_switch"
|
||||
tools:text="Off" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/recipient_media_card"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/group_manage_fragment_card_vertical_padding"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@id/recipient_notifications_card"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shared_media_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/recipient_preference_activity__shared_media"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:minWidth="48dp"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_see_all"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="@color/ultramarine_text_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThreadPhotoRailView
|
||||
android:id="@+id/recent_photos"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="90dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/shared_media_row" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/recipient_chat_color"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/group_manage_fragment_card_vertical_padding"
|
||||
app:layout_constraintTop_toBottomOf="@id/recipient_media_card">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/color_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_chat_color"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/color_chip"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:contentDescription="@string/ManageRecipientActivity_chat_color"
|
||||
android:gravity="center"
|
||||
tools:src="@drawable/circle_tintable"
|
||||
tools:tint="@color/core_ultramarine_light" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/recipient_membership_card"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/group_manage_fragment_card_vertical_padding"
|
||||
app:layout_constraintTop_toBottomOf="@id/recipient_chat_color">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/groups_in_common_count"
|
||||
style="@style/TextAppearance.Signal.Subtitle2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:textColor="?title_text_color_secondary"
|
||||
tools:text="8 groups in common" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/add_to_a_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:drawableStart="?attr/manage_group_add_members_icon"
|
||||
android:drawablePadding="8dp"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_add_to_a_group"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="@color/ultramarine_text_button" />
|
||||
|
||||
<org.thoughtcrime.securesms.groups.ui.GroupMemberListView
|
||||
android:id="@+id/shared_group_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:listitem="@layout/group_recipient_list_item" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/toggle_all_groups"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:drawableStart="?attr/manage_group_view_all_icon"
|
||||
android:drawablePadding="8dp"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_view_all_groups"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="?title_text_color_secondary"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/recipient_block_and_leave_card"
|
||||
style="@style/Widget.Signal.CardView.PreferenceRow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/group_manage_fragment_card_vertical_padding"
|
||||
app:layout_constraintTop_toBottomOf="@id/recipient_membership_card">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/view_safety_number"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_view_safety_number"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/block"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_block"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="@color/core_red" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/unblock"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/group_manage_fragment_row_height"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:paddingEnd="@dimen/group_manage_fragment_row_horizontal_padding"
|
||||
android:text="@string/ManageRecipientActivity_unblock"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="@color/core_red"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
android:icon="?attr/menu_edit_icon"
|
||||
android:title="@string/ManageGroupActivity_edit_name_and_picture"
|
||||
android:visible="false"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
|
@ -301,6 +301,11 @@
|
|||
<attr name="recipient_make_admin_icon" format="reference"/>
|
||||
<attr name="recipient_remove_icon" format="reference"/>
|
||||
|
||||
<attr name="recipient_message_circle_icon" format="reference"/>
|
||||
<attr name="recipient_call_circle_icon" format="reference"/>
|
||||
<attr name="recipient_video_call_circle_icon" format="reference"/>
|
||||
<attr name="recipient_contact_button_color" format="reference"/>
|
||||
|
||||
<declare-styleable name="ColorPreference">
|
||||
<attr name="itemLayout" format="reference" />
|
||||
<attr name="choices" format="reference" />
|
||||
|
|
|
@ -555,6 +555,31 @@
|
|||
|
||||
<string name="GroupManagement_choose_who_can_add_or_invite_new_members">Choose who can add or invite new members</string>
|
||||
<string name="GroupManagement_choose_who_can_change_the_group_name_and_photo">Choose who can change the group name and photo</string>
|
||||
|
||||
|
||||
<!-- ManageRecipientActivity -->
|
||||
<string name="ManageRecipientActivity_disappearing_messages">Disappearing messages</string>
|
||||
<string name="ManageRecipientActivity_chat_color">Chat color</string>
|
||||
<string name="ManageRecipientActivity_block">Block</string>
|
||||
<string name="ManageRecipientActivity_unblock">Unblock</string>
|
||||
<string name="ManageRecipientActivity_view_safety_number">View safety number</string>
|
||||
<string name="ManageRecipientActivity_mute_notifications">Mute notifications</string>
|
||||
<string name="ManageRecipientActivity_custom_notifications">Custom notifications</string>
|
||||
<string name="ManageRecipientActivity_until_s">Until %1$s</string>
|
||||
<string name="ManageRecipientActivity_off">Off</string>
|
||||
<string name="ManageRecipientActivity_on">On</string>
|
||||
<string name="ManageRecipientActivity_add_to_a_group">Add to a group</string>
|
||||
<string name="ManageRecipientActivity_view_all_groups">View all groups</string>
|
||||
<string name="ManageRecipientActivity_see_all">See all</string>
|
||||
<string name="ManageRecipientActivity_no_groups_in_common">No groups in common</string>
|
||||
<plurals name="ManageRecipientActivity_d_groups_in_common">
|
||||
<item quantity="one">%d group in common</item>
|
||||
<item quantity="other">%d groups in common</item>
|
||||
</plurals>
|
||||
<string name="ManageRecipientActivity_edit_name_and_picture">Edit name and picture</string>
|
||||
<string name="ManageRecipientActivity_message_description">Message</string>
|
||||
<string name="ManageRecipientActivity_voice_call_description">Voice call</string>
|
||||
<string name="ManageRecipientActivity_video_call_description">Video call</string>
|
||||
|
||||
<plurals name="GroupMemberList_invited">
|
||||
<item quantity="one">%1$s invited 1 person</item>
|
||||
|
@ -567,6 +592,11 @@
|
|||
<string name="CustomNotificationsDialogFragment__use_custom_notifications">Use custom notifications</string>
|
||||
<string name="CustomNotificationsDialogFragment__notification_sound">Notification sound</string>
|
||||
<string name="CustomNotificationsDialogFragment__vibrate">Vibrate</string>
|
||||
<string name="CustomNotificationsDialogFragment__call_settings">Call settings</string>
|
||||
<string name="CustomNotificationsDialogFragment__ringtone">Ringtone</string>
|
||||
<string name="CustomNotificationsDialogFragment__enabled">Enabled</string>
|
||||
<string name="CustomNotificationsDialogFragment__disabled">Disabled</string>
|
||||
<string name="CustomNotificationsDialogFragment__default">Default</string>
|
||||
|
||||
<!-- GV2 Invite cancellation confirmation -->
|
||||
<string name="GroupManagement_cancel_own_single_invite">Do you want to cancel the invite you sent to %1$s?</string>
|
||||
|
|
|
@ -448,4 +448,26 @@
|
|||
<item name="cardElevation">0.5dp</item>
|
||||
<item name="cardBackgroundColor">?android:attr/windowBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Signal.Button.Icon.Circular" parent="Widget.MaterialComponents.Button.Icon">
|
||||
<item name="android:layout_width">48dp</item>
|
||||
<item name="android:layout_height">48dp</item>
|
||||
<item name="iconSize">24dp</item>
|
||||
<item name="android:insetRight">0dp</item>
|
||||
<item name="android:insetLeft">0dp</item>
|
||||
<item name="android:insetTop">0dp</item>
|
||||
<item name="android:insetBottom">0dp</item>
|
||||
<item name="android:elevation" tools:ignore="NewApi">0dp</item>
|
||||
<item name="android:stateListAnimator" tools:ignore="NewApi">@null</item>
|
||||
<item name="iconTint">@color/white</item>
|
||||
<item name="iconTintMode">multiply</item>
|
||||
<item name="iconPadding">0dp</item>
|
||||
<item name="rippleColor">@color/core_ultramarine</item>
|
||||
<item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.Signal.Button.Rounded</item>
|
||||
</style>
|
||||
|
||||
<style name="ShapeAppearanceOverlay.Signal.Button.Rounded" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">50%</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -437,6 +437,11 @@
|
|||
<item name="colorControlNormal">@color/core_grey_90</item>
|
||||
|
||||
<item name="circular_progress_button_state">@drawable/progress_button_state_light</item>
|
||||
|
||||
<item name="recipient_message_circle_icon">@drawable/ic_message_outline_ultramarine_24</item>
|
||||
<item name="recipient_call_circle_icon">@drawable/ic_phone_right_outline_ultramarine_24</item>
|
||||
<item name="recipient_video_call_circle_icon">@drawable/ic_video_outline_ultramarine_24</item>
|
||||
<item name="recipient_contact_button_color">@color/core_grey_02</item>
|
||||
</style>
|
||||
|
||||
<style name="TextSecure.DarkTheme" parent="@style/TextSecure.BaseDarkTheme">
|
||||
|
@ -727,6 +732,11 @@
|
|||
<item name="colorControlNormal">@color/core_white</item>
|
||||
|
||||
<item name="circular_progress_button_state">@drawable/progress_button_state_dark</item>
|
||||
|
||||
<item name="recipient_message_circle_icon">@drawable/ic_message_solid_ultramarine_light_24</item>
|
||||
<item name="recipient_call_circle_icon">@drawable/ic_phone_right_solid_ultramarine_light_24</item>
|
||||
<item name="recipient_video_call_circle_icon">@drawable/ic_video_solid_ultramarine_light_24</item>
|
||||
<item name="recipient_contact_button_color">@color/core_grey_75</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Signal.AlertDialog.Light.Cornered" parent="Theme.AppCompat.Light.Dialog.Alert">
|
||||
|
|
Loading…
Reference in New Issue