めいすきーのリアクションの@を含む絵文字の表示
This commit is contained in:
parent
2b8f0a63cc
commit
1902b58fc0
|
@ -1191,7 +1191,7 @@ internal class ItemViewHolder(
|
|||
enlargeEmoji = 1.5f,
|
||||
enlargeCustomEmoji = 1.5f
|
||||
)
|
||||
val ssb = MisskeyReaction.toSpannableStringBuilder(misskeyReaction,options)
|
||||
val ssb = MisskeyReaction.toSpannableStringBuilder(misskeyReaction,options,boost_status)
|
||||
ssb.append(" ")
|
||||
ssb.append(who.decodeDisplayName(activity)
|
||||
.intoStringResource(activity, string_id))
|
||||
|
@ -2546,7 +2546,7 @@ internal class ItemViewHolder(
|
|||
val key = entry.key
|
||||
val count = entry.value
|
||||
if(count <= 0) continue
|
||||
val ssb = MisskeyReaction.toSpannableStringBuilder(key,options)
|
||||
val ssb = MisskeyReaction.toSpannableStringBuilder(key,options,status)
|
||||
.also{ it.append(" $count")}
|
||||
|
||||
val b = Button(activity).apply {
|
||||
|
@ -2599,7 +2599,7 @@ internal class ItemViewHolder(
|
|||
llExtra.addView(box)
|
||||
}
|
||||
|
||||
private fun addReaction(status : TootStatus, codeArg : String?) {
|
||||
private fun addReaction(status : TootStatus, code : String?) {
|
||||
|
||||
if(status.myReaction?.isNotEmpty() == true) {
|
||||
activity.showToast(false, R.string.already_reactioned)
|
||||
|
@ -2608,7 +2608,7 @@ internal class ItemViewHolder(
|
|||
|
||||
if(access_info.isPseudo || ! access_info.isMisskey) return
|
||||
|
||||
if(codeArg == null) {
|
||||
if(code == null) {
|
||||
EmojiPicker(activity, access_info,closeOnSelected = true) { name, instance, _, _, _ ->
|
||||
val item = EmojiMap.sShortNameToEmojiInfo[name]
|
||||
val code = if(item == null || instance != null) {
|
||||
|
@ -2636,12 +2636,8 @@ internal class ItemViewHolder(
|
|||
TootTaskRunner(activity, progress_style = TootTaskRunner.PROGRESS_NONE).run(access_info,
|
||||
object : TootTask {
|
||||
|
||||
var code :String = codeArg
|
||||
|
||||
override suspend fun background(client : TootApiClient) : TootApiResult? {
|
||||
|
||||
code = MisskeyReaction.toLegacyReaction(client,code)
|
||||
|
||||
val params = access_info.putMisskeyApiToken().apply {
|
||||
put("noteId", status.id.toString())
|
||||
put("reaction", code)
|
||||
|
|
|
@ -1309,7 +1309,7 @@ object Action_Toot {
|
|||
nCrossAccountMode: Int,
|
||||
callback: () -> Unit,
|
||||
bSet: Boolean = true,
|
||||
codeArg: String? = null
|
||||
code: String? = null
|
||||
) {
|
||||
if (access_info.isPseudo || !access_info.isMisskey) return
|
||||
|
||||
|
@ -1319,34 +1319,31 @@ object Action_Toot {
|
|||
return
|
||||
}
|
||||
|
||||
if (codeArg == null) {
|
||||
if (bSet)
|
||||
EmojiPicker(activity, access_info, closeOnSelected = true) { name, instance, _, _, _ ->
|
||||
val item = EmojiMap.sShortNameToEmojiInfo[name]
|
||||
val newCode = if (item == null || instance != null) {
|
||||
":$name:"
|
||||
} else {
|
||||
item.unified
|
||||
}
|
||||
reaction(
|
||||
activity,
|
||||
access_info,
|
||||
arg_status,
|
||||
status_owner_acct,
|
||||
nCrossAccountMode,
|
||||
callback,
|
||||
bSet,
|
||||
newCode
|
||||
)
|
||||
}.show()
|
||||
if (code == null) {
|
||||
if (!bSet) error("will not happen")
|
||||
EmojiPicker(activity, access_info, closeOnSelected = true) { name, instance, _, _, _ ->
|
||||
val item = EmojiMap.sShortNameToEmojiInfo[name]
|
||||
val newCode = if (item == null || instance != null) {
|
||||
":$name:"
|
||||
} else {
|
||||
item.unified
|
||||
}
|
||||
reaction(
|
||||
activity,
|
||||
access_info,
|
||||
arg_status,
|
||||
status_owner_acct,
|
||||
nCrossAccountMode,
|
||||
callback,
|
||||
bSet,
|
||||
newCode
|
||||
)
|
||||
}.show()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
TootTaskRunner(activity, TootTaskRunner.PROGRESS_NONE).run(access_info, object : TootTask {
|
||||
|
||||
var code: String = codeArg
|
||||
|
||||
override suspend fun background(client: TootApiClient): TootApiResult? {
|
||||
|
||||
val target_status = if (nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) {
|
||||
|
@ -1378,8 +1375,6 @@ object Action_Toot {
|
|||
// 成功すると204 no content
|
||||
} else {
|
||||
|
||||
code = MisskeyReaction.toLegacyReaction(client, code)
|
||||
|
||||
client.request(
|
||||
"/api/notes/reactions/create",
|
||||
access_info.putMisskeyApiToken().apply {
|
||||
|
@ -1433,7 +1428,7 @@ object Action_Toot {
|
|||
status_owner,
|
||||
calcCrossAccountMode(timeline_account, action_account),
|
||||
activity.reaction_complete_callback,
|
||||
codeArg = code
|
||||
code = code
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import android.graphics.drawable.PictureDrawable
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.widget.ImageView
|
||||
import com.bumptech.glide.Glide
|
||||
import jp.juggler.emoji.EmojiMap
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.App1
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
import jp.juggler.subwaytooter.span.NetworkEmojiSpan
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
|
@ -46,51 +40,58 @@ object MisskeyReaction {
|
|||
"star" to "\u2B50", // リモートからのFavを示す代替リアクション。ピッカーには表示しない
|
||||
)
|
||||
|
||||
fun toSpannableStringBuilder(code: String, options: DecodeOptions): SpannableStringBuilder {
|
||||
private val reCustomEmoji = """\A:([^:]+):\z""".toRegex()
|
||||
|
||||
fun toSpannableStringBuilder(
|
||||
code: String,
|
||||
options: DecodeOptions,
|
||||
status:TootStatus?
|
||||
): SpannableStringBuilder {
|
||||
|
||||
// 古い形式の絵文字はUnicode絵文字にする
|
||||
oldReactions[code]?.let {
|
||||
return EmojiDecoder.decodeEmoji(options, it)
|
||||
}
|
||||
|
||||
// カスタム絵文字
|
||||
val customCode = code.replace(":", "")
|
||||
if (customCode != code) {
|
||||
val accessInfo = options.linkHelper as? SavedAccount
|
||||
if (accessInfo != null) {
|
||||
val emojiUrl =
|
||||
App1.custom_emoji_lister
|
||||
.getMap(accessInfo)
|
||||
?.get(customCode)
|
||||
?.let {
|
||||
if (Pref.bpDisableEmojiAnimation(App1.pref)) {
|
||||
it.static_url
|
||||
} else {
|
||||
it.url
|
||||
}
|
||||
}
|
||||
if (emojiUrl != null)
|
||||
return SpannableStringBuilder(code).apply {
|
||||
setSpan(
|
||||
NetworkEmojiSpan(emojiUrl, scale = options.enlargeCustomEmoji),
|
||||
0,
|
||||
length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
|
||||
fun CustomEmoji.toSpannableStringBuilder():SpannableStringBuilder?{
|
||||
return if (Pref.bpDisableEmojiAnimation(App1.pref)) {
|
||||
static_url
|
||||
} else {
|
||||
url
|
||||
}?.let{
|
||||
SpannableStringBuilder(code).apply {
|
||||
setSpan(
|
||||
NetworkEmojiSpan(it, scale = options.enlargeCustomEmoji),
|
||||
0,
|
||||
length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// カスタム絵文字
|
||||
val customCode = reCustomEmoji.find(code)?.groupValues?.elementAtOrNull(1)
|
||||
if(customCode != null){
|
||||
var ce = status?.custom_emojis?.get( customCode)
|
||||
if(ce != null) return ce.toSpannableStringBuilder()?: EmojiDecoder.decodeEmoji(options, code)
|
||||
|
||||
val accessInfo = options.linkHelper as? SavedAccount
|
||||
|
||||
val cols = customCode.split("@",limit = 2)
|
||||
val key = cols.elementAtOrNull(0)
|
||||
val domain = cols.elementAtOrNull(1)
|
||||
if( domain == null || domain=="" || domain=="." || domain == accessInfo?.apiHost?.ascii ){
|
||||
if( accessInfo != null){
|
||||
ce = App1.custom_emoji_lister
|
||||
.getMap(accessInfo)
|
||||
?.get(key)
|
||||
if(ce != null) return ce.toSpannableStringBuilder()?: EmojiDecoder.decodeEmoji(options, code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unicode絵文字、もしくは :xxx: などのshortcode表現
|
||||
return EmojiDecoder.decodeEmoji(options, code)
|
||||
}
|
||||
|
||||
// Misskey v12 未満はレガシーなリアクションを送ることになる
|
||||
suspend fun toLegacyReaction(client: TootApiClient, code: String): String {
|
||||
val(ti,ri) = TootInstance.get(client)
|
||||
if(ti!=null && ! ti.versionGE(TootInstance.MISSKEY_VERSION_12)){
|
||||
val entry = oldReactions.entries.firstOrNull { it.value == code }
|
||||
if( entry != null && entry.key != "star") return entry.key
|
||||
}
|
||||
return code
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.regex.Pattern
|
|||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.LinkedHashMap
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class FilterTrees(
|
||||
|
@ -927,6 +928,18 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
|
|||
return list
|
||||
}
|
||||
|
||||
private fun getAnotherReactionExpression(reaction:String):String{
|
||||
// :reaction: => reaction
|
||||
// :reaction@xxx: => reaction@xxx
|
||||
val customCode = reaction.replace(":","")
|
||||
|
||||
// reaction => :reaction@.:
|
||||
return if( customCode != reaction && !customCode.contains("@"))
|
||||
":${customCode}@.:"
|
||||
else
|
||||
reaction
|
||||
}
|
||||
|
||||
// return true if updated
|
||||
fun increaseReaction(reaction: String?, byMe: Boolean, caller: String): Boolean {
|
||||
reaction ?: return false
|
||||
|
@ -948,8 +961,17 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
|
|||
map = LinkedHashMap()
|
||||
this.reactionCounts = map
|
||||
}
|
||||
map[reaction] = (map[reaction] ?: 0) + 1
|
||||
|
||||
|
||||
val anotherExpression = getAnotherReactionExpression(reaction)
|
||||
|
||||
for( entry in map){
|
||||
if( entry.key == reaction || entry.key == anotherExpression){
|
||||
map[entry.key] = entry.value +1
|
||||
return true
|
||||
}
|
||||
}
|
||||
map[reaction] = 1
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -975,8 +997,16 @@ class TootStatus(parser: TootParser, src: JsonObject) : TimelineItem() {
|
|||
map = LinkedHashMap()
|
||||
this.reactionCounts = map
|
||||
}
|
||||
map[reaction] = (map[reaction] ?: 1) - 1
|
||||
|
||||
val anotherExpression = getAnotherReactionExpression(reaction)
|
||||
|
||||
for( entry in map){
|
||||
if( entry.key == reaction || entry.key == anotherExpression){
|
||||
map[entry.key] = max(0,entry.value -1)
|
||||
return true
|
||||
}
|
||||
}
|
||||
map[reaction] = 0
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue