Move bidi methods to BidiUtil.

This commit is contained in:
Greyson Parrelli
2025-02-27 13:58:22 -05:00
parent 791e95c645
commit e9e62b98f3
15 changed files with 201 additions and 186 deletions

View File

@@ -16,7 +16,7 @@ import androidx.appcompat.widget.AppCompatEditText
import androidx.core.animation.doOnEnd
import androidx.core.text.isDigitsOnly
import com.google.android.material.button.MaterialButton
import org.signal.core.util.StringUtil
import org.signal.core.util.BidiUtil
import org.signal.core.util.money.FiatMoney
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.badges.BadgeImageView
@@ -255,7 +255,7 @@ data class Boost(
dend: Int
): CharSequence? {
val result = dest.subSequence(0, dstart).toString() + source.toString() + dest.subSequence(dend, dest.length)
val resultWithoutCurrencyPrefix = StringUtil.stripBidiIndicator(result.removePrefix(symbol).removeSuffix(symbol).trim())
val resultWithoutCurrencyPrefix = BidiUtil.stripBidiIndicator(result.removePrefix(symbol).removeSuffix(symbol).trim())
if (resultWithoutCurrencyPrefix.length == 1 && !resultWithoutCurrencyPrefix.isDigitsOnly() && resultWithoutCurrencyPrefix != separator.toString()) {
return dest.subSequence(dstart, dend)

View File

@@ -11,7 +11,7 @@ import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy
import io.reactivex.rxjava3.processors.BehaviorProcessor
import io.reactivex.rxjava3.subjects.PublishSubject
import org.signal.core.util.StringUtil
import org.signal.core.util.BidiUtil
import org.signal.core.util.logging.Log
import org.signal.core.util.money.FiatMoney
import org.signal.core.util.money.PlatformCurrencyUtil
@@ -158,7 +158,7 @@ class DonateToSignalViewModel(
}
fun setCustomAmount(rawAmount: String) {
val amount = StringUtil.stripBidiIndicator(rawAmount)
val amount = BidiUtil.stripBidiIndicator(rawAmount)
val bigDecimalAmount: BigDecimal = if (amount.isEmpty() || amount == DecimalFormatSymbols.getInstance().decimalSeparator.toString()) {
BigDecimal.ZERO
} else {

View File

@@ -70,6 +70,7 @@ import com.google.common.collect.Sets;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.signal.core.util.BidiUtil;
import org.signal.core.util.DimensionUnit;
import org.signal.core.util.StringUtil;
import org.signal.core.util.logging.Log;
@@ -561,7 +562,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
isFooterVisible(messageRecord, nextMessageRecord, groupThread) &&
!bodyText.isJumbomoji() &&
conversationMessage.getBottomButton() == null &&
!StringUtil.hasMixedTextDirection(bodyText.getText()) &&
!BidiUtil.hasMixedTextDirection(bodyText.getText()) &&
!messageRecord.isRemoteDelete() &&
bodyText.getLastLineWidth() > 0)
{

View File

@@ -7,7 +7,7 @@ package org.thoughtcrime.securesms.conversation.v2.items
import android.view.View
import android.widget.Space
import org.signal.core.util.StringUtil
import org.signal.core.util.BidiUtil
import org.signal.core.util.dp
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.emoji.EmojiTextView
@@ -80,7 +80,7 @@ class V2FooterPositionDelegate private constructor(
return false
}
if (body.isJumbomoji || StringUtil.hasMixedTextDirection(body.text)) {
if (body.isJumbomoji || BidiUtil.hasMixedTextDirection(body.text)) {
displayUnderneathBody()
return true
}

View File

@@ -6,7 +6,7 @@
package org.thoughtcrime.securesms.database.model
import okio.ByteString
import org.signal.core.util.StringUtil
import org.signal.core.util.BidiUtil
import org.signal.core.util.isNullOrEmpty
import org.signal.storageservice.protos.groups.AccessControl
import org.signal.storageservice.protos.groups.AccessControl.AccessRequired
@@ -340,7 +340,7 @@ object GroupsV2UpdateMessageConverter {
fun translateNewTitle(change: DecryptedGroupChange, editorUnknown: Boolean, updates: MutableList<GroupChangeChatUpdate.Update>) {
if (change.newTitle != null) {
val editorAci = if (editorUnknown) null else change.editorServiceIdBytes
val newTitle = StringUtil.isolateBidi(change.newTitle?.value_)
val newTitle = BidiUtil.isolateBidi(change.newTitle?.value_)
updates.add(
GroupChangeChatUpdate.Update(
groupNameUpdate = GroupNameUpdate(

View File

@@ -12,6 +12,7 @@ import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.core.content.ContextCompat;
import org.signal.core.util.BidiUtil;
import org.signal.core.util.StringUtil;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.Member;
@@ -551,9 +552,9 @@ final class GroupsV2UpdateMessageProducer {
private void describeGroupNameUpdate(@NonNull GroupNameUpdate update, @NonNull List<UpdateDescription> updates) {
if (update.updaterAci == null) {
updates.add(updateDescription(context.getString(R.string.MessageRecord_the_group_name_has_changed_to_s, StringUtil.isolateBidi(update.newGroupName)), R.drawable.ic_update_group_name_16));
updates.add(updateDescription(context.getString(R.string.MessageRecord_the_group_name_has_changed_to_s, BidiUtil.isolateBidi(update.newGroupName)), R.drawable.ic_update_group_name_16));
} else {
String newTitle = StringUtil.isolateBidi(update.newGroupName);
String newTitle = BidiUtil.isolateBidi(update.newGroupName);
if (selfIds.matches(update.updaterAci)) {
updates.add(updateDescription(context.getString(R.string.MessageRecord_you_changed_the_group_name_to_s, newTitle), R.drawable.ic_update_group_name_16));
} else {
@@ -1081,7 +1082,7 @@ final class GroupsV2UpdateMessageProducer {
boolean editorIsYou = selfIds.matches(change.editorServiceIdBytes);
if (change.newTitle != null) {
String newTitle = StringUtil.isolateBidi(change.newTitle.value_);
String newTitle = BidiUtil.isolateBidi(change.newTitle.value_);
if (editorIsYou) {
updates.add(updateDescription(context.getString(R.string.MessageRecord_you_changed_the_group_name_to_s, newTitle), R.drawable.ic_update_group_name_16));
} else {
@@ -1104,7 +1105,7 @@ final class GroupsV2UpdateMessageProducer {
private void describeUnknownEditorNewTitle(@NonNull DecryptedGroupChange change, @NonNull List<UpdateDescription> updates) {
if (change.newTitle != null) {
updates.add(updateDescription(context.getString(R.string.MessageRecord_the_group_name_has_changed_to_s, StringUtil.isolateBidi(change.newTitle.value_)), R.drawable.ic_update_group_name_16));
updates.add(updateDescription(context.getString(R.string.MessageRecord_the_group_name_has_changed_to_s, BidiUtil.isolateBidi(change.newTitle.value_)), R.drawable.ic_update_group_name_16));
}
}
@@ -1118,7 +1119,7 @@ final class GroupsV2UpdateMessageProducer {
updates.add(updateDescription(R.string.MessageRecord_s_changed_the_group_description, groupDescriptionUpdate.updaterAci, R.drawable.ic_update_group_name_16));
}
} else {
updates.add(updateDescription(context.getString(R.string.MessageRecord_the_group_name_has_changed_to_s, StringUtil.isolateBidi(groupDescriptionUpdate.newDescription)), R.drawable.ic_update_group_name_16));
updates.add(updateDescription(context.getString(R.string.MessageRecord_the_group_name_has_changed_to_s, BidiUtil.isolateBidi(groupDescriptionUpdate.newDescription)), R.drawable.ic_update_group_name_16));
}
}

View File

@@ -34,6 +34,7 @@ import androidx.core.content.ContextCompat;
import com.annimon.stream.Stream;
import org.signal.core.util.Base64;
import org.signal.core.util.BidiUtil;
import org.signal.core.util.StringUtil;
import org.signal.core.util.logging.Log;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
@@ -470,8 +471,8 @@ public abstract class MessageRecord extends DisplayRecord {
if (profileChangeDetails != null) {
if (profileChangeDetails.profileNameChange != null) {
String displayName = getFromRecipient().getDisplayName(context);
String newName = StringUtil.isolateBidi(ProfileName.fromSerialized(profileChangeDetails.profileNameChange.newValue).toString());
String previousName = StringUtil.isolateBidi(ProfileName.fromSerialized(profileChangeDetails.profileNameChange.previous).toString());
String newName = BidiUtil.isolateBidi(ProfileName.fromSerialized(profileChangeDetails.profileNameChange.newValue).toString());
String previousName = BidiUtil.isolateBidi(ProfileName.fromSerialized(profileChangeDetails.profileNameChange.previous).toString());
String updateMessage;
if (getFromRecipient().isSystemContact()) {

View File

@@ -10,6 +10,7 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import com.google.i18n.phonenumbers.ShortNumberInfo;
import org.signal.core.util.BidiUtil;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.util.Pair;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
@@ -80,7 +81,7 @@ public class PhoneNumberFormatter {
}
public static @NonNull String prettyPrint(@NonNull String e164) {
return StringUtil.forceLtr(get(AppDependencies.getApplication()).prettyPrintFormat(e164));
return BidiUtil.forceLtr(get(AppDependencies.getApplication()).prettyPrintFormat(e164));
}
public @NonNull String prettyPrintFormat(@NonNull String e164) {
@@ -91,13 +92,13 @@ public class PhoneNumberFormatter {
localNumber.get().countryCode == parsedNumber.getCountryCode() &&
NATIONAL_FORMAT_COUNTRY_CODES.contains(localNumber.get().getCountryCode()))
{
return StringUtil.isolateBidi(phoneNumberUtil.format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.NATIONAL));
return BidiUtil.isolateBidi(phoneNumberUtil.format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.NATIONAL));
} else {
return StringUtil.isolateBidi(phoneNumberUtil.format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL));
return BidiUtil.isolateBidi(phoneNumberUtil.format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL));
}
} catch (NumberParseException e) {
Log.w(TAG, "Failed to format number: " + e.toString());
return StringUtil.isolateBidi(e164);
return BidiUtil.isolateBidi(e164);
}
}

View File

@@ -8,6 +8,7 @@ import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import org.signal.core.util.BidiUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.conversation.colors.AvatarColor;
import org.thoughtcrime.securesms.groups.GroupId;
@@ -155,9 +156,9 @@ class EditProfileViewModel extends ViewModel {
repository.uploadProfile(profileName,
displayName,
!Objects.equals(StringUtil.stripBidiProtection(oldDisplayName), displayName),
!Objects.equals(BidiUtil.stripBidiProtection(oldDisplayName), displayName),
description,
!Objects.equals(StringUtil.stripBidiProtection(oldDescription), description),
!Objects.equals(BidiUtil.stripBidiProtection(oldDescription), description),
newAvatar,
!Arrays.equals(oldAvatar, newAvatar),
uploadResult::postValue);

View File

@@ -7,7 +7,7 @@ import androidx.annotation.WorkerThread
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.collections.immutable.toImmutableList
import org.signal.core.util.StringUtil
import org.signal.core.util.BidiUtil
import org.signal.core.util.isNotNullOrBlank
import org.signal.core.util.logging.Log
import org.signal.core.util.nullIfBlank
@@ -532,7 +532,7 @@ class Recipient(
if (Util.isEmpty(name)) {
name = getUnknownDisplayName(context)
}
return StringUtil.isolateBidi(name)
return BidiUtil.isolateBidi(name)
}
fun hasNonUsernameDisplayName(context: Context): Boolean {
@@ -569,21 +569,21 @@ class Recipient(
/** A display name to use when rendering a mention of this user. */
fun getMentionDisplayName(context: Context): String {
var name: String? = if (isSelf) profileName.toString() else getGroupName(context)
name = StringUtil.isolateBidi(name)
name = BidiUtil.isolateBidi(name)
if (name.isBlank()) {
name = if (isSelf) getGroupName(context) else nickname.toString()
name = StringUtil.isolateBidi(name)
name = BidiUtil.isolateBidi(name)
}
if (name.isBlank()) {
name = if (isSelf) getGroupName(context) else systemContactName
name = StringUtil.isolateBidi(name)
name = BidiUtil.isolateBidi(name)
}
if (name.isBlank()) {
name = if (isSelf) getGroupName(context) else profileName.toString()
name = StringUtil.isolateBidi(name)
name = BidiUtil.isolateBidi(name)
}
if (name.isBlank() && e164Value.isNotNullOrBlank()) {
@@ -591,11 +591,11 @@ class Recipient(
}
if (name.isBlank()) {
name = StringUtil.isolateBidi(emailValue)
name = BidiUtil.isolateBidi(emailValue)
}
if (name.isBlank()) {
name = StringUtil.isolateBidi(context.getString(R.string.Recipient_unknown))
name = BidiUtil.isolateBidi(context.getString(R.string.Recipient_unknown))
}
return name
@@ -615,7 +615,7 @@ class Recipient(
getDisplayName(context)
).firstOrNull { it.isNotNullOrBlank() }
return StringUtil.isolateBidi(name)
return BidiUtil.isolateBidi(name)
}
private fun getUnknownDisplayName(context: Context): String {

View File

@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.signal.core.util.BidiUtil;
import org.signal.core.util.StringUtil;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.zkgroup.InvalidInputException;
@@ -115,7 +116,7 @@ public final class GroupUtil {
return description.toString();
}
String title = StringUtil.isolateBidi(groupContext.getName());
String title = BidiUtil.isolateBidi(groupContext.getName());
if (members != null && members.size() > 0) {
description.append("\n");