mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 19:28:26 +00:00
parent
5ffee53faa
commit
b17cba621e
@ -75,7 +75,8 @@
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?conversation_item_received_text_primary_color"
|
||||
android:textColorLink="?conversation_item_received_text_primary_color"
|
||||
android:textSize="@dimen/conversation_item_body_text_size" />
|
||||
android:textSize="@dimen/conversation_item_body_text_size"
|
||||
app:scaleEmojis="true" />
|
||||
|
||||
<LinearLayout android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -65,7 +65,8 @@
|
||||
android:textColor="?conversation_item_sent_text_primary_color"
|
||||
android:textColorLink="?conversation_item_sent_text_primary_color"
|
||||
android:textSize="@dimen/conversation_item_body_text_size"
|
||||
tools:text="Mango pickle lorem ipsum" />
|
||||
app:scaleEmojis="true"
|
||||
tools:text="Mango pickle lorem ipsum"/>
|
||||
|
||||
<LinearLayout android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -194,5 +194,9 @@
|
||||
<attr name="documentForegroundTintColor" format="color" />
|
||||
<attr name="documentBackgroundTintColor" format="color" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="EmojiTextView">
|
||||
<attr name="scaleEmojis" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.components.emoji.parsing.EmojiTree;
|
||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
class EmojiProvider {
|
||||
@ -71,10 +70,19 @@ class EmojiProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
|
||||
@Nullable EmojiParser.CandidateList getCandidates(@Nullable CharSequence text) {
|
||||
if (text == null) return null;
|
||||
return new EmojiParser(emojiTree).findCandidates(text);
|
||||
}
|
||||
|
||||
List<EmojiParser.Candidate> matches = new EmojiParser(emojiTree).findCandidates(text);
|
||||
@Nullable Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
|
||||
return emojify(getCandidates(text), text, tv);
|
||||
}
|
||||
|
||||
@Nullable Spannable emojify(@Nullable EmojiParser.CandidateList matches,
|
||||
@Nullable CharSequence text,
|
||||
@NonNull TextView tv) {
|
||||
if (matches == null || text == null) return null;
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(text);
|
||||
|
||||
for (EmojiParser.Candidate candidate : matches) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms.components.emoji;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Paint.FontMetricsInt;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
@ -9,12 +10,18 @@ import android.support.v7.widget.AppCompatTextView;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextUtils.TruncateAt;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
|
||||
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
public class EmojiTextView extends AppCompatTextView {
|
||||
private final boolean scaleEmojis;
|
||||
private final float originalFontSize;
|
||||
|
||||
private CharSequence source;
|
||||
private boolean needsEllipsizing;
|
||||
|
||||
@ -28,15 +35,38 @@ public class EmojiTextView extends AppCompatTextView {
|
||||
|
||||
public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EmojiTextView, 0, 0);
|
||||
scaleEmojis = a.getBoolean(R.styleable.EmojiTextView_scaleEmojis, false);
|
||||
a.recycle();
|
||||
|
||||
a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.textSize});
|
||||
originalFontSize = a.getDimensionPixelSize(0, 0);
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@Override public void setText(@Nullable CharSequence text, BufferType type) {
|
||||
EmojiProvider provider = EmojiProvider.getInstance(getContext());
|
||||
EmojiParser.CandidateList candidates = provider.getCandidates(text);
|
||||
|
||||
if (scaleEmojis && candidates != null && candidates.allEmojis) {
|
||||
int emojis = candidates.size();
|
||||
float scale = 1.0f;
|
||||
if (emojis <= 8) scale += 0.25f;
|
||||
if (emojis <= 6) scale += 0.25f;
|
||||
if (emojis <= 4) scale += 0.25f;
|
||||
if (emojis <= 2) scale += 0.25f;
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize() * scale);
|
||||
} else if (scaleEmojis) {
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_PX, originalFontSize);
|
||||
}
|
||||
|
||||
if (useSystemEmoji()) {
|
||||
super.setText(text, type);
|
||||
return;
|
||||
}
|
||||
|
||||
source = EmojiProvider.getInstance(getContext()).emojify(text, this);
|
||||
source = EmojiProvider.getInstance(getContext()).emojify(candidates, text, this);
|
||||
setTextEllipsized(source);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ package org.thoughtcrime.securesms.components.emoji.parsing;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -38,10 +39,12 @@ public class EmojiParser {
|
||||
this.emojiTree = emojiTree;
|
||||
}
|
||||
|
||||
public @NonNull List<Candidate> findCandidates(@Nullable CharSequence text) {
|
||||
public @NonNull CandidateList findCandidates(@Nullable CharSequence text) {
|
||||
List<Candidate> results = new LinkedList<>();
|
||||
|
||||
if (text == null) return results;
|
||||
if (text == null) return new CandidateList(results, false);
|
||||
|
||||
boolean allEmojis = text.length() > 0;
|
||||
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
int emojiEnd = getEmojiEndPos(text, i);
|
||||
@ -58,10 +61,12 @@ public class EmojiParser {
|
||||
results.add(new Candidate(i, emojiEnd, drawInfo));
|
||||
|
||||
i = emojiEnd - 1;
|
||||
} else {
|
||||
allEmojis = false;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
return new CandidateList(results, allEmojis);
|
||||
}
|
||||
|
||||
private int getEmojiEndPos(CharSequence text, int startPos) {
|
||||
@ -105,4 +110,23 @@ public class EmojiParser {
|
||||
}
|
||||
}
|
||||
|
||||
public class CandidateList implements Iterable<Candidate> {
|
||||
public final List<EmojiParser.Candidate> list;
|
||||
public final boolean allEmojis;
|
||||
|
||||
public CandidateList(List<EmojiParser.Candidate> candidates, boolean allEmojis) {
|
||||
this.list = candidates;
|
||||
this.allEmojis = allEmojis;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Candidate> iterator() {
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user