On android 6.0, filter 0x00ad (unicode soft hyphen) from statuses (#884)
Fixes #563
This commit is contained in:
parent
16b53a5917
commit
25c3defd33
1 changed files with 42 additions and 3 deletions
|
@ -15,7 +15,9 @@
|
||||||
|
|
||||||
package com.keylesspalace.tusky.viewdata;
|
package com.keylesspalace.tusky.viewdata;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
|
||||||
import com.keylesspalace.tusky.entity.Attachment;
|
import com.keylesspalace.tusky.entity.Attachment;
|
||||||
|
@ -47,6 +49,9 @@ public abstract class StatusViewData {
|
||||||
public abstract boolean deepEquals(StatusViewData other);
|
public abstract boolean deepEquals(StatusViewData other);
|
||||||
|
|
||||||
public static final class Concrete extends StatusViewData {
|
public static final class Concrete extends StatusViewData {
|
||||||
|
private static final char SOFT_HYPHEN = '\u00ad';
|
||||||
|
private static final char ASCII_HYPHEN = '-';
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final Spanned content;
|
private final Spanned content;
|
||||||
private final boolean reblogged;
|
private final boolean reblogged;
|
||||||
|
@ -92,10 +97,18 @@ public abstract class StatusViewData {
|
||||||
Status.Application application, List<Emoji> statusEmojis, List<Emoji> accountEmojis, @Nullable Card card,
|
Status.Application application, List<Emoji> statusEmojis, List<Emoji> accountEmojis, @Nullable Card card,
|
||||||
boolean isCollapsible, boolean isCollapsed) {
|
boolean isCollapsible, boolean isCollapsed) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.content = content;
|
if (Build.VERSION.SDK_INT == 23) {
|
||||||
|
// https://github.com/tuskyapp/Tusky/issues/563
|
||||||
|
this.content = replaceCrashingCharacters(content);
|
||||||
|
this.spoilerText = spoilerText == null ? null : replaceCrashingCharacters(spoilerText).toString();
|
||||||
|
this.nickname = replaceCrashingCharacters(nickname).toString();
|
||||||
|
} else {
|
||||||
|
this.content = content;
|
||||||
|
this.spoilerText = spoilerText;
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
this.reblogged = reblogged;
|
this.reblogged = reblogged;
|
||||||
this.favourited = favourited;
|
this.favourited = favourited;
|
||||||
this.spoilerText = spoilerText;
|
|
||||||
this.visibility = visibility;
|
this.visibility = visibility;
|
||||||
this.attachments = attachments;
|
this.attachments = attachments;
|
||||||
this.rebloggedByUsername = rebloggedByUsername;
|
this.rebloggedByUsername = rebloggedByUsername;
|
||||||
|
@ -104,7 +117,6 @@ public abstract class StatusViewData {
|
||||||
this.isExpanded = isExpanded;
|
this.isExpanded = isExpanded;
|
||||||
this.isShowingContent = isShowingContent;
|
this.isShowingContent = isShowingContent;
|
||||||
this.userFullName = userFullName;
|
this.userFullName = userFullName;
|
||||||
this.nickname = nickname;
|
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
this.createdAt = createdAt;
|
this.createdAt = createdAt;
|
||||||
this.reblogsCount = reblogsCount;
|
this.reblogsCount = reblogsCount;
|
||||||
|
@ -288,6 +300,33 @@ public abstract class StatusViewData {
|
||||||
Objects.equals(card, concrete.card)
|
Objects.equals(card, concrete.card)
|
||||||
&& isCollapsed == concrete.isCollapsed;
|
&& isCollapsed == concrete.isCollapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Spanned replaceCrashingCharacters(Spanned content) {
|
||||||
|
return (Spanned) replaceCrashingCharacters((CharSequence) content);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CharSequence replaceCrashingCharacters(CharSequence content) {
|
||||||
|
Boolean replacing = false;
|
||||||
|
SpannableStringBuilder builder = null;
|
||||||
|
int length = content.length();
|
||||||
|
|
||||||
|
for (int index = 0; index < length; ++index) {
|
||||||
|
char character = content.charAt(index);
|
||||||
|
|
||||||
|
// If there are more than one or two, switch to a map
|
||||||
|
if (character == SOFT_HYPHEN) {
|
||||||
|
if (!replacing) {
|
||||||
|
replacing = true;
|
||||||
|
builder = new SpannableStringBuilder(content, 0, index);
|
||||||
|
}
|
||||||
|
builder.append(ASCII_HYPHEN);
|
||||||
|
} else if (replacing) {
|
||||||
|
builder.append(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return replacing ? builder : content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Placeholder extends StatusViewData {
|
public static final class Placeholder extends StatusViewData {
|
||||||
|
|
Loading…
Reference in a new issue