mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-21 09:28:27 +00:00
parent
5ffee53faa
commit
b17cba621e
@ -75,7 +75,8 @@
|
|||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textColor="?conversation_item_received_text_primary_color"
|
android:textColor="?conversation_item_received_text_primary_color"
|
||||||
android:textColorLink="?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"
|
<LinearLayout android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -65,7 +65,8 @@
|
|||||||
android:textColor="?conversation_item_sent_text_primary_color"
|
android:textColor="?conversation_item_sent_text_primary_color"
|
||||||
android:textColorLink="?conversation_item_sent_text_primary_color"
|
android:textColorLink="?conversation_item_sent_text_primary_color"
|
||||||
android:textSize="@dimen/conversation_item_body_text_size"
|
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"
|
<LinearLayout android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -194,5 +194,9 @@
|
|||||||
<attr name="documentForegroundTintColor" format="color" />
|
<attr name="documentForegroundTintColor" format="color" />
|
||||||
<attr name="documentBackgroundTintColor" format="color" />
|
<attr name="documentBackgroundTintColor" format="color" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="EmojiTextView">
|
||||||
|
<attr name="scaleEmojis" format="boolean" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.components.emoji.parsing.EmojiTree;
|
|||||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
class EmojiProvider {
|
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;
|
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);
|
SpannableStringBuilder builder = new SpannableStringBuilder(text);
|
||||||
|
|
||||||
for (EmojiParser.Candidate candidate : matches) {
|
for (EmojiParser.Candidate candidate : matches) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.components.emoji;
|
package org.thoughtcrime.securesms.components.emoji;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Paint.FontMetricsInt;
|
import android.graphics.Paint.FontMetricsInt;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
@ -9,12 +10,18 @@ import android.support.v7.widget.AppCompatTextView;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextUtils.TruncateAt;
|
import android.text.TextUtils.TruncateAt;
|
||||||
import android.util.AttributeSet;
|
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.EmojiProvider.EmojiDrawable;
|
||||||
|
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
public class EmojiTextView extends AppCompatTextView {
|
public class EmojiTextView extends AppCompatTextView {
|
||||||
|
private final boolean scaleEmojis;
|
||||||
|
private final float originalFontSize;
|
||||||
|
|
||||||
private CharSequence source;
|
private CharSequence source;
|
||||||
private boolean needsEllipsizing;
|
private boolean needsEllipsizing;
|
||||||
|
|
||||||
@ -28,15 +35,38 @@ public class EmojiTextView extends AppCompatTextView {
|
|||||||
|
|
||||||
public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, 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) {
|
@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()) {
|
if (useSystemEmoji()) {
|
||||||
super.setText(text, type);
|
super.setText(text, type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
source = EmojiProvider.getInstance(getContext()).emojify(text, this);
|
source = EmojiProvider.getInstance(getContext()).emojify(candidates, text, this);
|
||||||
setTextEllipsized(source);
|
setTextEllipsized(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ package org.thoughtcrime.securesms.components.emoji.parsing;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -38,10 +39,12 @@ public class EmojiParser {
|
|||||||
this.emojiTree = emojiTree;
|
this.emojiTree = emojiTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull List<Candidate> findCandidates(@Nullable CharSequence text) {
|
public @NonNull CandidateList findCandidates(@Nullable CharSequence text) {
|
||||||
List<Candidate> results = new LinkedList<>();
|
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++) {
|
for (int i = 0; i < text.length(); i++) {
|
||||||
int emojiEnd = getEmojiEndPos(text, i);
|
int emojiEnd = getEmojiEndPos(text, i);
|
||||||
@ -58,10 +61,12 @@ public class EmojiParser {
|
|||||||
results.add(new Candidate(i, emojiEnd, drawInfo));
|
results.add(new Candidate(i, emojiEnd, drawInfo));
|
||||||
|
|
||||||
i = emojiEnd - 1;
|
i = emojiEnd - 1;
|
||||||
|
} else {
|
||||||
|
allEmojis = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return new CandidateList(results, allEmojis);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getEmojiEndPos(CharSequence text, int startPos) {
|
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