diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/utils/TextWithEmoji.java b/app/src/main/java/org/nuclearfog/twidda/backend/utils/EmojiUtils.java similarity index 57% rename from app/src/main/java/org/nuclearfog/twidda/backend/utils/TextWithEmoji.java rename to app/src/main/java/org/nuclearfog/twidda/backend/utils/EmojiUtils.java index c63f1cdd..beac44e7 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/utils/TextWithEmoji.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/utils/EmojiUtils.java @@ -17,11 +17,15 @@ import java.util.regex.Pattern; * * @author nuclearfog */ -public class TextWithEmoji { +public class EmojiUtils { + /** + * emoji pattern used by Mastodon + */ private static final Pattern EMOJI_PATTERN = Pattern.compile(":\\w+:"); - private TextWithEmoji() {} + + private EmojiUtils() {} /** * replace tags with emojis @@ -31,16 +35,14 @@ public class TextWithEmoji { */ public static Spannable addEmojis(Context context, Spannable spannable, Map emojis) { if (spannable.length() > 0 && !emojis.isEmpty()) { - SpannableStringBuilder builder = new SpannableStringBuilder(spannable); - Matcher matcher = EMOJI_PATTERN.matcher(spannable); - Stack indexes = new Stack<>(); - while (matcher.find()) { - indexes.push(matcher.start()); - indexes.push(matcher.end()); + Stack indexes = getTagIndexes(spannable); + if (indexes.isEmpty()) { + return spannable; } + SpannableStringBuilder builder = new SpannableStringBuilder(spannable); while (!indexes.isEmpty()) { - int end = indexes.pop(); int start = indexes.pop(); + int end = indexes.pop(); String tag = builder.subSequence(start + 1, end - 1).toString(); Bitmap emoji = emojis.get(tag); if (emoji != null) { @@ -54,4 +56,39 @@ public class TextWithEmoji { } return spannable; } + + /** + * remove emoji tags from spannable + */ + public static Spannable removeTags(Spannable spannable) { + if (spannable.length() > 0) { + Stack indexes = getTagIndexes(spannable); + if (!indexes.isEmpty()) { + SpannableStringBuilder builder = new SpannableStringBuilder(spannable); + while (!indexes.isEmpty()) { + int start = indexes.pop(); + int end = indexes.pop(); + builder.delete(start, end); + } + return builder; + } + } + return spannable; + } + + /** + * create a stack with indexes of emoji tags + * + * @param spannable spannable containing emoji tags + * @return indexes stack + */ + private static Stack getTagIndexes(Spannable spannable) { + Matcher matcher = EMOJI_PATTERN.matcher(spannable); + Stack indexes = new Stack<>(); + while (matcher.find()) { + indexes.push(matcher.end()); + indexes.push(matcher.start()); + } + return indexes; + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java index 6b0a67cc..b8991090 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java @@ -74,7 +74,7 @@ import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.image.PicassoBuilder; import org.nuclearfog.twidda.backend.utils.StringUtils; -import org.nuclearfog.twidda.backend.utils.TextWithEmoji; +import org.nuclearfog.twidda.backend.utils.EmojiUtils; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Relation; import org.nuclearfog.twidda.model.User; @@ -765,6 +765,9 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult } if (!user.getDescription().isEmpty()) { descriptionSpan = Tagger.makeTextWithLinks(user.getDescription(), settings.getHighlightColor(), this); + if (user.getEmojis().length > 0) { + descriptionSpan = EmojiUtils.removeTags(descriptionSpan); + } description.setText(descriptionSpan); description.setVisibility(VISIBLE); } else { @@ -834,7 +837,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult */ private void onUsernameUpdate(@NonNull EmojiResult result) { if (result.images != null) { - Spannable spannable = TextWithEmoji.addEmojis(getApplicationContext(), result.spannable, result.images); + Spannable spannable = EmojiUtils.addEmojis(getApplicationContext(), result.spannable, result.images); username.setText(spannable); } } @@ -844,7 +847,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult */ private void onUserDescriptionUpdate(@NonNull EmojiResult result) { if (result.images != null) { - Spannable spannable = TextWithEmoji.addEmojis(getApplicationContext(), result.spannable, result.images); + Spannable spannable = EmojiUtils.addEmojis(getApplicationContext(), result.spannable, result.images); description.setText(spannable); } } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java index 837c50b9..5e08d808 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java @@ -71,7 +71,7 @@ import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.image.PicassoBuilder; import org.nuclearfog.twidda.backend.utils.StringUtils; -import org.nuclearfog.twidda.backend.utils.TextWithEmoji; +import org.nuclearfog.twidda.backend.utils.EmojiUtils; import org.nuclearfog.twidda.config.Configuration; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Card; @@ -1141,7 +1141,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener */ private void onStatusTextUpdate(@NonNull EmojiResult result) { if (settings.getLogin().getConfiguration() == Configuration.MASTODON && result.images != null) { - Spannable spannable = TextWithEmoji.addEmojis(getApplicationContext(), result.spannable, result.images); + Spannable spannable = EmojiUtils.addEmojis(getApplicationContext(), result.spannable, result.images); statusText.setText(spannable); } } @@ -1151,7 +1151,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener */ private void onUsernameUpdate(@NonNull EmojiResult result) { if (settings.getLogin().getConfiguration() == Configuration.MASTODON && result.images != null) { - Spannable spannable = TextWithEmoji.addEmojis(getApplicationContext(), result.spannable, result.images); + Spannable spannable = EmojiUtils.addEmojis(getApplicationContext(), result.spannable, result.images); username.setText(spannable); } } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/StatusHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/StatusHolder.java index 16d7c0c9..b0878ccf 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/StatusHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/StatusHolder.java @@ -32,7 +32,7 @@ import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiParam; import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiResult; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.StringUtils; -import org.nuclearfog.twidda.backend.utils.TextWithEmoji; +import org.nuclearfog.twidda.backend.utils.EmojiUtils; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Notification; import org.nuclearfog.twidda.model.Status; @@ -155,6 +155,9 @@ public class StatusHolder extends ViewHolder implements OnClickListener { created.setText(StringUtils.formatCreationTime(itemView.getResources(), status.getTimestamp())); if (!status.getText().trim().isEmpty()) { textSpan = Tagger.makeTextWithLinks(status.getText(), settings.getHighlightColor()); + if (status.getEmojis().length > 0) { + textSpan = EmojiUtils.removeTags(textSpan); + } statusText.setText(textSpan); statusText.setVisibility(View.VISIBLE); } else { @@ -288,7 +291,7 @@ public class StatusHolder extends ViewHolder implements OnClickListener { */ private void setUsernameEmojis(@NonNull EmojiResult result) { if (result.id == tagId && result.images != null) { - Spannable spannable = TextWithEmoji.addEmojis(username.getContext(), result.spannable, result.images); + Spannable spannable = EmojiUtils.addEmojis(username.getContext(), result.spannable, result.images); username.setText(spannable); } } @@ -300,7 +303,7 @@ public class StatusHolder extends ViewHolder implements OnClickListener { */ private void setTextEmojis(@NonNull EmojiResult result) { if (result.id == tagId && result.images != null) { - Spannable spannable = TextWithEmoji.addEmojis(statusText.getContext(), result.spannable, result.images); + Spannable spannable = EmojiUtils.addEmojis(statusText.getContext(), result.spannable, result.images); statusText.setText(spannable); } } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/UserHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/UserHolder.java index 77ed289d..fec83ee6 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/UserHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/UserHolder.java @@ -30,7 +30,7 @@ import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiParam; import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiResult; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.StringUtils; -import org.nuclearfog.twidda.backend.utils.TextWithEmoji; +import org.nuclearfog.twidda.backend.utils.EmojiUtils; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Notification; import org.nuclearfog.twidda.model.User; @@ -110,7 +110,7 @@ public class UserHolder extends ViewHolder implements OnClickListener, AsyncCall @Override public void onResult(@NonNull EmojiResult result) { if (result.id == tagId && result.images != null) { - Spannable spannable = TextWithEmoji.addEmojis(username.getContext(), result.spannable, result.images); + Spannable spannable = EmojiUtils.addEmojis(username.getContext(), result.spannable, result.images); username.setText(spannable); } }