diff --git a/app/build.gradle b/app/build.gradle
index eed689f9..ecb2055f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -137,9 +137,14 @@ dependencies {
implementation project(':emoji')
implementation project(':apng_android')
-
implementation "androidx.appcompat:appcompat:$appcompat_version"
+ def emojiVersion = "1.0.0-rc01"
+ implementation "androidx.emoji2:emoji2:$emojiVersion"
+ implementation "androidx.emoji2:emoji2-bundled:$emojiVersion"
+ implementation "androidx.emoji2:emoji2-views:$emojiVersion"
+ implementation "androidx.emoji2:emoji2-views-helper:$emojiVersion"
+
// DrawerLayout
implementation "androidx.drawerlayout:drawerlayout:1.1.1"
@@ -157,7 +162,7 @@ dependencies {
// Recyclerview
implementation "androidx.recyclerview:recyclerview:1.2.1"
- kapt 'androidx.annotation:annotation:1.2.0'
+ kapt 'androidx.annotation:annotation:1.3.0'
// https://firebase.google.com/support/release-notes/android
implementation "com.google.firebase:firebase-messaging:23.0.0"
@@ -228,7 +233,7 @@ dependencies {
implementation 'com.astuetz:pagerslidingtabstrip:1.0.1'
- implementation 'com.google.android.exoplayer:exoplayer:2.15.1'
+ implementation 'com.google.android.exoplayer:exoplayer:2.16.0'
/*
WARNING: [Processor] Library '…\exoplayer-ui-2.12.0.aar' contains references to both AndroidX and old support library. This seems like the library is partially migrated. Jetifier will try to rewrite the library anyway.
Example of androidX reference: 'androidx/core/app/NotificationCompat$Builder'
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt b/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt
index e5e9d66f..02791d69 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActMain.kt
@@ -343,7 +343,7 @@ class ActMain : AppCompatActivity(),
density = appState.density
completionHelper = CompletionHelper(this, pref, appState.handler)
- EmojiDecoder.handleUnicodeEmoji = PrefB.bpInAppUnicodeEmoji(pref)
+ EmojiDecoder.useTwemoji = PrefB.bpUseTwemoji(pref)
acctPadLr = (0.5f + 4f * density).toInt()
reloadTextSize()
diff --git a/app/src/main/java/jp/juggler/subwaytooter/Styler.kt b/app/src/main/java/jp/juggler/subwaytooter/Styler.kt
index 685054a3..243a6395 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/Styler.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/Styler.kt
@@ -12,9 +12,10 @@ import android.widget.ImageButton
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
-import jp.juggler.subwaytooter.emoji.EmojiMap
import jp.juggler.subwaytooter.api.entity.TootAccount
import jp.juggler.subwaytooter.api.entity.TootVisibility
+import jp.juggler.subwaytooter.emoji.EmojiMap
+import jp.juggler.subwaytooter.pref.PrefB
import jp.juggler.subwaytooter.pref.PrefI
import jp.juggler.subwaytooter.pref.pref
import jp.juggler.subwaytooter.span.EmojiImageSpan
@@ -384,14 +385,24 @@ fun SpannableStringBuilder.appendMisskeyReaction(
emojiUtf16: String,
text: String
): SpannableStringBuilder {
- val start = this.length
- this.append(text)
- val end = this.length
- this.setSpan(
- EmojiMap.unicodeMap[emojiUtf16]!!.createSpan(context),
- start, end,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
- )
+ val emoji = EmojiMap.unicodeMap[emojiUtf16]
+ when {
+ emoji == null ->
+ append("text")
+
+ PrefB.bpUseTwemoji(context) -> {
+ val start = this.length
+ append(text)
+ val end = this.length
+ this.setSpan(
+ emoji.createSpan(context),
+ start, end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ }
+ else ->
+ this.append(emoji.unifiedCode)
+ }
return this
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppSettingItem.kt b/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppSettingItem.kt
index e085e19d..e174da2f 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppSettingItem.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppSettingItem.kt
@@ -784,7 +784,7 @@ val appSettingRoot = AppSettingItem(null, SettingType.Section, R.string.app_sett
sw(PrefB.bpEmojioneShortcode, R.string.emojione_shortcode_support) {
desc = R.string.emojione_shortcode_support_desc
}
- sw(PrefB.bpInAppUnicodeEmoji, R.string.in_app_unicode_emoji)
+ sw(PrefB.bpUseTwemoji, R.string.use_twemoji_emoji)
sw(PrefB.bpKeepReactionSpace, R.string.keep_reaction_space)
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/columnviewholder/ViewHolderHeaderProfile.kt b/app/src/main/java/jp/juggler/subwaytooter/columnviewholder/ViewHolderHeaderProfile.kt
index b144e67e..95810cdb 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/columnviewholder/ViewHolderHeaderProfile.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/columnviewholder/ViewHolderHeaderProfile.kt
@@ -568,39 +568,50 @@ internal class ViewHolderHeaderProfile(
}
}
- private fun encodeAcctText(who: TootAccount, whoDetail: TootAccount?) = SpannableStringBuilder().apply {
- append("@")
- append(accessInfo.getFullAcct(who).pretty)
- if (whoDetail?.locked ?: who.locked) {
- append(" ")
- val emoji = EmojiMap.shortNameMap["lock"]
- if (emoji != null) {
- appendSpan("locked", emoji.createSpan(activity))
- } else {
- append("locked")
- }
- }
+ private fun encodeAcctText(who: TootAccount, whoDetail: TootAccount?) =
+ SpannableStringBuilder().apply {
+ append("@")
+ append(accessInfo.getFullAcct(who).pretty)
+ if (whoDetail?.locked ?: who.locked) {
+ append(" ")
+ val emoji = EmojiMap.shortNameMap["lock"]
+ when {
+ emoji == null ->
+ append("locked")
+ PrefB.bpUseTwemoji(App1.pref) ->
+ appendSpan("locked", emoji.createSpan(activity))
+ else ->
+ append(emoji.unifiedCode)
+ }
- if (who.bot) {
- append(" ")
- val emoji = EmojiMap.shortNameMap["robot_face"]
- if (emoji != null) {
- appendSpan("bot", emoji.createSpan(activity))
- } else {
- append("bot")
}
- }
- if (who.suspended) {
- append(" ")
- val emoji = EmojiMap.shortNameMap["cross_mark"]
- if (emoji != null) {
- appendSpan("suspended", emoji.createSpan(activity))
- } else {
- append("suspended")
+ if (who.bot) {
+ append(" ")
+ val emoji = EmojiMap.shortNameMap["robot_face"]
+ when {
+ emoji == null ->
+ append("bot")
+ PrefB.bpUseTwemoji(App1.pref) ->
+ appendSpan("bot", emoji.createSpan(activity))
+ else ->
+ append(emoji.unifiedCode)
+ }
+ }
+
+ if (who.suspended) {
+ append(" ")
+ val emoji = EmojiMap.shortNameMap["cross_mark"]
+ when {
+ emoji == null ->
+ append("suspended")
+ PrefB.bpUseTwemoji(App1.pref) ->
+ appendSpan("suspended", emoji.createSpan(activity))
+ else ->
+ append(emoji.unifiedCode)
+ }
}
}
- }
private fun encodeMisskeyExtra(whoDetail: TootAccount?) = SpannableStringBuilder().apply {
var s = whoDetail?.location
diff --git a/app/src/main/java/jp/juggler/subwaytooter/dialog/EmojiPicker.kt b/app/src/main/java/jp/juggler/subwaytooter/dialog/EmojiPicker.kt
index 1ac23440..379bc127 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/dialog/EmojiPicker.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/dialog/EmojiPicker.kt
@@ -6,6 +6,7 @@ import android.app.Dialog
import android.graphics.Typeface
import android.graphics.drawable.PictureDrawable
import android.util.SparseArray
+import android.util.TypedValue
import android.view.*
import android.widget.*
import androidx.annotation.StringRes
@@ -463,8 +464,13 @@ class EmojiPicker(
val view: View
val item = page.emojiList[position]
var unicodeEmoji = item.unicodeEmoji
- if (unicodeEmoji != null) {
-
+ if (unicodeEmoji == null) {
+ view = viewOld ?: NetworkEmojiView(activity).apply {
+ layoutParams = AbsListView.LayoutParams(wh, wh)
+ }
+ view.setTag(R.id.btnAbout, item)
+ (view as? NetworkEmojiView)?.setEmoji(customEmojiMap[item.name]?.url)
+ } else if(PrefB.bpUseTwemoji(App1.pref)){
view = viewOld
?: ImageView(activity).apply {
layoutParams = AbsListView.LayoutParams(wh, wh)
@@ -486,12 +492,22 @@ class EmojiPicker(
.into(view)
}
}
- } else {
- view = viewOld ?: NetworkEmojiView(activity).apply {
- layoutParams = AbsListView.LayoutParams(wh, wh)
- }
+ }else{
+ view = viewOld
+ ?: TextView(activity).apply {
+ layoutParams = AbsListView.LayoutParams(wh, wh)
+ }
+
view.setTag(R.id.btnAbout, item)
- (view as? NetworkEmojiView)?.setEmoji(customEmojiMap[item.name]?.url)
+
+ if (view is TextView && view.activity?.isDestroyed == false) {
+ if (page.hasSkinTone) unicodeEmoji = applySkinTone(unicodeEmoji)
+
+ view.text = unicodeEmoji.unifiedCode
+ view.gravity = Gravity.CENTER
+ view.setLineSpacing(0f,0f)
+ view.setTextSize(TypedValue.COMPLEX_UNIT_PX, wh.toFloat()*0.7f)
+ }
}
return view
diff --git a/app/src/main/java/jp/juggler/subwaytooter/pref/PrefB.kt b/app/src/main/java/jp/juggler/subwaytooter/pref/PrefB.kt
index 5676065b..fa8378de 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/pref/PrefB.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/pref/PrefB.kt
@@ -319,9 +319,9 @@ object PrefB {
false
)
- val bpInAppUnicodeEmoji = BooleanPref(
- "InAppUnicodeEmoji",
- true
+ val bpUseTwemoji = BooleanPref(
+ "UseTwemoji",
+ false
)
val bpKeepReactionSpace = BooleanPref(
@@ -347,4 +347,4 @@ object PrefB {
"MfmDecorationShowUnsupportedMarkup",
true
)
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/span/SvgEmojiSpan.kt b/app/src/main/java/jp/juggler/subwaytooter/span/SvgEmojiSpan.kt
index ad510e88..14fcb527 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/span/SvgEmojiSpan.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/span/SvgEmojiSpan.kt
@@ -8,14 +8,16 @@ import android.text.style.ReplacementSpan
import androidx.annotation.IntRange
import com.caverock.androidsvg.SVG
import jp.juggler.subwaytooter.emoji.UnicodeEmoji
+import jp.juggler.subwaytooter.pref.PrefB
import jp.juggler.util.LogCategory
// 絵文字リソースの種類によって異なるスパンを作る
-fun UnicodeEmoji.createSpan(context: Context, scale: Float = 1f) = if (isSvg) {
- SvgEmojiSpan(context, assetsName!!, scale = scale)
-} else {
- EmojiImageSpan(context, drawableId, scale = scale)
-}
+fun UnicodeEmoji.createSpan(context: Context, scale: Float = 1f) =
+ if (isSvg) {
+ SvgEmojiSpan(context, assetsName!!, scale = scale)
+ } else {
+ EmojiImageSpan(context, drawableId, scale = scale)
+ }
// SVG絵文字スパン
class SvgEmojiSpan internal constructor(
diff --git a/app/src/main/java/jp/juggler/subwaytooter/util/EmojiDecoder.kt b/app/src/main/java/jp/juggler/subwaytooter/util/EmojiDecoder.kt
index ba04279c..94304ae9 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/util/EmojiDecoder.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/util/EmojiDecoder.kt
@@ -7,11 +7,11 @@ import android.text.Spanned
import android.util.SparseBooleanArray
import androidx.annotation.DrawableRes
import jp.juggler.subwaytooter.App1
-import jp.juggler.subwaytooter.pref.PrefB
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.emoji.CustomEmoji
import jp.juggler.subwaytooter.emoji.EmojiMap
import jp.juggler.subwaytooter.emoji.UnicodeEmoji
+import jp.juggler.subwaytooter.pref.PrefB
import jp.juggler.subwaytooter.pref.pref
import jp.juggler.subwaytooter.span.EmojiImageSpan
import jp.juggler.subwaytooter.span.HighlightSpan
@@ -32,13 +32,14 @@ object EmojiDecoder {
private const val cpZwsp = '\u200B'.code
- var handleUnicodeEmoji = true
+ var useTwemoji = true
- fun customEmojiSeparator(pref: SharedPreferences) = if (PrefB.bpCustomEmojiSeparatorZwsp(pref)) {
- '\u200B'
- } else {
- ' '
- }
+ fun customEmojiSeparator(pref: SharedPreferences) =
+ if (PrefB.bpCustomEmojiSeparatorZwsp(pref)) {
+ '\u200B'
+ } else {
+ ' '
+ }
// タンス側が落ち着いたら [^[:almun:]_] から [:space:]に切り替える
// private fun isHeadOrAfterWhitespace( s:CharSequence,index:Int):Boolean {
@@ -168,26 +169,33 @@ object EmojiDecoder {
fun addImageSpan(text: String, emoji: UnicodeEmoji) {
val context = options.context
- if (context == null) {
- openNormalText()
- sb.append(text)
- } else {
- closeNormalText()
- val start = sb.length
- sb.append(text)
- val end = sb.length
- sb.setSpan(
- emoji.createSpan(context, scale = options.enlargeEmoji),
- start,
- end,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
- )
+ when {
+ context == null -> {
+ openNormalText()
+ sb.append(text)
+ }
+ PrefB.bpUseTwemoji(context) -> {
+ closeNormalText()
+ val start = sb.length
+ sb.append(text)
+ val end = sb.length
+ sb.setSpan(
+ emoji.createSpan(context, scale = options.enlargeEmoji),
+ start,
+ end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ }
+ else -> {
+ openNormalText()
+ sb.append(emoji.unifiedCode)
+ }
}
}
fun addUnicodeString(s: String) {
- if (!handleUnicodeEmoji) {
+ if (!useTwemoji) {
openNormalText()
sb.append(s)
return
@@ -466,16 +474,21 @@ object EmojiDecoder {
val emoji = EmojiMap.shortNameMap[shortCode] ?: continue
val sb = SpannableStringBuilder()
- val start = 0
- sb.append(' ')
- val end = sb.length
- sb.setSpan(
- emoji.createSpan(context),
- start,
- end,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
- )
+ if(PrefB.bpUseTwemoji(context)){
+ val start = 0
+ sb.append(' ')
+ val end = sb.length
+
+ sb.setSpan(
+ emoji.createSpan(context),
+ start,
+ end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ }else{
+ sb.append(emoji.unifiedCode)
+ }
sb.append(' ')
.append(':')
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 940688d0..125b2571 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -1101,4 +1101,5 @@
(Misskey)未対応のマークアップを表示する
添付メディアの説明文を表示する
背景パターン
+ Twemoji絵文字を使う
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7df43b84..82c2b1c9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1112,4 +1112,5 @@
(Misskey)Show unsupported markups
Show media description
Background pattern
+ Use Twemoji emoji
diff --git a/build.gradle b/build.gradle
index c8d63227..e75974b8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
ext.target_sdk_version = 31
ext.compile_sdk_version = 31
- ext.appcompat_version = '1.3.1'
+ ext.appcompat_version = '1.4.0-rc01'
ext.lifecycle_version = "2.4.0"
ext.arch_version = "2.1.0"