fix #139, add authentication header when get custom emoji list.
This commit is contained in:
parent
68b90fc8d0
commit
b3df0080e7
|
@ -794,13 +794,12 @@ class ActMain : AsyncActivity()
|
|||
column.startLoading()
|
||||
}
|
||||
scrollColumnStrip(position)
|
||||
when {
|
||||
column.access_info.isNA -> post_helper.setInstance(null, false)
|
||||
else -> post_helper.setInstance(
|
||||
column.access_info.host,
|
||||
column.access_info.isMisskey
|
||||
)
|
||||
}
|
||||
post_helper.setInstance(
|
||||
when {
|
||||
column.access_info.isNA -> null
|
||||
else -> column.access_info
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -968,7 +967,7 @@ class ActMain : AsyncActivity()
|
|||
post_helper.in_reply_to_id = null
|
||||
post_helper.attachment_list = null
|
||||
post_helper.emojiMapCustom =
|
||||
App1.custom_emoji_lister.getMap(account.host.ascii, account.isMisskey)
|
||||
App1.custom_emoji_lister.getMap(account)
|
||||
|
||||
|
||||
etQuickToot.hideKeyboard()
|
||||
|
|
|
@ -1453,16 +1453,17 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
private fun selectAccount(a : SavedAccount?) {
|
||||
this.account = a
|
||||
|
||||
post_helper.setInstance(a)
|
||||
|
||||
if(a == null) {
|
||||
post_helper.setInstance(null, false)
|
||||
btnAccount.text = getString(R.string.not_selected)
|
||||
btnAccount.setTextColor(getAttributeColor(this, android.R.attr.textColorPrimary))
|
||||
btnAccount.setBackgroundResource(R.drawable.btn_bg_transparent_round6dp)
|
||||
} else {
|
||||
post_helper.setInstance(a.host, a.isMisskey)
|
||||
|
||||
// 先読みしてキャッシュに保持しておく
|
||||
App1.custom_emoji_lister.getList(a.host.ascii, a.isMisskey) {
|
||||
App1.custom_emoji_lister.getList(a) {
|
||||
// 何もしない
|
||||
}
|
||||
|
||||
|
@ -2331,7 +2332,7 @@ class ActPost : AsyncActivity(),
|
|||
if(jsonObject != null) {
|
||||
val a = parseItem(::TootAttachment, ServiceType.MASTODON, jsonObject)
|
||||
if(a == null) {
|
||||
result?.error = "TootAttachment.parse failed"
|
||||
result.error = "TootAttachment.parse failed"
|
||||
} else {
|
||||
pa.attachment = a
|
||||
}
|
||||
|
@ -2624,8 +2625,7 @@ class ActPost : AsyncActivity(),
|
|||
|
||||
post_helper.attachment_list = this.attachment_list
|
||||
|
||||
post_helper.emojiMapCustom =
|
||||
App1.custom_emoji_lister.getMap(account.host.ascii, account.isMisskey)
|
||||
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account)
|
||||
|
||||
post_helper.redraft_status_id = redraft_status_id
|
||||
|
||||
|
|
|
@ -49,13 +49,8 @@ import java.net.CookieManager
|
|||
import java.net.CookiePolicy
|
||||
import java.security.Security
|
||||
import java.util.*
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import java.util.concurrent.ThreadFactory
|
||||
import java.util.concurrent.ThreadPoolExecutor
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
|
||||
class App1 : Application() {
|
||||
|
@ -323,21 +318,21 @@ class App1 : Application() {
|
|||
// preferring to have 1 less than the CPU count to avoid saturating
|
||||
// the CPU with background work
|
||||
|
||||
// val CPU_COUNT = Runtime.getRuntime().availableProcessors()
|
||||
// val CORE_POOL_SIZE = max(2, min(CPU_COUNT - 1, 4))
|
||||
// val MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1
|
||||
// val KEEP_ALIVE_SECONDS = 30
|
||||
// val CPU_COUNT = Runtime.getRuntime().availableProcessors()
|
||||
// val CORE_POOL_SIZE = max(2, min(CPU_COUNT - 1, 4))
|
||||
// val MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1
|
||||
// val KEEP_ALIVE_SECONDS = 30
|
||||
|
||||
// // デフォルトだとキューはmax128で、溢れることがある
|
||||
// val sPoolWorkQueue = LinkedBlockingQueue<Runnable>(999)
|
||||
//
|
||||
// val sThreadFactory = object : ThreadFactory {
|
||||
// private val mCount = AtomicInteger(1)
|
||||
//
|
||||
// override fun newThread(r : Runnable) : Thread {
|
||||
// return Thread(r, "SubwayTooterTask #" + mCount.getAndIncrement())
|
||||
// }
|
||||
// }
|
||||
// // デフォルトだとキューはmax128で、溢れることがある
|
||||
// val sPoolWorkQueue = LinkedBlockingQueue<Runnable>(999)
|
||||
//
|
||||
// val sThreadFactory = object : ThreadFactory {
|
||||
// private val mCount = AtomicInteger(1)
|
||||
//
|
||||
// override fun newThread(r : Runnable) : Thread {
|
||||
// return Thread(r, "SubwayTooterTask #" + mCount.getAndIncrement())
|
||||
// }
|
||||
// }
|
||||
|
||||
// task_executor = ThreadPoolExecutor(
|
||||
// CORE_POOL_SIZE // pool size
|
||||
|
@ -565,6 +560,7 @@ class App1 : Application() {
|
|||
|
||||
fun getHttpCachedString(
|
||||
url : String,
|
||||
accessInfo : SavedAccount? = null,
|
||||
builderBlock : (Request.Builder) -> Unit = {}
|
||||
) : String? {
|
||||
val response : Response
|
||||
|
@ -574,6 +570,11 @@ class App1 : Application() {
|
|||
.url(url)
|
||||
.cacheControl(CACHE_CONTROL)
|
||||
|
||||
val access_token = accessInfo?.getAccessToken()
|
||||
if(access_token?.isNotEmpty() == true) {
|
||||
request_builder.header("Authorization", "Bearer $access_token")
|
||||
}
|
||||
|
||||
builderBlock(request_builder)
|
||||
|
||||
val call = ok_http_client2.newCall(request_builder.build())
|
||||
|
|
|
@ -2720,10 +2720,8 @@ class ColumnViewHolder(
|
|||
|
||||
private fun addReaction(item : TootAnnouncement, sample : TootAnnouncement.Reaction?) {
|
||||
val column = column ?: return
|
||||
val host = column.access_info.host.ascii
|
||||
val isMisskey = column.isMisskey
|
||||
if(sample == null) {
|
||||
EmojiPicker(activity, host, isMisskey) { name, _, _, unicode, customEmoji ->
|
||||
EmojiPicker(activity, column.access_info) { name, _, _, unicode, customEmoji ->
|
||||
log.d("addReaction: $name")
|
||||
addReaction(item, TootAnnouncement.Reaction(jsonObject {
|
||||
put("name", unicode ?: name)
|
||||
|
|
|
@ -572,8 +572,8 @@ internal class ItemViewHolder(
|
|||
|
||||
showStatusTimeScheduled(activity, tvTime, item)
|
||||
|
||||
val who = column.who_account!!.get()
|
||||
val whoRef = TootAccountRef(TootParser(activity, access_info), who )
|
||||
val who = column.who_account !!.get()
|
||||
val whoRef = TootAccountRef(TootParser(activity, access_info), who)
|
||||
this.status_account = whoRef
|
||||
|
||||
setAcct(tvAcct, access_info, who)
|
||||
|
@ -1234,12 +1234,12 @@ internal class ItemViewHolder(
|
|||
)
|
||||
} else {
|
||||
val c = colorBg.notZero()
|
||||
|
||||
|
||||
?: when(status.bookmarked) {
|
||||
true -> Pref.ipEventBgColorBookmark(App1.pref)
|
||||
false -> 0
|
||||
}.notZero()
|
||||
|
||||
|
||||
?: when(status.getBackgroundColorType(access_info)) {
|
||||
TootVisibility.UnlistedHome -> toot_color_unlisted
|
||||
TootVisibility.PrivateFollowers -> toot_color_follower
|
||||
|
@ -2517,7 +2517,7 @@ internal class ItemViewHolder(
|
|||
setPadding(paddingH, paddingV, paddingH, paddingV)
|
||||
|
||||
val emoji = status.custom_emojis?.get(customCode)
|
||||
?: App1.custom_emoji_lister.getMap(access_info.host.ascii, true)
|
||||
?: App1.custom_emoji_lister.getMap(access_info)
|
||||
?.get(customCode)
|
||||
|
||||
val emojiUrl = emoji?.let {
|
||||
|
|
|
@ -117,7 +117,7 @@ class TootApiClient(
|
|||
if(error_message != null) {
|
||||
return error_message
|
||||
}
|
||||
}catch(_:Throwable) {
|
||||
} catch(_ : Throwable) {
|
||||
}
|
||||
|
||||
// HTMLならタグの除去を試みる
|
||||
|
@ -126,7 +126,7 @@ class TootApiClient(
|
|||
val decoded = DecodeOptions().decodeHTML(sv).toString()
|
||||
return reWhiteSpace.matcher(decoded).replaceAll(" ").trim()
|
||||
}
|
||||
|
||||
|
||||
// XXX: Amazon S3 が403を返した場合にcontent-typeが?/xmlでserverがAmazonならXMLをパースしてエラーを整形することもできるが、多分必要ない
|
||||
|
||||
return reWhiteSpace.matcher(sv).replaceAll(" ").trim()
|
||||
|
@ -837,7 +837,7 @@ class TootApiClient(
|
|||
log.d("getClientCredential: ${jsonObject}")
|
||||
|
||||
val sv = jsonObject.string("access_token")?.notEmpty()
|
||||
if(sv != null ) {
|
||||
if(sv != null) {
|
||||
result.data = sv
|
||||
} else {
|
||||
result.data = null
|
||||
|
@ -1093,7 +1093,7 @@ class TootApiClient(
|
|||
|
||||
// 認証されたアカウントのユーザ情報を取得する
|
||||
if(! sendRequest(result) {
|
||||
JsonObject().apply{
|
||||
JsonObject().apply {
|
||||
put("i", access_token)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
|
@ -1260,7 +1260,7 @@ class TootApiClient(
|
|||
if("utoken" == detail) {
|
||||
isUserTokenError = true
|
||||
}
|
||||
|
||||
|
||||
val type = json.string("type")
|
||||
"API returns error: $type $error"
|
||||
}
|
||||
|
@ -1430,7 +1430,7 @@ fun TootApiClient.syncAccountByUrl(
|
|||
"/api/users/show",
|
||||
accessInfo.putMisskeyApiToken().apply {
|
||||
put("username", acct.username)
|
||||
acct.host?.let{ put("host", it.ascii )}
|
||||
acct.host?.let { put("host", it.ascii) }
|
||||
}.toPostRequestBuilder()
|
||||
)
|
||||
?.apply {
|
||||
|
@ -1460,7 +1460,7 @@ fun TootApiClient.syncAccountByAcct(
|
|||
|
||||
fun TootApiClient.syncAccountByAcct(
|
||||
accessInfo : SavedAccount,
|
||||
acct:Acct
|
||||
acct : Acct
|
||||
) : Pair<TootApiResult?, TootAccountRef?> {
|
||||
|
||||
val parser = TootParser(context, accessInfo)
|
||||
|
@ -1470,8 +1470,8 @@ fun TootApiClient.syncAccountByAcct(
|
|||
"/api/users/show",
|
||||
accessInfo.putMisskeyApiToken()
|
||||
.apply {
|
||||
if( acct.isValid) put("username", acct.username)
|
||||
if( acct.host!=null ) put("host", acct.host.ascii )
|
||||
if(acct.isValid) put("username", acct.username)
|
||||
if(acct.host != null) put("host", acct.host.ascii)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
)
|
||||
|
@ -1507,14 +1507,14 @@ fun TootApiClient.syncStatus(
|
|||
// これを投稿元タンスのURLに変換しないと、投稿の同期には使えない
|
||||
val m = TootStatus.reStatusPageMisskey.matcher(urlArg)
|
||||
if(m.find()) {
|
||||
val host = Host.parse(m.groupEx(1)!!)
|
||||
val host = Host.parse(m.groupEx(1) !!)
|
||||
val noteId = m.groupEx(2)
|
||||
|
||||
TootApiClient(context, callback = callback)
|
||||
.apply { instance = host }
|
||||
.request(
|
||||
"/api/notes/show",
|
||||
JsonObject().apply{
|
||||
JsonObject().apply {
|
||||
put("noteId", noteId)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
|
@ -1527,7 +1527,7 @@ fun TootApiClient.syncStatus(
|
|||
)
|
||||
.status(result.jsonObject)
|
||||
?.apply {
|
||||
if( accessInfo.host == host) {
|
||||
if(accessInfo.host == host) {
|
||||
return Pair(result, this)
|
||||
}
|
||||
uri.letNotEmpty { url = it }
|
||||
|
@ -1543,7 +1543,7 @@ fun TootApiClient.syncStatus(
|
|||
var targetStatus : TootStatus? = null
|
||||
val result = request(
|
||||
"/api/ap/show",
|
||||
accessInfo.putMisskeyApiToken().apply{
|
||||
accessInfo.putMisskeyApiToken().apply {
|
||||
put("uri", url)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
|
|
|
@ -17,6 +17,7 @@ import jp.juggler.subwaytooter.Pref
|
|||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
||||
import jp.juggler.subwaytooter.put
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.view.HeaderGridView
|
||||
import jp.juggler.subwaytooter.view.MyViewPager
|
||||
import jp.juggler.subwaytooter.view.NetworkEmojiView
|
||||
|
@ -28,8 +29,7 @@ import java.util.*
|
|||
@SuppressLint("InflateParams")
|
||||
class EmojiPicker(
|
||||
private val activity : Activity,
|
||||
private val instance : String?,
|
||||
@Suppress("CanBeParameter") private val isMisskey : Boolean,
|
||||
private val accessInfo : SavedAccount?,
|
||||
private val onEmojiPicked : (
|
||||
name : String,
|
||||
instance : String?,
|
||||
|
@ -205,9 +205,9 @@ class EmojiPicker(
|
|||
onPageSelected(0)
|
||||
|
||||
// カスタム絵文字をロードする
|
||||
if(instance != null && instance.isNotEmpty()) {
|
||||
if(accessInfo != null) {
|
||||
setCustomEmojiList(
|
||||
App1.custom_emoji_lister.getList(instance, isMisskey = isMisskey) {
|
||||
App1.custom_emoji_lister.getList(accessInfo) {
|
||||
setCustomEmojiList(it) // ロード完了時に呼ばれる
|
||||
}
|
||||
)
|
||||
|
@ -237,7 +237,7 @@ class EmojiPicker(
|
|||
subList = ArrayList()
|
||||
newList[category] = subList
|
||||
}
|
||||
subList.add(EmojiItem(emoji.shortcode, instance))
|
||||
subList.add(EmojiItem(emoji.shortcode, accessInfo !!.host.ascii))
|
||||
emoji_url_map[emoji.shortcode] = emoji
|
||||
}
|
||||
// compose categories data list
|
||||
|
@ -367,7 +367,7 @@ class EmojiPicker(
|
|||
|
||||
CATEGORY_RECENT -> ArrayList<EmojiItem>().apply {
|
||||
for(item in recent_list) {
|
||||
if(item.instance != null && item.instance != instance) continue
|
||||
if(item.instance != null && item.instance != accessInfo?.host?.ascii) continue
|
||||
add(item)
|
||||
}
|
||||
}
|
||||
|
@ -521,7 +521,7 @@ class EmojiPicker(
|
|||
}
|
||||
}
|
||||
|
||||
selected(name, null, unicode= ei.unified)
|
||||
selected(name, null, unicode = ei.unified)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -577,7 +577,7 @@ class EmojiPicker(
|
|||
|
||||
}
|
||||
|
||||
onEmojiPicked(name, instance, bInstanceHasCustomEmoji, unicode,customEmoji)
|
||||
onEmojiPicked(name, instance, bInstanceHasCustomEmoji, unicode, customEmoji)
|
||||
}
|
||||
|
||||
internal inner class EmojiPickerPagerAdapter : androidx.viewpager.widget.PagerAdapter() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.os.SystemClock
|
|||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
||||
import jp.juggler.subwaytooter.api.entity.parseList
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.util.*
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
@ -26,7 +27,7 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
}
|
||||
|
||||
internal class CacheItem(
|
||||
val instance : String,
|
||||
val key : String,
|
||||
var list : ArrayList<CustomEmoji>? = null,
|
||||
var listWithAliases : ArrayList<CustomEmoji>? = null,
|
||||
// ロードした時刻
|
||||
|
@ -36,8 +37,7 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
)
|
||||
|
||||
internal class Request(
|
||||
val instance : String,
|
||||
val isMisskey : Boolean,
|
||||
val accessInfo : SavedAccount,
|
||||
val reportWithAliases : Boolean = false,
|
||||
val onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit?
|
||||
)
|
||||
|
@ -68,17 +68,18 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
cache_error.clear()
|
||||
}
|
||||
|
||||
private fun getCached(now : Long, instance : String) : CacheItem? {
|
||||
private fun getCached(now : Long, accessInfo : SavedAccount) : CacheItem? {
|
||||
val host = accessInfo.host.ascii
|
||||
|
||||
// 成功キャッシュ
|
||||
val item = cache[instance]
|
||||
val item = cache[host]
|
||||
if(item != null && now - item.time_update <= ERROR_EXPIRE) {
|
||||
item.time_used = now
|
||||
return item
|
||||
}
|
||||
|
||||
// エラーキャッシュ
|
||||
val time_error = cache_error[instance]
|
||||
val time_error = cache_error[host]
|
||||
if(time_error != null && now < time_error + ERROR_EXPIRE) {
|
||||
return cache_error_item
|
||||
}
|
||||
|
@ -87,20 +88,16 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
}
|
||||
|
||||
fun getList(
|
||||
_instance : String,
|
||||
isMisskey : Boolean,
|
||||
accessInfo : SavedAccount,
|
||||
onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit
|
||||
) : ArrayList<CustomEmoji>? {
|
||||
try {
|
||||
if(_instance.isEmpty()) return null
|
||||
val instance = _instance.toLowerCase(Locale.JAPAN)
|
||||
|
||||
synchronized(cache) {
|
||||
val item = getCached(elapsedTime, instance)
|
||||
val item = getCached(elapsedTime, accessInfo)
|
||||
if(item != null) return item.list
|
||||
}
|
||||
|
||||
queue.add(Request(instance, isMisskey, onListLoaded = onListLoaded))
|
||||
queue.add(Request(accessInfo, onListLoaded = onListLoaded))
|
||||
worker.notifyEx()
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
|
@ -109,23 +106,18 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
}
|
||||
|
||||
fun getListWithAliases(
|
||||
_instance : String,
|
||||
isMisskey : Boolean,
|
||||
accessInfo : SavedAccount,
|
||||
onListLoaded : (list : ArrayList<CustomEmoji>) -> Unit
|
||||
) : ArrayList<CustomEmoji>? {
|
||||
try {
|
||||
if(_instance.isEmpty()) return null
|
||||
val instance = _instance.toLowerCase(Locale.JAPAN)
|
||||
|
||||
synchronized(cache) {
|
||||
val item = getCached(elapsedTime, instance)
|
||||
val item = getCached(elapsedTime, accessInfo)
|
||||
if(item != null) return item.listWithAliases
|
||||
}
|
||||
|
||||
queue.add(
|
||||
Request(
|
||||
instance,
|
||||
isMisskey,
|
||||
accessInfo,
|
||||
reportWithAliases = true,
|
||||
onListLoaded = onListLoaded
|
||||
)
|
||||
|
@ -137,8 +129,8 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
return null
|
||||
}
|
||||
|
||||
fun getMap(host : String, isMisskey : Boolean) : HashMap<String, CustomEmoji>? {
|
||||
val list = getList(host, isMisskey) {
|
||||
fun getMap(accessInfo : SavedAccount) : HashMap<String, CustomEmoji>? {
|
||||
val list = getList(accessInfo) {
|
||||
// 遅延ロード非対応
|
||||
} ?: return null
|
||||
//
|
||||
|
@ -149,8 +141,6 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
return dst
|
||||
}
|
||||
|
||||
|
||||
|
||||
private inner class Worker : WorkerBase() {
|
||||
|
||||
override fun cancel() {
|
||||
|
@ -169,7 +159,8 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
}
|
||||
|
||||
val cached = synchronized(cache) {
|
||||
val item = getCached(elapsedTime, request.instance)
|
||||
|
||||
val item = getCached(elapsedTime, request.accessInfo)
|
||||
return@synchronized if(item != null) {
|
||||
val list = item.list
|
||||
val listWithAliases = item.listWithAliases
|
||||
|
@ -185,19 +176,27 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
}
|
||||
if(cached) continue
|
||||
|
||||
val accessInfo = request.accessInfo
|
||||
val cacheKey = accessInfo.host.ascii
|
||||
var list : ArrayList<CustomEmoji>? = null
|
||||
var listWithAlias : ArrayList<CustomEmoji>? = null
|
||||
try {
|
||||
val data = if(request.isMisskey) {
|
||||
App1.getHttpCachedString("https://${request.instance}/api/meta") { builder ->
|
||||
val data = if(accessInfo.isMisskey) {
|
||||
App1.getHttpCachedString(
|
||||
"https://${cacheKey}/api/meta",
|
||||
accessInfo = accessInfo
|
||||
) { builder ->
|
||||
builder.post(JsonObject().toRequestBody())
|
||||
}
|
||||
} else {
|
||||
App1.getHttpCachedString("https://${request.instance}/api/v1/custom_emojis")
|
||||
App1.getHttpCachedString(
|
||||
"https://${cacheKey}/api/v1/custom_emojis",
|
||||
accessInfo = accessInfo
|
||||
)
|
||||
}
|
||||
|
||||
if(data != null) {
|
||||
val a = decodeEmojiList(data, request.instance, request.isMisskey)
|
||||
val a = decodeEmojiList(data, accessInfo)
|
||||
list = a
|
||||
listWithAlias = makeListWithAlias(a)
|
||||
}
|
||||
|
@ -209,12 +208,12 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
synchronized(cache) {
|
||||
val now = elapsedTime
|
||||
if(list == null || listWithAlias == null) {
|
||||
cache_error.put(request.instance, now)
|
||||
cache_error.put(cacheKey, now)
|
||||
} else {
|
||||
var item : CacheItem? = cache[request.instance]
|
||||
var item : CacheItem? = cache[cacheKey]
|
||||
if(item == null) {
|
||||
item = CacheItem(request.instance, list, listWithAlias)
|
||||
cache[request.instance] = item
|
||||
item = CacheItem(cacheKey, list, listWithAlias)
|
||||
cache[cacheKey] = item
|
||||
} else {
|
||||
item.list = list
|
||||
item.listWithAliases = listWithAlias
|
||||
|
@ -265,26 +264,28 @@ class CustomEmojiLister(internal val context : Context) {
|
|||
// 古い物から順に捨てる
|
||||
var removed = 0
|
||||
for(item in list) {
|
||||
cache.remove(item.instance)
|
||||
cache.remove(item.key)
|
||||
if(++ removed >= over) break
|
||||
}
|
||||
}
|
||||
|
||||
private fun decodeEmojiList(
|
||||
data : String,
|
||||
instance : String,
|
||||
isMisskey : Boolean
|
||||
accessInfo : SavedAccount
|
||||
) : ArrayList<CustomEmoji>? {
|
||||
return try {
|
||||
val list = if(isMisskey) {
|
||||
parseList(CustomEmoji.decodeMisskey, data.decodeJsonObject().jsonArray("emojis"))
|
||||
val list = if(accessInfo.isMisskey) {
|
||||
parseList(
|
||||
CustomEmoji.decodeMisskey,
|
||||
data.decodeJsonObject().jsonArray("emojis")
|
||||
)
|
||||
} else {
|
||||
parseList(CustomEmoji.decode, data.decodeJsonArray())
|
||||
}
|
||||
list.sortWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.shortcode })
|
||||
list
|
||||
} catch(ex : Throwable) {
|
||||
log.e(ex, "decodeEmojiList failed. instance=%s", instance)
|
||||
log.e(ex, "decodeEmojiList failed. instance=%s", accessInfo.host.ascii)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ class PostHelper(
|
|||
if(enquete_items?.isNotEmpty() == true) {
|
||||
|
||||
val choice_max_chars = when {
|
||||
isMisskey -> 15
|
||||
account.isMisskey -> 15
|
||||
poll_type == TootPollsType.FriendsNico -> 15
|
||||
else -> 25 // TootPollsType.Mastodon
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ class PostHelper(
|
|||
}
|
||||
|
||||
if(! bConfirmTagCharacter && Pref.bpWarnHashtagAsciiAndNonAscii(App1.pref)) {
|
||||
val tags = TootTag.findHashtags(content, isMisskey)
|
||||
val tags = TootTag.findHashtags(content, account.isMisskey)
|
||||
val badTags = tags
|
||||
?.filter {
|
||||
val hasAscii = reAscii.matcher(it).find()
|
||||
|
@ -317,7 +317,7 @@ class PostHelper(
|
|||
|
||||
// 元の投稿を削除する
|
||||
if(redraft_status_id != null) {
|
||||
result = if(isMisskey) {
|
||||
result = if(account.isMisskey) {
|
||||
val params = account.putMisskeyApiToken(JsonObject()).apply {
|
||||
put("noteId", redraft_status_id)
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ class PostHelper(
|
|||
request_builder.header("Idempotency-Key", digest)
|
||||
}
|
||||
|
||||
result = if(isMisskey) {
|
||||
result = if(account.isMisskey) {
|
||||
// log.d("misskey json %s", body_string)
|
||||
client.request("/api/notes/create", request_builder)
|
||||
} else {
|
||||
|
@ -596,7 +596,7 @@ class PostHelper(
|
|||
}
|
||||
|
||||
val status = parser.status(
|
||||
if(isMisskey) {
|
||||
if(account.isMisskey) {
|
||||
result?.jsonObject?.jsonObject("createdNote") ?: result?.jsonObject
|
||||
} else {
|
||||
result?.jsonObject
|
||||
|
@ -671,8 +671,7 @@ class PostHelper(
|
|||
private var formRoot : View? = null
|
||||
private var bMainScreen : Boolean = false
|
||||
|
||||
private var instance : Host? = null
|
||||
private var isMisskey = false
|
||||
private var accessInfo : SavedAccount? = null
|
||||
|
||||
private val onEmojiListLoad : (list : ArrayList<CustomEmoji>) -> Unit =
|
||||
{
|
||||
|
@ -783,7 +782,7 @@ class PostHelper(
|
|||
}
|
||||
|
||||
val part = src.substring(last_sharp + 1, end)
|
||||
if(! TootTag.isValid(part, isMisskey)) {
|
||||
if(! TootTag.isValid(part, accessInfo?.isMisskey == true)) {
|
||||
checkEmoji(et, src)
|
||||
return
|
||||
}
|
||||
|
@ -835,7 +834,7 @@ class PostHelper(
|
|||
val limit = 100
|
||||
|
||||
// カスタム絵文字の候補を部分一致検索
|
||||
code_list.addAll(customEmojiCodeList(instance?.ascii, limit, part))
|
||||
code_list.addAll(customEmojiCodeList(accessInfo, limit, part))
|
||||
|
||||
// 通常の絵文字を部分一致で検索
|
||||
val remain = limit - code_list.size
|
||||
|
@ -859,62 +858,56 @@ class PostHelper(
|
|||
|
||||
// カスタム絵文字の候補を作る
|
||||
private fun customEmojiCodeList(
|
||||
instance : String?,
|
||||
accessInfo : SavedAccount?,
|
||||
@Suppress("SameParameterValue") limit : Int,
|
||||
needle : String
|
||||
) = ArrayList<CharSequence>().also { dst ->
|
||||
|
||||
if(instance?.isNotEmpty() == true) {
|
||||
val custom_list = App1.custom_emoji_lister.getListWithAliases(
|
||||
instance,
|
||||
isMisskey,
|
||||
onEmojiListLoad
|
||||
)
|
||||
|
||||
if(custom_list != null) {
|
||||
|
||||
for(item in custom_list) {
|
||||
if(dst.size >= limit) break
|
||||
if(! item.shortcode.contains(needle)) continue
|
||||
|
||||
val sb = SpannableStringBuilder()
|
||||
sb.append(' ')
|
||||
sb.setSpan(
|
||||
NetworkEmojiSpan(item.url),
|
||||
0,
|
||||
sb.length,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
sb.append(' ')
|
||||
if(item.alias != null) {
|
||||
val start = sb.length
|
||||
sb.append(":")
|
||||
sb.append(item.alias)
|
||||
sb.append(": → ")
|
||||
sb.setSpan(
|
||||
ForegroundColorSpan(
|
||||
getAttributeColor(
|
||||
activity,
|
||||
R.attr.colorTimeSmall
|
||||
)
|
||||
),
|
||||
start,
|
||||
sb.length,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
|
||||
sb.append(':')
|
||||
sb.append(item.shortcode)
|
||||
sb.append(':')
|
||||
|
||||
dst.add(sb)
|
||||
}
|
||||
}
|
||||
}
|
||||
accessInfo ?: return@also
|
||||
|
||||
val custom_list =
|
||||
App1.custom_emoji_lister.getListWithAliases(accessInfo, onEmojiListLoad)
|
||||
?: return@also
|
||||
|
||||
|
||||
for(item in custom_list) {
|
||||
if(dst.size >= limit) break
|
||||
if(! item.shortcode.contains(needle)) continue
|
||||
|
||||
val sb = SpannableStringBuilder()
|
||||
sb.append(' ')
|
||||
sb.setSpan(
|
||||
NetworkEmojiSpan(item.url),
|
||||
0,
|
||||
sb.length,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
sb.append(' ')
|
||||
if(item.alias != null) {
|
||||
val start = sb.length
|
||||
sb.append(":")
|
||||
sb.append(item.alias)
|
||||
sb.append(": → ")
|
||||
sb.setSpan(
|
||||
ForegroundColorSpan(
|
||||
getAttributeColor(
|
||||
activity,
|
||||
R.attr.colorTimeSmall
|
||||
)
|
||||
),
|
||||
start,
|
||||
sb.length,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
|
||||
sb.append(':')
|
||||
sb.append(item.shortcode)
|
||||
sb.append(':')
|
||||
|
||||
dst.add(sb)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun openPopup() : PopupAutoCompleteAcct? {
|
||||
|
@ -933,12 +926,11 @@ class PostHelper(
|
|||
fun canOpenPopup() : Boolean
|
||||
}
|
||||
|
||||
fun setInstance(instanceArg : Host?, isMisskey : Boolean) {
|
||||
this.instance = instanceArg
|
||||
this.isMisskey = isMisskey
|
||||
fun setInstance(accessInfo : SavedAccount?) {
|
||||
this.accessInfo = accessInfo
|
||||
|
||||
if(instanceArg != null) {
|
||||
App1.custom_emoji_lister.getList(instanceArg.ascii, isMisskey, onEmojiListLoad)
|
||||
if(accessInfo != null) {
|
||||
App1.custom_emoji_lister.getList(accessInfo, onEmojiListLoad)
|
||||
}
|
||||
|
||||
val popup = this.popup
|
||||
|
@ -1038,11 +1030,7 @@ class PostHelper(
|
|||
}
|
||||
|
||||
private val open_picker_emoji : Runnable = Runnable {
|
||||
EmojiPicker(
|
||||
activity,
|
||||
instance?.ascii,
|
||||
isMisskey
|
||||
) { name, instance, bInstanceHasCustomEmoji, _, _ ->
|
||||
EmojiPicker(activity, accessInfo) { name, instance, bInstanceHasCustomEmoji, _, _ ->
|
||||
val et = this.et ?: return@EmojiPicker
|
||||
|
||||
val src = et.text ?: ""
|
||||
|
@ -1070,11 +1058,7 @@ class PostHelper(
|
|||
}
|
||||
|
||||
fun openEmojiPickerFromMore() {
|
||||
EmojiPicker(
|
||||
activity,
|
||||
instance?.ascii,
|
||||
isMisskey
|
||||
) { name, instance, bInstanceHasCustomEmoji, _, _ ->
|
||||
EmojiPicker(activity, accessInfo) { name, instance, bInstanceHasCustomEmoji, _, _ ->
|
||||
val et = this.et ?: return@EmojiPicker
|
||||
|
||||
val src = et.text ?: ""
|
||||
|
|
Loading…
Reference in New Issue