Enforce two line limit on group description.
Sorry.
This commit is contained in:
parent
5d5d61d8ed
commit
f890ae8ddc
11 changed files with 75 additions and 57 deletions
|
@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
|
|||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
|
||||
import org.thoughtcrime.securesms.components.mention.MentionRendererDelegate;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
|
@ -91,7 +90,8 @@ public class EmojiTextView extends AppCompatTextView {
|
|||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@Override public void setText(@Nullable CharSequence text, BufferType type) {
|
||||
@Override
|
||||
public void setText(@Nullable CharSequence text, BufferType type) {
|
||||
EmojiParser.CandidateList candidates = isInEditMode() ? null : EmojiProvider.getCandidates(text);
|
||||
|
||||
if (scaleEmojis && candidates != null && candidates.allEmojis) {
|
||||
|
@ -118,23 +118,19 @@ public class EmojiTextView extends AppCompatTextView {
|
|||
useSystemEmoji = useSystemEmoji();
|
||||
|
||||
if (useSystemEmoji || candidates == null || candidates.size() == 0) {
|
||||
super.setText(new SpannableStringBuilder(Optional.fromNullable(text).or("")).append(Optional.fromNullable(overflowText).or("")), BufferType.NORMAL);
|
||||
|
||||
if (getEllipsize() == TextUtils.TruncateAt.END && maxLength > 0) {
|
||||
ellipsizeAnyTextForMaxLength();
|
||||
}
|
||||
super.setText(new SpannableStringBuilder(Optional.fromNullable(text).or("")), BufferType.NORMAL);
|
||||
} else {
|
||||
CharSequence emojified = EmojiProvider.emojify(candidates, text, this);
|
||||
super.setText(new SpannableStringBuilder(emojified).append(Optional.fromNullable(overflowText).or("")), BufferType.SPANNABLE);
|
||||
super.setText(new SpannableStringBuilder(emojified), BufferType.SPANNABLE);
|
||||
}
|
||||
|
||||
// Android fails to ellipsize spannable strings. (https://issuetracker.google.com/issues/36991688)
|
||||
// We ellipsize them ourselves by manually truncating the appropriate section.
|
||||
if (getEllipsize() == TextUtils.TruncateAt.END) {
|
||||
if (maxLength > 0) {
|
||||
ellipsizeAnyTextForMaxLength();
|
||||
} else {
|
||||
ellipsizeEmojiTextForMaxLines();
|
||||
}
|
||||
// Android fails to ellipsize spannable strings. (https://issuetracker.google.com/issues/36991688)
|
||||
// We ellipsize them ourselves by manually truncating the appropriate section.
|
||||
if (getText() != null && getText().length() > 0 && getEllipsize() == TextUtils.TruncateAt.END) {
|
||||
if (maxLength > 0) {
|
||||
ellipsizeAnyTextForMaxLength();
|
||||
} else if (getMaxLines() > 0) {
|
||||
ellipsizeEmojiTextForMaxLines();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +188,8 @@ public class EmojiTextView extends AppCompatTextView {
|
|||
if (lineCount > maxLines) {
|
||||
int overflowStart = getLayout().getLineStart(maxLines - 1);
|
||||
CharSequence overflow = getText().subSequence(overflowStart, getText().length());
|
||||
CharSequence ellipsized = TextUtils.ellipsize(overflow, getPaint(), getWidth(), TextUtils.TruncateAt.END);
|
||||
float adjust = overflowText != null ? getPaint().measureText(overflowText, 0, overflowText.length()) : 0f;
|
||||
CharSequence ellipsized = TextUtils.ellipsize(overflow, getPaint(), getWidth() - adjust, TextUtils.TruncateAt.END);
|
||||
|
||||
SpannableStringBuilder newContent = new SpannableStringBuilder();
|
||||
newContent.append(getText().subSequence(0, overflowStart))
|
||||
|
|
|
@ -19,6 +19,7 @@ import androidx.core.widget.ImageViewCompat;
|
|||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
|
@ -31,7 +32,7 @@ public class ConversationBannerView extends ConstraintLayout {
|
|||
private TextView contactTitle;
|
||||
private TextView contactAbout;
|
||||
private TextView contactSubtitle;
|
||||
private TextView contactDescription;
|
||||
private EmojiTextView contactDescription;
|
||||
private View tapToView;
|
||||
|
||||
public ConversationBannerView(Context context) {
|
||||
|
@ -91,6 +92,10 @@ public class ConversationBannerView extends ConstraintLayout {
|
|||
contactDescription.setVisibility(TextUtils.isEmpty(description) ? GONE : VISIBLE);
|
||||
}
|
||||
|
||||
public @NonNull EmojiTextView getDescription() {
|
||||
return contactDescription;
|
||||
}
|
||||
|
||||
public void showBackgroundBubble(boolean enabled) {
|
||||
if (enabled) {
|
||||
setBackgroundResource(R.drawable.wallpaper_bubble_background_12);
|
||||
|
|
|
@ -541,13 +541,15 @@ public class ConversationFragment extends LoggingFragment {
|
|||
} else {
|
||||
conversationBanner.setLinkifyDescription(true);
|
||||
boolean linkifyWebLinks = recipientInfo.getMessageRequestState() == MessageRequestState.NONE;
|
||||
conversationBanner.setDescription(GroupDescriptionUtil.style(context,
|
||||
recipientInfo.getGroupDescription(),
|
||||
linkifyWebLinks,
|
||||
() -> GroupDescriptionDialog.show(getChildFragmentManager(),
|
||||
recipient.getDisplayName(context),
|
||||
recipientInfo.getGroupDescription(),
|
||||
linkifyWebLinks)));
|
||||
conversationBanner.showDescription();
|
||||
GroupDescriptionUtil.setText(context,
|
||||
conversationBanner.getDescription(),
|
||||
recipientInfo.getGroupDescription(),
|
||||
linkifyWebLinks,
|
||||
() -> GroupDescriptionDialog.show(getChildFragmentManager(),
|
||||
recipient.getDisplayName(context),
|
||||
recipientInfo.getGroupDescription(),
|
||||
linkifyWebLinks));
|
||||
}
|
||||
} else {
|
||||
final String description;
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.signal.core.util.logging.Log;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
||||
import org.thoughtcrime.securesms.conversation.ConversationIntents;
|
||||
|
@ -46,7 +47,7 @@ public final class GroupJoinBottomSheetDialogFragment extends BottomSheetDialogF
|
|||
private AvatarImageView avatar;
|
||||
private TextView groupName;
|
||||
private TextView groupDetails;
|
||||
private TextView groupDescription;
|
||||
private EmojiTextView groupDescription;
|
||||
private TextView groupJoinExplain;
|
||||
private Button groupJoinButton;
|
||||
private Button groupCancelButton;
|
||||
|
@ -158,10 +159,11 @@ public final class GroupJoinBottomSheetDialogFragment extends BottomSheetDialogF
|
|||
private void updateGroupDescription(@NonNull String name, @NonNull String description) {
|
||||
groupDescription.setVisibility(View.VISIBLE);
|
||||
groupDescription.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
groupDescription.setText(GroupDescriptionUtil.style(requireContext(),
|
||||
description,
|
||||
true,
|
||||
() -> GroupDescriptionDialog.show(getChildFragmentManager(), name, description, true)));
|
||||
GroupDescriptionUtil.setText(requireContext(),
|
||||
groupDescription,
|
||||
description,
|
||||
true,
|
||||
() -> GroupDescriptionDialog.show(getChildFragmentManager(), name, description, true));
|
||||
}
|
||||
|
||||
private static ExtendedGroupJoinStatus getGroupJoinStatus() {
|
||||
|
|
|
@ -458,15 +458,17 @@ public class ManageGroupFragment extends LoggingFragment {
|
|||
|
||||
if (TextUtils.isEmpty(description.getDescription())) {
|
||||
if (FeatureFlags.groupsV2Description() && description.canEditDescription()) {
|
||||
groupDescription.setOverflowText(null);
|
||||
groupDescription.setText(R.string.ManageGroupActivity_add_group_description);
|
||||
groupDescription.setOnClickListener(v -> startActivity(EditProfileActivity.getIntentForGroupProfile(requireActivity(), getGroupId())));
|
||||
}
|
||||
} else {
|
||||
groupDescription.setOnClickListener(null);
|
||||
groupDescription.setText(GroupDescriptionUtil.style(requireContext(),
|
||||
description.getDescription(),
|
||||
description.shouldLinkifyWebLinks(),
|
||||
() -> GroupDescriptionDialog.show(getChildFragmentManager(), getGroupId(), null, description.shouldLinkifyWebLinks())));
|
||||
GroupDescriptionUtil.setText(requireContext(),
|
||||
groupDescription,
|
||||
description.getDescription(),
|
||||
description.shouldLinkifyWebLinks(),
|
||||
() -> GroupDescriptionDialog.show(getChildFragmentManager(), getGroupId(), null, description.shouldLinkifyWebLinks()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import androidx.fragment.app.FragmentManager;
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.LiveGroup;
|
||||
import org.thoughtcrime.securesms.groups.ParcelableGroupId;
|
||||
|
@ -34,7 +35,7 @@ public final class GroupDescriptionDialog extends DialogFragment {
|
|||
private static final String ARGUMENT_LINKIFY = "linkify";
|
||||
private static final String DIALOG_TAG = "GroupDescriptionDialog";
|
||||
|
||||
private TextView descriptionText;
|
||||
private EmojiTextView descriptionText;
|
||||
|
||||
public static void show(@NonNull FragmentManager fragmentManager, @NonNull String title, @Nullable String description, boolean linkify) {
|
||||
show(fragmentManager, null, title, description, linkify);
|
||||
|
@ -76,9 +77,9 @@ public final class GroupDescriptionDialog extends DialogFragment {
|
|||
.create();
|
||||
|
||||
if (argumentDescription != null) {
|
||||
descriptionText.setText(GroupDescriptionUtil.style(requireContext(), argumentDescription, linkify, null));
|
||||
GroupDescriptionUtil.setText(requireContext(), descriptionText, argumentDescription, linkify, null);
|
||||
} else if (liveGroup != null) {
|
||||
liveGroup.getDescription().observe(this, d -> descriptionText.setText(GroupDescriptionUtil.style(requireContext(), d, linkify, null)));
|
||||
liveGroup.getDescription().observe(this, d -> GroupDescriptionUtil.setText(requireContext(), descriptionText, d, linkify, null));
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(argumentTitle) && liveGroup != null) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.text.SpannableString;
|
|||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
|
@ -18,6 +19,7 @@ import androidx.annotation.Nullable;
|
|||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||
|
||||
public final class GroupDescriptionUtil {
|
||||
|
@ -25,14 +27,14 @@ public final class GroupDescriptionUtil {
|
|||
public static final int MAX_DESCRIPTION_LENGTH = 80;
|
||||
|
||||
/**
|
||||
* Style a group description.
|
||||
* Set a group description.
|
||||
*
|
||||
* @param description full description
|
||||
* @param linkify flag indicating if web urls should be linkified
|
||||
* @param moreClick Callback for when truncating and need to show more via another means. Required to enable truncating.
|
||||
* @return styled group description
|
||||
* @param description full description
|
||||
* @param emojiTextView Text view to update with description
|
||||
* @param linkify flag indicating if web urls should be linkified
|
||||
* @param moreClick Callback for when truncating and need to show more via another means. Required to enable truncating.
|
||||
*/
|
||||
public static @NonNull Spannable style(@NonNull Context context, @NonNull String description, boolean linkify, @Nullable Runnable moreClick) {
|
||||
public static void setText(@NonNull Context context, @NonNull EmojiTextView emojiTextView, @NonNull String description, boolean linkify, @Nullable Runnable moreClick) {
|
||||
SpannableString descriptionSpannable = new SpannableString(description);
|
||||
|
||||
if (linkify) {
|
||||
|
@ -46,7 +48,7 @@ public final class GroupDescriptionUtil {
|
|||
}
|
||||
}
|
||||
|
||||
if (moreClick != null && descriptionSpannable.length() > MAX_DESCRIPTION_LENGTH) {
|
||||
if (moreClick != null) {
|
||||
ClickableSpan style = new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
|
@ -59,11 +61,14 @@ public final class GroupDescriptionUtil {
|
|||
}
|
||||
};
|
||||
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(descriptionSpannable.subSequence(0, MAX_DESCRIPTION_LENGTH)).append(context.getString(R.string.ManageGroupActivity_more));
|
||||
builder.setSpan(style, MAX_DESCRIPTION_LENGTH + 1, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
return builder;
|
||||
emojiTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
emojiTextView.setMaxLines(2);
|
||||
|
||||
SpannableString overflowText = new SpannableString(context.getString(R.string.ManageGroupActivity_more));
|
||||
overflowText.setSpan(style, 0, overflowText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
emojiTextView.setOverflowText(overflowText);
|
||||
}
|
||||
|
||||
return descriptionSpannable;
|
||||
emojiTextView.setText(descriptionSpannable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -261,16 +262,15 @@ final class StickerManagementAdapter extends SectionedRecyclerViewAdapter<String
|
|||
boolean lastInList,
|
||||
boolean allowApngAnimation)
|
||||
{
|
||||
title.setText(stickerPack.getTitle().or(itemView.getResources().getString(R.string.StickerManagementAdapter_untitled)));
|
||||
SpannableStringBuilder titleBuilder = new SpannableStringBuilder(stickerPack.getTitle().or(itemView.getResources().getString(R.string.StickerManagementAdapter_untitled)));
|
||||
if (BlessedPacks.contains(stickerPack.getPackId())) {
|
||||
titleBuilder.append(blessedBadge);
|
||||
}
|
||||
|
||||
title.setText(titleBuilder);
|
||||
author.setText(stickerPack.getAuthor().or(itemView.getResources().getString(R.string.StickerManagementAdapter_unknown)));
|
||||
divider.setVisibility(lastInList ? View.GONE : View.VISIBLE);
|
||||
|
||||
if (BlessedPacks.contains(stickerPack.getPackId())) {
|
||||
title.setOverflowText(blessedBadge);
|
||||
} else {
|
||||
title.setOverflowText(null);
|
||||
}
|
||||
|
||||
glideRequests.load(new DecryptableUri(stickerPack.getCover().getUri()))
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
.set(ApngOptions.ANIMATE, allowApngAnimation)
|
||||
|
|
|
@ -61,7 +61,9 @@
|
|||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:maxLines="2"
|
||||
android:textColor="@color/signal_text_secondary"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
@ -58,10 +58,12 @@
|
|||
android:id="@+id/manage_group_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:textColor="@color/signal_text_secondary"
|
||||
android:visibility="gone"
|
||||
|
|
|
@ -748,7 +748,7 @@
|
|||
<string name="ManageGroupActivity_upgrade_this_group">upgrade this group.</string>
|
||||
<string name="ManageGroupActivity_this_is_an_insecure_mms_group">This is an insecure MMS Group. To chat privately, invite your contacts to Signal.</string>
|
||||
<string name="ManageGroupActivity_invite_now">Invite now</string>
|
||||
<string name="ManageGroupActivity_more">…more</string>
|
||||
<string name="ManageGroupActivity_more">more</string>
|
||||
<string name="ManageGroupActivity_add_group_description">Add group description…</string>
|
||||
|
||||
<!-- GroupMentionSettingDialog -->
|
||||
|
|
Loading…
Add table
Reference in a new issue