(Misskey 10.38.1)カスタム絵文字のピッカーと入力補完。投稿後の表示はまだできません
This commit is contained in:
parent
ed8ae0bcbe
commit
9ed778eb33
|
@ -705,7 +705,7 @@ class ActMain : AppCompatActivity()
|
|||
post_helper.bNSFW = false
|
||||
post_helper.in_reply_to_id = null
|
||||
post_helper.attachment_list = null
|
||||
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account.host)
|
||||
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account.host,account.isMisskey)
|
||||
|
||||
|
||||
etQuickToot.hideKeyboard()
|
||||
|
|
|
@ -1021,11 +1021,9 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||
} else {
|
||||
post_helper.setInstance(a.host, a.isMisskey)
|
||||
|
||||
if(! a.isMisskey) {
|
||||
// 先読みしてキャッシュに保持しておく
|
||||
App1.custom_emoji_lister.getList(a.host) {
|
||||
// 何もしない
|
||||
}
|
||||
// 先読みしてキャッシュに保持しておく
|
||||
App1.custom_emoji_lister.getList(a.host,a.isMisskey) {
|
||||
// 何もしない
|
||||
}
|
||||
|
||||
val acct = a.acct
|
||||
|
@ -1972,7 +1970,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||
|
||||
post_helper.attachment_list = this.attachment_list
|
||||
|
||||
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account.host)
|
||||
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account.host,account.isMisskey)
|
||||
|
||||
post_helper.redraft_status_id = redraft_status_id
|
||||
|
||||
|
|
|
@ -508,13 +508,15 @@ class App1 : Application() {
|
|||
|
||||
}
|
||||
|
||||
fun getHttpCachedString(url : String) : String? {
|
||||
fun getHttpCachedString(url : String, builderBlock:(Request.Builder)->Unit = {}) : String? {
|
||||
val response : Response
|
||||
|
||||
try {
|
||||
val request_builder = okhttp3.Request.Builder()
|
||||
request_builder.url(url)
|
||||
request_builder.cacheControl(CACHE_5MIN)
|
||||
.url(url)
|
||||
.cacheControl(CACHE_5MIN)
|
||||
|
||||
builderBlock(request_builder)
|
||||
|
||||
val call = App1.ok_http_client2.newCall(request_builder.build())
|
||||
response = call.execute()
|
||||
|
|
|
@ -11,12 +11,44 @@ class CustomEmoji(
|
|||
val static_url : String? // アニメーションなしの画像URL
|
||||
) : Mappable<String> {
|
||||
|
||||
constructor(src : JSONObject) : this(
|
||||
shortcode = src.notEmptyOrThrow("shortcode"),
|
||||
url = src.notEmptyOrThrow("url"),
|
||||
static_url = src.parseString("static_url")
|
||||
)
|
||||
|
||||
override val mapKey : String
|
||||
get() = shortcode
|
||||
|
||||
companion object {
|
||||
val decode : (JSONObject) -> CustomEmoji = { src ->
|
||||
CustomEmoji(
|
||||
shortcode = src.notEmptyOrThrow("shortcode"),
|
||||
url = src.notEmptyOrThrow("url"),
|
||||
static_url = src.parseString("static_url")
|
||||
)
|
||||
}
|
||||
val decodeMisskey : (JSONObject) -> CustomEmoji = { src ->
|
||||
val url = src.parseString("url") ?: error("missing url")
|
||||
val name = src.parseString("name") ?: error("missing name")
|
||||
|
||||
// 使い方が分からない val aliases = parseAliases(src.optJSONArray("aliases"))
|
||||
|
||||
CustomEmoji(
|
||||
shortcode = name,
|
||||
url = url,
|
||||
static_url = url
|
||||
)
|
||||
}
|
||||
|
||||
// private fun parseAliases(src : JSONArray?) : ArrayList<String>? {
|
||||
// var dst = null as ArrayList<String>?
|
||||
// if(src != null) {
|
||||
// val size = src.length()
|
||||
// for(i in 0 until size) {
|
||||
// val str = src.parseString(i) ?: continue
|
||||
// if(str.isNotEmpty()) {
|
||||
// if(dst == null) dst = ArrayList(size)
|
||||
// dst.add(str)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return dst
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ inline fun <reified T> parseList(
|
|||
val src_length = src.length()
|
||||
if(src_length > 0) {
|
||||
dst.ensureCapacity(src_length)
|
||||
for(i in 0 until src.length()) {
|
||||
for(i in 0 until src_length) {
|
||||
val item = parseItem(factory, src.optJSONObject(i), log)
|
||||
if(item != null) dst.add(item)
|
||||
}
|
||||
|
|
|
@ -198,7 +198,8 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
|
|||
val remoteHost = src.parseString("host")
|
||||
val instance = remoteHost ?: parser.linkHelper.host ?: error("missing host")
|
||||
|
||||
this.custom_emojis = null
|
||||
this.custom_emojis = parseMapOrNull(CustomEmoji.decodeMisskey, src.optJSONArray("emojis"))
|
||||
|
||||
this.profile_emojis = null
|
||||
|
||||
this.username = src.notEmptyOrThrow("username")
|
||||
|
@ -256,7 +257,7 @@ open class TootAccount(parser : TootParser, src : JSONObject) {
|
|||
} else {
|
||||
|
||||
// 絵文字データは先に読んでおく
|
||||
this.custom_emojis = parseMapOrNull(::CustomEmoji, src.optJSONArray("emojis"))
|
||||
this.custom_emojis = parseMapOrNull(CustomEmoji.decode, src.optJSONArray("emojis"))
|
||||
this.profile_emojis =
|
||||
parseMapOrNull(::NicoProfileEmoji, src.optJSONArray("profile_emojis"))
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
|
|||
// お気に入りカラムなどではパース直後に変更することがある
|
||||
|
||||
// 絵文字マップはすぐ後で使うので、最初の方で読んでおく
|
||||
this.custom_emojis = null
|
||||
this.custom_emojis = parseMapOrNull(CustomEmoji.decodeMisskey, src.optJSONArray("emojis"), log)
|
||||
this.profile_emojis = null
|
||||
|
||||
val who = parser.account(src.optJSONObject("user"))
|
||||
|
@ -323,7 +323,7 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
|
|||
this.created_at = src.parseString("created_at")
|
||||
|
||||
// 絵文字マップはすぐ後で使うので、最初の方で読んでおく
|
||||
this.custom_emojis = parseMapOrNull(::CustomEmoji, src.optJSONArray("emojis"), log)
|
||||
this.custom_emojis = parseMapOrNull(CustomEmoji.decode, src.optJSONArray("emojis"), log)
|
||||
this.profile_emojis =
|
||||
parseMapOrNull(::NicoProfileEmoji, src.optJSONArray("profile_emojis"), log)
|
||||
|
||||
|
|
|
@ -117,12 +117,8 @@ class EmojiPicker(
|
|||
page_list.add(EmojiPickerPage(false, CATEGORY_RECENT, R.string.emoji_category_recent))
|
||||
|
||||
|
||||
if(! isMisskey) {
|
||||
this.custom_page_idx = page_list.size
|
||||
page_list.add(EmojiPickerPage(false, CATEGORY_CUSTOM, R.string.emoji_category_custom))
|
||||
} else {
|
||||
this.custom_page_idx = - 1
|
||||
}
|
||||
this.custom_page_idx = page_list.size
|
||||
page_list.add(EmojiPickerPage(false, CATEGORY_CUSTOM, R.string.emoji_category_custom))
|
||||
|
||||
page_list.add(
|
||||
EmojiPickerPage(
|
||||
|
@ -202,9 +198,9 @@ class EmojiPicker(
|
|||
onPageSelected(0)
|
||||
|
||||
// カスタム絵文字をロードする
|
||||
if(! isMisskey && instance != null && instance.isNotEmpty()) {
|
||||
if( instance != null && instance.isNotEmpty()) {
|
||||
setCustomEmojiList(
|
||||
App1.custom_emoji_lister.getList(instance) {
|
||||
App1.custom_emoji_lister.getList(instance,isMisskey=isMisskey) {
|
||||
setCustomEmojiList(it) // ロード完了時に呼ばれる
|
||||
}
|
||||
)
|
||||
|
|
|
@ -9,8 +9,13 @@ import java.util.concurrent.ConcurrentHashMap
|
|||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
||||
import jp.juggler.subwaytooter.api.entity.TootInstance
|
||||
import jp.juggler.subwaytooter.api.entity.parseItem
|
||||
import jp.juggler.subwaytooter.api.entity.parseList
|
||||
import okhttp3.RequestBody
|
||||
import org.json.JSONObject
|
||||
import java.util.HashMap
|
||||
|
||||
class CustomEmojiLister(internal val context : Context) {
|
||||
|
@ -43,6 +48,7 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
|
||||
internal class Request(
|
||||
val instance : String,
|
||||
val isMisskey : Boolean,
|
||||
val onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit?
|
||||
)
|
||||
|
||||
|
@ -87,6 +93,7 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
|
||||
fun getList(
|
||||
_instance : String,
|
||||
isMisskey : Boolean,
|
||||
onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit
|
||||
) : ArrayList<CustomEmoji>? {
|
||||
try {
|
||||
|
@ -98,7 +105,7 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
if(item != null) return item.list
|
||||
}
|
||||
|
||||
queue.add(Request(instance, onListLoaded))
|
||||
queue.add(Request(instance, isMisskey, onListLoaded))
|
||||
worker.notifyEx()
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
|
@ -106,13 +113,13 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
return null
|
||||
}
|
||||
|
||||
fun getMap(host : String) : HashMap<String, CustomEmoji>? {
|
||||
val list = getList(host) {
|
||||
fun getMap(host : String, isMisskey : Boolean) : HashMap<String, CustomEmoji>? {
|
||||
val list = getList(host, isMisskey) {
|
||||
// 遅延ロード非対応
|
||||
} ?: return null
|
||||
//
|
||||
val dst = HashMap<String, CustomEmoji>()
|
||||
for( e in list){
|
||||
for(e in list) {
|
||||
dst[e.shortcode] = e
|
||||
}
|
||||
return dst
|
||||
|
@ -153,11 +160,21 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
|
||||
var list : ArrayList<CustomEmoji>? = null
|
||||
try {
|
||||
val data =
|
||||
val data = if(request.isMisskey) {
|
||||
App1.getHttpCachedString("https://" + request.instance + "/api/meta") { builder ->
|
||||
builder.post(
|
||||
RequestBody.create(TootApiClient.MEDIA_TYPE_JSON, "{}")
|
||||
)
|
||||
}
|
||||
|
||||
} else {
|
||||
App1.getHttpCachedString("https://" + request.instance + "/api/v1/custom_emojis")
|
||||
if(data != null) {
|
||||
list = decodeEmojiList(data, request.instance)
|
||||
}
|
||||
|
||||
if(data != null) {
|
||||
list = decodeEmojiList(data, request.instance, request.isMisskey)
|
||||
}
|
||||
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
|
@ -213,17 +230,24 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun decodeEmojiList(data : String, instance : String) : ArrayList<CustomEmoji>? {
|
||||
private fun decodeEmojiList(
|
||||
data : String,
|
||||
instance : String,
|
||||
isMisskey : Boolean
|
||||
) : ArrayList<CustomEmoji>? {
|
||||
return try {
|
||||
val list = parseList(::CustomEmoji, data.toJsonArray() )
|
||||
list.sortWith(compareBy(String.CASE_INSENSITIVE_ORDER, { it.shortcode }))
|
||||
val list = if(isMisskey) {
|
||||
parseList(CustomEmoji.decodeMisskey, JSONObject(data).optJSONArray("emojis"))
|
||||
} else {
|
||||
parseList(CustomEmoji.decode, data.toJsonArray())
|
||||
}
|
||||
list.sortWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.shortcode })
|
||||
list
|
||||
} catch(ex : Throwable) {
|
||||
log.e(ex, "decodeEmojiList failed. instance=%s", instance)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -672,8 +672,8 @@ class PostHelper(
|
|||
|
||||
// カスタム絵文字を検索
|
||||
val instance = this@PostHelper.instance
|
||||
if(instance != null && instance.isNotEmpty() && ! isMisskey) {
|
||||
val custom_list = App1.custom_emoji_lister.getList(instance, onEmojiListLoad)
|
||||
if(instance != null && instance.isNotEmpty() ) {
|
||||
val custom_list = App1.custom_emoji_lister.getList(instance,isMisskey, onEmojiListLoad)
|
||||
if(custom_list != null) {
|
||||
val needle = src.substring(last_colon + 1, end)
|
||||
for(item in custom_list) {
|
||||
|
@ -731,8 +731,8 @@ class PostHelper(
|
|||
this.instance = instance
|
||||
this.isMisskey = isMisskey
|
||||
|
||||
if(instance != null && ! isMisskey) {
|
||||
App1.custom_emoji_lister.getList(instance, onEmojiListLoad)
|
||||
if(instance != null ) {
|
||||
App1.custom_emoji_lister.getList(instance, isMisskey,onEmojiListLoad)
|
||||
}
|
||||
|
||||
val popup = this.popup
|
||||
|
|
Loading…
Reference in New Issue