mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-27 04:04:43 +01:00
Implement the majority of the new nicknames and notes feature.
This commit is contained in:
committed by
Nicholas Tinsley
parent
7a24554b68
commit
303929090b
@@ -505,6 +505,10 @@ public class Recipient {
|
||||
return contactUri;
|
||||
}
|
||||
|
||||
public @Nullable String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public @Nullable String getGroupName(@NonNull Context context) {
|
||||
if (groupId != null && Util.isEmpty(this.groupName)) {
|
||||
RecipientId selfId = ApplicationDependencies.getRecipientCache().getSelfId();
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -17,6 +18,7 @@ import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
@@ -27,9 +29,11 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
@@ -44,6 +48,7 @@ import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.avatar.AvatarImage
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.nicknames.ViewNoteSheet
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
@@ -101,10 +106,12 @@ class AboutSheet : ComposeBottomSheetDialogFragment() {
|
||||
},
|
||||
groupsInCommon = groupsInCommonCount,
|
||||
profileSharing = recipient.get().isProfileSharing,
|
||||
systemContact = recipient.get().isSystemContact
|
||||
systemContact = recipient.get().isSystemContact,
|
||||
note = recipient.get().note ?: ""
|
||||
),
|
||||
onClickSignalConnections = this::openSignalConnectionsSheet,
|
||||
onAvatarClicked = this::openProfilePhotoViewer
|
||||
onAvatarClicked = this::openProfilePhotoViewer,
|
||||
onNoteClicked = this::openNoteSheet
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -117,6 +124,11 @@ class AboutSheet : ComposeBottomSheetDialogFragment() {
|
||||
private fun openProfilePhotoViewer() {
|
||||
startActivity(AvatarPreviewActivity.intentFromRecipientId(requireContext(), recipientId))
|
||||
}
|
||||
|
||||
private fun openNoteSheet() {
|
||||
dismiss()
|
||||
ViewNoteSheet.create(recipientId).show(parentFragmentManager, null)
|
||||
}
|
||||
}
|
||||
|
||||
private data class AboutModel(
|
||||
@@ -130,14 +142,16 @@ private data class AboutModel(
|
||||
val formattedE164: String?,
|
||||
val profileSharing: Boolean,
|
||||
val systemContact: Boolean,
|
||||
val groupsInCommon: Int
|
||||
val groupsInCommon: Int,
|
||||
val note: String
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun Content(
|
||||
model: AboutModel,
|
||||
onClickSignalConnections: () -> Unit,
|
||||
onAvatarClicked: () -> Unit
|
||||
onAvatarClicked: () -> Unit,
|
||||
onNoteClicked: () -> Unit
|
||||
) {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
@@ -180,12 +194,15 @@ private fun Content(
|
||||
)
|
||||
|
||||
if (model.about.isNotNullOrBlank()) {
|
||||
val textColor = LocalContentColor.current
|
||||
|
||||
AboutRow(
|
||||
startIcon = painterResource(R.drawable.symbol_edit_24),
|
||||
text = {
|
||||
Row {
|
||||
AndroidView(factory = ::EmojiTextView) {
|
||||
it.text = model.about
|
||||
it.setTextColor(textColor.toArgb())
|
||||
|
||||
TextViewCompat.setTextAppearance(it, R.style.Signal_Text_BodyLarge)
|
||||
}
|
||||
@@ -255,6 +272,16 @@ private fun Content(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
if (model.note.isNotBlank()) {
|
||||
AboutRow(
|
||||
startIcon = painterResource(id = R.drawable.symbol_note_light_24),
|
||||
text = model.note,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
endIcon = painterResource(id = R.drawable.symbol_chevron_right_compact_bold_16),
|
||||
onClick = onNoteClicked
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.size(26.dp))
|
||||
}
|
||||
}
|
||||
@@ -272,7 +299,10 @@ private fun AboutRow(
|
||||
text = {
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f, false)
|
||||
)
|
||||
},
|
||||
modifier = modifier,
|
||||
@@ -284,7 +314,7 @@ private fun AboutRow(
|
||||
@Composable
|
||||
private fun AboutRow(
|
||||
startIcon: Painter,
|
||||
text: @Composable () -> Unit,
|
||||
text: @Composable RowScope.() -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
endIcon: Painter? = null,
|
||||
onClick: (() -> Unit)? = null
|
||||
@@ -346,10 +376,12 @@ private fun ContentPreviewDefault() {
|
||||
formattedE164 = "(123) 456-7890",
|
||||
profileSharing = true,
|
||||
systemContact = true,
|
||||
groupsInCommon = 0
|
||||
groupsInCommon = 0,
|
||||
note = "GET ME SPIDERMAN BEFORE I BLOW A DANG GASKET"
|
||||
),
|
||||
onClickSignalConnections = {},
|
||||
onAvatarClicked = {}
|
||||
onAvatarClicked = {},
|
||||
onNoteClicked = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -373,10 +405,12 @@ private fun ContentPreviewInContactsNotProfileSharing() {
|
||||
formattedE164 = null,
|
||||
profileSharing = false,
|
||||
systemContact = true,
|
||||
groupsInCommon = 3
|
||||
groupsInCommon = 3,
|
||||
note = "GET ME SPIDER MAN"
|
||||
),
|
||||
onClickSignalConnections = {},
|
||||
onAvatarClicked = {}
|
||||
onAvatarClicked = {},
|
||||
onNoteClicked = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -400,10 +434,12 @@ private fun ContentPreviewGroupsInCommonNoE164() {
|
||||
formattedE164 = null,
|
||||
profileSharing = true,
|
||||
systemContact = false,
|
||||
groupsInCommon = 3
|
||||
groupsInCommon = 3,
|
||||
note = "GET ME SPIDERMAN"
|
||||
),
|
||||
onClickSignalConnections = {},
|
||||
onAvatarClicked = {}
|
||||
onAvatarClicked = {},
|
||||
onNoteClicked = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -427,10 +463,12 @@ private fun ContentPreviewNotAConnection() {
|
||||
formattedE164 = null,
|
||||
profileSharing = false,
|
||||
systemContact = false,
|
||||
groupsInCommon = 3
|
||||
groupsInCommon = 3,
|
||||
note = "GET ME SPIDERMAN"
|
||||
),
|
||||
onClickSignalConnections = {},
|
||||
onAvatarClicked = {}
|
||||
onAvatarClicked = {},
|
||||
onNoteClicked = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
@@ -39,6 +40,7 @@ import org.thoughtcrime.securesms.contacts.avatars.FallbackPhoto80dp;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.nicknames.NicknameActivity;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientExporter;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
@@ -46,6 +48,7 @@ import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.recipients.ui.about.AboutSheet;
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil;
|
||||
import org.thoughtcrime.securesms.util.ContextUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.SpanUtil;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -74,6 +77,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
|
||||
private AvatarView avatar;
|
||||
private TextView fullName;
|
||||
private TextView about;
|
||||
private TextView nickname;
|
||||
private TextView blockButton;
|
||||
private TextView unblockButton;
|
||||
private TextView addContactButton;
|
||||
@@ -92,6 +96,8 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
|
||||
|
||||
private ButtonStripPreference.ViewHolder buttonStripViewHolder;
|
||||
|
||||
private ActivityResultLauncher<NicknameActivity.Args> nicknameLauncher;
|
||||
|
||||
public static void show(FragmentManager fragmentManager, @NonNull RecipientId recipientId, @Nullable GroupId groupId) {
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
if (recipient.isSelf()) {
|
||||
@@ -127,6 +133,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
|
||||
avatar = view.findViewById(R.id.rbs_recipient_avatar);
|
||||
fullName = view.findViewById(R.id.rbs_full_name);
|
||||
about = view.findViewById(R.id.rbs_about);
|
||||
nickname = view.findViewById(R.id.rbs_nickname_button);
|
||||
blockButton = view.findViewById(R.id.rbs_block_button);
|
||||
unblockButton = view.findViewById(R.id.rbs_unblock_button);
|
||||
addContactButton = view.findViewById(R.id.rbs_add_contact_button);
|
||||
@@ -150,6 +157,8 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
|
||||
public void onViewCreated(@NonNull View fragmentView, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(fragmentView, savedInstanceState);
|
||||
|
||||
nicknameLauncher = registerForActivityResult(new NicknameActivity.Contract(), (b) -> {});
|
||||
|
||||
Bundle arguments = requireArguments();
|
||||
RecipientId recipientId = RecipientId.from(Objects.requireNonNull(arguments.getString(ARGS_RECIPIENT_ID)));
|
||||
GroupId groupId = GroupId.parseNullableOrThrow(arguments.getString(ARGS_GROUP_ID));
|
||||
@@ -214,6 +223,16 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF
|
||||
dismiss();
|
||||
AboutSheet.create(recipient).show(getParentFragmentManager(), null);
|
||||
});
|
||||
|
||||
if (FeatureFlags.nicknames() && groupId != null) {
|
||||
nickname.setVisibility(View.VISIBLE);
|
||||
nickname.setOnClickListener(v -> {
|
||||
nicknameLauncher.launch(new NicknameActivity.Args(
|
||||
recipientId,
|
||||
false
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
String aboutText = recipient.getCombinedAboutAndEmoji();
|
||||
|
||||
Reference in New Issue
Block a user