(Misskey)カスタム絵文字リアクションの中途半端な対応。SVG絵文字のバリデーションが厳しすぎた問題の対応。

This commit is contained in:
tateisu 2019-04-07 22:47:05 +09:00
parent 33bc34075b
commit 24b26de8a7
6 changed files with 133 additions and 61 deletions

View File

@ -2300,56 +2300,103 @@ internal class ItemViewHolder(
box.addView(b)
}
var lastButton : View? = null
for(mr in MisskeyReaction.values()) {
val count = reactionsCount?.get(mr.shortcode)
if(count == null || count <= 0) continue
val b = CountImageButton(activity)
val blp = FlexboxLayout.LayoutParams(
FlexboxLayout.LayoutParams.WRAP_CONTENT,
buttonHeight
)
b.minimumWidth = buttonHeight
b.imageResource = mr.btnDrawableId
b.scaleType = ImageView.ScaleType.FIT_CENTER
b.layoutParams = blp
blp.endMargin = marginBetween
b.background = ContextCompat.getDrawable(
activity,
R.drawable.btn_bg_transparent
)
b.setTextColor(content_color)
b.setPaddingAndText(
paddingH, paddingV
, count.toString()
, 14f
, compoundPaddingDp
)
b.tag = mr.shortcode
b.setOnClickListener { addReaction(status, it.tag as? String) }
b.setOnLongClickListener {
Action_Toot.reactionFromAnotherAccount(
activity,
access_info,
status_showing,
it.tag as? String
if( reactionsCount != null){
var lastButton : View? = null
for(mr in MisskeyReaction.values()) {
val count = reactionsCount[mr.shortcode]
if(count == null || count <= 0) continue
val b = CountImageButton(activity)
val blp = FlexboxLayout.LayoutParams(
FlexboxLayout.LayoutParams.WRAP_CONTENT,
buttonHeight
)
true
b.minimumWidth = buttonHeight
b.imageResource = mr.btnDrawableId
b.scaleType = ImageView.ScaleType.FIT_CENTER
b.layoutParams = blp
blp.endMargin = marginBetween
b.background = ContextCompat.getDrawable(
activity,
R.drawable.btn_bg_transparent
)
b.setTextColor(content_color)
b.setPaddingAndText(
paddingH, paddingV
, count.toString()
, 14f
, compoundPaddingDp
)
b.tag = mr.shortcode
b.setOnClickListener { addReaction(status, it.tag as? String) }
b.setOnLongClickListener {
Action_Toot.reactionFromAnotherAccount(
activity,
access_info,
status_showing,
it.tag as? String
)
true
}
box.addView(b)
lastButton = b
}
box.addView(b)
lastButton = b
// カスタム絵文字リアクション
val list = reactionsCount.keys
.filter { MisskeyReaction.shortcodeMap[ it] == null }
.sorted()
for( key in list ){
val count = reactionsCount.get(key)
if(count == null || count <= 0) continue
val b = Button(activity)
val blp = FlexboxLayout.LayoutParams(
FlexboxLayout.LayoutParams.WRAP_CONTENT,
buttonHeight
)
b.minimumWidth = buttonHeight
b.layoutParams = blp
blp.endMargin = marginBetween
b.background = ContextCompat.getDrawable(
activity,
R.drawable.btn_bg_transparent
)
b.setTextColor(content_color)
b.setPadding(paddingH,paddingV,paddingH,paddingV)
b.text = "$key $count"
b.allCaps = false
b.tag = key
b.setOnClickListener { addReaction(status, it.tag as? String) }
b.setOnLongClickListener {
Action_Toot.reactionFromAnotherAccount(
activity,
access_info,
status_showing,
it.tag as? String
)
true
}
box.addView(b)
lastButton = b
}
if(lastButton != null) {
val lp = lastButton.layoutParams
if(lp is ViewGroup.MarginLayoutParams) {
lp.endMargin = 0
}
}
}
if(lastButton != null) {
val lp = lastButton.layoutParams
if(lp is ViewGroup.MarginLayoutParams) {
lp.endMargin = 0
}
}
llExtra.addView(box)
}

View File

@ -215,6 +215,10 @@ internal class StreamReader(
fireTimelineItem(parser.notification(body))
}
"readAllNotifications"->{
// nothing to do
}
else -> {
log.v("ignore streaming event $type")
}

View File

@ -2,11 +2,15 @@ package jp.juggler.subwaytooter.api
import com.google.android.exoplayer2.Timeline
import jp.juggler.subwaytooter.api.entity.*
import jp.juggler.util.LogCategory
import java.util.ArrayList
import java.util.HashSet
class DuplicateMap {
companion object {
val log = LogCategory("DuplicateMap")
}
private val set_id = HashSet<EntityId>()
private val set_uri = HashSet<String>()
@ -39,10 +43,18 @@ class DuplicateMap {
is TootStatus,
is TootAccount,
is TootNotification -> {
val id = o.getOrderId()
var id = o.getOrderId()
if(id.notDefault){
if(set_id.contains(o.getOrderId())) return true
set_id.add(o.getOrderId())
// Misskeyで時刻順ページングを行う際は重複排除は時刻ではなくオブジェクトIDを使う
if( id.fromTime ){
when(o) {
is TootStatus -> id = o.id
}
}
if(set_id.contains(id)) return true
set_id.add(id)
}
}
}
@ -50,11 +62,15 @@ class DuplicateMap {
return false
}
fun filterDuplicate(src : Collection<TimelineItem>?) : ArrayList<TimelineItem> {
val list_new = ArrayList<TimelineItem>()
if(src != null) {
for(o in src) {
if(isDuplicate(o)) continue
if(isDuplicate(o) ){
log.w("filterDuplicate: filter orderId ${o.getOrderId()}")
continue
}
list_new.add(o)
}
}

View File

@ -8,7 +8,10 @@ import jp.juggler.util.getStringOrNull
import jp.juggler.util.notZero
import org.json.JSONObject
class EntityId(val x : String) : Comparable<EntityId> {
class EntityId(
val x : String,
val fromTime: Boolean = false
) : Comparable<EntityId> {
companion object {

View File

@ -206,7 +206,7 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
this.id = EntityId.mayDefault(misskeyId)
// ページネーションには日時を使う
this._orderId = EntityId(time_created_at.toString())
this._orderId = EntityId(time_created_at.toString(),fromTime = true)
// お気に入りカラムなどではパース直後に変更することがある
@ -912,8 +912,9 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
var rv : HashMap<String, Int>? = null
if(src != null) {
for(key in src.keys()) {
if( key?.isEmpty() != false ) continue
val v = src.parseInt(key) ?: continue
MisskeyReaction.shortcodeMap[key] ?: continue
// カスタム絵文字などが含まれるようになったので、内容のバリデーションはできない
if(rv == null) rv = HashMap()
rv[key] = v
}

View File

@ -287,7 +287,7 @@ class CustomEmojiCache(internal val context : Context) {
// SVGのロードを試みる
try {
val b = decodeSVG(data, 128.toFloat())
val b = decodeSVG(url,data, 128.toFloat())
if(b != null) {
if(DEBUG) log.d("SVG decoded.")
return ApngFrames(b)
@ -326,17 +326,18 @@ class CustomEmojiCache(internal val context : Context) {
return BitmapFactory.decodeByteArray(data, 0, data.size, options)
}
private fun decodeSVG(data : ByteArray, pixelMax : Float) : Bitmap? {
private fun decodeSVG(url:String, data : ByteArray, pixelMax : Float) : Bitmap? {
try {
val svg = SVG.getFromInputStream(ByteArrayInputStream(data))
val src_w = svg.documentWidth
val src_h = svg.documentHeight
// http://bigbadaboom.github.io/androidsvg/
// ロード失敗時に-1を返す例があるらしい
if( src_w <= 0f || src_h <=0f) return null
val aspect = src_w / src_h
val src_w = svg.documentWidth // the width in pixels, or -1 if there is no width available.
val src_h = svg.documentHeight // the height in pixels, or -1 if there is no height available.
val aspect = if( src_w <= 0f || src_h <=0f){
// widthやheightの情報がない
1f
}else{
src_w / src_h
}
val dst_w : Float
val dst_h : Float