2018-01-04 19:52:25 +01:00
|
|
|
|
package jp.juggler.subwaytooter
|
|
|
|
|
|
2020-09-07 14:20:11 +02:00
|
|
|
|
import android.annotation.SuppressLint
|
2018-01-04 19:52:25 +01:00
|
|
|
|
import android.content.Context
|
2019-01-20 10:27:29 +01:00
|
|
|
|
import android.content.res.ColorStateList
|
2018-01-04 19:52:25 +01:00
|
|
|
|
import android.graphics.Typeface
|
2018-01-17 18:39:16 +01:00
|
|
|
|
import android.os.SystemClock
|
2018-11-18 03:38:52 +01:00
|
|
|
|
import android.text.Spannable
|
|
|
|
|
import android.text.SpannableString
|
|
|
|
|
import android.text.SpannableStringBuilder
|
|
|
|
|
import android.text.TextUtils
|
2019-05-05 06:41:13 +02:00
|
|
|
|
import android.text.style.BackgroundColorSpan
|
2018-12-08 16:29:07 +01:00
|
|
|
|
import android.util.TypedValue
|
2018-01-14 22:47:42 +01:00
|
|
|
|
import android.view.Gravity
|
2018-01-04 19:52:25 +01:00
|
|
|
|
import android.view.View
|
2018-01-14 22:47:42 +01:00
|
|
|
|
import android.view.ViewGroup
|
|
|
|
|
import android.widget.*
|
2021-01-03 06:11:04 +01:00
|
|
|
|
import androidx.appcompat.app.AlertDialog
|
|
|
|
|
import androidx.core.content.ContextCompat
|
2018-08-21 03:53:52 +02:00
|
|
|
|
import com.google.android.flexbox.FlexWrap
|
|
|
|
|
import com.google.android.flexbox.FlexboxLayout
|
2018-08-21 15:31:44 +02:00
|
|
|
|
import com.google.android.flexbox.JustifyContent
|
2021-01-03 06:11:04 +01:00
|
|
|
|
import jp.juggler.emoji.EmojiMap
|
2019-01-16 13:33:07 +01:00
|
|
|
|
import jp.juggler.subwaytooter.Styler.defaultColorIcon
|
2018-07-07 07:15:16 +02:00
|
|
|
|
import jp.juggler.subwaytooter.action.*
|
2019-01-06 15:55:25 +01:00
|
|
|
|
import jp.juggler.subwaytooter.api.*
|
2018-01-04 19:52:25 +01:00
|
|
|
|
import jp.juggler.subwaytooter.api.entity.*
|
|
|
|
|
import jp.juggler.subwaytooter.dialog.ActionsDialog
|
|
|
|
|
import jp.juggler.subwaytooter.dialog.DlgConfirm
|
2021-01-03 06:11:04 +01:00
|
|
|
|
import jp.juggler.subwaytooter.dialog.EmojiPicker
|
2019-03-06 10:49:02 +01:00
|
|
|
|
import jp.juggler.subwaytooter.drawable.PollPlotDrawable
|
2018-11-12 18:19:57 +01:00
|
|
|
|
import jp.juggler.subwaytooter.drawable.PreviewCardBorder
|
2018-10-28 14:08:10 +01:00
|
|
|
|
import jp.juggler.subwaytooter.span.MyClickableSpan
|
2018-08-21 15:31:44 +02:00
|
|
|
|
import jp.juggler.subwaytooter.table.*
|
2018-01-14 22:47:42 +01:00
|
|
|
|
import jp.juggler.subwaytooter.util.*
|
2018-01-04 19:52:25 +01:00
|
|
|
|
import jp.juggler.subwaytooter.view.*
|
2018-12-01 00:02:18 +01:00
|
|
|
|
import jp.juggler.util.*
|
2018-01-14 22:47:42 +01:00
|
|
|
|
import org.jetbrains.anko.*
|
2018-11-18 03:38:52 +01:00
|
|
|
|
import kotlin.math.max
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
|
|
internal class ItemViewHolder(
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val activity: ActMain
|
2018-01-04 19:52:25 +01:00
|
|
|
|
) : View.OnClickListener, View.OnLongClickListener {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
|
|
|
|
|
private val log = LogCategory("ItemViewHolder")
|
|
|
|
|
var toot_color_unlisted: Int = 0
|
|
|
|
|
var toot_color_follower: Int = 0
|
|
|
|
|
var toot_color_direct_user: Int = 0
|
|
|
|
|
var toot_color_direct_me: Int = 0
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val viewRoot: View
|
|
|
|
|
|
|
|
|
|
private var bSimpleList: Boolean = false
|
|
|
|
|
|
|
|
|
|
lateinit var column: Column
|
|
|
|
|
|
|
|
|
|
internal lateinit var list_adapter: ItemListAdapter
|
|
|
|
|
|
|
|
|
|
private lateinit var llBoosted: View
|
|
|
|
|
private lateinit var ivBoosted: ImageView
|
|
|
|
|
private lateinit var tvBoosted: TextView
|
|
|
|
|
private lateinit var tvBoostedAcct: TextView
|
|
|
|
|
private lateinit var tvBoostedTime: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var llReply: View
|
|
|
|
|
private lateinit var ivReply: ImageView
|
|
|
|
|
private lateinit var tvReply: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var llFollow: View
|
|
|
|
|
private lateinit var ivFollow: MyNetworkImageView
|
|
|
|
|
private lateinit var tvFollowerName: TextView
|
|
|
|
|
private lateinit var tvFollowerAcct: TextView
|
|
|
|
|
private lateinit var btnFollow: ImageButton
|
|
|
|
|
private lateinit var ivFollowedBy: ImageView
|
|
|
|
|
|
|
|
|
|
private lateinit var llStatus: View
|
|
|
|
|
private lateinit var ivThumbnail: MyNetworkImageView
|
|
|
|
|
private lateinit var tvName: TextView
|
|
|
|
|
private lateinit var tvTime: TextView
|
|
|
|
|
private lateinit var tvAcct: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var llContentWarning: View
|
|
|
|
|
private lateinit var tvContentWarning: MyTextView
|
|
|
|
|
private lateinit var btnContentWarning: Button
|
|
|
|
|
|
|
|
|
|
private lateinit var llContents: View
|
|
|
|
|
private lateinit var tvMentions: MyTextView
|
|
|
|
|
internal lateinit var tvContent: MyTextView
|
|
|
|
|
|
|
|
|
|
private lateinit var flMedia: View
|
|
|
|
|
private lateinit var llMedia: View
|
|
|
|
|
private lateinit var btnShowMedia: BlurhashView
|
|
|
|
|
private lateinit var ivMedia1: MyNetworkImageView
|
|
|
|
|
private lateinit var ivMedia2: MyNetworkImageView
|
|
|
|
|
private lateinit var ivMedia3: MyNetworkImageView
|
|
|
|
|
private lateinit var ivMedia4: MyNetworkImageView
|
|
|
|
|
private lateinit var btnHideMedia: ImageButton
|
|
|
|
|
|
|
|
|
|
private lateinit var statusButtonsViewHolder: StatusButtonsViewHolder
|
|
|
|
|
private lateinit var llButtonBar: View
|
|
|
|
|
|
|
|
|
|
private lateinit var llSearchTag: View
|
|
|
|
|
private lateinit var btnSearchTag: Button
|
|
|
|
|
private lateinit var btnGapHead: ImageButton
|
|
|
|
|
private lateinit var btnGapTail: ImageButton
|
|
|
|
|
private lateinit var llTrendTag: View
|
|
|
|
|
private lateinit var tvTrendTagName: TextView
|
|
|
|
|
private lateinit var tvTrendTagDesc: TextView
|
|
|
|
|
private lateinit var tvTrendTagCount: TextView
|
|
|
|
|
private lateinit var cvTagHistory: TagHistoryView
|
|
|
|
|
|
|
|
|
|
private lateinit var llList: View
|
|
|
|
|
private lateinit var btnListTL: Button
|
|
|
|
|
private lateinit var btnListMore: ImageButton
|
|
|
|
|
|
|
|
|
|
private lateinit var llFollowRequest: View
|
|
|
|
|
private lateinit var btnFollowRequestAccept: ImageButton
|
|
|
|
|
private lateinit var btnFollowRequestDeny: ImageButton
|
|
|
|
|
|
|
|
|
|
private lateinit var llFilter: View
|
|
|
|
|
private lateinit var tvFilterPhrase: TextView
|
|
|
|
|
private lateinit var tvFilterDetail: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var tvMediaDescription: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var llCardOuter: View
|
|
|
|
|
private lateinit var tvCardText: MyTextView
|
|
|
|
|
private lateinit var flCardImage: View
|
|
|
|
|
private lateinit var llCardImage: View
|
|
|
|
|
private lateinit var ivCardImage: MyNetworkImageView
|
|
|
|
|
private lateinit var btnCardImageHide: ImageButton
|
|
|
|
|
private lateinit var btnCardImageShow: BlurhashView
|
|
|
|
|
|
|
|
|
|
private lateinit var llExtra: LinearLayout
|
|
|
|
|
|
|
|
|
|
private lateinit var llConversationIcons: View
|
|
|
|
|
private lateinit var ivConversationIcon1: MyNetworkImageView
|
|
|
|
|
private lateinit var ivConversationIcon2: MyNetworkImageView
|
|
|
|
|
private lateinit var ivConversationIcon3: MyNetworkImageView
|
|
|
|
|
private lateinit var ivConversationIcon4: MyNetworkImageView
|
|
|
|
|
private lateinit var tvConversationIconsMore: TextView
|
|
|
|
|
private lateinit var tvConversationParticipants: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var tvApplication: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var tvMessageHolder: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var llOpenSticker: View
|
|
|
|
|
private lateinit var ivOpenSticker: MyNetworkImageView
|
|
|
|
|
private lateinit var tvOpenSticker: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var tvLastStatusAt: TextView
|
|
|
|
|
|
|
|
|
|
private lateinit var access_info: SavedAccount
|
|
|
|
|
|
|
|
|
|
private var buttons_for_status: StatusButtons? = null
|
|
|
|
|
|
|
|
|
|
private var item: TimelineItem? = null
|
|
|
|
|
|
|
|
|
|
private var status_showing: TootStatus? = null
|
|
|
|
|
private var status_reply: TootStatus? = null
|
|
|
|
|
private var status_account: TootAccountRef? = null
|
|
|
|
|
private var boost_account: TootAccountRef? = null
|
|
|
|
|
private var follow_account: TootAccountRef? = null
|
|
|
|
|
|
|
|
|
|
private var boost_time: Long = 0L
|
|
|
|
|
|
|
|
|
|
private var content_color: Int = 0
|
|
|
|
|
private var acct_color: Int = 0
|
|
|
|
|
private var content_color_csl: ColorStateList = ColorStateList.valueOf(0)
|
|
|
|
|
|
|
|
|
|
private val boost_invalidator: NetworkEmojiInvalidator
|
|
|
|
|
private val reply_invalidator: NetworkEmojiInvalidator
|
|
|
|
|
private val follow_invalidator: NetworkEmojiInvalidator
|
|
|
|
|
private val name_invalidator: NetworkEmojiInvalidator
|
|
|
|
|
private val content_invalidator: NetworkEmojiInvalidator
|
|
|
|
|
private val spoiler_invalidator: NetworkEmojiInvalidator
|
|
|
|
|
private val lastActive_invalidator: NetworkEmojiInvalidator
|
|
|
|
|
private val extra_invalidator_list = ArrayList<NetworkEmojiInvalidator>()
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
|
this.viewRoot = inflate(activity)
|
|
|
|
|
|
|
|
|
|
for (v in arrayOf(
|
2020-09-11 21:34:58 +02:00
|
|
|
|
btnListTL,
|
|
|
|
|
btnListMore,
|
|
|
|
|
btnSearchTag,
|
|
|
|
|
btnGapHead,
|
|
|
|
|
btnGapTail,
|
|
|
|
|
btnContentWarning,
|
|
|
|
|
btnShowMedia,
|
|
|
|
|
ivMedia1,
|
|
|
|
|
ivMedia2,
|
|
|
|
|
ivMedia3,
|
|
|
|
|
ivMedia4,
|
|
|
|
|
btnFollow,
|
|
|
|
|
ivCardImage,
|
|
|
|
|
btnCardImageHide,
|
|
|
|
|
btnCardImageShow,
|
|
|
|
|
ivThumbnail,
|
|
|
|
|
llBoosted,
|
|
|
|
|
llReply,
|
|
|
|
|
llFollow,
|
|
|
|
|
btnFollow,
|
|
|
|
|
btnFollowRequestAccept,
|
|
|
|
|
btnFollowRequestDeny,
|
|
|
|
|
btnHideMedia,
|
|
|
|
|
llTrendTag,
|
|
|
|
|
llFilter
|
|
|
|
|
)) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
v.setOnClickListener(this)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (v in arrayOf(
|
2020-09-11 21:34:58 +02:00
|
|
|
|
btnSearchTag,
|
|
|
|
|
btnFollow,
|
|
|
|
|
ivCardImage,
|
|
|
|
|
llBoosted,
|
|
|
|
|
llReply,
|
|
|
|
|
llFollow,
|
|
|
|
|
llConversationIcons,
|
|
|
|
|
ivThumbnail,
|
|
|
|
|
llTrendTag
|
|
|
|
|
)) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
v.setOnLongClickListener(this)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
tvContent.movementMethod = MyLinkMovementMethod
|
|
|
|
|
tvMentions.movementMethod = MyLinkMovementMethod
|
|
|
|
|
tvContentWarning.movementMethod = MyLinkMovementMethod
|
|
|
|
|
tvMediaDescription.movementMethod = MyLinkMovementMethod
|
|
|
|
|
tvCardText.movementMethod = MyLinkMovementMethod
|
|
|
|
|
|
|
|
|
|
var f: Float
|
|
|
|
|
|
|
|
|
|
f = activity.timeline_font_size_sp
|
|
|
|
|
if (!f.isNaN()) {
|
|
|
|
|
tvFollowerName.textSize = f
|
|
|
|
|
tvName.textSize = f
|
|
|
|
|
tvMentions.textSize = f
|
|
|
|
|
tvContentWarning.textSize = f
|
|
|
|
|
tvContent.textSize = f
|
|
|
|
|
btnShowMedia.textSize = f
|
|
|
|
|
btnCardImageShow.textSize = f
|
|
|
|
|
tvApplication.textSize = f
|
|
|
|
|
tvMessageHolder.textSize = f
|
|
|
|
|
btnListTL.textSize = f
|
|
|
|
|
tvTrendTagName.textSize = f
|
|
|
|
|
tvTrendTagCount.textSize = f
|
|
|
|
|
tvFilterPhrase.textSize = f
|
|
|
|
|
tvMediaDescription.textSize = f
|
|
|
|
|
tvCardText.textSize = f
|
|
|
|
|
tvConversationIconsMore.textSize = f
|
|
|
|
|
tvConversationParticipants.textSize = f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f = activity.notification_tl_font_size_sp
|
|
|
|
|
if (!f.isNaN()) {
|
|
|
|
|
tvBoosted.textSize = f
|
|
|
|
|
tvReply.textSize = f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f = activity.acct_font_size_sp
|
|
|
|
|
if (!f.isNaN()) {
|
|
|
|
|
tvBoostedAcct.textSize = f
|
|
|
|
|
tvBoostedTime.textSize = f
|
|
|
|
|
tvFollowerAcct.textSize = f
|
|
|
|
|
tvLastStatusAt.textSize = f
|
|
|
|
|
tvAcct.textSize = f
|
|
|
|
|
tvTime.textSize = f
|
|
|
|
|
tvTrendTagDesc.textSize = f
|
|
|
|
|
tvFilterDetail.textSize = f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val spacing = activity.timeline_spacing
|
|
|
|
|
if (spacing != null) {
|
|
|
|
|
tvFollowerName.setLineSpacing(0f, spacing)
|
|
|
|
|
tvName.setLineSpacing(0f, spacing)
|
|
|
|
|
tvMentions.setLineSpacing(0f, spacing)
|
|
|
|
|
tvContentWarning.setLineSpacing(0f, spacing)
|
|
|
|
|
tvContent.setLineSpacing(0f, spacing)
|
|
|
|
|
btnShowMedia.setLineSpacing(0f, spacing)
|
|
|
|
|
btnCardImageShow.setLineSpacing(0f, spacing)
|
|
|
|
|
tvApplication.setLineSpacing(0f, spacing)
|
|
|
|
|
tvMessageHolder.setLineSpacing(0f, spacing)
|
|
|
|
|
btnListTL.setLineSpacing(0f, spacing)
|
|
|
|
|
tvTrendTagName.setLineSpacing(0f, spacing)
|
|
|
|
|
tvTrendTagCount.setLineSpacing(0f, spacing)
|
|
|
|
|
tvFilterPhrase.setLineSpacing(0f, spacing)
|
|
|
|
|
tvMediaDescription.setLineSpacing(0f, spacing)
|
|
|
|
|
tvCardText.setLineSpacing(0f, spacing)
|
|
|
|
|
tvConversationIconsMore.setLineSpacing(0f, spacing)
|
|
|
|
|
tvConversationParticipants.setLineSpacing(0f, spacing)
|
|
|
|
|
tvBoosted.setLineSpacing(0f, spacing)
|
|
|
|
|
tvReply.setLineSpacing(0f, spacing)
|
|
|
|
|
tvLastStatusAt.setLineSpacing(0f, spacing)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var s = activity.avatarIconSize
|
|
|
|
|
ivThumbnail.layoutParams.height = s
|
|
|
|
|
ivThumbnail.layoutParams.width = s
|
|
|
|
|
ivFollow.layoutParams.width = s
|
|
|
|
|
ivBoosted.layoutParams.width = s
|
|
|
|
|
|
|
|
|
|
s = ActMain.replyIconSize + (activity.density * 8).toInt()
|
|
|
|
|
ivReply.layoutParams.width = s
|
|
|
|
|
ivReply.layoutParams.height = s
|
|
|
|
|
|
|
|
|
|
s = activity.notificationTlIconSize
|
|
|
|
|
ivBoosted.layoutParams.height = s
|
|
|
|
|
|
|
|
|
|
this.content_invalidator = NetworkEmojiInvalidator(activity.handler, tvContent)
|
|
|
|
|
this.spoiler_invalidator = NetworkEmojiInvalidator(activity.handler, tvContentWarning)
|
|
|
|
|
this.boost_invalidator = NetworkEmojiInvalidator(activity.handler, tvBoosted)
|
|
|
|
|
this.reply_invalidator = NetworkEmojiInvalidator(activity.handler, tvReply)
|
|
|
|
|
this.follow_invalidator = NetworkEmojiInvalidator(activity.handler, tvFollowerName)
|
|
|
|
|
this.name_invalidator = NetworkEmojiInvalidator(activity.handler, tvName)
|
|
|
|
|
this.lastActive_invalidator = NetworkEmojiInvalidator(activity.handler, tvLastStatusAt)
|
|
|
|
|
|
|
|
|
|
val cardBackground = llCardOuter.background
|
|
|
|
|
if (cardBackground is PreviewCardBorder) {
|
|
|
|
|
val density = activity.density
|
|
|
|
|
cardBackground.round = (density * 8f)
|
|
|
|
|
cardBackground.width = (density * 1f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val textShowMedia = SpannableString(activity.getString(R.string.tap_to_show))
|
|
|
|
|
.apply {
|
|
|
|
|
val colorBg = activity.attrColor(R.attr.colorShowMediaBackground)
|
|
|
|
|
.applyAlphaMultiplier(0.5f)
|
|
|
|
|
setSpan(
|
2020-01-29 06:15:32 +01:00
|
|
|
|
BackgroundColorSpan(colorBg),
|
|
|
|
|
0,
|
|
|
|
|
this.length,
|
|
|
|
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnShowMedia.text = textShowMedia
|
|
|
|
|
btnCardImageShow.text = textShowMedia
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onViewRecycled() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
|
|
|
fun bind(
|
|
|
|
|
list_adapter: ItemListAdapter,
|
|
|
|
|
column: Column,
|
|
|
|
|
bSimpleList: Boolean,
|
|
|
|
|
item: TimelineItem
|
2018-01-21 13:46:36 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val b = Benchmark(log, "Item-bind", 40L)
|
|
|
|
|
|
|
|
|
|
this.list_adapter = list_adapter
|
|
|
|
|
this.column = column
|
|
|
|
|
this.bSimpleList = bSimpleList
|
|
|
|
|
|
|
|
|
|
this.access_info = column.access_info
|
|
|
|
|
|
|
|
|
|
val font_bold = ActMain.timeline_font_bold
|
|
|
|
|
val font_normal = ActMain.timeline_font
|
|
|
|
|
viewRoot.scan { v ->
|
|
|
|
|
try {
|
|
|
|
|
when (v) {
|
|
|
|
|
// ボタンは太字なので触らない
|
2018-08-22 03:05:54 +02:00
|
|
|
|
is CountImageButton -> {
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
// ボタンは太字なので触らない
|
2018-08-22 03:05:54 +02:00
|
|
|
|
is Button -> {
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-22 03:05:54 +02:00
|
|
|
|
is TextView -> v.typeface = when {
|
|
|
|
|
v === tvName ||
|
|
|
|
|
v === tvFollowerName ||
|
|
|
|
|
v === tvBoosted ||
|
2018-08-23 05:46:14 +02:00
|
|
|
|
v === tvReply ||
|
2018-08-22 03:05:54 +02:00
|
|
|
|
v === tvTrendTagCount ||
|
|
|
|
|
v === tvTrendTagName ||
|
2018-11-11 11:43:20 +01:00
|
|
|
|
v === tvConversationIconsMore ||
|
|
|
|
|
v === tvConversationParticipants ||
|
2018-08-22 03:05:54 +02:00
|
|
|
|
v === tvFilterPhrase -> font_bold
|
|
|
|
|
else -> font_normal
|
2018-01-17 18:39:16 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
|
log.trace(ex)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bSimpleList) {
|
|
|
|
|
|
|
|
|
|
viewRoot.setOnTouchListener { _, ev ->
|
|
|
|
|
// ポップアップを閉じた時にクリックでリストを触ったことになってしまう不具合の回避
|
|
|
|
|
val now = SystemClock.elapsedRealtime()
|
|
|
|
|
// ポップアップを閉じた直後はタッチダウンを無視する
|
|
|
|
|
if (now - StatusButtonsPopup.last_popup_close >= 30L) {
|
|
|
|
|
false
|
|
|
|
|
} else {
|
|
|
|
|
val action = ev.action
|
|
|
|
|
log.d("onTouchEvent action=$action")
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
viewRoot.setOnClickListener { viewClicked ->
|
|
|
|
|
activity.closeListItemPopup()
|
|
|
|
|
status_showing?.let { status ->
|
|
|
|
|
val popup =
|
|
|
|
|
StatusButtonsPopup(activity, column, bSimpleList, this@ItemViewHolder)
|
|
|
|
|
activity.listItemPopup = popup
|
|
|
|
|
popup.show(
|
2018-01-17 18:39:16 +01:00
|
|
|
|
list_adapter.columnVh.listView,
|
|
|
|
|
viewClicked,
|
|
|
|
|
status,
|
|
|
|
|
item as? TootNotification
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
llButtonBar.visibility = View.GONE
|
|
|
|
|
this.buttons_for_status = null
|
|
|
|
|
} else {
|
|
|
|
|
viewRoot.isClickable = false
|
|
|
|
|
llButtonBar.visibility = View.VISIBLE
|
|
|
|
|
this.buttons_for_status = StatusButtons(
|
2018-01-17 18:39:16 +01:00
|
|
|
|
activity,
|
|
|
|
|
column,
|
|
|
|
|
false,
|
2018-10-28 14:08:10 +01:00
|
|
|
|
statusButtonsViewHolder,
|
|
|
|
|
this
|
2018-01-17 18:39:16 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.status_showing = null
|
|
|
|
|
this.status_reply = null
|
|
|
|
|
this.status_account = null
|
|
|
|
|
this.boost_account = null
|
|
|
|
|
this.follow_account = null
|
|
|
|
|
this.boost_time = 0L
|
|
|
|
|
this.viewRoot.setBackgroundColor(0)
|
|
|
|
|
this.boostedAction = defaultBoostedAction
|
|
|
|
|
|
|
|
|
|
llOpenSticker.visibility = View.GONE
|
|
|
|
|
llBoosted.visibility = View.GONE
|
|
|
|
|
llReply.visibility = View.GONE
|
|
|
|
|
llFollow.visibility = View.GONE
|
|
|
|
|
llStatus.visibility = View.GONE
|
|
|
|
|
llSearchTag.visibility = View.GONE
|
|
|
|
|
btnGapHead.visibility = View.GONE
|
|
|
|
|
btnGapTail.visibility = View.GONE
|
|
|
|
|
llList.visibility = View.GONE
|
|
|
|
|
llFollowRequest.visibility = View.GONE
|
|
|
|
|
tvMessageHolder.visibility = View.GONE
|
|
|
|
|
llTrendTag.visibility = View.GONE
|
|
|
|
|
llFilter.visibility = View.GONE
|
|
|
|
|
tvMediaDescription.visibility = View.GONE
|
|
|
|
|
llCardOuter.visibility = View.GONE
|
|
|
|
|
tvCardText.visibility = View.GONE
|
|
|
|
|
flCardImage.visibility = View.GONE
|
|
|
|
|
llConversationIcons.visibility = View.GONE
|
|
|
|
|
|
|
|
|
|
removeExtraView()
|
|
|
|
|
|
|
|
|
|
var c: Int
|
|
|
|
|
c = column.getContentColor()
|
|
|
|
|
this.content_color = c
|
|
|
|
|
this.content_color_csl = ColorStateList.valueOf(c)
|
|
|
|
|
|
|
|
|
|
tvBoosted.setTextColor(c)
|
|
|
|
|
tvReply.setTextColor(c)
|
|
|
|
|
tvFollowerName.setTextColor(c)
|
|
|
|
|
tvName.setTextColor(c)
|
|
|
|
|
tvMentions.setTextColor(c)
|
|
|
|
|
tvContentWarning.setTextColor(c)
|
|
|
|
|
tvContent.setTextColor(c)
|
|
|
|
|
//NSFWは文字色固定 btnShowMedia.setTextColor( c );
|
|
|
|
|
tvApplication.setTextColor(c)
|
|
|
|
|
tvMessageHolder.setTextColor(c)
|
|
|
|
|
tvTrendTagName.setTextColor(c)
|
|
|
|
|
tvTrendTagCount.setTextColor(c)
|
|
|
|
|
cvTagHistory.setColor(c)
|
|
|
|
|
tvFilterPhrase.setTextColor(c)
|
|
|
|
|
tvMediaDescription.setTextColor(c)
|
|
|
|
|
tvCardText.setTextColor(c)
|
|
|
|
|
tvConversationIconsMore.setTextColor(c)
|
|
|
|
|
tvConversationParticipants.setTextColor(c)
|
|
|
|
|
|
|
|
|
|
(llCardOuter.background as? PreviewCardBorder)?.let {
|
|
|
|
|
val rgb = c and 0xffffff
|
|
|
|
|
val alpha = max(1, c ushr (24 + 1)) // 本来の値の半分にする
|
|
|
|
|
it.color = rgb or (alpha shl 24)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c = column.getAcctColor()
|
|
|
|
|
this.acct_color = c
|
|
|
|
|
tvBoostedTime.setTextColor(c)
|
|
|
|
|
tvTime.setTextColor(c)
|
|
|
|
|
tvTrendTagDesc.setTextColor(c)
|
|
|
|
|
tvFilterDetail.setTextColor(c)
|
|
|
|
|
tvFilterPhrase.setTextColor(c)
|
|
|
|
|
|
|
|
|
|
// 以下のビューの文字色はsetAcct() で設定される
|
|
|
|
|
// tvBoostedAcct.setTextColor(c)
|
|
|
|
|
// tvFollowerAcct.setTextColor(c)
|
|
|
|
|
// tvAcct.setTextColor(c)
|
|
|
|
|
|
|
|
|
|
this.item = item
|
|
|
|
|
when (item) {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
is TootStatus -> {
|
|
|
|
|
val reblog = item.reblog
|
2018-08-31 14:47:40 +02:00
|
|
|
|
when {
|
2018-08-23 05:46:14 +02:00
|
|
|
|
reblog == null -> showStatusOrReply(item)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-02-23 14:48:32 +01:00
|
|
|
|
item.isQuoteToot -> {
|
2018-08-23 05:46:14 +02:00
|
|
|
|
// 引用Renote
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorBoost(activity.pref)
|
2020-02-23 14:48:32 +01:00
|
|
|
|
showReply(reblog, R.drawable.ic_repeat, R.string.quote_to)
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showStatus(item, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
|
else -> {
|
2018-08-23 05:46:14 +02:00
|
|
|
|
// 引用なしブースト
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorBoost(activity.pref)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
showBoost(
|
|
|
|
|
item.accountRef,
|
|
|
|
|
item.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_repeat,
|
2019-04-04 05:13:15 +02:00
|
|
|
|
R.string.display_name_boosted_by,
|
|
|
|
|
boost_status = item
|
2018-08-23 05:46:14 +02:00
|
|
|
|
)
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showStatusOrReply(item.reblog, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-20 00:31:59 +02:00
|
|
|
|
is TootAccountRef -> showAccount(item)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-20 00:31:59 +02:00
|
|
|
|
is TootNotification -> showNotification(item)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-09-12 19:47:00 +02:00
|
|
|
|
is TootGap -> showGap()
|
2019-08-12 06:36:42 +02:00
|
|
|
|
is TootSearchGap -> showSearchGap(item)
|
2018-05-20 00:31:59 +02:00
|
|
|
|
is TootDomainBlock -> showDomainBlock(item)
|
|
|
|
|
is TootList -> showList(item)
|
2020-04-07 03:38:29 +02:00
|
|
|
|
is MisskeyAntenna -> showAntenna(item)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-20 00:31:59 +02:00
|
|
|
|
is TootMessageHolder -> showMessageHolder(item)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-30 07:18:45 +02:00
|
|
|
|
is TootTag -> showSearchTag(item)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-07-07 07:15:16 +02:00
|
|
|
|
is TootFilter -> showFilter(item)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-10-09 01:20:43 +02:00
|
|
|
|
is TootConversationSummary -> {
|
2018-11-16 15:44:23 +01:00
|
|
|
|
showStatusOrReply(item.last_status)
|
2018-11-11 11:43:20 +01:00
|
|
|
|
showConversationIcons(item)
|
2018-10-09 01:20:43 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-16 13:33:07 +01:00
|
|
|
|
is TootScheduled -> {
|
2019-01-06 11:17:54 +01:00
|
|
|
|
showScheduled(item)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
b.report()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showScheduled(item: TootScheduled) {
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
llStatus.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
|
|
this.viewRoot.setBackgroundColor(0)
|
|
|
|
|
|
|
|
|
|
showStatusTimeScheduled(activity, tvTime, item)
|
|
|
|
|
|
|
|
|
|
val who = column.who_account!!.get()
|
|
|
|
|
val whoRef = TootAccountRef(TootParser(activity, access_info), who)
|
|
|
|
|
this.status_account = whoRef
|
|
|
|
|
|
|
|
|
|
setAcct(tvAcct, access_info, who)
|
|
|
|
|
|
|
|
|
|
tvName.text = whoRef.decoded_display_name
|
|
|
|
|
name_invalidator.register(whoRef.decoded_display_name)
|
|
|
|
|
ivThumbnail.setImageUrl(
|
2019-01-06 15:55:25 +01:00
|
|
|
|
activity.pref,
|
|
|
|
|
Styler.calcIconRound(ivThumbnail.layoutParams),
|
|
|
|
|
access_info.supplyBaseUrl(who.avatar_static),
|
|
|
|
|
access_info.supplyBaseUrl(who.avatar)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
val content = SpannableString(item.text ?: "")
|
|
|
|
|
|
|
|
|
|
tvMentions.visibility = View.GONE
|
|
|
|
|
|
|
|
|
|
tvContent.text = content
|
|
|
|
|
content_invalidator.register(content)
|
|
|
|
|
|
|
|
|
|
tvContent.minLines = -1
|
|
|
|
|
|
|
|
|
|
val decoded_spoiler_text = SpannableString(item.spoiler_text ?: "")
|
|
|
|
|
when {
|
|
|
|
|
decoded_spoiler_text.isNotEmpty() -> {
|
|
|
|
|
// 元データに含まれるContent Warning を使う
|
|
|
|
|
llContentWarning.visibility = View.VISIBLE
|
|
|
|
|
tvContentWarning.text = decoded_spoiler_text
|
|
|
|
|
spoiler_invalidator.register(decoded_spoiler_text)
|
|
|
|
|
val cw_shown = ContentWarning.isShown(item.uri, access_info.expand_cw)
|
|
|
|
|
showContent(cw_shown)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
// CWしない
|
|
|
|
|
llContentWarning.visibility = View.GONE
|
|
|
|
|
llContents.visibility = View.VISIBLE
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val media_attachments = item.media_attachments
|
|
|
|
|
if (media_attachments?.isEmpty() != false) {
|
|
|
|
|
flMedia.visibility = View.GONE
|
|
|
|
|
llMedia.visibility = View.GONE
|
|
|
|
|
btnShowMedia.visibility = View.GONE
|
|
|
|
|
} else {
|
|
|
|
|
flMedia.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
|
|
// hide sensitive media
|
|
|
|
|
val default_shown = when {
|
|
|
|
|
column.hide_media_default -> false
|
|
|
|
|
access_info.dont_hide_nsfw -> true
|
|
|
|
|
else -> !item.sensitive
|
|
|
|
|
}
|
|
|
|
|
val is_shown = MediaShown.isShown(item.uri, default_shown)
|
|
|
|
|
|
|
|
|
|
btnShowMedia.visibility = if (!is_shown) View.VISIBLE else View.GONE
|
|
|
|
|
llMedia.visibility = if (!is_shown) View.GONE else View.VISIBLE
|
|
|
|
|
val sb = StringBuilder()
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia1, 0)
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia2, 1)
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia3, 2)
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia4, 3)
|
|
|
|
|
if (sb.isNotEmpty()) {
|
|
|
|
|
tvMediaDescription.visibility = View.VISIBLE
|
|
|
|
|
tvMediaDescription.text = sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIconDrawableId(
|
2019-01-06 15:55:25 +01:00
|
|
|
|
activity,
|
|
|
|
|
btnHideMedia,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_close,
|
2019-01-06 15:55:25 +01:00
|
|
|
|
color = content_color,
|
|
|
|
|
alphaMultiplier = Styler.boost_alpha
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buttons_for_status?.hide()
|
|
|
|
|
|
|
|
|
|
tvApplication.visibility = View.GONE
|
|
|
|
|
|
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
llSearchTag.visibility = View.VISIBLE
|
|
|
|
|
btnSearchTag.text = activity.getString(R.string.scheduled_status) + " " +
|
|
|
|
|
TootStatus.formatTime(
|
2019-01-16 13:33:07 +01:00
|
|
|
|
activity,
|
|
|
|
|
item.timeScheduledAt,
|
|
|
|
|
true
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun removeExtraView() {
|
|
|
|
|
llExtra.scan { v ->
|
|
|
|
|
if (v is MyNetworkImageView) {
|
|
|
|
|
v.cancelLoading()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
llExtra.removeAllViews()
|
|
|
|
|
|
|
|
|
|
for (invalidator in extra_invalidator_list) {
|
|
|
|
|
invalidator.register(null)
|
|
|
|
|
}
|
|
|
|
|
extra_invalidator_list.clear()
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showConversationIcons(cs: TootConversationSummary) {
|
|
|
|
|
|
|
|
|
|
val last_account_id = cs.last_status.account.id
|
|
|
|
|
|
|
|
|
|
val accountsOther = cs.accounts.filter { it.get().id != last_account_id }
|
|
|
|
|
if (accountsOther.isNotEmpty()) {
|
|
|
|
|
llConversationIcons.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
|
|
val size = accountsOther.size
|
|
|
|
|
|
|
|
|
|
tvConversationParticipants.text = if (size <= 1) {
|
|
|
|
|
activity.getString(R.string.conversation_to)
|
|
|
|
|
} else {
|
|
|
|
|
activity.getString(R.string.participants)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun showIcon(iv: MyNetworkImageView, idx: Int) {
|
|
|
|
|
val bShown = idx < size
|
|
|
|
|
iv.visibility = if (bShown) View.VISIBLE else View.GONE
|
|
|
|
|
if (!bShown) return
|
|
|
|
|
|
|
|
|
|
val who = accountsOther[idx].get()
|
|
|
|
|
iv.setImageUrl(
|
2018-11-11 11:43:20 +01:00
|
|
|
|
activity.pref,
|
|
|
|
|
Styler.calcIconRound(iv.layoutParams),
|
|
|
|
|
access_info.supplyBaseUrl(who.avatar_static),
|
|
|
|
|
access_info.supplyBaseUrl(who.avatar)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
showIcon(ivConversationIcon1, 0)
|
|
|
|
|
showIcon(ivConversationIcon2, 1)
|
|
|
|
|
showIcon(ivConversationIcon3, 2)
|
|
|
|
|
showIcon(ivConversationIcon4, 3)
|
|
|
|
|
|
|
|
|
|
tvConversationIconsMore.text = when {
|
|
|
|
|
size <= 4 -> ""
|
|
|
|
|
else -> activity.getString(R.string.participants_and_more)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cs.last_status.in_reply_to_id != null) {
|
|
|
|
|
llSearchTag.visibility = View.VISIBLE
|
|
|
|
|
btnSearchTag.text = activity.getString(R.string.show_conversation)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun openConversationSummary() {
|
|
|
|
|
val cs = item as? TootConversationSummary ?: return
|
|
|
|
|
|
|
|
|
|
if (cs.unread) {
|
|
|
|
|
cs.unread = false
|
|
|
|
|
// 表示の更新
|
|
|
|
|
list_adapter.notifyChange(
|
2018-11-11 11:43:20 +01:00
|
|
|
|
reason = "ConversationSummary reset unread",
|
|
|
|
|
reset = true
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
// 未読フラグのクリアをサーバに送る
|
|
|
|
|
Action_Toot.clearConversationUnread(activity, access_info, cs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Action_Toot.conversation(
|
2018-11-11 11:43:20 +01:00
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
|
|
|
|
access_info,
|
|
|
|
|
cs.last_status
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showStatusOrReply(item: TootStatus, colorBgArg: Int = 0) {
|
|
|
|
|
var colorBg = colorBgArg
|
|
|
|
|
val reply = item.reply
|
|
|
|
|
val in_reply_to_id = item.in_reply_to_id
|
|
|
|
|
val in_reply_to_account_id = item.in_reply_to_account_id
|
|
|
|
|
when {
|
|
|
|
|
reply != null -> {
|
|
|
|
|
showReply(reply, R.drawable.ic_reply, R.string.reply_to)
|
|
|
|
|
if (colorBgArg == 0) colorBg = Pref.ipEventBgColorMention(activity.pref)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
in_reply_to_id != null && in_reply_to_account_id != null -> {
|
|
|
|
|
showReply(item, in_reply_to_account_id)
|
|
|
|
|
if (colorBgArg == 0) colorBg = Pref.ipEventBgColorMention(activity.pref)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
showStatus(item, colorBg)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showMessageHolder(item: TootMessageHolder) {
|
|
|
|
|
tvMessageHolder.visibility = View.VISIBLE
|
|
|
|
|
tvMessageHolder.text = item.text
|
|
|
|
|
tvMessageHolder.gravity = item.gravity
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showNotification(n: TootNotification) {
|
|
|
|
|
val n_status = n.status
|
|
|
|
|
val n_accountRef = n.accountRef
|
|
|
|
|
val n_account = n_accountRef?.get()
|
|
|
|
|
|
|
|
|
|
fun showNotificationStatus(item: TootStatus, colorBgDefault: Int) {
|
|
|
|
|
val reblog = item.reblog
|
|
|
|
|
when {
|
|
|
|
|
reblog == null -> showStatusOrReply(item, colorBgDefault)
|
|
|
|
|
|
|
|
|
|
item.isQuoteToot -> {
|
|
|
|
|
// 引用Renote
|
|
|
|
|
showReply(reblog, R.drawable.ic_repeat, R.string.quote_to)
|
|
|
|
|
showStatus(item, Pref.ipEventBgColorQuote(activity.pref))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
// 通常のブースト。引用なしブースト。
|
|
|
|
|
// ブースト表示は通知イベントと被るのでしない
|
|
|
|
|
showStatusOrReply(reblog, Pref.ipEventBgColorBoost(activity.pref))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
when (n.type) {
|
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
|
TootNotification.TYPE_FAVOURITE -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorFavourite(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2018-05-08 10:25:02 +02:00
|
|
|
|
n_accountRef,
|
2018-01-21 13:46:36 +01:00
|
|
|
|
n.time_created_at,
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (access_info.isNicoru(n_account)) R.drawable.ic_nicoru else R.drawable.ic_star,
|
2019-02-04 05:19:57 +01:00
|
|
|
|
R.string.display_name_favourited_by
|
2018-01-04 19:52:25 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 15:31:44 +02:00
|
|
|
|
TootNotification.TYPE_REBLOG -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorBoost(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2018-05-08 10:25:02 +02:00
|
|
|
|
n_accountRef,
|
2018-01-21 13:46:36 +01:00
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_repeat,
|
2019-04-04 05:13:15 +02:00
|
|
|
|
R.string.display_name_boosted_by,
|
|
|
|
|
boost_status = n_status
|
2018-01-04 19:52:25 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 15:31:44 +02:00
|
|
|
|
TootNotification.TYPE_RENOTE -> {
|
2018-08-21 12:19:02 +02:00
|
|
|
|
// 引用のないreblog
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorBoost(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2018-08-21 12:19:02 +02:00
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_repeat,
|
2019-04-04 05:13:15 +02:00
|
|
|
|
R.string.display_name_boosted_by,
|
|
|
|
|
boost_status = n_status
|
2018-08-21 12:19:02 +02:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
2018-08-21 12:19:02 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
|
TootNotification.TYPE_FOLLOW -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorFollow(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
showBoost(
|
2018-05-08 10:25:02 +02:00
|
|
|
|
n_accountRef,
|
2018-01-21 13:46:36 +01:00
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_follow_plus,
|
2019-02-04 05:19:57 +01:00
|
|
|
|
R.string.display_name_followed_by
|
2018-01-04 19:52:25 +01:00
|
|
|
|
)
|
2018-05-08 10:25:02 +02:00
|
|
|
|
showAccount(n_accountRef)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (colorBg != 0) this.viewRoot.backgroundColor = colorBg
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-25 02:29:24 +02:00
|
|
|
|
TootNotification.TYPE_UNFOLLOW -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorUnfollow(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) {
|
2018-08-25 02:29:24 +02:00
|
|
|
|
showBoost(
|
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_follow_cross,
|
2019-02-04 05:19:57 +01:00
|
|
|
|
R.string.display_name_unfollowed_by
|
2018-08-25 02:29:24 +02:00
|
|
|
|
)
|
|
|
|
|
showAccount(n_accountRef)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (colorBg != 0) this.viewRoot.backgroundColor = colorBg
|
2018-08-25 02:29:24 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-11-18 03:38:52 +01:00
|
|
|
|
TootNotification.TYPE_MENTION,
|
|
|
|
|
TootNotification.TYPE_REPLY -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorMention(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (!bSimpleList && !access_info.isMisskey) {
|
2019-08-24 05:35:22 +02:00
|
|
|
|
when {
|
|
|
|
|
n_account == null -> {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-08-24 05:35:22 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-08-24 05:35:22 +02:00
|
|
|
|
n_status?.in_reply_to_id != null || n_status?.reply != null -> {
|
2018-11-18 03:38:52 +01:00
|
|
|
|
// トゥート内部に「~への返信」を表示するので、
|
|
|
|
|
// 通知イベントの「~からの返信」は表示しない
|
2019-08-24 05:35:22 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-08-24 05:35:22 +02:00
|
|
|
|
else -> // 返信ではなくメンションの場合は「~からの返信」を表示する
|
2018-11-18 03:38:52 +01:00
|
|
|
|
showBoost(
|
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_reply,
|
2019-02-04 05:19:57 +01:00
|
|
|
|
R.string.display_name_mentioned_by
|
2018-11-18 03:38:52 +01:00
|
|
|
|
)
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 12:19:02 +02:00
|
|
|
|
TootNotification.TYPE_REACTION -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorReaction(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2018-08-21 12:19:02 +02:00
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2021-01-03 06:11:04 +01:00
|
|
|
|
R.drawable.ic_face,
|
2019-02-03 17:58:37 +01:00
|
|
|
|
R.string.display_name_reaction_by,
|
2021-02-07 00:31:51 +01:00
|
|
|
|
misskeyReaction = n.reaction ?: "?",
|
|
|
|
|
boost_status = n_status
|
2018-08-21 12:19:02 +02:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2018-08-21 12:19:02 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 15:31:44 +02:00
|
|
|
|
TootNotification.TYPE_QUOTE -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorQuote(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2018-08-21 12:19:02 +02:00
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_repeat,
|
2019-02-04 05:19:57 +01:00
|
|
|
|
R.string.display_name_quoted_by
|
2018-08-21 12:19:02 +02:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2018-08-21 12:19:02 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-09-20 04:51:15 +02:00
|
|
|
|
TootNotification.TYPE_STATUS -> {
|
|
|
|
|
val colorBg = Pref.ipEventBgColorStatus(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2020-09-20 04:51:15 +02:00
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status == null) {
|
2020-09-20 04:51:15 +02:00
|
|
|
|
R.drawable.ic_question
|
2020-09-20 15:10:49 +02:00
|
|
|
|
} else {
|
|
|
|
|
Styler.getVisibilityIconId(access_info.isMisskey, n_status.visibility)
|
2020-09-20 04:51:15 +02:00
|
|
|
|
},
|
|
|
|
|
R.string.display_name_posted_by
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2020-09-20 04:51:15 +02:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-02-16 09:13:11 +01:00
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST,
|
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_MISSKEY -> {
|
|
|
|
|
val colorBg = Pref.ipEventBgColorFollowRequest(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) {
|
2020-02-16 09:13:11 +01:00
|
|
|
|
showBoost(
|
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
|
|
|
|
R.drawable.ic_follow_wait,
|
|
|
|
|
R.string.display_name_follow_request_by
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (colorBg != 0) this.viewRoot.backgroundColor = colorBg
|
2020-02-16 09:13:11 +01:00
|
|
|
|
boostedAction = {
|
|
|
|
|
activity.addColumn(
|
2020-09-11 21:34:58 +02:00
|
|
|
|
activity.nextPosition(column), access_info, ColumnType.FOLLOW_REQUESTS
|
2020-02-16 09:13:11 +01:00
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-02-16 09:13:11 +01:00
|
|
|
|
TootNotification.TYPE_FOLLOW_REQUEST_ACCEPTED_MISSKEY -> {
|
|
|
|
|
val colorBg = Pref.ipEventBgColorFollow(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) {
|
2020-02-16 09:13:11 +01:00
|
|
|
|
showBoost(
|
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
|
|
|
|
R.drawable.ic_follow_plus,
|
|
|
|
|
R.string.display_name_follow_request_accepted_by
|
|
|
|
|
)
|
|
|
|
|
showAccount(n_accountRef)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (colorBg != 0) this.viewRoot.backgroundColor = colorBg
|
2020-02-16 09:13:11 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-02-16 09:13:11 +01:00
|
|
|
|
TootNotification.TYPE_VOTE,
|
|
|
|
|
TootNotification.TYPE_POLL_VOTE_MISSKEY -> {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
val colorBg = Pref.ipEventBgColorVote(activity.pref)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2018-08-21 12:19:02 +02:00
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_vote,
|
2019-02-04 05:19:57 +01:00
|
|
|
|
R.string.display_name_voted_by
|
2018-08-21 12:19:02 +02:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
2018-08-21 12:19:02 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-03-13 18:34:56 +01:00
|
|
|
|
TootNotification.TYPE_POLL -> {
|
|
|
|
|
val colorBg = 0
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_account != null) showBoost(
|
2019-03-13 18:34:56 +01:00
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
|
|
|
|
R.drawable.ic_vote,
|
|
|
|
|
R.string.end_of_polling_from
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
2019-03-13 18:34:56 +01:00
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
val colorBg = 0
|
|
|
|
|
if (n_account != null) showBoost(
|
2018-08-21 12:19:02 +02:00
|
|
|
|
n_accountRef,
|
|
|
|
|
n.time_created_at,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.drawable.ic_question,
|
2019-02-04 05:19:57 +01:00
|
|
|
|
R.string.unknown_notification_from
|
2018-08-21 12:19:02 +02:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (n_status != null) {
|
|
|
|
|
showNotificationStatus(n_status, colorBg)
|
|
|
|
|
}
|
|
|
|
|
tvMessageHolder.visibility = View.VISIBLE
|
|
|
|
|
tvMessageHolder.text = "notification type is ${n.type}"
|
|
|
|
|
tvMessageHolder.gravity = Gravity.CENTER
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showList(list: TootList) {
|
|
|
|
|
llList.visibility = View.VISIBLE
|
|
|
|
|
btnListTL.text = list.title
|
|
|
|
|
btnListTL.textColor = content_color
|
|
|
|
|
btnListMore.imageTintList = content_color_csl
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showAntenna(a: MisskeyAntenna) {
|
|
|
|
|
llList.visibility = View.VISIBLE
|
|
|
|
|
btnListTL.text = a.name
|
|
|
|
|
btnListTL.textColor = content_color
|
|
|
|
|
btnListMore.imageTintList = content_color_csl
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showDomainBlock(domain_block: TootDomainBlock) {
|
|
|
|
|
llSearchTag.visibility = View.VISIBLE
|
|
|
|
|
btnSearchTag.text = domain_block.domain.pretty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showFilter(filter: TootFilter) {
|
|
|
|
|
llFilter.visibility = View.VISIBLE
|
|
|
|
|
tvFilterPhrase.text = filter.phrase
|
|
|
|
|
|
|
|
|
|
val sb = StringBuffer()
|
|
|
|
|
//
|
|
|
|
|
sb.append(activity.getString(R.string.filter_context))
|
|
|
|
|
.append(": ")
|
|
|
|
|
.append(filter.getContextNames(activity).joinToString("/"))
|
|
|
|
|
//
|
|
|
|
|
val flags = ArrayList<String>()
|
|
|
|
|
if (filter.irreversible) flags.add(activity.getString(R.string.filter_irreversible))
|
|
|
|
|
if (filter.whole_word) flags.add(activity.getString(R.string.filter_word_match))
|
|
|
|
|
if (flags.isNotEmpty()) {
|
|
|
|
|
sb.append('\n')
|
|
|
|
|
.append(flags.joinToString(", "))
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
if (filter.time_expires_at != 0L) {
|
|
|
|
|
sb.append('\n')
|
|
|
|
|
.append(activity.getString(R.string.filter_expires_at))
|
|
|
|
|
.append(": ")
|
|
|
|
|
.append(TootStatus.formatTime(activity, filter.time_expires_at, false))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvFilterDetail.text = sb.toString()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showSearchTag(tag: TootTag) {
|
|
|
|
|
if (tag.history?.isNotEmpty() == true) {
|
|
|
|
|
llTrendTag.visibility = View.VISIBLE
|
|
|
|
|
tvTrendTagName.text = "#${tag.name}"
|
|
|
|
|
tvTrendTagDesc.text =
|
|
|
|
|
activity.getString(R.string.people_talking, tag.accountDaily, tag.accountWeekly)
|
|
|
|
|
tvTrendTagCount.text = "${tag.countDaily}(${tag.countWeekly})"
|
|
|
|
|
cvTagHistory.setHistory(tag.history)
|
|
|
|
|
} else {
|
|
|
|
|
llSearchTag.visibility = View.VISIBLE
|
|
|
|
|
btnSearchTag.text = "#" + tag.name
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showGap() {
|
|
|
|
|
llSearchTag.visibility = View.VISIBLE
|
|
|
|
|
btnSearchTag.text = activity.getString(R.string.read_gap)
|
|
|
|
|
|
|
|
|
|
btnGapHead.vg(column.type.gapDirection(column, true))
|
|
|
|
|
?.imageTintList = content_color_csl
|
|
|
|
|
|
|
|
|
|
btnGapTail.vg(column.type.gapDirection(column, false))
|
|
|
|
|
?.imageTintList = content_color_csl
|
|
|
|
|
|
|
|
|
|
val c = Pref.ipEventBgColorGap(App1.pref)
|
|
|
|
|
if (c != 0) this.viewRoot.backgroundColor = c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showSearchGap(item: TootSearchGap) {
|
|
|
|
|
llSearchTag.visibility = View.VISIBLE
|
|
|
|
|
btnSearchTag.text = activity.getString(
|
|
|
|
|
when (item.type) {
|
2019-08-23 01:49:20 +02:00
|
|
|
|
TootSearchGap.SearchType.Hashtag -> R.string.read_more_hashtag
|
|
|
|
|
TootSearchGap.SearchType.Account -> R.string.read_more_account
|
|
|
|
|
TootSearchGap.SearchType.Status -> R.string.read_more_status
|
|
|
|
|
}
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showReply(iconId: Int, text: Spannable) {
|
|
|
|
|
|
|
|
|
|
llReply.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setIconDrawableId(
|
2018-11-18 03:38:52 +01:00
|
|
|
|
activity,
|
|
|
|
|
ivReply,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
iconId,
|
2018-11-18 15:29:35 +01:00
|
|
|
|
color = content_color,
|
|
|
|
|
alphaMultiplier = Styler.boost_alpha
|
2018-11-18 03:38:52 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
tvReply.text = text
|
|
|
|
|
reply_invalidator.register(text)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showReply(reply: TootStatus, iconId: Int, stringId: Int) {
|
|
|
|
|
status_reply = reply
|
|
|
|
|
showReply(
|
2019-09-23 19:02:01 +02:00
|
|
|
|
iconId,
|
|
|
|
|
reply.accountRef.decoded_display_name.intoStringResource(activity, stringId)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showReply(reply: TootStatus, accountId: EntityId) {
|
|
|
|
|
val name = if (accountId == reply.account.id) {
|
|
|
|
|
// 自己レスなら
|
|
|
|
|
AcctColor.getNicknameWithColor(access_info, reply.account)
|
|
|
|
|
} else {
|
|
|
|
|
val m = reply.mentions?.find { it.id == accountId }
|
|
|
|
|
if (m != null) {
|
|
|
|
|
AcctColor.getNicknameWithColor(access_info.getFullAcct(m.acct))
|
|
|
|
|
} else {
|
|
|
|
|
SpannableString("ID(${accountId})")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val text = name.intoStringResource(activity, R.string.reply_to)
|
|
|
|
|
showReply(R.drawable.ic_reply, text)
|
|
|
|
|
|
|
|
|
|
// tootsearchはreplyオブジェクトがなくin_reply_toだけが提供される場合があるが
|
|
|
|
|
// tootsearchではどのタンスから読んだか分からないのでin_reply_toのIDも信用できない
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showBoost(
|
|
|
|
|
whoRef: TootAccountRef,
|
|
|
|
|
time: Long,
|
|
|
|
|
iconId: Int,
|
|
|
|
|
string_id: Int,
|
|
|
|
|
misskeyReaction: String? = null,
|
|
|
|
|
boost_status: TootStatus? = null
|
2018-05-08 10:55:08 +02:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
boost_account = whoRef
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
setIconDrawableId(
|
2021-01-03 06:11:04 +01:00
|
|
|
|
activity,
|
|
|
|
|
ivBoosted,
|
|
|
|
|
iconId,
|
|
|
|
|
color = content_color,
|
|
|
|
|
alphaMultiplier = Styler.boost_alpha
|
|
|
|
|
)
|
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val who = whoRef.get()
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
// フォローの場合 decoded_display_name が2箇所で表示に使われるのを避ける必要がある
|
|
|
|
|
val text: Spannable = if (misskeyReaction != null) {
|
|
|
|
|
val options = DecodeOptions(
|
2018-11-18 03:38:52 +01:00
|
|
|
|
activity,
|
2021-01-03 06:11:04 +01:00
|
|
|
|
access_info,
|
|
|
|
|
decodeEmoji = true,
|
|
|
|
|
enlargeEmoji = 1.5f,
|
|
|
|
|
enlargeCustomEmoji = 1.5f
|
2018-11-18 03:38:52 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val ssb = MisskeyReaction.toSpannableStringBuilder(misskeyReaction, options, boost_status)
|
|
|
|
|
ssb.append(" ")
|
|
|
|
|
ssb.append(who.decodeDisplayName(activity)
|
2021-01-03 06:11:04 +01:00
|
|
|
|
.intoStringResource(activity, string_id))
|
2021-01-04 02:11:45 +01:00
|
|
|
|
} else {
|
|
|
|
|
who.decodeDisplayName(activity)
|
|
|
|
|
.intoStringResource(activity, string_id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boost_time = time
|
|
|
|
|
llBoosted.visibility = View.VISIBLE
|
|
|
|
|
showStatusTime(activity, tvBoostedTime, who, time = time, status = boost_status)
|
|
|
|
|
tvBoosted.text = text
|
|
|
|
|
boost_invalidator.register(text)
|
|
|
|
|
setAcct(tvBoostedAcct, access_info, who)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showAccount(whoRef: TootAccountRef) {
|
|
|
|
|
|
|
|
|
|
follow_account = whoRef
|
|
|
|
|
val who = whoRef.get()
|
|
|
|
|
llFollow.visibility = View.VISIBLE
|
|
|
|
|
ivFollow.setImageUrl(
|
2018-01-21 13:46:36 +01:00
|
|
|
|
activity.pref,
|
|
|
|
|
Styler.calcIconRound(ivFollow.layoutParams),
|
2018-11-11 11:43:20 +01:00
|
|
|
|
access_info.supplyBaseUrl(who.avatar_static),
|
|
|
|
|
access_info.supplyBaseUrl(who.avatar)
|
2018-01-21 13:46:36 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
tvFollowerName.text = whoRef.decoded_display_name
|
|
|
|
|
follow_invalidator.register(whoRef.decoded_display_name)
|
|
|
|
|
|
|
|
|
|
setAcct(tvFollowerAcct, access_info, who)
|
|
|
|
|
|
|
|
|
|
who.setAccountExtra(access_info, tvLastStatusAt, lastActive_invalidator)
|
|
|
|
|
|
|
|
|
|
val relation = UserRelation.load(access_info.db_id, who.id)
|
|
|
|
|
Styler.setFollowIcon(
|
2018-11-18 15:29:35 +01:00
|
|
|
|
activity,
|
|
|
|
|
btnFollow,
|
|
|
|
|
ivFollowedBy,
|
|
|
|
|
relation,
|
|
|
|
|
who,
|
|
|
|
|
content_color,
|
|
|
|
|
alphaMultiplier = Styler.boost_alpha
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
if (column.type == ColumnType.FOLLOW_REQUESTS) {
|
|
|
|
|
llFollowRequest.visibility = View.VISIBLE
|
|
|
|
|
btnFollowRequestAccept.imageTintList = content_color_csl
|
|
|
|
|
btnFollowRequestDeny.imageTintList = content_color_csl
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showStatus(status: TootStatus, colorBg: Int = 0) {
|
|
|
|
|
|
|
|
|
|
val filteredWord = status.filteredWord
|
|
|
|
|
if (filteredWord != null) {
|
|
|
|
|
showMessageHolder(
|
2019-12-15 16:34:46 +01:00
|
|
|
|
TootMessageHolder(
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (Pref.bpShowFilteredWord(activity.pref)) {
|
2019-12-15 16:34:46 +01:00
|
|
|
|
"${activity.getString(R.string.filtered)} / $filteredWord"
|
|
|
|
|
} else {
|
|
|
|
|
activity.getString(R.string.filtered)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.status_showing = status
|
|
|
|
|
llStatus.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
|
|
if (status.conversation_main) {
|
|
|
|
|
|
|
|
|
|
val conversationMainBgColor =
|
|
|
|
|
Pref.ipConversationMainTootBgColor(activity.pref).notZero()
|
|
|
|
|
?: (activity.attrColor(R.attr.colorImageButtonAccent) and 0xffffff) or 0x20000000
|
|
|
|
|
|
|
|
|
|
this.viewRoot.setBackgroundColor(conversationMainBgColor)
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
val c = colorBg.notZero()
|
|
|
|
|
|
|
|
|
|
?: when (status.bookmarked) {
|
2020-04-07 03:38:29 +02:00
|
|
|
|
true -> Pref.ipEventBgColorBookmark(App1.pref)
|
|
|
|
|
false -> 0
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}.notZero()
|
|
|
|
|
|
|
|
|
|
?: when (status.getBackgroundColorType(access_info)) {
|
2019-02-04 05:19:57 +01:00
|
|
|
|
TootVisibility.UnlistedHome -> toot_color_unlisted
|
|
|
|
|
TootVisibility.PrivateFollowers -> toot_color_follower
|
|
|
|
|
TootVisibility.DirectSpecified -> toot_color_direct_user
|
|
|
|
|
TootVisibility.DirectPrivate -> toot_color_direct_me
|
2021-02-10 09:08:00 +01:00
|
|
|
|
// TODO add color setting for limited?
|
|
|
|
|
TootVisibility.Limited -> toot_color_follower
|
2021-01-04 02:11:45 +01:00
|
|
|
|
else -> 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (c != 0) {
|
|
|
|
|
this.viewRoot.backgroundColor = c
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showStatusTime(activity, tvTime, who = status.account, status = status)
|
|
|
|
|
|
|
|
|
|
val whoRef = status.accountRef
|
|
|
|
|
val who = whoRef.get()
|
|
|
|
|
this.status_account = whoRef
|
|
|
|
|
|
|
|
|
|
setAcct(tvAcct, access_info, who)
|
|
|
|
|
|
|
|
|
|
// if(who == null) {
|
|
|
|
|
// tvName.text = "?"
|
|
|
|
|
// name_invalidator.register(null)
|
|
|
|
|
// ivThumbnail.setImageUrl(activity.pref, 16f, null, null)
|
|
|
|
|
// } else {
|
|
|
|
|
tvName.text = whoRef.decoded_display_name
|
|
|
|
|
name_invalidator.register(whoRef.decoded_display_name)
|
|
|
|
|
ivThumbnail.setImageUrl(
|
2018-01-17 18:39:16 +01:00
|
|
|
|
activity.pref,
|
2018-01-18 08:53:32 +01:00
|
|
|
|
Styler.calcIconRound(ivThumbnail.layoutParams),
|
2018-01-17 18:39:16 +01:00
|
|
|
|
access_info.supplyBaseUrl(who.avatar_static),
|
|
|
|
|
access_info.supplyBaseUrl(who.avatar)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
showOpenSticker(who)
|
|
|
|
|
|
|
|
|
|
var content = status.decoded_content
|
|
|
|
|
|
|
|
|
|
// ニコフレのアンケートの表示
|
|
|
|
|
val enquete = status.enquete
|
|
|
|
|
when {
|
|
|
|
|
enquete == null -> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enquete.pollType == TootPollsType.FriendsNico && enquete.type != TootPolls.TYPE_ENQUETE -> {
|
|
|
|
|
// フレニコの投票の結果表示は普通にテキストを表示するだけでよい
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
|
|
|
|
|
// アンケートの本文を上書きする
|
|
|
|
|
val question = enquete.decoded_question
|
|
|
|
|
if (question.isNotBlank()) content = question
|
|
|
|
|
|
|
|
|
|
showEnqueteItems(status, enquete)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showPreviewCard(status)
|
|
|
|
|
|
|
|
|
|
// if( status.decoded_tags == null ){
|
|
|
|
|
// tvTags.setVisibility( View.GONE );
|
|
|
|
|
// }else{
|
|
|
|
|
// tvTags.setVisibility( View.VISIBLE );
|
|
|
|
|
// tvTags.setText( status.decoded_tags );
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (status.decoded_mentions.isEmpty()) {
|
|
|
|
|
tvMentions.visibility = View.GONE
|
|
|
|
|
} else {
|
|
|
|
|
tvMentions.visibility = View.VISIBLE
|
|
|
|
|
tvMentions.text = status.decoded_mentions
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status.time_deleted_at > 0L) {
|
|
|
|
|
val s = SpannableStringBuilder()
|
|
|
|
|
.append('(')
|
|
|
|
|
.append(
|
2018-08-31 14:47:40 +02:00
|
|
|
|
activity.getString(
|
|
|
|
|
R.string.deleted_at,
|
|
|
|
|
TootStatus.formatTime(activity, status.time_deleted_at, true)
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
.append(')')
|
|
|
|
|
content = s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvContent.text = content
|
|
|
|
|
content_invalidator.register(content)
|
|
|
|
|
|
|
|
|
|
activity.checkAutoCW(status, content)
|
|
|
|
|
val r = status.auto_cw
|
|
|
|
|
|
|
|
|
|
tvContent.minLines = r?.originalLineCount ?: -1
|
|
|
|
|
|
|
|
|
|
val decoded_spoiler_text = status.decoded_spoiler_text
|
|
|
|
|
when {
|
|
|
|
|
decoded_spoiler_text.isNotEmpty() -> {
|
|
|
|
|
// 元データに含まれるContent Warning を使う
|
|
|
|
|
llContentWarning.visibility = View.VISIBLE
|
|
|
|
|
tvContentWarning.text = status.decoded_spoiler_text
|
|
|
|
|
spoiler_invalidator.register(status.decoded_spoiler_text)
|
|
|
|
|
val cw_shown = ContentWarning.isShown(status, access_info.expand_cw)
|
|
|
|
|
showContent(cw_shown)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r?.decoded_spoiler_text != null -> {
|
|
|
|
|
// 自動CW
|
|
|
|
|
llContentWarning.visibility = View.VISIBLE
|
|
|
|
|
tvContentWarning.text = r.decoded_spoiler_text
|
|
|
|
|
spoiler_invalidator.register(r.decoded_spoiler_text)
|
|
|
|
|
val cw_shown = ContentWarning.isShown(status, access_info.expand_cw)
|
|
|
|
|
showContent(cw_shown)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
// CWしない
|
|
|
|
|
llContentWarning.visibility = View.GONE
|
|
|
|
|
llContents.visibility = View.VISIBLE
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val media_attachments = status.media_attachments
|
|
|
|
|
if (media_attachments == null || media_attachments.isEmpty()) {
|
|
|
|
|
flMedia.visibility = View.GONE
|
|
|
|
|
llMedia.visibility = View.GONE
|
|
|
|
|
btnShowMedia.visibility = View.GONE
|
|
|
|
|
} else {
|
|
|
|
|
flMedia.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
|
|
// hide sensitive media
|
|
|
|
|
val default_shown = when {
|
|
|
|
|
column.hide_media_default -> false
|
|
|
|
|
access_info.dont_hide_nsfw -> true
|
|
|
|
|
else -> !status.sensitive
|
|
|
|
|
}
|
|
|
|
|
val is_shown = MediaShown.isShown(status, default_shown)
|
|
|
|
|
|
|
|
|
|
btnShowMedia.visibility = if (!is_shown) View.VISIBLE else View.GONE
|
|
|
|
|
llMedia.visibility = if (!is_shown) View.GONE else View.VISIBLE
|
|
|
|
|
val sb = StringBuilder()
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia1, 0)
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia2, 1)
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia3, 2)
|
|
|
|
|
setMedia(media_attachments, sb, ivMedia4, 3)
|
|
|
|
|
|
|
|
|
|
val m0 =
|
|
|
|
|
if (media_attachments.isEmpty()) null else media_attachments[0] as? TootAttachment
|
|
|
|
|
btnShowMedia.blurhash = m0?.blurhash
|
|
|
|
|
|
|
|
|
|
if (sb.isNotEmpty()) {
|
|
|
|
|
tvMediaDescription.visibility = View.VISIBLE
|
|
|
|
|
tvMediaDescription.text = sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIconDrawableId(
|
|
|
|
|
activity,
|
|
|
|
|
btnHideMedia,
|
|
|
|
|
R.drawable.ic_close,
|
|
|
|
|
color = content_color,
|
|
|
|
|
alphaMultiplier = Styler.boost_alpha
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
makeReactionsView(status)
|
|
|
|
|
|
|
|
|
|
buttons_for_status?.bind(status, (item as? TootNotification))
|
|
|
|
|
|
|
|
|
|
var sb: StringBuilder? = null
|
|
|
|
|
|
|
|
|
|
fun prepareSb(): StringBuilder =
|
|
|
|
|
sb?.append(", ") ?: StringBuilder().also { sb = it }
|
|
|
|
|
|
|
|
|
|
val application = status.application
|
|
|
|
|
if (application != null &&
|
|
|
|
|
(column.type == ColumnType.CONVERSATION || Pref.bpShowAppName(activity.pref))
|
|
|
|
|
) {
|
|
|
|
|
prepareSb().append(activity.getString(R.string.application_is, application.name ?: ""))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val language = status.language
|
|
|
|
|
if (language != null &&
|
|
|
|
|
(column.type == ColumnType.CONVERSATION || Pref.bpShowLanguage(activity.pref))
|
|
|
|
|
) {
|
|
|
|
|
prepareSb().append(activity.getString(R.string.language_is, language))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvApplication.vg(sb != null)?.text = sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showOpenSticker(who: TootAccount) {
|
|
|
|
|
try {
|
|
|
|
|
if (!Column.showOpenSticker) return
|
|
|
|
|
|
|
|
|
|
val host = who.apDomain
|
|
|
|
|
|
|
|
|
|
// LTLでホスト名が同じならTickerを表示しない
|
|
|
|
|
when (column.type) {
|
|
|
|
|
ColumnType.LOCAL, ColumnType.LOCAL_AROUND -> {
|
|
|
|
|
if (host == access_info.apDomain) return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val item = OpenSticker.lastList[host.ascii] ?: return
|
|
|
|
|
|
|
|
|
|
tvOpenSticker.text = item.name
|
|
|
|
|
tvOpenSticker.textColor = item.fontColor
|
|
|
|
|
|
|
|
|
|
val density = activity.density
|
|
|
|
|
|
|
|
|
|
val lp = ivOpenSticker.layoutParams
|
|
|
|
|
lp.height = (density * 16f + 0.5f).toInt()
|
|
|
|
|
lp.width = (density * item.imageWidth + 0.5f).toInt()
|
|
|
|
|
|
|
|
|
|
ivOpenSticker.layoutParams = lp
|
|
|
|
|
ivOpenSticker.setImageUrl(activity.pref, 0f, item.favicon)
|
|
|
|
|
val colorBg = item.bgColor
|
|
|
|
|
when (colorBg.size) {
|
2020-10-16 17:41:40 +02:00
|
|
|
|
1 -> {
|
|
|
|
|
val c = colorBg.first()
|
|
|
|
|
tvOpenSticker.setBackgroundColor(c)
|
|
|
|
|
ivOpenSticker.setBackgroundColor(c)
|
2018-12-16 12:24:44 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
ivOpenSticker.setBackgroundColor(colorBg.last())
|
|
|
|
|
tvOpenSticker.background = colorBg.getGradation()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
llOpenSticker.visibility = View.VISIBLE
|
|
|
|
|
llOpenSticker.requestLayout()
|
|
|
|
|
|
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
|
log.trace(ex)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showStatusTime(
|
|
|
|
|
activity: ActMain,
|
|
|
|
|
tv: TextView,
|
|
|
|
|
@Suppress("UNUSED_PARAMETER") who: TootAccount,
|
|
|
|
|
status: TootStatus? = null,
|
|
|
|
|
time: Long? = null
|
2018-04-05 20:04:45 +02:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val sb = SpannableStringBuilder()
|
2020-12-06 19:44:49 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (status != null) {
|
2020-12-06 19:44:49 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (status.account.isAdmin) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_shield, "admin")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status.account.isPro) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_authorized, "pro")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status.account.isCat) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_cat, "cat")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// botマーク
|
|
|
|
|
if (status.account.bot) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_bot, "bot")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status.account.suspended) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_delete, "suspended")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// mobileマーク
|
|
|
|
|
if (status.viaMobile) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_mobile, "mobile")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// mobileマーク
|
|
|
|
|
if (status.bookmarked) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_bookmark, "bookmarked")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NSFWマーク
|
|
|
|
|
if (status.hasMedia() && status.sensitive) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_eye_off, "NSFW")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// visibility
|
|
|
|
|
val visIconId =
|
|
|
|
|
Styler.getVisibilityIconId(access_info.isMisskey, status.visibility)
|
|
|
|
|
if (R.drawable.ic_public != visIconId) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(
|
2018-11-18 03:38:52 +01:00
|
|
|
|
activity,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
visIconId,
|
2018-08-21 03:53:52 +02:00
|
|
|
|
Styler.getVisibilityString(
|
|
|
|
|
activity,
|
|
|
|
|
access_info.isMisskey,
|
|
|
|
|
status.visibility
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pinned
|
|
|
|
|
if (status.pinned) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_pin, "pinned")
|
|
|
|
|
|
|
|
|
|
// val start = sb.length
|
|
|
|
|
// sb.append("pinned")
|
|
|
|
|
// val end = sb.length
|
|
|
|
|
// val icon_id = Styler.getAttributeResourceId(activity, R.attr.ic_pin)
|
|
|
|
|
// sb.setSpan(
|
|
|
|
|
// EmojiImageSpan(activity, icon_id),
|
|
|
|
|
// start,
|
|
|
|
|
// end,
|
|
|
|
|
// Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
|
|
|
// )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// unread
|
|
|
|
|
if (status.conversationSummary?.unread == true) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
|
|
|
|
|
sb.appendColorShadeIcon(
|
2018-10-28 14:08:10 +01:00
|
|
|
|
activity,
|
|
|
|
|
R.drawable.ic_unread,
|
|
|
|
|
"unread",
|
2019-01-21 00:00:59 +01:00
|
|
|
|
color = MyClickableSpan.defaultLinkColor
|
2018-10-28 14:08:10 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status.isPromoted) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append(' ')
|
|
|
|
|
sb.append(activity.getString(R.string.promoted))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status.isFeatured) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append(' ')
|
|
|
|
|
sb.append(activity.getString(R.string.featured))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sb.isNotEmpty()) sb.append(' ')
|
|
|
|
|
sb.append(
|
2018-04-05 20:04:45 +02:00
|
|
|
|
when {
|
|
|
|
|
time != null -> TootStatus.formatTime(
|
|
|
|
|
activity,
|
|
|
|
|
time,
|
2019-08-23 01:49:20 +02:00
|
|
|
|
column.type != ColumnType.CONVERSATION
|
2018-04-05 20:04:45 +02:00
|
|
|
|
)
|
|
|
|
|
status != null -> TootStatus.formatTime(
|
|
|
|
|
activity,
|
|
|
|
|
status.time_created_at,
|
2019-08-23 01:49:20 +02:00
|
|
|
|
column.type != ColumnType.CONVERSATION
|
2018-04-05 20:04:45 +02:00
|
|
|
|
)
|
|
|
|
|
else -> "?"
|
|
|
|
|
}
|
2018-01-17 18:39:16 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
tv.text = sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showStatusTimeScheduled(
|
|
|
|
|
activity: ActMain,
|
|
|
|
|
tv: TextView,
|
|
|
|
|
item: TootScheduled
|
2019-01-06 15:55:25 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val sb = SpannableStringBuilder()
|
|
|
|
|
|
|
|
|
|
// NSFWマーク
|
|
|
|
|
if (item.hasMedia() && item.sensitive) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(activity, R.drawable.ic_eye_off, "NSFW")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// visibility
|
|
|
|
|
val visIconId =
|
|
|
|
|
Styler.getVisibilityIconId(access_info.isMisskey, item.visibility)
|
|
|
|
|
if (R.drawable.ic_public != visIconId) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append('\u200B')
|
|
|
|
|
sb.appendColorShadeIcon(
|
2019-01-16 13:33:07 +01:00
|
|
|
|
activity,
|
|
|
|
|
visIconId,
|
|
|
|
|
Styler.getVisibilityString(
|
2019-01-06 15:55:25 +01:00
|
|
|
|
activity,
|
2019-01-16 13:33:07 +01:00
|
|
|
|
access_info.isMisskey,
|
|
|
|
|
item.visibility
|
2019-01-06 15:55:25 +01:00
|
|
|
|
)
|
2019-01-16 13:33:07 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sb.isNotEmpty()) sb.append(' ')
|
|
|
|
|
sb.append(
|
2019-01-06 15:55:25 +01:00
|
|
|
|
TootStatus.formatTime(
|
|
|
|
|
activity,
|
|
|
|
|
item.timeScheduledAt,
|
2019-08-23 01:49:20 +02:00
|
|
|
|
column.type != ColumnType.CONVERSATION
|
2019-01-06 15:55:25 +01:00
|
|
|
|
)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
tv.text = sb
|
|
|
|
|
}
|
|
|
|
|
// fun updateRelativeTime() {
|
|
|
|
|
// val boost_time = this.boost_time
|
|
|
|
|
// if(boost_time != 0L) {
|
|
|
|
|
// tvBoostedTime.text = TootStatus.formatTime(tvBoostedTime.context, boost_time, true)
|
|
|
|
|
// }
|
|
|
|
|
// val status_showing = this.status_showing
|
|
|
|
|
// if(status_showing != null) {
|
|
|
|
|
// showStatusTime(activity, status_showing)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
private fun setAcct(tv: TextView, accessInfo: SavedAccount, who: TootAccount) {
|
|
|
|
|
val ac = AcctColor.load(accessInfo, who)
|
|
|
|
|
tv.text = when {
|
|
|
|
|
AcctColor.hasNickname(ac) -> ac.nickname
|
|
|
|
|
Pref.bpShortAcctLocalUser(App1.pref) -> "@${who.acct.pretty}"
|
|
|
|
|
else -> "@${ac.nickname}"
|
|
|
|
|
}
|
|
|
|
|
tv.textColor = ac.color_fg.notZero() ?: this.acct_color
|
|
|
|
|
|
|
|
|
|
tv.setBackgroundColor(ac.color_bg) // may 0
|
|
|
|
|
tv.setPaddingRelative(activity.acct_pad_lr, 0, activity.acct_pad_lr, 0)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showContent(shown: Boolean) {
|
|
|
|
|
llContents.visibility = if (shown) View.VISIBLE else View.GONE
|
|
|
|
|
btnContentWarning.setText(if (shown) R.string.hide else R.string.show)
|
|
|
|
|
status_showing?.let { status ->
|
|
|
|
|
val r = status.auto_cw
|
|
|
|
|
tvContent.minLines = r?.originalLineCount ?: -1
|
|
|
|
|
if (r?.decoded_spoiler_text != null) {
|
|
|
|
|
// 自動CWの場合はContentWarningのテキストを切り替える
|
|
|
|
|
tvContentWarning.text =
|
|
|
|
|
if (shown) activity.getString(R.string.auto_cw_prefix) else r.decoded_spoiler_text
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun setMedia(
|
|
|
|
|
media_attachments: ArrayList<TootAttachmentLike>,
|
|
|
|
|
sbDesc: StringBuilder,
|
|
|
|
|
iv: MyNetworkImageView,
|
|
|
|
|
idx: Int
|
2018-01-17 18:39:16 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val ta = if (idx < media_attachments.size) media_attachments[idx] else null
|
|
|
|
|
if (ta == null) {
|
|
|
|
|
iv.visibility = View.GONE
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iv.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
|
|
iv.setFocusPoint(ta.focusX, ta.focusY)
|
|
|
|
|
|
|
|
|
|
if (Pref.bpDontCropMediaThumb(App1.pref)) {
|
|
|
|
|
iv.scaleType = ImageView.ScaleType.FIT_CENTER
|
|
|
|
|
} else {
|
|
|
|
|
iv.setScaleTypeForMedia()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val showUrl: Boolean
|
|
|
|
|
|
|
|
|
|
when (ta.type) {
|
2019-06-23 16:58:53 +02:00
|
|
|
|
TootAttachmentType.Audio -> {
|
2018-12-17 21:41:17 +01:00
|
|
|
|
iv.setMediaType(0)
|
2019-01-18 13:16:01 +01:00
|
|
|
|
iv.setDefaultImage(defaultColorIcon(activity, R.drawable.wide_music))
|
2020-07-22 20:46:33 +02:00
|
|
|
|
iv.setImageUrl(activity.pref, 0f, ta.urlForThumbnail(activity.pref))
|
2019-01-18 13:16:01 +01:00
|
|
|
|
showUrl = true
|
2018-12-17 21:41:17 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-06-23 16:58:53 +02:00
|
|
|
|
TootAttachmentType.Unknown -> {
|
2018-12-17 21:41:17 +01:00
|
|
|
|
iv.setMediaType(0)
|
2019-01-18 13:16:01 +01:00
|
|
|
|
iv.setDefaultImage(defaultColorIcon(activity, R.drawable.wide_question))
|
2018-12-26 05:47:16 +01:00
|
|
|
|
iv.setImageUrl(activity.pref, 0f, null)
|
2019-01-18 13:16:01 +01:00
|
|
|
|
showUrl = true
|
2018-12-17 21:41:17 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
else -> when (val urlThumbnail = ta.urlForThumbnail(activity.pref)) {
|
2019-01-18 13:16:01 +01:00
|
|
|
|
null, "" -> {
|
|
|
|
|
iv.setMediaType(0)
|
|
|
|
|
iv.setDefaultImage(defaultColorIcon(activity, R.drawable.wide_question))
|
|
|
|
|
iv.setImageUrl(activity.pref, 0f, null)
|
|
|
|
|
showUrl = true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
iv.setMediaType(
|
|
|
|
|
when (ta.type) {
|
2019-06-23 16:58:53 +02:00
|
|
|
|
TootAttachmentType.Video -> R.drawable.media_type_video
|
|
|
|
|
TootAttachmentType.GIFV -> R.drawable.media_type_gifv
|
2019-01-18 13:16:01 +01:00
|
|
|
|
else -> 0
|
|
|
|
|
}
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
iv.setDefaultImage(null)
|
|
|
|
|
iv.setImageUrl(
|
2019-01-18 13:16:01 +01:00
|
|
|
|
activity.pref,
|
|
|
|
|
0f,
|
|
|
|
|
access_info.supplyBaseUrl(urlThumbnail),
|
|
|
|
|
access_info.supplyBaseUrl(urlThumbnail)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
showUrl = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun appendDescription(s: String) {
|
|
|
|
|
// val lp = LinearLayout.LayoutParams(
|
|
|
|
|
// LinearLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
|
// LinearLayout.LayoutParams.WRAP_CONTENT
|
|
|
|
|
// )
|
|
|
|
|
// lp.topMargin = (0.5f + activity.density * 3f).toInt()
|
|
|
|
|
//
|
|
|
|
|
// val tv = MyTextView(activity)
|
|
|
|
|
// tv.layoutParams = lp
|
|
|
|
|
// //
|
|
|
|
|
// tv.movementMethod = MyLinkMovementMethod
|
|
|
|
|
// if(! activity.timeline_font_size_sp.isNaN()) {
|
|
|
|
|
// tv.textSize = activity.timeline_font_size_sp
|
|
|
|
|
// }
|
|
|
|
|
// tv.setTextColor(content_color)
|
|
|
|
|
|
|
|
|
|
if (sbDesc.isNotEmpty()) sbDesc.append("\n")
|
|
|
|
|
val desc = activity.getString(R.string.media_description, idx + 1, s)
|
|
|
|
|
sbDesc.append(desc)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
when (val description = ta.description.notEmpty()) {
|
|
|
|
|
null -> if (showUrl) ta.urlForDescription.notEmpty()?.let { appendDescription(it) }
|
|
|
|
|
else -> appendDescription(description)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private val defaultBoostedAction: () -> Unit = {
|
|
|
|
|
val pos = activity.nextPosition(column)
|
|
|
|
|
val notification = (item as? TootNotification)
|
|
|
|
|
boost_account?.let { whoRef ->
|
|
|
|
|
if (access_info.isPseudo) {
|
|
|
|
|
DlgContextMenu(activity, column, whoRef, null, notification, tvContent).show()
|
|
|
|
|
} else {
|
|
|
|
|
Action_User.profileLocal(activity, pos, access_info, whoRef.get())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private var boostedAction: () -> Unit = defaultBoostedAction
|
|
|
|
|
|
|
|
|
|
override fun onClick(v: View) {
|
|
|
|
|
|
|
|
|
|
val pos = activity.nextPosition(column)
|
|
|
|
|
val item = this.item
|
|
|
|
|
val notification = (item as? TootNotification)
|
|
|
|
|
when (v) {
|
|
|
|
|
|
2020-01-29 06:15:32 +01:00
|
|
|
|
btnHideMedia, btnCardImageHide -> {
|
2020-02-16 09:13:11 +01:00
|
|
|
|
fun hideViews() {
|
2020-01-29 06:15:32 +01:00
|
|
|
|
llMedia.visibility = View.GONE
|
|
|
|
|
btnShowMedia.visibility = View.VISIBLE
|
2020-02-16 09:13:11 +01:00
|
|
|
|
llCardImage.visibility = View.GONE
|
2020-01-29 06:15:32 +01:00
|
|
|
|
btnCardImageShow.visibility = View.VISIBLE
|
|
|
|
|
}
|
2019-01-06 15:55:25 +01:00
|
|
|
|
status_showing?.let { status ->
|
|
|
|
|
MediaShown.save(status, false)
|
2020-01-29 06:15:32 +01:00
|
|
|
|
hideViews()
|
2019-01-06 15:55:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (item is TootScheduled) {
|
2019-01-06 15:55:25 +01:00
|
|
|
|
MediaShown.save(item.uri, false)
|
2020-01-29 06:15:32 +01:00
|
|
|
|
hideViews()
|
2019-01-06 15:55:25 +01:00
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-01-29 06:15:32 +01:00
|
|
|
|
btnShowMedia, btnCardImageShow -> {
|
2020-02-16 09:13:11 +01:00
|
|
|
|
fun showViews() {
|
2020-01-29 06:15:32 +01:00
|
|
|
|
llMedia.visibility = View.VISIBLE
|
|
|
|
|
btnShowMedia.visibility = View.GONE
|
2020-02-16 09:13:11 +01:00
|
|
|
|
llCardImage.visibility = View.VISIBLE
|
2020-01-29 06:15:32 +01:00
|
|
|
|
btnCardImageShow.visibility = View.GONE
|
|
|
|
|
}
|
2019-01-06 15:55:25 +01:00
|
|
|
|
status_showing?.let { status ->
|
|
|
|
|
MediaShown.save(status, true)
|
2020-01-29 06:15:32 +01:00
|
|
|
|
showViews()
|
2019-01-06 15:55:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (item is TootScheduled) {
|
2019-01-06 15:55:25 +01:00
|
|
|
|
MediaShown.save(item.uri, true)
|
2020-01-29 06:15:32 +01:00
|
|
|
|
showViews()
|
2019-01-06 15:55:25 +01:00
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-14 22:47:42 +01:00
|
|
|
|
ivMedia1 -> clickMedia(0)
|
|
|
|
|
ivMedia2 -> clickMedia(1)
|
|
|
|
|
ivMedia3 -> clickMedia(2)
|
|
|
|
|
ivMedia4 -> clickMedia(3)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-16 13:33:07 +01:00
|
|
|
|
btnContentWarning -> {
|
2019-01-06 15:55:25 +01:00
|
|
|
|
status_showing?.let { status ->
|
|
|
|
|
val new_shown = llContents.visibility == View.GONE
|
|
|
|
|
ContentWarning.save(status, new_shown)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-06 15:55:25 +01:00
|
|
|
|
// 1個だけ開閉するのではなく、例えば通知TLにある複数の要素をまとめて開閉するなどある
|
|
|
|
|
list_adapter.notifyChange(reason = "ContentWarning onClick", reset = true)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-06 15:55:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (item is TootScheduled) {
|
2019-01-06 15:55:25 +01:00
|
|
|
|
val new_shown = llContents.visibility == View.GONE
|
|
|
|
|
ContentWarning.save(item.uri, new_shown)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-06 15:55:25 +01:00
|
|
|
|
// 1個だけ開閉するのではなく、例えば通知TLにある複数の要素をまとめて開閉するなどある
|
|
|
|
|
list_adapter.notifyChange(reason = "ContentWarning onClick", reset = true)
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-08 10:25:02 +02:00
|
|
|
|
ivThumbnail -> status_account?.let { whoRef ->
|
2018-08-18 12:58:14 +02:00
|
|
|
|
when {
|
2019-01-06 09:35:22 +01:00
|
|
|
|
access_info.isNA -> DlgContextMenu(
|
2018-08-21 03:53:52 +02:00
|
|
|
|
activity,
|
|
|
|
|
column,
|
|
|
|
|
whoRef,
|
|
|
|
|
null,
|
2019-01-08 10:41:07 +01:00
|
|
|
|
notification,
|
|
|
|
|
tvContent
|
2018-08-21 03:53:52 +02:00
|
|
|
|
).show()
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-12-26 05:47:16 +01:00
|
|
|
|
// 2018/12/26 疑似アカウントでもプロフカラムを表示する https://github.com/tootsuite/mastodon/commit/108b2139cd87321f6c0aec63ef93db85ce30bfec
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-12-26 05:47:16 +01:00
|
|
|
|
else -> Action_User.profileLocal(
|
|
|
|
|
activity,
|
|
|
|
|
pos,
|
|
|
|
|
access_info,
|
|
|
|
|
whoRef.get()
|
|
|
|
|
)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 12:19:02 +02:00
|
|
|
|
llBoosted -> boostedAction()
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
|
llReply -> {
|
2018-11-16 15:44:23 +01:00
|
|
|
|
val s = status_reply
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-09-23 19:02:01 +02:00
|
|
|
|
when {
|
|
|
|
|
s != null -> Action_Toot.conversation(activity, pos, access_info, s)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-09-23 19:02:01 +02:00
|
|
|
|
// tootsearchは返信元のIDを取得するのにひと手間必要
|
2020-12-07 13:53:55 +01:00
|
|
|
|
column.type == ColumnType.SEARCH_TS ||
|
|
|
|
|
column.type == ColumnType.SEARCH_NOTESTOCK ->
|
2019-09-23 19:02:01 +02:00
|
|
|
|
Action_Toot.showReplyTootsearch(activity, pos, status_showing)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-09-23 19:02:01 +02:00
|
|
|
|
else -> {
|
|
|
|
|
val id = status_showing?.in_reply_to_id
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (id != null) {
|
2019-09-23 19:02:01 +02:00
|
|
|
|
Action_Toot.conversationLocal(activity, pos, access_info, id)
|
|
|
|
|
}
|
2018-11-16 15:44:23 +01:00
|
|
|
|
}
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-08 10:25:02 +02:00
|
|
|
|
llFollow -> follow_account?.let { whoRef ->
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (access_info.isPseudo) {
|
2019-01-16 13:33:07 +01:00
|
|
|
|
DlgContextMenu(activity, column, whoRef, null, notification, tvContent).show()
|
2018-01-04 19:52:25 +01:00
|
|
|
|
} else {
|
2018-05-18 19:08:46 +02:00
|
|
|
|
Action_User.profileLocal(activity, pos, access_info, whoRef.get())
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-14 22:47:42 +01:00
|
|
|
|
btnFollow -> follow_account?.let { who ->
|
2019-01-16 13:33:07 +01:00
|
|
|
|
DlgContextMenu(activity, column, who, null, notification, tvContent).show()
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
btnGapHead -> when (item) {
|
2020-09-11 21:34:58 +02:00
|
|
|
|
is TootGap -> column.startGap(item, isHead = true)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
btnGapTail -> when (item) {
|
2020-09-11 21:34:58 +02:00
|
|
|
|
is TootGap -> column.startGap(item, isHead = false)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
btnSearchTag, llTrendTag -> when (item) {
|
|
|
|
|
|
2018-11-11 11:43:20 +01:00
|
|
|
|
is TootConversationSummary -> openConversationSummary()
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-09-12 19:47:00 +02:00
|
|
|
|
is TootGap -> when {
|
|
|
|
|
column.type.gapDirection(column, true) ->
|
|
|
|
|
column.startGap(item, isHead = true)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-09-12 19:47:00 +02:00
|
|
|
|
column.type.gapDirection(column, false) ->
|
|
|
|
|
column.startGap(item, isHead = false)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-09-12 19:47:00 +02:00
|
|
|
|
else ->
|
2020-09-29 19:44:56 +02:00
|
|
|
|
activity.showToast(true, "This column can't support gap reading.")
|
2020-09-12 19:47:00 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-09-20 15:10:49 +02:00
|
|
|
|
is TootSearchGap -> column.startGap(item, isHead = true)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
|
is TootDomainBlock -> {
|
|
|
|
|
AlertDialog.Builder(activity)
|
2020-02-16 09:13:11 +01:00
|
|
|
|
.setMessage(
|
|
|
|
|
activity.getString(
|
|
|
|
|
R.string.confirm_unblock_domain,
|
|
|
|
|
item.domain.pretty
|
|
|
|
|
)
|
|
|
|
|
)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
.setNegativeButton(R.string.cancel, null)
|
2018-01-17 18:39:16 +01:00
|
|
|
|
.setPositiveButton(R.string.ok) { _, _ ->
|
|
|
|
|
Action_Instance.blockDomain(
|
|
|
|
|
activity,
|
|
|
|
|
access_info,
|
2020-02-02 15:19:57 +01:00
|
|
|
|
item.domain,
|
|
|
|
|
bBlock = false
|
2018-01-17 18:39:16 +01:00
|
|
|
|
)
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
.show()
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-20 07:51:14 +01:00
|
|
|
|
is TootTag -> {
|
2018-01-17 18:39:16 +01:00
|
|
|
|
Action_HashTag.timeline(
|
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
|
|
|
|
access_info,
|
2018-01-20 07:51:14 +01:00
|
|
|
|
item.name // #を含まない
|
2018-01-17 18:39:16 +01:00
|
|
|
|
)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-16 13:33:07 +01:00
|
|
|
|
is TootScheduled -> {
|
2019-01-06 11:17:54 +01:00
|
|
|
|
ActionsDialog()
|
2019-11-11 13:34:50 +01:00
|
|
|
|
.addAction(activity.getString(R.string.edit)) {
|
|
|
|
|
Action_Toot.editScheduledPost(activity, access_info, item)
|
|
|
|
|
}
|
|
|
|
|
.addAction(activity.getString(R.string.delete)) {
|
2019-01-16 13:33:07 +01:00
|
|
|
|
Action_Toot.deleteScheduledPost(activity, access_info, item) {
|
2019-01-06 11:17:54 +01:00
|
|
|
|
column.onScheduleDeleted(item)
|
2020-09-29 19:44:56 +02:00
|
|
|
|
activity.showToast(false, R.string.scheduled_post_deleted)
|
2019-01-06 11:17:54 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.show(activity)
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
btnListTL -> if (item is TootList) {
|
2019-08-23 01:49:20 +02:00
|
|
|
|
activity.addColumn(pos, access_info, ColumnType.LIST_TL, item.id)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
} else if (item is MisskeyAntenna) {
|
2020-02-19 12:18:54 +01:00
|
|
|
|
// TODO
|
|
|
|
|
activity.addColumn(pos, access_info, ColumnType.MISSKEY_ANTENNA_TL, item.id)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
btnListMore -> when (item) {
|
2020-09-11 21:34:58 +02:00
|
|
|
|
is TootList -> {
|
|
|
|
|
ActionsDialog()
|
|
|
|
|
.addAction(activity.getString(R.string.list_timeline)) {
|
|
|
|
|
activity.addColumn(pos, access_info, ColumnType.LIST_TL, item.id)
|
|
|
|
|
}
|
|
|
|
|
.addAction(activity.getString(R.string.list_member)) {
|
|
|
|
|
activity.addColumn(
|
|
|
|
|
false,
|
|
|
|
|
pos,
|
|
|
|
|
access_info,
|
|
|
|
|
ColumnType.LIST_MEMBER,
|
|
|
|
|
item.id
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
.addAction(activity.getString(R.string.rename)) {
|
|
|
|
|
Action_List.rename(activity, access_info, item)
|
|
|
|
|
}
|
|
|
|
|
.addAction(activity.getString(R.string.delete)) {
|
|
|
|
|
Action_List.delete(activity, access_info, item)
|
|
|
|
|
}
|
|
|
|
|
.show(activity, item.title)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-09-11 21:34:58 +02:00
|
|
|
|
is MisskeyAntenna -> {
|
|
|
|
|
// TODO
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-08 10:25:02 +02:00
|
|
|
|
btnFollowRequestAccept -> follow_account?.let { whoRef ->
|
2018-05-18 19:08:46 +02:00
|
|
|
|
val who = whoRef.get()
|
2018-05-08 10:55:08 +02:00
|
|
|
|
DlgConfirm.openSimple(
|
|
|
|
|
activity,
|
|
|
|
|
activity.getString(
|
|
|
|
|
R.string.follow_accept_confirm,
|
2020-02-16 09:13:11 +01:00
|
|
|
|
AcctColor.getNickname(access_info, who)
|
2018-05-08 10:55:08 +02:00
|
|
|
|
)
|
|
|
|
|
) {
|
2018-05-08 10:25:02 +02:00
|
|
|
|
Action_Follow.authorizeFollowRequest(activity, access_info, whoRef, true)
|
2018-04-17 18:29:50 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-08 10:25:02 +02:00
|
|
|
|
btnFollowRequestDeny -> follow_account?.let { whoRef ->
|
2018-05-18 19:08:46 +02:00
|
|
|
|
val who = whoRef.get()
|
2018-05-08 10:55:08 +02:00
|
|
|
|
DlgConfirm.openSimple(
|
|
|
|
|
activity,
|
|
|
|
|
activity.getString(
|
|
|
|
|
R.string.follow_deny_confirm,
|
2020-02-16 09:13:11 +01:00
|
|
|
|
AcctColor.getNickname(access_info, who)
|
2018-05-08 10:55:08 +02:00
|
|
|
|
)
|
|
|
|
|
) {
|
2018-05-08 10:25:02 +02:00
|
|
|
|
Action_Follow.authorizeFollowRequest(activity, access_info, whoRef, false)
|
2018-04-17 18:29:50 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
llFilter -> if (item is TootFilter) {
|
2018-07-07 07:15:16 +02:00
|
|
|
|
openFilterMenu(item)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-11-14 07:47:25 +01:00
|
|
|
|
ivCardImage -> status_showing?.card?.let { card ->
|
2018-11-12 18:19:57 +01:00
|
|
|
|
val originalStatus = card.originalStatus
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (originalStatus != null) {
|
2018-11-12 18:19:57 +01:00
|
|
|
|
Action_Toot.conversation(
|
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
|
|
|
|
access_info,
|
|
|
|
|
originalStatus
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
val url = card.url
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (url?.isNotEmpty() == true) {
|
2020-12-07 09:33:01 +01:00
|
|
|
|
openCustomTab(
|
2018-11-12 18:19:57 +01:00
|
|
|
|
activity,
|
|
|
|
|
pos,
|
|
|
|
|
url,
|
|
|
|
|
accessInfo = access_info
|
2020-12-07 09:33:01 +01:00
|
|
|
|
)
|
2018-11-12 18:19:57 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-14 22:47:42 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-11-11 11:43:20 +01:00
|
|
|
|
llConversationIcons -> openConversationSummary()
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onLongClick(v: View): Boolean {
|
|
|
|
|
|
|
|
|
|
val notification = (item as? TootNotification)
|
|
|
|
|
|
|
|
|
|
when (v) {
|
|
|
|
|
|
2018-01-14 22:47:42 +01:00
|
|
|
|
ivThumbnail -> {
|
2018-01-17 18:39:16 +01:00
|
|
|
|
status_account?.let { who ->
|
|
|
|
|
DlgContextMenu(
|
|
|
|
|
activity,
|
|
|
|
|
column,
|
|
|
|
|
who,
|
|
|
|
|
null,
|
2019-01-08 10:41:07 +01:00
|
|
|
|
notification,
|
|
|
|
|
tvContent
|
2018-01-17 18:39:16 +01:00
|
|
|
|
).show()
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
return true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-14 22:47:42 +01:00
|
|
|
|
llBoosted -> {
|
2018-01-17 18:39:16 +01:00
|
|
|
|
boost_account?.let { who ->
|
|
|
|
|
DlgContextMenu(
|
|
|
|
|
activity,
|
|
|
|
|
column,
|
|
|
|
|
who,
|
|
|
|
|
null,
|
2019-01-08 10:41:07 +01:00
|
|
|
|
notification,
|
|
|
|
|
tvContent
|
2018-01-17 18:39:16 +01:00
|
|
|
|
).show()
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
return true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
|
llReply -> {
|
2018-11-16 15:44:23 +01:00
|
|
|
|
val s = status_reply
|
2019-09-23 19:02:01 +02:00
|
|
|
|
when {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-09-23 19:02:01 +02:00
|
|
|
|
// 返信元のstatusがあるならコンテキストメニュー
|
|
|
|
|
s != null -> DlgContextMenu(
|
2018-08-23 05:46:14 +02:00
|
|
|
|
activity,
|
|
|
|
|
column,
|
|
|
|
|
s.accountRef,
|
|
|
|
|
s,
|
2019-01-08 10:41:07 +01:00
|
|
|
|
notification,
|
|
|
|
|
tvContent
|
2018-08-23 05:46:14 +02:00
|
|
|
|
).show()
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-09-23 19:02:01 +02:00
|
|
|
|
// それ以外はコンテキストメニューではなく会話を開く
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-09-23 19:02:01 +02:00
|
|
|
|
// tootsearchは返信元のIDを取得するのにひと手間必要
|
2020-12-07 13:53:55 +01:00
|
|
|
|
column.type == ColumnType.SEARCH_TS ||
|
|
|
|
|
column.type == ColumnType.SEARCH_NOTESTOCK ->
|
2019-09-23 19:02:01 +02:00
|
|
|
|
Action_Toot.showReplyTootsearch(
|
2018-11-18 03:38:52 +01:00
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
2019-09-23 19:02:01 +02:00
|
|
|
|
status_showing
|
2018-11-18 03:38:52 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-09-23 19:02:01 +02:00
|
|
|
|
else -> {
|
|
|
|
|
val id = status_showing?.in_reply_to_id
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (id != null) {
|
2019-09-23 19:02:01 +02:00
|
|
|
|
Action_Toot.conversationLocal(
|
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
|
|
|
|
access_info,
|
|
|
|
|
id
|
|
|
|
|
)
|
|
|
|
|
}
|
2018-11-16 15:44:23 +01:00
|
|
|
|
}
|
2018-08-23 05:46:14 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-14 22:47:42 +01:00
|
|
|
|
llFollow -> {
|
2018-05-08 10:25:02 +02:00
|
|
|
|
follow_account?.let { whoRef ->
|
2018-01-17 18:39:16 +01:00
|
|
|
|
DlgContextMenu(
|
|
|
|
|
activity,
|
|
|
|
|
column,
|
2018-05-08 10:25:02 +02:00
|
|
|
|
whoRef,
|
2018-01-17 18:39:16 +01:00
|
|
|
|
null,
|
|
|
|
|
notification
|
|
|
|
|
).show()
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
return true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-14 22:47:42 +01:00
|
|
|
|
btnFollow -> {
|
2018-05-08 10:25:02 +02:00
|
|
|
|
follow_account?.let { whoRef ->
|
2018-01-17 18:39:16 +01:00
|
|
|
|
Action_Follow.followFromAnotherAccount(
|
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
|
|
|
|
access_info,
|
2018-05-18 19:08:46 +02:00
|
|
|
|
whoRef.get()
|
2018-01-17 18:39:16 +01:00
|
|
|
|
)
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
return true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-11-14 07:47:25 +01:00
|
|
|
|
ivCardImage -> Action_Toot.conversationOtherInstance(
|
2018-11-12 18:19:57 +01:00
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
|
|
|
|
status_showing?.card?.originalStatus
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-05-30 07:18:45 +02:00
|
|
|
|
btnSearchTag, llTrendTag -> {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
when (val item = this.item) {
|
2018-08-21 03:53:52 +02:00
|
|
|
|
// is TootGap -> column.startGap(item)
|
|
|
|
|
//
|
|
|
|
|
// is TootDomainBlock -> {
|
|
|
|
|
// val domain = item.domain
|
|
|
|
|
// AlertDialog.Builder(activity)
|
|
|
|
|
// .setMessage(activity.getString(R.string.confirm_unblock_domain, domain))
|
|
|
|
|
// .setNegativeButton(R.string.cancel, null)
|
|
|
|
|
// .setPositiveButton(R.string.ok) { _, _ -> Action_Instance.blockDomain(activity, access_info, domain, false) }
|
|
|
|
|
// .show()
|
|
|
|
|
// }
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-20 07:51:14 +01:00
|
|
|
|
is TootTag -> {
|
2018-01-10 16:47:35 +01:00
|
|
|
|
// search_tag は#を含まない
|
2018-01-21 13:46:36 +01:00
|
|
|
|
val tagEncoded = item.name.encodePercent()
|
2020-09-07 14:20:11 +02:00
|
|
|
|
val url = "https://${access_info.apiHost.ascii}/tags/$tagEncoded"
|
2018-01-10 16:47:35 +01:00
|
|
|
|
Action_HashTag.timelineOtherInstance(
|
2018-01-14 22:47:42 +01:00
|
|
|
|
activity = activity,
|
|
|
|
|
pos = activity.nextPosition(column),
|
|
|
|
|
url = url,
|
2020-09-07 14:20:11 +02:00
|
|
|
|
host = access_info.apiHost,
|
2018-01-20 07:51:14 +01:00
|
|
|
|
tag_without_sharp = item.name
|
2018-01-10 16:47:35 +01:00
|
|
|
|
)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-10 16:47:35 +01:00
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun clickMedia(i: Int) {
|
|
|
|
|
try {
|
|
|
|
|
val media_attachments =
|
|
|
|
|
status_showing?.media_attachments ?: (item as? TootScheduled)?.media_attachments
|
|
|
|
|
?: return
|
|
|
|
|
|
|
|
|
|
when (val item = if (i < media_attachments.size) media_attachments[i] else return) {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
is TootAttachmentMSP -> {
|
|
|
|
|
// マストドン検索ポータルのデータではmedia_attachmentsが簡略化されている
|
|
|
|
|
// 会話の流れを表示する
|
2018-01-17 18:39:16 +01:00
|
|
|
|
Action_Toot.conversationOtherInstance(
|
|
|
|
|
activity,
|
|
|
|
|
activity.nextPosition(column),
|
2018-01-18 22:22:27 +01:00
|
|
|
|
status_showing
|
2018-01-17 18:39:16 +01:00
|
|
|
|
)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-18 13:28:02 +01:00
|
|
|
|
is TootAttachment -> when {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-18 13:28:02 +01:00
|
|
|
|
// unknownが1枚だけなら内蔵ビューアを使わずにインテントを投げる
|
2019-12-22 14:06:03 +01:00
|
|
|
|
item.type == TootAttachmentType.Unknown && media_attachments.size == 1 -> {
|
|
|
|
|
// https://github.com/tateisu/SubwayTooter/pull/119
|
|
|
|
|
// メディアタイプがunknownの場合、そのほとんどはリモートから来たURLである
|
|
|
|
|
// Pref.bpPriorLocalURL の状態に関わらずリモートURLがあればそれをブラウザで開く
|
2021-01-04 02:11:45 +01:00
|
|
|
|
when (val remoteUrl = item.remote_url.notEmpty()) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
null -> activity.openCustomTab(item)
|
|
|
|
|
else -> activity.openCustomTab(remoteUrl)
|
2019-12-22 14:06:03 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-18 13:28:02 +01:00
|
|
|
|
// 内蔵メディアビューアを使う
|
|
|
|
|
Pref.bpUseInternalMediaViewer(App1.pref) ->
|
|
|
|
|
ActMediaViewer.open(
|
|
|
|
|
activity,
|
2021-01-04 02:11:45 +01:00
|
|
|
|
when (access_info.isMisskey) {
|
2019-01-18 13:28:02 +01:00
|
|
|
|
true -> ServiceType.MISSKEY
|
|
|
|
|
else -> ServiceType.MASTODON
|
|
|
|
|
},
|
|
|
|
|
media_attachments,
|
|
|
|
|
i
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-01-18 13:28:02 +01:00
|
|
|
|
// ブラウザで開く
|
2020-09-29 19:44:56 +02:00
|
|
|
|
else -> activity.openCustomTab(item)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
|
log.trace(ex)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showPreviewCard(status: TootStatus) {
|
|
|
|
|
|
|
|
|
|
if (Pref.bpDontShowPreviewCard(activity.pref)) return
|
|
|
|
|
|
|
|
|
|
val card = status.card ?: return
|
|
|
|
|
|
|
|
|
|
// 会話カラムで返信ステータスなら捏造したカードを表示しない
|
|
|
|
|
if (column.type == ColumnType.CONVERSATION
|
|
|
|
|
&& card.originalStatus != null
|
|
|
|
|
&& status.reply != null
|
|
|
|
|
) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bShowOuter = false
|
|
|
|
|
|
|
|
|
|
val sb = StringBuilder()
|
|
|
|
|
fun showString() {
|
|
|
|
|
if (sb.isNotEmpty()) {
|
|
|
|
|
val text = DecodeOptions(
|
2020-09-20 15:10:49 +02:00
|
|
|
|
activity, access_info,
|
|
|
|
|
forceHtml = true,
|
|
|
|
|
mentionDefaultHostDomain = status.account
|
|
|
|
|
).decodeHTML(sb.toString())
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (text.isNotEmpty()) {
|
|
|
|
|
tvCardText.visibility = View.VISIBLE
|
|
|
|
|
tvCardText.text = text
|
|
|
|
|
bShowOuter = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status.reblog?.quote_muted == true) {
|
|
|
|
|
addLinkAndCaption(
|
2020-06-08 01:29:20 +02:00
|
|
|
|
sb,
|
|
|
|
|
null,
|
|
|
|
|
card.url,
|
|
|
|
|
activity.getString(R.string.muted_quote)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
showString()
|
|
|
|
|
} else {
|
|
|
|
|
addLinkAndCaption(
|
2020-06-08 01:29:20 +02:00
|
|
|
|
sb,
|
|
|
|
|
activity.getString(R.string.card_header_card),
|
|
|
|
|
card.url,
|
|
|
|
|
card.title
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
addLinkAndCaption(
|
2020-06-08 01:29:20 +02:00
|
|
|
|
sb,
|
|
|
|
|
activity.getString(R.string.card_header_author),
|
|
|
|
|
card.author_url,
|
|
|
|
|
card.author_name
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
addLinkAndCaption(
|
2020-06-08 01:29:20 +02:00
|
|
|
|
sb,
|
|
|
|
|
activity.getString(R.string.card_header_provider),
|
|
|
|
|
card.provider_url,
|
|
|
|
|
card.provider_name
|
2018-11-12 18:19:57 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
val description = card.description
|
|
|
|
|
if (description != null && description.isNotEmpty()) {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append("<br>")
|
|
|
|
|
|
|
|
|
|
val limit = Pref.spCardDescriptionLength.toInt(activity.pref)
|
|
|
|
|
|
|
|
|
|
sb.append(
|
2020-06-08 01:29:20 +02:00
|
|
|
|
HTMLDecoder.encodeEntity(
|
|
|
|
|
ellipsize(
|
|
|
|
|
description,
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (limit <= 0) 64 else limit
|
2020-06-08 01:29:20 +02:00
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showString()
|
|
|
|
|
|
|
|
|
|
val image = card.image
|
|
|
|
|
if (flCardImage.vg(image?.isNotEmpty() == true) != null) {
|
|
|
|
|
|
|
|
|
|
flCardImage.layoutParams.height = if (card.originalStatus != null) {
|
|
|
|
|
activity.avatarIconSize
|
|
|
|
|
} else {
|
|
|
|
|
activity.app_state.media_thumb_height
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val imageUrl = access_info.supplyBaseUrl(image)
|
|
|
|
|
ivCardImage.setImageUrl(activity.pref, 0f, imageUrl, imageUrl)
|
|
|
|
|
|
|
|
|
|
btnCardImageShow.blurhash = card.blurhash
|
|
|
|
|
|
|
|
|
|
// show about card outer
|
|
|
|
|
bShowOuter = true
|
|
|
|
|
|
|
|
|
|
// show about image content
|
|
|
|
|
val default_shown = when {
|
|
|
|
|
column.hide_media_default -> false
|
|
|
|
|
access_info.dont_hide_nsfw -> true
|
|
|
|
|
else -> !status.sensitive
|
|
|
|
|
}
|
|
|
|
|
val is_shown = MediaShown.isShown(status, default_shown)
|
|
|
|
|
llCardImage.vg(is_shown)
|
|
|
|
|
btnCardImageShow.vg(!is_shown)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bShowOuter) llCardOuter.visibility = View.VISIBLE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun addLinkAndCaption(
|
|
|
|
|
sb: StringBuilder,
|
|
|
|
|
header: String?,
|
|
|
|
|
url: String?,
|
|
|
|
|
caption: String?
|
2018-01-17 18:39:16 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
if (url.isNullOrEmpty() && caption.isNullOrEmpty()) return
|
|
|
|
|
|
|
|
|
|
if (sb.isNotEmpty()) sb.append("<br>")
|
|
|
|
|
|
|
|
|
|
if (header?.isNotEmpty() == true) {
|
|
|
|
|
sb.append(HTMLDecoder.encodeEntity(header)).append(": ")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (url != null && url.isNotEmpty()) {
|
|
|
|
|
sb.append("<a href=\"").append(HTMLDecoder.encodeEntity(url)).append("\">")
|
|
|
|
|
}
|
|
|
|
|
sb.append(
|
2018-01-17 18:39:16 +01:00
|
|
|
|
HTMLDecoder.encodeEntity(
|
|
|
|
|
when {
|
|
|
|
|
caption != null && caption.isNotEmpty() -> caption
|
|
|
|
|
url != null && url.isNotEmpty() -> url
|
|
|
|
|
else -> "???"
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
if (url != null && url.isNotEmpty()) {
|
|
|
|
|
sb.append("</a>")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun makeReactionsView(status: TootStatus) {
|
|
|
|
|
if (!access_info.isMisskey) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val density = activity.density
|
|
|
|
|
|
|
|
|
|
val buttonHeight = ActMain.boostButtonSize
|
|
|
|
|
val marginBetween = (buttonHeight.toFloat() * 0.05f + 0.5f).toInt()
|
|
|
|
|
|
|
|
|
|
val paddingH = (buttonHeight.toFloat() * 0.1f + 0.5f).toInt()
|
|
|
|
|
val paddingV = (buttonHeight.toFloat() * 0.1f + 0.5f).toInt()
|
|
|
|
|
|
|
|
|
|
val act = this@ItemViewHolder.activity // not Button(View).getActivity()
|
|
|
|
|
|
|
|
|
|
val box = FlexboxLayout(activity).apply {
|
|
|
|
|
flexWrap = FlexWrap.WRAP
|
|
|
|
|
justifyContent = JustifyContent.FLEX_START
|
|
|
|
|
layoutParams = LinearLayout.LayoutParams(
|
2020-01-04 15:17:19 +01:00
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
2020-01-07 09:03:32 +01:00
|
|
|
|
).apply {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
topMargin = (0.5f + density * 3f).toInt()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-30 07:18:43 +01:00
|
|
|
|
// +/- ボタン
|
|
|
|
|
box.addView(ImageButton(act).also{b->
|
|
|
|
|
b.layoutParams = FlexboxLayout.LayoutParams(
|
|
|
|
|
buttonHeight,
|
|
|
|
|
buttonHeight
|
|
|
|
|
).apply{
|
|
|
|
|
endMargin = marginBetween
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-30 07:18:43 +01:00
|
|
|
|
b.background = ContextCompat.getDrawable(
|
2021-01-04 02:11:45 +01:00
|
|
|
|
activity,
|
2021-01-30 07:18:43 +01:00
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
2021-01-04 02:11:45 +01:00
|
|
|
|
)
|
|
|
|
|
|
2021-01-30 07:18:43 +01:00
|
|
|
|
val hasMyReaction = status.myReaction?.isNotEmpty() == true
|
|
|
|
|
b.contentDescription =
|
|
|
|
|
activity.getString(if (hasMyReaction) R.string.reaction_remove else R.string.reaction_add)
|
|
|
|
|
b.scaleType = ImageView.ScaleType.FIT_CENTER
|
|
|
|
|
b.padding = paddingV
|
|
|
|
|
b.setOnClickListener {
|
|
|
|
|
if (hasMyReaction) {
|
|
|
|
|
removeReaction(status, false)
|
|
|
|
|
} else {
|
|
|
|
|
addReaction(status, null)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b.setOnLongClickListener {
|
|
|
|
|
Action_Toot.reactionFromAnotherAccount(
|
|
|
|
|
activity,
|
|
|
|
|
access_info,
|
|
|
|
|
status_showing
|
|
|
|
|
)
|
|
|
|
|
true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2021-01-30 07:18:43 +01:00
|
|
|
|
setIconDrawableId(
|
|
|
|
|
act,
|
|
|
|
|
b,
|
|
|
|
|
if (hasMyReaction) R.drawable.ic_remove else R.drawable.ic_add,
|
|
|
|
|
color = content_color,
|
|
|
|
|
alphaMultiplier = Styler.boost_alpha
|
|
|
|
|
)
|
|
|
|
|
})
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2021-01-30 07:18:43 +01:00
|
|
|
|
val reactionCounts = status.reactionCounts
|
|
|
|
|
if (reactionCounts != null) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
var lastButton: View? = null
|
|
|
|
|
|
|
|
|
|
val options = DecodeOptions(
|
|
|
|
|
act,
|
2020-01-04 15:17:19 +01:00
|
|
|
|
access_info,
|
|
|
|
|
decodeEmoji = true,
|
2020-09-20 15:10:49 +02:00
|
|
|
|
enlargeEmoji = 1.5f,
|
2021-01-03 06:11:04 +01:00
|
|
|
|
enlargeCustomEmoji = 1.5f
|
2020-01-04 15:17:19 +01:00
|
|
|
|
)
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2021-01-30 07:18:43 +01:00
|
|
|
|
for (entry in reactionCounts.entries) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val key = entry.key
|
|
|
|
|
val count = entry.value
|
|
|
|
|
if (count <= 0) continue
|
|
|
|
|
val ssb = MisskeyReaction.toSpannableStringBuilder(key, options, status)
|
|
|
|
|
.also { it.append(" $count") }
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val b = Button(act).apply {
|
|
|
|
|
layoutParams = FlexboxLayout.LayoutParams(
|
2020-01-05 09:24:52 +01:00
|
|
|
|
FlexboxLayout.LayoutParams.WRAP_CONTENT,
|
|
|
|
|
buttonHeight
|
2020-01-07 09:03:32 +01:00
|
|
|
|
).apply {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
endMargin = marginBetween
|
|
|
|
|
}
|
|
|
|
|
minWidthCompat = buttonHeight
|
|
|
|
|
|
|
|
|
|
background = if (MisskeyReaction.equals(status.myReaction, key)) {
|
|
|
|
|
// 自分がリアクションしたやつは背景を変える
|
|
|
|
|
getAdaptiveRippleDrawableRound(
|
|
|
|
|
act,
|
2021-01-30 07:18:43 +01:00
|
|
|
|
Pref.ipButtonReactionedColor(act.pref).notZero() ?: act.attrColor(R.attr.colorImageButtonAccent),
|
2021-01-04 02:11:45 +01:00
|
|
|
|
act.attrColor(R.attr.colorRippleEffect),
|
|
|
|
|
roundNormal = true
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
ContextCompat.getDrawable(
|
|
|
|
|
act,
|
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
|
|
|
)
|
|
|
|
|
}
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
setTextColor(content_color)
|
|
|
|
|
setPadding(paddingH, paddingV, paddingH, paddingV)
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
text = ssb
|
|
|
|
|
|
|
|
|
|
allCaps = false
|
|
|
|
|
tag = key
|
|
|
|
|
setOnClickListener {
|
|
|
|
|
val code = it.tag as? String
|
|
|
|
|
if( MisskeyReaction.equals(status.myReaction, code)){
|
|
|
|
|
removeReaction(status, false)
|
|
|
|
|
}else{
|
|
|
|
|
addReaction(status,code)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setOnLongClickListener {
|
|
|
|
|
Action_Toot.reactionFromAnotherAccount(
|
2020-01-05 09:24:52 +01:00
|
|
|
|
this@ItemViewHolder.activity,
|
|
|
|
|
access_info,
|
|
|
|
|
status_showing,
|
|
|
|
|
it.tag as? String
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
// カスタム絵文字の場合、アニメーション等のコールバックを処理する必要がある
|
|
|
|
|
val invalidator = NetworkEmojiInvalidator(this@ItemViewHolder.activity.handler, this)
|
|
|
|
|
invalidator.register(ssb)
|
|
|
|
|
extra_invalidator_list.add(invalidator)
|
|
|
|
|
}
|
|
|
|
|
box.addView(b)
|
|
|
|
|
lastButton = b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastButton
|
|
|
|
|
?.layoutParams
|
|
|
|
|
?.cast<ViewGroup.MarginLayoutParams>()
|
|
|
|
|
?.endMargin = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llExtra.addView(box)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun addReaction(status: TootStatus, code: String?) {
|
|
|
|
|
|
|
|
|
|
if (status.myReaction?.isNotEmpty() == true) {
|
|
|
|
|
activity.showToast(false, R.string.already_reactioned)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (access_info.isPseudo || !access_info.isMisskey) return
|
|
|
|
|
|
|
|
|
|
if (code == null) {
|
|
|
|
|
EmojiPicker(activity, access_info, closeOnSelected = true) { name, instance, _, _, _ ->
|
2021-02-20 00:40:02 +01:00
|
|
|
|
val item = EmojiMap.sMap.shortNameToEmojiInfo[name]
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val newCode = if (item == null || instance != null) {
|
|
|
|
|
":$name:"
|
|
|
|
|
} else {
|
|
|
|
|
item.unified
|
|
|
|
|
}
|
|
|
|
|
addReaction(status, newCode)
|
|
|
|
|
}.show()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TootTaskRunner(activity, progress_style = TootTaskRunner.PROGRESS_NONE).run(access_info,
|
2018-08-21 15:31:44 +02:00
|
|
|
|
object : TootTask {
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2021-01-04 02:11:45 +01:00
|
|
|
|
override suspend fun background(client: TootApiClient): TootApiResult? {
|
2021-01-03 06:11:04 +01:00
|
|
|
|
|
2020-01-07 09:03:32 +01:00
|
|
|
|
val params = access_info.putMisskeyApiToken().apply {
|
|
|
|
|
put("noteId", status.id.toString())
|
|
|
|
|
put("reaction", code)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 15:31:44 +02:00
|
|
|
|
// 成功すると204 no content
|
2021-01-03 06:11:04 +01:00
|
|
|
|
return client.request("/api/notes/reactions/create", params.toPostRequestBuilder())
|
2018-08-21 03:53:52 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
override suspend fun handleResult(result: TootApiResult?) {
|
2018-08-21 15:31:44 +02:00
|
|
|
|
result ?: return
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 15:31:44 +02:00
|
|
|
|
val error = result.error
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (error != null) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
activity.showToast(false, error)
|
2018-08-21 15:31:44 +02:00
|
|
|
|
return
|
2018-08-21 03:53:52 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
when (val resCode = result.response?.code) {
|
|
|
|
|
in 200 until 300 -> {
|
2021-02-07 20:39:38 +01:00
|
|
|
|
if (status.increaseReaction(code, true, caller="addReaction")) {
|
2021-01-03 06:11:04 +01:00
|
|
|
|
// 1個だけ描画更新するのではなく、TLにある複数の要素をまとめて更新する
|
|
|
|
|
list_adapter.notifyChange(reason = "addReaction complete", reset = true)
|
|
|
|
|
}
|
2018-08-21 15:31:44 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
else -> activity.showToast(false, "HTTP error $resCode")
|
2018-08-21 15:31:44 +02:00
|
|
|
|
}
|
2018-08-21 03:53:52 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-08-21 15:31:44 +02:00
|
|
|
|
})
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun removeReaction(status: TootStatus, confirmed: Boolean = false) {
|
|
|
|
|
|
|
|
|
|
val reaction = status.myReaction
|
|
|
|
|
|
|
|
|
|
if (reaction?.isNotEmpty() != true) {
|
|
|
|
|
activity.showToast(false, R.string.not_reactioned)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (access_info.isPseudo || !access_info.isMisskey) return
|
|
|
|
|
|
|
|
|
|
if (!confirmed) {
|
|
|
|
|
AlertDialog.Builder(activity)
|
|
|
|
|
.setMessage(activity.getString(R.string.reaction_remove_confirm, reaction))
|
|
|
|
|
.setNegativeButton(R.string.cancel, null)
|
|
|
|
|
.setPositiveButton(R.string.ok) { _, _ ->
|
|
|
|
|
removeReaction(status, confirmed = true)
|
|
|
|
|
}
|
|
|
|
|
.show()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TootTaskRunner(activity, progress_style = TootTaskRunner.PROGRESS_NONE).run(access_info,
|
|
|
|
|
object : TootTask {
|
|
|
|
|
override suspend fun background(client: TootApiClient): TootApiResult? =
|
|
|
|
|
// 成功すると204 no content
|
|
|
|
|
client.request(
|
2018-12-29 17:38:52 +01:00
|
|
|
|
"/api/notes/reactions/delete",
|
2020-01-07 09:03:32 +01:00
|
|
|
|
access_info.putMisskeyApiToken().apply {
|
|
|
|
|
put("noteId", status.id.toString())
|
|
|
|
|
}
|
2018-12-29 17:38:52 +01:00
|
|
|
|
.toPostRequestBuilder()
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
override suspend fun handleResult(result: TootApiResult?) {
|
2018-12-29 17:38:52 +01:00
|
|
|
|
result ?: return
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-12-29 17:38:52 +01:00
|
|
|
|
val error = result.error
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (error != null) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
activity.showToast(false, error)
|
2018-12-29 17:38:52 +01:00
|
|
|
|
return
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
if ((result.response?.code ?: -1) in 200 until 300) {
|
|
|
|
|
if (status.decreaseReaction(reaction, true, "removeReaction")) {
|
2018-12-29 17:38:52 +01:00
|
|
|
|
// 1個だけ描画更新するのではなく、TLにある複数の要素をまとめて更新する
|
2019-01-06 09:35:22 +01:00
|
|
|
|
list_adapter.notifyChange(
|
|
|
|
|
reason = "removeReaction complete",
|
|
|
|
|
reset = true
|
|
|
|
|
)
|
2018-12-29 17:38:52 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun showEnqueteItems(status: TootStatus, enquete: TootPolls) {
|
|
|
|
|
val items = enquete.items ?: return
|
|
|
|
|
|
|
|
|
|
val now = System.currentTimeMillis()
|
|
|
|
|
|
|
|
|
|
val canVote = when (enquete.pollType) {
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.Mastodon -> when {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
enquete.expired -> false
|
|
|
|
|
now >= enquete.expired_at -> false
|
2019-09-22 20:25:00 +02:00
|
|
|
|
enquete.ownVoted -> false
|
2019-03-06 10:49:02 +01:00
|
|
|
|
else -> true
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.FriendsNico -> {
|
|
|
|
|
val remain = enquete.time_start + TootPolls.ENQUETE_EXPIRE - now
|
2021-01-04 02:11:45 +01:00
|
|
|
|
remain > 0L && !enquete.ownVoted
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
TootPollsType.Misskey -> !enquete.ownVoted
|
2020-12-07 13:23:14 +01:00
|
|
|
|
|
|
|
|
|
TootPollsType.Notestock -> false
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
items.forEachIndexed { index, choice ->
|
|
|
|
|
makeEnqueteChoiceView(status, enquete, canVote, index, choice)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
when (enquete.pollType) {
|
|
|
|
|
TootPollsType.Mastodon, TootPollsType.Notestock ->
|
2020-12-07 13:23:14 +01:00
|
|
|
|
makeEnqueteFooterMastodon(status, enquete, canVote)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-12-07 13:23:14 +01:00
|
|
|
|
TootPollsType.FriendsNico ->
|
|
|
|
|
makeEnqueteFooterFriendsNico(enquete)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.Misskey -> {
|
2020-12-07 13:23:14 +01:00
|
|
|
|
// no footer?
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun makeEnqueteChoiceView(
|
|
|
|
|
status: TootStatus,
|
|
|
|
|
enquete: TootPolls,
|
|
|
|
|
canVote: Boolean,
|
|
|
|
|
i: Int,
|
|
|
|
|
item: TootPollsChoice
|
2018-01-04 19:52:25 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
val text = when (enquete.pollType) {
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.Misskey -> {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
val sb = SpannableStringBuilder()
|
|
|
|
|
.append(item.decoded_text)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
if (enquete.ownVoted) {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
sb.append(" / ")
|
|
|
|
|
sb.append(activity.getString(R.string.vote_count_text, item.votes))
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (item.isVoted) sb.append(' ').append(0x2713.toChar())
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
|
|
|
|
sb
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.FriendsNico -> {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
item.decoded_text
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
TootPollsType.Mastodon, TootPollsType.Notestock -> if (canVote) {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
item.decoded_text
|
|
|
|
|
} else {
|
|
|
|
|
val sb = SpannableStringBuilder()
|
|
|
|
|
.append(item.decoded_text)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (!canVote) {
|
2019-12-03 15:55:30 +01:00
|
|
|
|
val v = item.votes
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-03-06 10:49:02 +01:00
|
|
|
|
sb.append(" / ")
|
|
|
|
|
sb.append(
|
2019-12-03 15:55:30 +01:00
|
|
|
|
when {
|
|
|
|
|
v == null ||
|
|
|
|
|
(column.isSearchColumn && column.access_info.isNA) ->
|
|
|
|
|
activity.getString(R.string.vote_count_unavailable)
|
|
|
|
|
else ->
|
|
|
|
|
activity.getString(R.string.vote_count_text, v)
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (item.isVoted) sb.append(' ').append(0x2713.toChar())
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
|
|
|
|
sb
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 投票ボタンの表示
|
|
|
|
|
val lp = LinearLayout.LayoutParams(
|
2018-01-17 18:39:16 +01:00
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
2019-03-06 10:49:02 +01:00
|
|
|
|
).apply {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (i == 0) topMargin = (0.5f + activity.density * 3f).toInt()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!canVote) {
|
|
|
|
|
|
|
|
|
|
val b = TextView(activity)
|
|
|
|
|
b.layoutParams = lp
|
|
|
|
|
|
|
|
|
|
b.text = text
|
|
|
|
|
val invalidator = NetworkEmojiInvalidator(activity.handler, b)
|
|
|
|
|
extra_invalidator_list.add(invalidator)
|
|
|
|
|
invalidator.register(text)
|
|
|
|
|
|
|
|
|
|
b.padding = (activity.density * 3f + 0.5f).toInt()
|
|
|
|
|
|
|
|
|
|
val ratio = when (enquete.pollType) {
|
2019-04-25 04:06:41 +02:00
|
|
|
|
TootPollsType.Mastodon -> {
|
|
|
|
|
val votesCount = enquete.votes_count ?: 0
|
|
|
|
|
val max = enquete.maxVotesCount ?: 0
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (max > 0 && votesCount > 0) {
|
2019-04-25 04:06:41 +02:00
|
|
|
|
(item.votes ?: 0).toFloat() / votesCount.toFloat()
|
|
|
|
|
} else {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
null
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
val ratios = enquete.ratios
|
|
|
|
|
if (ratios != null && i <= ratios.size) {
|
|
|
|
|
ratios[i]
|
|
|
|
|
} else {
|
|
|
|
|
null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ratio != null) {
|
|
|
|
|
b.backgroundDrawable = PollPlotDrawable(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
color = (content_color and 0xFFFFFF) or 0x20000000,
|
|
|
|
|
ratio = ratio,
|
|
|
|
|
isRtl = b.layoutDirection == View.LAYOUT_DIRECTION_RTL,
|
|
|
|
|
startWidth = (activity.density * 2f + 0.5f).toInt()
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llExtra.addView(b)
|
|
|
|
|
|
|
|
|
|
} else if (enquete.multiple) {
|
|
|
|
|
// 複数選択なのでチェックボックス
|
|
|
|
|
val b = CheckBox(activity)
|
|
|
|
|
b.layoutParams = lp
|
|
|
|
|
b.isAllCaps = false
|
|
|
|
|
b.text = text
|
|
|
|
|
val invalidator = NetworkEmojiInvalidator(activity.handler, b)
|
|
|
|
|
extra_invalidator_list.add(invalidator)
|
|
|
|
|
invalidator.register(text)
|
|
|
|
|
if (!canVote) {
|
|
|
|
|
b.isEnabled = false
|
|
|
|
|
} else {
|
|
|
|
|
b.isChecked = item.checked
|
|
|
|
|
b.setOnCheckedChangeListener { _, checked ->
|
|
|
|
|
item.checked = checked
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
llExtra.addView(b)
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
val b = Button(activity)
|
|
|
|
|
b.layoutParams = lp
|
|
|
|
|
b.isAllCaps = false
|
|
|
|
|
b.text = text
|
|
|
|
|
val invalidator = NetworkEmojiInvalidator(activity.handler, b)
|
|
|
|
|
extra_invalidator_list.add(invalidator)
|
|
|
|
|
invalidator.register(text)
|
|
|
|
|
if (!canVote) {
|
|
|
|
|
b.isEnabled = false
|
|
|
|
|
} else {
|
|
|
|
|
val accessInfo = this@ItemViewHolder.access_info
|
|
|
|
|
b.setOnClickListener { view ->
|
|
|
|
|
val context = view.context ?: return@setOnClickListener
|
|
|
|
|
onClickEnqueteChoice(status, enquete, context, accessInfo, i)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
llExtra.addView(b)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun makeEnqueteFooterFriendsNico(enquete: TootPolls) {
|
|
|
|
|
val density = activity.density
|
|
|
|
|
val height = (0.5f + 6 * density).toInt()
|
|
|
|
|
val view = EnqueteTimerView(activity)
|
|
|
|
|
view.layoutParams =
|
|
|
|
|
LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height)
|
|
|
|
|
view.setParams(enquete.time_start, TootPolls.ENQUETE_EXPIRE)
|
|
|
|
|
llExtra.addView(view)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun makeEnqueteFooterMastodon(
|
|
|
|
|
status: TootStatus,
|
|
|
|
|
enquete: TootPolls,
|
|
|
|
|
canVote: Boolean
|
2019-03-06 10:49:02 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
val density = activity.density
|
|
|
|
|
|
|
|
|
|
if (canVote && enquete.multiple) {
|
|
|
|
|
// 複数選択の投票ボタン
|
|
|
|
|
val lp = LinearLayout.LayoutParams(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
|
|
|
).apply {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
topMargin = (0.5f + density * 3f).toInt()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val b = Button(activity)
|
|
|
|
|
b.layoutParams = lp
|
|
|
|
|
b.isAllCaps = false
|
|
|
|
|
b.text = activity.getString(R.string.vote_button)
|
|
|
|
|
val accessInfo = this@ItemViewHolder.access_info
|
|
|
|
|
b.setOnClickListener { view ->
|
|
|
|
|
val context = view.context ?: return@setOnClickListener
|
|
|
|
|
sendMultiple(status, enquete, context, accessInfo)
|
|
|
|
|
}
|
|
|
|
|
llExtra.addView(b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val tv = TextView(activity)
|
|
|
|
|
val lp = LinearLayout.LayoutParams(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
lp.topMargin = (0.5f + 3 * density).toInt()
|
|
|
|
|
tv.layoutParams = lp
|
|
|
|
|
|
|
|
|
|
val sb = StringBuilder()
|
|
|
|
|
|
|
|
|
|
val votes_count = enquete.votes_count ?: 0
|
|
|
|
|
when {
|
|
|
|
|
votes_count == 1 -> sb.append(activity.getString(R.string.vote_1))
|
|
|
|
|
votes_count > 1 -> sb.append(activity.getString(R.string.vote_2, votes_count))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
when (val t = enquete.expired_at) {
|
|
|
|
|
|
2019-03-06 10:49:02 +01:00
|
|
|
|
Long.MAX_VALUE -> {
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
if (sb.isNotEmpty()) sb.append(" ")
|
|
|
|
|
sb.append(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
activity.getString(
|
|
|
|
|
R.string.vote_expire_at,
|
|
|
|
|
TootStatus.formatTime(activity, t, false)
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tv.text = sb.toString()
|
|
|
|
|
|
|
|
|
|
llExtra.addView(tv)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun onClickEnqueteChoice(
|
|
|
|
|
status: TootStatus,
|
|
|
|
|
enquete: TootPolls,
|
|
|
|
|
context: Context,
|
|
|
|
|
accessInfo: SavedAccount,
|
|
|
|
|
idx: Int
|
2018-01-04 19:52:25 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (enquete.ownVoted) {
|
|
|
|
|
context.showToast(false, R.string.already_voted)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val now = System.currentTimeMillis()
|
|
|
|
|
|
|
|
|
|
when (enquete.pollType) {
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.Misskey -> {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
// Misskeyのアンケートには期限がない?
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.FriendsNico -> {
|
|
|
|
|
val remain = enquete.time_start + TootPolls.ENQUETE_EXPIRE - now
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (remain <= 0L) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(false, R.string.enquete_was_end)
|
2019-03-06 10:49:02 +01:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
TootPollsType.Mastodon, TootPollsType.Notestock -> {
|
|
|
|
|
if (enquete.expired || now >= enquete.expired_at) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(false, R.string.enquete_was_end)
|
2019-03-06 10:49:02 +01:00
|
|
|
|
return
|
|
|
|
|
}
|
2018-08-24 18:24:11 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TootTaskRunner(context).run(accessInfo, object : TootTask {
|
|
|
|
|
override suspend fun background(client: TootApiClient) = when (enquete.pollType) {
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.Misskey -> client.request(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
"/api/notes/polls/vote",
|
2020-01-07 09:03:32 +01:00
|
|
|
|
accessInfo.putMisskeyApiToken().apply {
|
|
|
|
|
put("noteId", enquete.status_id.toString())
|
|
|
|
|
put("choice", idx)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2020-01-07 09:03:32 +01:00
|
|
|
|
}.toPostRequestBuilder()
|
2019-03-06 10:49:02 +01:00
|
|
|
|
)
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.Mastodon -> client.request(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
"/api/v1/polls/${enquete.pollId}/votes",
|
2020-01-07 09:03:32 +01:00
|
|
|
|
jsonObject {
|
|
|
|
|
put("choices", jsonArray { add(idx) })
|
|
|
|
|
}.toPostRequestBuilder()
|
2019-03-06 10:49:02 +01:00
|
|
|
|
)
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.FriendsNico -> client.request(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
"/api/v1/votes/${enquete.status_id}",
|
2020-01-07 09:03:32 +01:00
|
|
|
|
jsonObject {
|
|
|
|
|
put("item_index", idx.toString())
|
|
|
|
|
}.toPostRequestBuilder()
|
2019-03-06 10:49:02 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
TootPollsType.Notestock -> TootApiResult("can't vote on pseudo account column.")
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
override suspend fun handleResult(result: TootApiResult?) {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
result ?: return // cancelled.
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
|
val data = result.jsonObject
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (data != null) {
|
|
|
|
|
when (enquete.pollType) {
|
|
|
|
|
TootPollsType.Misskey -> if (enquete.increaseVote(activity, idx, true)) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(false, R.string.enquete_voted)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-11-03 17:14:14 +01:00
|
|
|
|
// 1個だけ開閉するのではなく、例えば通知TLにある複数の要素をまとめて開閉するなどある
|
|
|
|
|
list_adapter.notifyChange(reason = "onClickEnqueteChoice", reset = true)
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.Mastodon -> {
|
|
|
|
|
val newPoll = TootPolls.parse(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
TootParser(activity, accessInfo),
|
2020-12-07 13:23:14 +01:00
|
|
|
|
TootPollsType.Mastodon,
|
2019-03-06 10:49:02 +01:00
|
|
|
|
status,
|
|
|
|
|
status.media_attachments,
|
|
|
|
|
data,
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (newPoll != null) {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
status.enquete = newPoll
|
|
|
|
|
// 1個だけ開閉するのではなく、例えば通知TLにある複数の要素をまとめて開閉するなどある
|
|
|
|
|
list_adapter.notifyChange(
|
|
|
|
|
reason = "onClickEnqueteChoice",
|
|
|
|
|
reset = true
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
} else if (result.error != null) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(true, "response parse error")
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
2018-08-24 18:24:11 +02:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-04-14 05:41:29 +02:00
|
|
|
|
TootPollsType.FriendsNico -> {
|
2020-01-08 04:23:45 +01:00
|
|
|
|
val message = data.string("message") ?: "?"
|
2019-03-06 10:49:02 +01:00
|
|
|
|
val valid = data.optBoolean("valid")
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (valid) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(false, R.string.enquete_voted)
|
2019-03-06 10:49:02 +01:00
|
|
|
|
} else {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(true, R.string.enquete_vote_failed, message)
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-07 13:23:14 +01:00
|
|
|
|
TootPollsType.Notestock -> error("will not happen")
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(true, result.error)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun sendMultiple(
|
|
|
|
|
status: TootStatus,
|
|
|
|
|
enquete: TootPolls,
|
|
|
|
|
context: Context,
|
|
|
|
|
accessInfo: SavedAccount
|
2019-03-06 10:49:02 +01:00
|
|
|
|
) {
|
2021-01-04 02:11:45 +01:00
|
|
|
|
val now = System.currentTimeMillis()
|
|
|
|
|
if (now >= enquete.expired_at) {
|
|
|
|
|
context.showToast(false, R.string.enquete_was_end)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (enquete.items?.find { it.checked } == null) {
|
|
|
|
|
context.showToast(false, R.string.polls_choice_not_selected)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TootTaskRunner(context).run(accessInfo, object : TootTask {
|
|
|
|
|
|
|
|
|
|
var newPoll: TootPolls? = null
|
|
|
|
|
|
|
|
|
|
override suspend fun background(client: TootApiClient): TootApiResult? {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
return client.request(
|
|
|
|
|
"/api/v1/polls/${enquete.pollId}/votes",
|
2020-01-07 09:03:32 +01:00
|
|
|
|
jsonObject {
|
|
|
|
|
put("choices", jsonArray {
|
2019-04-25 04:06:41 +02:00
|
|
|
|
enquete.items.forEachIndexed { index, choice ->
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (choice.checked) add(index)
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
2020-01-07 09:03:32 +01:00
|
|
|
|
}.toPostRequestBuilder()
|
2019-03-06 10:49:02 +01:00
|
|
|
|
)?.also { result ->
|
|
|
|
|
val data = result.jsonObject
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (data != null) {
|
2019-04-14 05:41:29 +02:00
|
|
|
|
newPoll = TootPolls.parse(
|
2019-03-06 10:49:02 +01:00
|
|
|
|
TootParser(activity, accessInfo),
|
2020-12-07 13:23:14 +01:00
|
|
|
|
TootPollsType.Mastodon,
|
2019-03-06 10:49:02 +01:00
|
|
|
|
status,
|
|
|
|
|
status.media_attachments,
|
|
|
|
|
data,
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (newPoll == null) result.setError("response parse error")
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
override suspend fun handleResult(result: TootApiResult?) {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
result ?: return // cancelled.
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
2019-03-06 10:49:02 +01:00
|
|
|
|
val newPoll = this.newPoll
|
2021-01-04 02:11:45 +01:00
|
|
|
|
if (newPoll != null) {
|
2019-03-06 10:49:02 +01:00
|
|
|
|
status.enquete = newPoll
|
|
|
|
|
// 1個だけ開閉するのではなく、例えば通知TLにある複数の要素をまとめて開閉するなどある
|
|
|
|
|
list_adapter.notifyChange(reason = "onClickEnqueteChoice", reset = true)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
} else if (result.error != null) {
|
2020-09-29 19:44:56 +02:00
|
|
|
|
context.showToast(true, result.error)
|
2019-03-06 10:49:02 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
2021-01-04 02:11:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun openFilterMenu(item: TootFilter) {
|
|
|
|
|
val ad = ActionsDialog()
|
|
|
|
|
ad.addAction(activity.getString(R.string.edit)) {
|
|
|
|
|
ActKeywordFilter.open(activity, access_info, item.id)
|
|
|
|
|
}
|
|
|
|
|
ad.addAction(activity.getString(R.string.delete)) {
|
|
|
|
|
Action_Filter.delete(activity, access_info, item)
|
|
|
|
|
}
|
|
|
|
|
ad.show(activity, activity.getString(R.string.filter_of, item.phrase))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal fun getAccount() = status_account ?: boost_account ?: follow_account
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
private fun inflate(activity: ActMain) = with(activity.UI {}) {
|
|
|
|
|
val b = Benchmark(log, "Item-Inflate", 40L)
|
|
|
|
|
val rv = verticalLayout {
|
|
|
|
|
// トップレベルのViewGroupのlparamsはイニシャライザ内部に置くしかないみたい
|
|
|
|
|
layoutParams =
|
|
|
|
|
androidx.recyclerview.widget.RecyclerView.LayoutParams(matchParent, wrapContent)
|
|
|
|
|
.apply {
|
|
|
|
|
marginStart = dip(8)
|
|
|
|
|
marginEnd = dip(8)
|
|
|
|
|
topMargin = dip(2f)
|
|
|
|
|
bottomMargin = dip(1f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setPaddingRelative(dip(4), dip(1f), dip(4), dip(2f))
|
|
|
|
|
|
|
|
|
|
descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
|
|
|
|
|
|
|
|
|
|
llBoosted = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
bottomMargin = dip(6)
|
|
|
|
|
}
|
|
|
|
|
backgroundResource = R.drawable.btn_bg_transparent_round6dp
|
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
|
|
|
|
|
|
ivBoosted = imageView {
|
|
|
|
|
scaleType = ImageView.ScaleType.FIT_END
|
|
|
|
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
|
|
|
}.lparams(dip(48), dip(32)) {
|
|
|
|
|
endMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
verticalLayout {
|
|
|
|
|
lparams(dip(0), wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvBoostedAcct = textView {
|
|
|
|
|
ellipsize = TextUtils.TruncateAt.END
|
|
|
|
|
gravity = Gravity.END
|
|
|
|
|
maxLines = 1
|
|
|
|
|
textSize = 12f // textSize の単位はSP
|
|
|
|
|
// tools:text ="who@hoge"
|
|
|
|
|
}.lparams(dip(0), wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvBoostedTime = textView {
|
|
|
|
|
|
|
|
|
|
startPadding = dip(2)
|
|
|
|
|
|
|
|
|
|
gravity = Gravity.END
|
|
|
|
|
textSize = 12f // textSize の単位はSP
|
|
|
|
|
// tools:ignore="RtlSymmetry"
|
|
|
|
|
// tools:text="2017-04-16 09:37:14"
|
|
|
|
|
}.lparams(wrapContent, wrapContent)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvBoosted = textView {
|
|
|
|
|
// tools:text = "~にブーストされました"
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llFollow = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
|
|
|
|
|
|
ivFollow = myNetworkImageView {
|
|
|
|
|
contentDescription = context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.FIT_END
|
|
|
|
|
}.lparams(dip(48), dip(40)) {
|
|
|
|
|
endMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
verticalLayout {
|
|
|
|
|
|
|
|
|
|
lparams(dip(0), wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvFollowerName = textView {
|
|
|
|
|
// tools:text="Follower Name"
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvFollowerAcct = textView {
|
|
|
|
|
setPaddingStartEnd(dip(4), dip(4))
|
|
|
|
|
textSize = 12f // SP
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvLastStatusAt = myTextView {
|
|
|
|
|
setPaddingStartEnd(dip(4), dip(4))
|
|
|
|
|
textSize = 12f // SP
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
frameLayout {
|
|
|
|
|
lparams(dip(40), dip(40)) {
|
|
|
|
|
startMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnFollow = imageButton {
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(
|
2020-02-16 09:13:11 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription = context.getString(R.string.follow)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER
|
|
|
|
|
// tools:src="?attr/ic_follow_plus"
|
|
|
|
|
}.lparams(matchParent, matchParent)
|
|
|
|
|
|
|
|
|
|
ivFollowedBy = imageView {
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER
|
|
|
|
|
// tools:src="?attr/ic_followed_by"
|
|
|
|
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
|
|
|
}.lparams(matchParent, matchParent)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
llStatus = verticalLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvAcct = textView {
|
|
|
|
|
ellipsize = TextUtils.TruncateAt.END
|
|
|
|
|
gravity = Gravity.END
|
|
|
|
|
maxLines = 1
|
|
|
|
|
textSize = 12f // SP
|
|
|
|
|
// tools:text="who@hoge"
|
|
|
|
|
}.lparams(dip(0), wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvTime = textView {
|
|
|
|
|
gravity = Gravity.END
|
|
|
|
|
startPadding = dip(2)
|
|
|
|
|
textSize = 12f // SP
|
|
|
|
|
// tools:ignore="RtlSymmetry"
|
|
|
|
|
// tools:text="2017-04-16 09:37:14"
|
|
|
|
|
}.lparams(wrapContent, wrapContent)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
ivThumbnail = myNetworkImageView {
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(
|
2020-02-16 09:13:11 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription = context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
}.lparams(dip(48), dip(48)) {
|
|
|
|
|
topMargin = dip(4)
|
|
|
|
|
endMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
verticalLayout {
|
|
|
|
|
lparams(dip(0), wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvName = textView {
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
llOpenSticker = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
ivOpenSticker = myNetworkImageView {
|
|
|
|
|
}.lparams(dip(16), dip(16)) {
|
|
|
|
|
isBaselineAligned = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvOpenSticker = textView {
|
|
|
|
|
setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10f)
|
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
|
setPaddingStartEnd(dip(4f), dip(4f))
|
|
|
|
|
}.lparams(0, dip(16)) {
|
|
|
|
|
isBaselineAligned = false
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llReply = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
bottomMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(
|
2018-11-15 23:08:11 +01:00
|
|
|
|
context,
|
2020-02-11 18:01:15 +01:00
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
2018-11-15 23:08:11 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
|
|
|
|
|
|
ivReply = imageView {
|
|
|
|
|
scaleType = ImageView.ScaleType.FIT_END
|
|
|
|
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
|
|
|
padding = dip(4)
|
|
|
|
|
}.lparams(dip(32), dip(32)) {
|
|
|
|
|
endMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvReply = textView {
|
|
|
|
|
}.lparams(dip(0), wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llContentWarning = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
isBaselineAligned = false
|
|
|
|
|
}
|
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
|
|
|
|
|
|
btnContentWarning = button {
|
|
|
|
|
|
|
|
|
|
backgroundDrawable =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.bg_button_cw)
|
|
|
|
|
minWidthCompat = dip(40)
|
|
|
|
|
padding = dip(4)
|
|
|
|
|
//tools:text="見る"
|
|
|
|
|
}.lparams(wrapContent, dip(40)) {
|
|
|
|
|
endMargin = dip(8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
verticalLayout {
|
|
|
|
|
lparams(dip(0), wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvMentions = myTextView {
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvContentWarning = myTextView {
|
|
|
|
|
}.lparams(matchParent, wrapContent) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llContents = verticalLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvContent = myTextView {
|
|
|
|
|
setLineSpacing(lineSpacingExtra, 1.1f)
|
|
|
|
|
// tools:text="Contents\nContents"
|
|
|
|
|
}.lparams(matchParent, wrapContent) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val thumbnailHeight = activity.app_state.media_thumb_height
|
|
|
|
|
val verticalArrangeThumbnails =
|
|
|
|
|
Pref.bpVerticalArrangeThumbnails(activity.pref)
|
|
|
|
|
|
|
|
|
|
flMedia = if (verticalArrangeThumbnails) {
|
|
|
|
|
frameLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
llMedia = verticalLayout {
|
|
|
|
|
lparams(matchParent, matchParent)
|
|
|
|
|
|
|
|
|
|
btnHideMedia = imageButton {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
2020-02-11 18:01:15 +01:00
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
2018-03-21 16:39:10 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription = context.getString(R.string.hide)
|
|
|
|
|
imageResource = R.drawable.ic_close
|
|
|
|
|
}.lparams(dip(32), dip(32)) {
|
|
|
|
|
gravity = Gravity.END
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivMedia1 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(matchParent, thumbnailHeight) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivMedia2 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(matchParent, thumbnailHeight) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivMedia3 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(matchParent, thumbnailHeight) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivMedia4 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(matchParent, thumbnailHeight) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnShowMedia = blurhashView {
|
|
|
|
|
|
|
|
|
|
errorColor = context.attrColor(
|
2019-07-24 10:59:07 +02:00
|
|
|
|
R.attr.colorShowMediaBackground
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
gravity = Gravity.CENTER
|
|
|
|
|
|
|
|
|
|
textColor = context.attrColor(
|
2019-07-24 10:59:07 +02:00
|
|
|
|
R.attr.colorShowMediaText
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
minHeightCompat = dip(48)
|
|
|
|
|
|
|
|
|
|
}.lparams(matchParent, thumbnailHeight)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
frameLayout {
|
|
|
|
|
lparams(matchParent, thumbnailHeight) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
llMedia = linearLayout {
|
|
|
|
|
lparams(matchParent, matchParent)
|
|
|
|
|
|
|
|
|
|
ivMedia1 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(0, matchParent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivMedia2 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(0, matchParent) {
|
|
|
|
|
startMargin = dip(8)
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivMedia3 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(0, matchParent) {
|
|
|
|
|
startMargin = dip(8)
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivMedia4 = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.bg_thumbnail
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(0, matchParent) {
|
|
|
|
|
startMargin = dip(8)
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnHideMedia = imageButton {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
context,
|
2020-02-11 18:01:15 +01:00
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
2018-03-21 16:39:10 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription = context.getString(R.string.hide)
|
|
|
|
|
imageResource = R.drawable.ic_close
|
|
|
|
|
}.lparams(dip(32), matchParent) {
|
|
|
|
|
startMargin = dip(8)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnShowMedia = blurhashView {
|
|
|
|
|
|
|
|
|
|
errorColor = context.attrColor(
|
2018-03-21 16:39:10 +01:00
|
|
|
|
R.attr.colorShowMediaBackground
|
2018-01-17 18:39:16 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
gravity = Gravity.CENTER
|
|
|
|
|
|
|
|
|
|
textColor = context.attrColor(
|
2019-01-16 13:33:07 +01:00
|
|
|
|
R.attr.colorShowMediaText
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
}.lparams(matchParent, matchParent)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvMediaDescription = textView {}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
llCardOuter = verticalLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
startMargin = dip(12)
|
|
|
|
|
endMargin = dip(6)
|
|
|
|
|
}
|
|
|
|
|
padding = dip(3)
|
|
|
|
|
bottomPadding = dip(6)
|
|
|
|
|
|
|
|
|
|
background = PreviewCardBorder()
|
|
|
|
|
|
|
|
|
|
tvCardText = myTextView {
|
|
|
|
|
}.lparams(matchParent, wrapContent) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
flCardImage = frameLayout {
|
|
|
|
|
lparams(matchParent, activity.app_state.media_thumb_height) {
|
|
|
|
|
topMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llCardImage = linearLayout {
|
|
|
|
|
lparams(matchParent, matchParent)
|
|
|
|
|
|
|
|
|
|
ivCardImage = myNetworkImageView {
|
|
|
|
|
|
|
|
|
|
contentDescription =
|
|
|
|
|
context.getString(R.string.thumbnail)
|
|
|
|
|
|
|
|
|
|
scaleType = if (Pref.bpDontCropMediaThumb(App1.pref))
|
|
|
|
|
ImageView.ScaleType.FIT_CENTER
|
|
|
|
|
else
|
|
|
|
|
ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
|
|
|
|
|
}.lparams(0, matchParent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
btnCardImageHide = imageButton {
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2020-01-29 06:15:32 +01:00
|
|
|
|
context,
|
2020-02-11 18:01:15 +01:00
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
2020-01-29 06:15:32 +01:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription = context.getString(R.string.hide)
|
|
|
|
|
imageResource = R.drawable.ic_close
|
|
|
|
|
}.lparams(dip(32), matchParent) {
|
|
|
|
|
startMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnCardImageShow = blurhashView {
|
|
|
|
|
|
|
|
|
|
errorColor = context.attrColor(
|
2020-01-29 06:15:32 +01:00
|
|
|
|
R.attr.colorShowMediaBackground
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
gravity = Gravity.CENTER
|
|
|
|
|
|
|
|
|
|
textColor = context.attrColor(
|
2020-01-29 06:15:32 +01:00
|
|
|
|
R.attr.colorShowMediaText
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
|
|
|
|
|
}.lparams(matchParent, matchParent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
llExtra = verticalLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
topMargin = dip(0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// button bar
|
|
|
|
|
statusButtonsViewHolder = StatusButtonsViewHolder(
|
2020-09-11 21:34:58 +02:00
|
|
|
|
activity,
|
|
|
|
|
matchParent,
|
|
|
|
|
3f,
|
2021-01-04 02:11:45 +01:00
|
|
|
|
justifyContent = when (Pref.ipBoostButtonJustify(App1.pref)) {
|
2018-08-22 15:54:44 +02:00
|
|
|
|
0 -> JustifyContent.FLEX_START
|
|
|
|
|
1 -> JustifyContent.CENTER
|
|
|
|
|
else -> JustifyContent.FLEX_END
|
|
|
|
|
}
|
2018-08-21 15:31:44 +02:00
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
llButtonBar = statusButtonsViewHolder.viewRoot
|
|
|
|
|
addView(llButtonBar)
|
|
|
|
|
|
|
|
|
|
tvApplication = textView {
|
|
|
|
|
gravity = Gravity.END
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llConversationIcons = linearLayout {
|
|
|
|
|
lparams(matchParent, dip(40))
|
|
|
|
|
|
|
|
|
|
isBaselineAligned = false
|
|
|
|
|
gravity = Gravity.START or Gravity.CENTER_VERTICAL
|
|
|
|
|
|
|
|
|
|
tvConversationParticipants = textView {
|
|
|
|
|
text = context.getString(R.string.participants)
|
|
|
|
|
}.lparams(wrapContent, wrapContent) {
|
|
|
|
|
endMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivConversationIcon1 = myNetworkImageView {
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
}.lparams(dip(24), dip(24)) {
|
|
|
|
|
endMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
ivConversationIcon2 = myNetworkImageView {
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
}.lparams(dip(24), dip(24)) {
|
|
|
|
|
endMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
ivConversationIcon3 = myNetworkImageView {
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
}.lparams(dip(24), dip(24)) {
|
|
|
|
|
endMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
ivConversationIcon4 = myNetworkImageView {
|
|
|
|
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
|
|
|
|
}.lparams(dip(24), dip(24)) {
|
|
|
|
|
endMargin = dip(3)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvConversationIconsMore = textView {
|
|
|
|
|
|
|
|
|
|
}.lparams(wrapContent, wrapContent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llSearchTag = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
btnSearchTag = button {
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
|
allCaps = false
|
|
|
|
|
}.lparams(0, wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnGapHead = imageButton {
|
|
|
|
|
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2020-09-11 21:34:58 +02:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription = context.getString(R.string.read_gap_head)
|
|
|
|
|
imageResource = R.drawable.ic_arrow_drop_down
|
|
|
|
|
}.lparams(dip(32), matchParent) {
|
|
|
|
|
startMargin = dip(8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnGapTail = imageButton {
|
|
|
|
|
background = ContextCompat.getDrawable(
|
2020-09-11 21:34:58 +02:00
|
|
|
|
context,
|
|
|
|
|
R.drawable.btn_bg_transparent_round6dp
|
|
|
|
|
)
|
2021-01-04 02:11:45 +01:00
|
|
|
|
contentDescription = context.getString(R.string.read_gap_tail)
|
|
|
|
|
imageResource = R.drawable.ic_arrow_drop_up
|
|
|
|
|
}.lparams(dip(32), matchParent) {
|
|
|
|
|
startMargin = dip(8)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llTrendTag = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
|
|
|
|
|
|
verticalLayout {
|
|
|
|
|
lparams(0, wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
tvTrendTagName = textView {
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvTrendTagDesc = textView {
|
|
|
|
|
textSize = 12f // SP
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
}
|
|
|
|
|
tvTrendTagCount = textView {
|
|
|
|
|
|
|
|
|
|
}.lparams(wrapContent, wrapContent) {
|
|
|
|
|
startMargin = dip(6)
|
|
|
|
|
endMargin = dip(6)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cvTagHistory = trendTagHistoryView {
|
|
|
|
|
|
|
|
|
|
}.lparams(dip(64), dip(32))
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llList = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
gravity = Gravity.CENTER_VERTICAL
|
|
|
|
|
isBaselineAligned = false
|
|
|
|
|
minimumHeight = dip(40)
|
|
|
|
|
|
|
|
|
|
btnListTL = button {
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
|
allCaps = false
|
|
|
|
|
}.lparams(0, wrapContent) {
|
|
|
|
|
weight = 1f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btnListMore = imageButton {
|
|
|
|
|
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
|
imageResource = R.drawable.ic_more
|
|
|
|
|
contentDescription = context.getString(R.string.more)
|
|
|
|
|
}.lparams(dip(40), matchParent) {
|
|
|
|
|
startMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tvMessageHolder = textView {
|
|
|
|
|
padding = dip(4)
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
llFollowRequest = linearLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
topMargin = dip(6)
|
|
|
|
|
}
|
|
|
|
|
gravity = Gravity.END
|
|
|
|
|
|
|
|
|
|
btnFollowRequestAccept = imageButton {
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
|
contentDescription = context.getString(R.string.follow_accept)
|
|
|
|
|
imageResource = R.drawable.ic_check
|
|
|
|
|
setPadding(0, 0, 0, 0)
|
|
|
|
|
}.lparams(dip(48f), dip(32f))
|
|
|
|
|
|
|
|
|
|
btnFollowRequestDeny = imageButton {
|
|
|
|
|
background =
|
|
|
|
|
ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent_round6dp)
|
|
|
|
|
contentDescription = context.getString(R.string.follow_deny)
|
|
|
|
|
imageResource = R.drawable.ic_close
|
|
|
|
|
setPadding(0, 0, 0, 0)
|
|
|
|
|
}.lparams(dip(48f), dip(32f)) {
|
|
|
|
|
startMargin = dip(4)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llFilter = verticalLayout {
|
|
|
|
|
lparams(matchParent, wrapContent) {
|
|
|
|
|
}
|
|
|
|
|
minimumHeight = dip(40)
|
|
|
|
|
|
|
|
|
|
tvFilterPhrase = textView {
|
|
|
|
|
typeface = Typeface.DEFAULT_BOLD
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
|
|
|
|
|
tvFilterDetail = textView {
|
|
|
|
|
textSize = 12f // SP
|
|
|
|
|
}.lparams(matchParent, wrapContent)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
b.report()
|
|
|
|
|
rv
|
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|