絵文字のショートコード解釈時にカスタム絵文字を優先する
This commit is contained in:
parent
0da675f4e0
commit
3b8cbbe030
@ -634,6 +634,8 @@ class ActMain : AppCompatActivity()
|
|||||||
post_helper.bNSFW = false
|
post_helper.bNSFW = false
|
||||||
post_helper.in_reply_to_id = - 1L
|
post_helper.in_reply_to_id = - 1L
|
||||||
post_helper.attachment_list = null
|
post_helper.attachment_list = null
|
||||||
|
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account.host)
|
||||||
|
|
||||||
|
|
||||||
etQuickToot.hideKeyboard()
|
etQuickToot.hideKeyboard()
|
||||||
|
|
||||||
@ -1599,7 +1601,7 @@ class ActMain : AppCompatActivity()
|
|||||||
try {
|
try {
|
||||||
val dataId = sv.substring(3).toLong(10)
|
val dataId = sv.substring(3).toLong(10)
|
||||||
val sa = SavedAccount.loadAccount(this@ActMain, dataId)
|
val sa = SavedAccount.loadAccount(this@ActMain, dataId)
|
||||||
?: return TootApiResult("missing account db_id=" + dataId)
|
?: return TootApiResult("missing account db_id=$dataId")
|
||||||
this.sa = sa
|
this.sa = sa
|
||||||
client.account = sa
|
client.account = sa
|
||||||
} catch(ex : Throwable) {
|
} catch(ex : Throwable) {
|
||||||
|
@ -549,11 +549,11 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
|
|
||||||
// 今回メンションを追加する?
|
// 今回メンションを追加する?
|
||||||
val who_acct = account.getFullAcct(reply_status.account)
|
val who_acct = account.getFullAcct(reply_status.account)
|
||||||
if(mention_list.contains("@" + who_acct)) {
|
if(mention_list.contains("@$who_acct")) {
|
||||||
// 既に含まれている
|
// 既に含まれている
|
||||||
} else if(! account.isMe(reply_status.account) || mention_list.isEmpty()) {
|
} else if(! account.isMe(reply_status.account) || mention_list.isEmpty()) {
|
||||||
// 自分ではない、もしくは、メンションが空
|
// 自分ではない、もしくは、メンションが空
|
||||||
mention_list.add("@" + who_acct)
|
mention_list.add("@$who_acct")
|
||||||
}
|
}
|
||||||
|
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
@ -729,7 +729,6 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
findViewById(R.id.etChoice2),
|
findViewById(R.id.etChoice2),
|
||||||
findViewById(R.id.etChoice3),
|
findViewById(R.id.etChoice3),
|
||||||
findViewById(R.id.etChoice4)
|
findViewById(R.id.etChoice4)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
tvCharCount = findViewById(R.id.tvCharCount)
|
tvCharCount = findViewById(R.id.tvCharCount)
|
||||||
@ -835,6 +834,12 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
btnAccount.setBackgroundResource(R.drawable.btn_bg_transparent)
|
btnAccount.setBackgroundResource(R.drawable.btn_bg_transparent)
|
||||||
} else {
|
} else {
|
||||||
post_helper.setInstance(a.host)
|
post_helper.setInstance(a.host)
|
||||||
|
|
||||||
|
// 先読みしてキャッシュに保持しておく
|
||||||
|
App1.custom_emoji_lister.getList(a.host) {
|
||||||
|
// 何もしない
|
||||||
|
}
|
||||||
|
|
||||||
val acct = a.acct
|
val acct = a.acct
|
||||||
val ac = AcctColor.load(acct)
|
val ac = AcctColor.load(acct)
|
||||||
val nickname = if(AcctColor.hasNickname(ac)) ac.nickname else acct
|
val nickname = if(AcctColor.hasNickname(ac)) ac.nickname else acct
|
||||||
@ -1158,7 +1163,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
TootApiClient.MEDIA_TYPE_JSON, body_string
|
TootApiClient.MEDIA_TYPE_JSON, body_string
|
||||||
)
|
)
|
||||||
val request_builder = Request.Builder().put(request_body)
|
val request_builder = Request.Builder().put(request_body)
|
||||||
val result = client.request("/api/v1/media/" + attachment_id, request_builder)
|
val result = client.request("/api/v1/media/$attachment_id", request_builder)
|
||||||
new_attachment = parseItem(::TootAttachment, result?.jsonObject)
|
new_attachment = parseItem(::TootAttachment, result?.jsonObject)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -1240,6 +1245,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
internal interface InputStreamOpener {
|
internal interface InputStreamOpener {
|
||||||
|
|
||||||
val mimeType : String
|
val mimeType : String
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun open() : InputStream
|
fun open() : InputStream
|
||||||
|
|
||||||
@ -1276,7 +1282,6 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cache_dir.mkdir()
|
cache_dir.mkdir()
|
||||||
|
|
||||||
val temp_file = File(cache_dir, "tmp." + Thread.currentThread().id)
|
val temp_file = File(cache_dir, "tmp." + Thread.currentThread().id)
|
||||||
@ -1288,7 +1293,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return object : ActPost.InputStreamOpener {
|
return object : InputStreamOpener {
|
||||||
|
|
||||||
override val mimeType : String
|
override val mimeType : String
|
||||||
get() = mime_type
|
get() = mime_type
|
||||||
@ -1314,6 +1319,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
return object : InputStreamOpener {
|
return object : InputStreamOpener {
|
||||||
|
|
||||||
override val mimeType : String
|
override val mimeType : String
|
||||||
@ -1646,40 +1652,29 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
private fun performMore() {
|
private fun performMore() {
|
||||||
val dialog = ActionsDialog()
|
val dialog = ActionsDialog()
|
||||||
|
|
||||||
dialog.addAction(
|
dialog.addAction(getString(R.string.open_picker_emoji)) {
|
||||||
getString(R.string.open_picker_emoji)
|
|
||||||
) {
|
|
||||||
post_helper.openEmojiPickerFromMore()
|
post_helper.openEmojiPickerFromMore()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialog.addAction(getString(R.string.clear_text)) {
|
||||||
dialog.addAction(
|
|
||||||
getString(R.string.clear_text)
|
|
||||||
) {
|
|
||||||
etContent.setText("")
|
etContent.setText("")
|
||||||
etContentWarning.setText("")
|
etContentWarning.setText("")
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.addAction(
|
dialog.addAction(getString(R.string.clear_text_and_media)) {
|
||||||
getString(R.string.clear_text_and_media)
|
|
||||||
) {
|
|
||||||
etContent.setText("")
|
etContent.setText("")
|
||||||
etContentWarning.setText("")
|
etContentWarning.setText("")
|
||||||
attachment_list.clear()
|
attachment_list.clear()
|
||||||
showMediaAttachment()
|
showMediaAttachment()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PostDraft.hasDraft()) {
|
if(PostDraft.hasDraft()) dialog.addAction(getString(R.string.restore_draft)) {
|
||||||
dialog.addAction(
|
openDraftPicker()
|
||||||
getString(R.string.restore_draft)
|
|
||||||
) { openDraftPicker() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.addAction(
|
dialog.addAction(getString(R.string.recommended_plugin)) {
|
||||||
getString(R.string.recommended_plugin)
|
showRecommendedPlugin(null)
|
||||||
) { showRecommendedPlugin(null) }
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dialog.show(this, null)
|
dialog.show(this, null)
|
||||||
}
|
}
|
||||||
@ -1723,6 +1718,8 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
|
|
||||||
post_helper.attachment_list = this.attachment_list
|
post_helper.attachment_list = this.attachment_list
|
||||||
|
|
||||||
|
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account.host)
|
||||||
|
|
||||||
post_helper.post(account, false, false) { target_account, status ->
|
post_helper.post(account, false, false) { target_account, status ->
|
||||||
val data = Intent()
|
val data = Intent()
|
||||||
data.putExtra(EXTRA_POSTED_ACCT, target_account.acct)
|
data.putExtra(EXTRA_POSTED_ACCT, target_account.acct)
|
||||||
@ -1884,7 +1881,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
api_client.account = account
|
api_client.account = account
|
||||||
|
|
||||||
if(in_reply_to_id != - 1L) {
|
if(in_reply_to_id != - 1L) {
|
||||||
val result = api_client.request("/api/v1/statuses/" + in_reply_to_id)
|
val result = api_client.request("/api/v1/statuses/$in_reply_to_id")
|
||||||
if(isCancelled) return null
|
if(isCancelled) return null
|
||||||
val jsonObject = result?.jsonObject
|
val jsonObject = result?.jsonObject
|
||||||
if(jsonObject == null) {
|
if(jsonObject == null) {
|
||||||
|
@ -11,6 +11,7 @@ import java.util.concurrent.ConcurrentLinkedQueue
|
|||||||
import jp.juggler.subwaytooter.App1
|
import jp.juggler.subwaytooter.App1
|
||||||
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
||||||
import jp.juggler.subwaytooter.api.entity.parseList
|
import jp.juggler.subwaytooter.api.entity.parseList
|
||||||
|
import java.util.HashMap
|
||||||
|
|
||||||
class CustomEmojiLister(internal val context : Context) {
|
class CustomEmojiLister(internal val context : Context) {
|
||||||
|
|
||||||
@ -105,6 +106,18 @@ class CustomEmojiLister(internal val context : Context) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMap(host : String) : HashMap<String, CustomEmoji>? {
|
||||||
|
val list = getList(host,{
|
||||||
|
// 遅延ロード非対応
|
||||||
|
}) ?: return null
|
||||||
|
//
|
||||||
|
val dst = HashMap<String, CustomEmoji>()
|
||||||
|
for( e in list){
|
||||||
|
dst[e.shortcode] = e
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
private inner class Worker : WorkerBase() {
|
private inner class Worker : WorkerBase() {
|
||||||
|
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
|
@ -13,10 +13,12 @@ import java.util.ArrayList
|
|||||||
import jp.juggler.subwaytooter.App1
|
import jp.juggler.subwaytooter.App1
|
||||||
import jp.juggler.subwaytooter.Pref
|
import jp.juggler.subwaytooter.Pref
|
||||||
import jp.juggler.subwaytooter.R
|
import jp.juggler.subwaytooter.R
|
||||||
|
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
||||||
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
||||||
import jp.juggler.subwaytooter.span.HighlightSpan
|
import jp.juggler.subwaytooter.span.HighlightSpan
|
||||||
import jp.juggler.subwaytooter.span.NetworkEmojiSpan
|
import jp.juggler.subwaytooter.span.NetworkEmojiSpan
|
||||||
import jp.juggler.subwaytooter.table.HighlightWord
|
import jp.juggler.subwaytooter.table.HighlightWord
|
||||||
|
import java.util.HashMap
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
object EmojiDecoder {
|
object EmojiDecoder {
|
||||||
@ -245,12 +247,18 @@ object EmojiDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onShortCode(part : String, name : String) {
|
override fun onShortCode(part : String, name : String) {
|
||||||
// 通常の絵文字
|
|
||||||
val info = EmojiMap201709.sShortNameToImageId[name.toLowerCase().replace('-', '_')]
|
// フレニコのプロフ絵文字
|
||||||
if(info != null) {
|
if(emojiMapProfile != null && name.length >= 2 && name[0] == '@') {
|
||||||
builder.addImageSpan(part, info.image_id)
|
val emojiProfile = emojiMapProfile[name] ?: emojiMapProfile[name.substring(1)]
|
||||||
|
if(emojiProfile != null) {
|
||||||
|
val url = emojiProfile.url
|
||||||
|
if(url.isNotEmpty()) {
|
||||||
|
builder.addNetworkEmojiSpan(part, url)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// カスタム絵文字
|
// カスタム絵文字
|
||||||
val emojiCustom = emojiMapCustom?.get(name)
|
val emojiCustom = emojiMapCustom?.get(name)
|
||||||
@ -263,17 +271,12 @@ object EmojiDecoder {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// フレニコのプロフ絵文字
|
// 通常の絵文字
|
||||||
if(emojiMapProfile != null && name.length >= 2 && name[0] == '@') {
|
val info = EmojiMap201709.sShortNameToImageId[name.toLowerCase().replace('-', '_')]
|
||||||
val emojiProfile = emojiMapProfile[name] ?: emojiMapProfile[name.substring(1)]
|
if(info != null) {
|
||||||
if(emojiProfile != null) {
|
builder.addImageSpan(part, info.image_id)
|
||||||
val url = emojiProfile.url
|
|
||||||
if(url.isNotEmpty()) {
|
|
||||||
builder.addNetworkEmojiSpan(part, url)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when {
|
when {
|
||||||
reHohoemi.matcher(name).find() -> builder.addImageSpan(
|
reHohoemi.matcher(name).find() -> builder.addImageSpan(
|
||||||
@ -297,7 +300,7 @@ object EmojiDecoder {
|
|||||||
|
|
||||||
// 投稿などの際、表示は不要だがショートコード=>Unicodeの解決を行いたい場合がある
|
// 投稿などの際、表示は不要だがショートコード=>Unicodeの解決を行いたい場合がある
|
||||||
// カスタム絵文字の変換も行わない
|
// カスタム絵文字の変換も行わない
|
||||||
fun decodeShortCode(s : String) : String {
|
fun decodeShortCode(s : String ,emojiMapCustom : HashMap<String, CustomEmoji>? =null ) : String {
|
||||||
|
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
|
|
||||||
@ -307,6 +310,15 @@ object EmojiDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onShortCode(part : String, name : String) {
|
override fun onShortCode(part : String, name : String) {
|
||||||
|
|
||||||
|
// カスタム絵文字にマッチするなら変換しない
|
||||||
|
val emojiCustom = emojiMapCustom?.get(name)
|
||||||
|
if(emojiCustom != null) {
|
||||||
|
sb.append(part)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// カスタム絵文字ではなく通常の絵文字のショートコードなら絵文字に変換する
|
||||||
val info = EmojiMap201709.sShortNameToImageId[name.toLowerCase().replace('-', '_')]
|
val info = EmojiMap201709.sShortNameToImageId[name.toLowerCase().replace('-', '_')]
|
||||||
sb.append(info?.unified ?: part)
|
sb.append(info?.unified ?: part)
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import jp.juggler.subwaytooter.table.TagSet
|
|||||||
import jp.juggler.subwaytooter.view.MyEditText
|
import jp.juggler.subwaytooter.view.MyEditText
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
|
import java.util.HashMap
|
||||||
|
|
||||||
class PostHelper(
|
class PostHelper(
|
||||||
private val activity : AppCompatActivity,
|
private val activity : AppCompatActivity,
|
||||||
@ -71,6 +72,7 @@ class PostHelper(
|
|||||||
var in_reply_to_id : Long = 0
|
var in_reply_to_id : Long = 0
|
||||||
var attachment_list : ArrayList<PostAttachment>? = null
|
var attachment_list : ArrayList<PostAttachment>? = null
|
||||||
var enquete_items : ArrayList<String>? = null
|
var enquete_items : ArrayList<String>? = null
|
||||||
|
var emojiMapCustom : HashMap<String, CustomEmoji>? =null
|
||||||
|
|
||||||
fun post(
|
fun post(
|
||||||
account : SavedAccount,
|
account : SavedAccount,
|
||||||
@ -221,12 +223,12 @@ class PostHelper(
|
|||||||
|
|
||||||
val json = JSONObject()
|
val json = JSONObject()
|
||||||
try {
|
try {
|
||||||
json.put("status", EmojiDecoder.decodeShortCode(content))
|
json.put("status", EmojiDecoder.decodeShortCode(content,emojiMapCustom=emojiMapCustom))
|
||||||
if(visibility_checked != null) {
|
if(visibility_checked != null) {
|
||||||
json.put("visibility", visibility_checked)
|
json.put("visibility", visibility_checked)
|
||||||
}
|
}
|
||||||
json.put("sensitive", bNSFW)
|
json.put("sensitive", bNSFW)
|
||||||
json.put("spoiler_text", EmojiDecoder.decodeShortCode(spoiler_text ?: ""))
|
json.put("spoiler_text", EmojiDecoder.decodeShortCode(spoiler_text ?: "",emojiMapCustom=emojiMapCustom))
|
||||||
json.put(
|
json.put(
|
||||||
"in_reply_to_id",
|
"in_reply_to_id",
|
||||||
if(in_reply_to_id == - 1L) null else in_reply_to_id
|
if(in_reply_to_id == - 1L) null else in_reply_to_id
|
||||||
@ -242,7 +244,7 @@ class PostHelper(
|
|||||||
json.put("isEnquete", true)
|
json.put("isEnquete", true)
|
||||||
array = JSONArray()
|
array = JSONArray()
|
||||||
for(item in enquete_items) {
|
for(item in enquete_items) {
|
||||||
array.put(EmojiDecoder.decodeShortCode(item))
|
array.put(EmojiDecoder.decodeShortCode(item,emojiMapCustom=emojiMapCustom))
|
||||||
}
|
}
|
||||||
json.put("enquete_items", array)
|
json.put("enquete_items", array)
|
||||||
} catch(ex : JSONException) {
|
} catch(ex : JSONException) {
|
||||||
@ -258,7 +260,7 @@ class PostHelper(
|
|||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
|
|
||||||
sb.append("status=")
|
sb.append("status=")
|
||||||
sb.append(EmojiDecoder.decodeShortCode(content).encodePercent())
|
sb.append(EmojiDecoder.decodeShortCode(content,emojiMapCustom=emojiMapCustom).encodePercent())
|
||||||
|
|
||||||
if(visibility_checked != null) {
|
if(visibility_checked != null) {
|
||||||
sb.append("&visibility=")
|
sb.append("&visibility=")
|
||||||
@ -271,7 +273,7 @@ class PostHelper(
|
|||||||
|
|
||||||
if(spoiler_text?.isNotEmpty() == true) {
|
if(spoiler_text?.isNotEmpty() == true) {
|
||||||
sb.append("&spoiler_text=")
|
sb.append("&spoiler_text=")
|
||||||
sb.append(EmojiDecoder.decodeShortCode(spoiler_text).encodePercent())
|
sb.append(EmojiDecoder.decodeShortCode(spoiler_text,emojiMapCustom=emojiMapCustom).encodePercent())
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_reply_to_id != - 1L) {
|
if(in_reply_to_id != - 1L) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user