703 lines
24 KiB
Kotlin
703 lines
24 KiB
Kotlin
package jp.juggler.subwaytooter.columnviewholder
|
|
|
|
import android.graphics.Color
|
|
import android.text.Spannable
|
|
import android.text.SpannableStringBuilder
|
|
import android.text.Spanned
|
|
import android.text.style.ForegroundColorSpan
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.widget.LinearLayout
|
|
import android.widget.TextView
|
|
import jp.juggler.subwaytooter.*
|
|
import jp.juggler.subwaytooter.action.followFromAnotherAccount
|
|
import jp.juggler.subwaytooter.action.userProfileLocal
|
|
import jp.juggler.subwaytooter.actmain.nextPosition
|
|
import jp.juggler.subwaytooter.api.MisskeyAccountDetailMap
|
|
import jp.juggler.subwaytooter.api.TootApiResult
|
|
import jp.juggler.subwaytooter.api.entity.TootAccount
|
|
import jp.juggler.subwaytooter.api.entity.TootAccountRef
|
|
import jp.juggler.subwaytooter.api.entity.TootStatus
|
|
import jp.juggler.subwaytooter.api.runApiTask
|
|
import jp.juggler.subwaytooter.column.*
|
|
import jp.juggler.subwaytooter.databinding.LvHeaderProfileBinding
|
|
import jp.juggler.subwaytooter.dialog.showTextInputDialog
|
|
import jp.juggler.subwaytooter.emoji.EmojiMap
|
|
import jp.juggler.subwaytooter.itemviewholder.DlgContextMenu
|
|
import jp.juggler.subwaytooter.pref.PrefB
|
|
import jp.juggler.subwaytooter.pref.PrefI
|
|
import jp.juggler.subwaytooter.span.*
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
|
import jp.juggler.subwaytooter.table.UserRelation
|
|
import jp.juggler.subwaytooter.table.daoAcctColor
|
|
import jp.juggler.subwaytooter.table.daoUserRelation
|
|
import jp.juggler.subwaytooter.util.*
|
|
import jp.juggler.subwaytooter.view.MyLinkMovementMethod
|
|
import jp.juggler.subwaytooter.view.MyTextView
|
|
import jp.juggler.util.coroutine.launchAndShowError
|
|
import jp.juggler.util.data.buildJsonObject
|
|
import jp.juggler.util.data.intoStringResource
|
|
import jp.juggler.util.data.notEmpty
|
|
import jp.juggler.util.data.notZero
|
|
import jp.juggler.util.log.showToast
|
|
import jp.juggler.util.network.toPostRequestBuilder
|
|
import jp.juggler.util.ui.attrColor
|
|
import jp.juggler.util.ui.setIconDrawableId
|
|
import jp.juggler.util.ui.vg
|
|
import org.jetbrains.anko.textColor
|
|
|
|
internal class ViewHolderHeaderProfile(
|
|
override val activity: ActMain,
|
|
parent: ViewGroup,
|
|
val views: LvHeaderProfileBinding =
|
|
LvHeaderProfileBinding.inflate(activity.layoutInflater, parent, false),
|
|
) : ViewHolderHeaderBase(views.root), View.OnClickListener, View.OnLongClickListener {
|
|
|
|
companion object {
|
|
private fun SpannableStringBuilder.appendSpan(text: String, span: Any) {
|
|
val start = length
|
|
append(text)
|
|
setSpan(
|
|
span,
|
|
start,
|
|
length,
|
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
)
|
|
}
|
|
}
|
|
|
|
private var whoRef: TootAccountRef? = null
|
|
|
|
private var movedRef: TootAccountRef? = null
|
|
|
|
private val nameInvalidator1 =
|
|
NetworkEmojiInvalidator(activity.handler, views.tvDisplayName)
|
|
|
|
private val noteInvalidator =
|
|
NetworkEmojiInvalidator(activity.handler, views.tvNote)
|
|
|
|
private val movedCaptionInvalidator =
|
|
NetworkEmojiInvalidator(activity.handler, views.tvMoved)
|
|
|
|
private val movedNameInvalidator =
|
|
NetworkEmojiInvalidator(activity.handler, views.tvMovedName)
|
|
|
|
private val density: Float
|
|
|
|
private var colorTextContent = 0
|
|
|
|
private var relation: UserRelation? = null
|
|
|
|
init {
|
|
views.root.tag = this
|
|
val holder = this
|
|
views.run {
|
|
|
|
density = tvDisplayName.resources.displayMetrics.density
|
|
|
|
for (v in arrayOf(
|
|
ivBackground,
|
|
btnFollowing,
|
|
btnFollowers,
|
|
btnStatusCount,
|
|
btnMore,
|
|
btnFollow,
|
|
tvRemoteProfileWarning,
|
|
btnPersonalNotesEdit,
|
|
|
|
btnMoved,
|
|
llMoved,
|
|
btnPersonalNotesEdit
|
|
)) {
|
|
v.setOnClickListener(holder)
|
|
}
|
|
|
|
btnMoved.setOnLongClickListener(holder)
|
|
btnFollow.setOnLongClickListener(holder)
|
|
|
|
tvNote.movementMethod = MyLinkMovementMethod
|
|
|
|
|
|
ivBackground.measureProfileBg = true
|
|
}
|
|
}
|
|
|
|
override fun getAccount(): TootAccountRef? = whoRef
|
|
|
|
override fun onViewRecycled() {
|
|
}
|
|
|
|
// fun updateRelativeTime() {
|
|
// val who = whoRef?.get()
|
|
// if(who != null) {
|
|
// tvCreated.text = TootStatus.formatTime(tvCreated.context, who.time_created_at, true)
|
|
// }
|
|
// }
|
|
|
|
override fun bindData(column: Column) {
|
|
super.bindData(column)
|
|
bindFonts()
|
|
bindColors()
|
|
views.run {
|
|
llMoved.visibility = View.GONE
|
|
tvMoved.visibility = View.GONE
|
|
llFields.visibility = View.GONE
|
|
llFields.removeAllViews()
|
|
}
|
|
val whoRef = column.whoAccount
|
|
this.whoRef = whoRef
|
|
when (val who = whoRef?.get()) {
|
|
null -> bindAccountNull()
|
|
else -> bindAccount(who, whoRef)
|
|
}
|
|
}
|
|
|
|
// カラム設定から戻った際に呼ばれる
|
|
override fun showColor() {
|
|
views.llProfile.setBackgroundColor(
|
|
when (val c = column.columnBgColor) {
|
|
0 -> activity.attrColor(R.attr.colorProfileBackgroundMask)
|
|
else -> -0x40000000 or (0x00ffffff and c)
|
|
}
|
|
)
|
|
}
|
|
|
|
// bind時に呼ばれる
|
|
private fun bindColors() {
|
|
val contentColor = column.getContentColor()
|
|
this.colorTextContent = contentColor
|
|
|
|
views.run {
|
|
|
|
tvPersonalNotes.textColor = contentColor
|
|
tvMoved.textColor = contentColor
|
|
tvMovedName.textColor = contentColor
|
|
tvDisplayName.textColor = contentColor
|
|
tvNote.textColor = contentColor
|
|
tvRemoteProfileWarning.textColor = contentColor
|
|
btnStatusCount.textColor = contentColor
|
|
btnFollowing.textColor = contentColor
|
|
btnFollowers.textColor = contentColor
|
|
tvFeaturedTags.textColor = contentColor
|
|
|
|
setIconDrawableId(
|
|
activity,
|
|
btnMore,
|
|
R.drawable.ic_more,
|
|
color = contentColor,
|
|
alphaMultiplier = stylerBoostAlpha
|
|
)
|
|
|
|
setIconDrawableId(
|
|
activity,
|
|
btnPersonalNotesEdit,
|
|
R.drawable.ic_edit,
|
|
color = contentColor,
|
|
alphaMultiplier = stylerBoostAlpha
|
|
)
|
|
|
|
val acctColor = column.getAcctColor()
|
|
tvCreated.textColor = acctColor
|
|
tvMovedAcct.textColor = acctColor
|
|
tvLastStatusAt.textColor = acctColor
|
|
|
|
showColor()
|
|
}
|
|
}
|
|
|
|
private fun bindFonts() {
|
|
views.run {
|
|
var f: Float
|
|
|
|
f = activity.timelineFontSizeSp
|
|
if (!f.isNaN()) {
|
|
tvMovedName.textSize = f
|
|
tvMoved.textSize = f
|
|
tvPersonalNotes.textSize = f
|
|
tvFeaturedTags.textSize = f
|
|
}
|
|
|
|
f = activity.acctFontSizeSp
|
|
if (!f.isNaN()) {
|
|
tvMovedAcct.textSize = f
|
|
tvCreated.textSize = f
|
|
tvLastStatusAt.textSize = f
|
|
}
|
|
|
|
val spacing = activity.timelineSpacing
|
|
if (spacing != null) {
|
|
tvMovedName.setLineSpacing(0f, spacing)
|
|
tvMoved.setLineSpacing(0f, spacing)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun bindAccountNull() {
|
|
relation = null
|
|
nameInvalidator1.register(null)
|
|
noteInvalidator.register(null)
|
|
views.run {
|
|
tvCreated.text = ""
|
|
tvLastStatusAt.vg(false)
|
|
tvFeaturedTags.vg(false)
|
|
ivBackground.setImageDrawable(null)
|
|
ivAvatar.setImageDrawable(null)
|
|
|
|
tvAcct.text = "@"
|
|
|
|
nameInvalidator1.text = ""
|
|
|
|
noteInvalidator.text = ""
|
|
tvMisskeyExtra.text = ""
|
|
|
|
btnStatusCount.text = activity.getString(R.string.statuses) + "\n" + "?"
|
|
btnFollowing.text = activity.getString(R.string.following) + "\n" + "?"
|
|
btnFollowers.text = activity.getString(R.string.followers) + "\n" + "?"
|
|
|
|
btnFollow.setImageDrawable(null)
|
|
tvRemoteProfileWarning.visibility = View.GONE
|
|
}
|
|
}
|
|
|
|
private fun bindAccount(who: TootAccount, whoRef: TootAccountRef) {
|
|
// Misskeyの場合はNote中のUserエンティティと /api/users/show の情報量がかなり異なる
|
|
val whoDetail = MisskeyAccountDetailMap.get(accessInfo, who.id)
|
|
val relation = daoUserRelation.load(accessInfo.db_id, who.id)
|
|
this.relation = relation
|
|
views.run {
|
|
tvCreated.text =
|
|
TootStatus.formatTime(tvCreated.context, (whoDetail ?: who).time_created_at, true)
|
|
|
|
who.setAccountExtra(
|
|
accessInfo,
|
|
NetworkEmojiInvalidator(activity.handler ,tvLastStatusAt),
|
|
fromProfileHeader = true
|
|
)
|
|
|
|
val featuredTagsText = formatFeaturedTags()
|
|
tvFeaturedTags.vg(featuredTagsText != null)?.let {
|
|
it.text = featuredTagsText!!
|
|
it.movementMethod = MyLinkMovementMethod
|
|
}
|
|
|
|
ivBackground.setImageUrl(0f, accessInfo.supplyBaseUrl(who.header_static))
|
|
|
|
ivAvatar.setImageUrl(
|
|
calcIconRound(ivAvatar.layoutParams),
|
|
accessInfo.supplyBaseUrl(who.avatar_static),
|
|
accessInfo.supplyBaseUrl(who.avatar)
|
|
)
|
|
|
|
val name = whoDetail?.decodeDisplayName(activity) ?: whoRef.decoded_display_name
|
|
nameInvalidator1.text = name
|
|
|
|
tvRemoteProfileWarning.vg(column.accessInfo.isRemoteUser(who))
|
|
|
|
tvAcct.text = encodeAcctText(who, whoDetail)
|
|
|
|
val note = whoRef.decoded_note
|
|
noteInvalidator.text = note
|
|
|
|
tvMisskeyExtra.text = encodeMisskeyExtra(whoDetail)
|
|
tvMisskeyExtra.vg(tvMisskeyExtra.text.isNotEmpty())
|
|
|
|
btnStatusCount.text =
|
|
"${activity.getString(R.string.statuses)}\n${
|
|
whoDetail?.statuses_count ?: who.statuses_count
|
|
}"
|
|
|
|
val hideFollowCount = PrefB.bpHideFollowCount.value
|
|
|
|
var caption = activity.getString(R.string.following)
|
|
btnFollowing.text = when {
|
|
hideFollowCount -> caption
|
|
else -> "${caption}\n${whoDetail?.following_count ?: who.following_count}"
|
|
}
|
|
|
|
caption = activity.getString(R.string.followers)
|
|
btnFollowers.text = when {
|
|
hideFollowCount -> caption
|
|
else -> "${caption}\n${whoDetail?.followers_count ?: who.followers_count}"
|
|
}
|
|
|
|
|
|
setFollowIcon(
|
|
activity,
|
|
btnFollow,
|
|
ivFollowedBy,
|
|
relation,
|
|
who,
|
|
colorTextContent,
|
|
alphaMultiplier = stylerBoostAlpha
|
|
)
|
|
|
|
tvPersonalNotes.text = relation.note ?: ""
|
|
|
|
showMoved(who, who.movedRef)
|
|
|
|
(whoDetail?.fields ?: who.fields)?.notEmpty()?.let { showFields(who, it) }
|
|
}
|
|
}
|
|
|
|
private fun showMoved(who: TootAccount, movedRef: TootAccountRef?) {
|
|
if (movedRef == null) return
|
|
this.movedRef = movedRef
|
|
val moved = movedRef.get()
|
|
|
|
views.run {
|
|
|
|
llMoved.visibility = View.VISIBLE
|
|
tvMoved.visibility = View.VISIBLE
|
|
|
|
val caption = who.decodeDisplayName(activity)
|
|
.intoStringResource(activity, R.string.account_moved_to)
|
|
|
|
movedCaptionInvalidator.text = caption
|
|
|
|
ivMoved.layoutParams.width = activity.avatarIconSize
|
|
ivMoved.setImageUrl(
|
|
calcIconRound(ivMoved.layoutParams),
|
|
accessInfo.supplyBaseUrl(moved.avatar_static)
|
|
)
|
|
|
|
movedNameInvalidator.text = movedRef.decoded_display_name
|
|
|
|
setAcct(tvMovedAcct, accessInfo, moved)
|
|
|
|
val relation = daoUserRelation.load(accessInfo.db_id, moved.id)
|
|
setFollowIcon(
|
|
activity,
|
|
btnMoved,
|
|
ivMovedBy,
|
|
relation,
|
|
moved,
|
|
colorTextContent,
|
|
alphaMultiplier = stylerBoostAlpha
|
|
)
|
|
}
|
|
}
|
|
|
|
override fun onClick(v: View) {
|
|
|
|
when (v.id) {
|
|
|
|
R.id.ivBackground, R.id.tvRemoteProfileWarning ->
|
|
activity.openCustomTab(whoRef?.get()?.url)
|
|
|
|
R.id.btnFollowing -> {
|
|
column.profileTab = ProfileTab.Following
|
|
activity.appState.saveColumnList()
|
|
column.startLoading()
|
|
}
|
|
|
|
R.id.btnFollowers -> {
|
|
column.profileTab = ProfileTab.Followers
|
|
activity.appState.saveColumnList()
|
|
column.startLoading()
|
|
}
|
|
|
|
R.id.btnStatusCount -> {
|
|
column.profileTab = ProfileTab.Status
|
|
activity.appState.saveColumnList()
|
|
column.startLoading()
|
|
}
|
|
|
|
R.id.btnMore -> whoRef?.let { whoRef ->
|
|
DlgContextMenu(activity, column, whoRef, null, null, null).show()
|
|
}
|
|
|
|
R.id.btnFollow -> whoRef?.let { whoRef ->
|
|
DlgContextMenu(activity, column, whoRef, null, null, null).show()
|
|
}
|
|
|
|
R.id.btnMoved -> movedRef?.let { movedRef ->
|
|
DlgContextMenu(activity, column, movedRef, null, null, null).show()
|
|
}
|
|
|
|
R.id.llMoved -> movedRef?.let { movedRef ->
|
|
if (accessInfo.isPseudo) {
|
|
DlgContextMenu(activity, column, movedRef, null, null, null).show()
|
|
} else {
|
|
activity.userProfileLocal(
|
|
|
|
activity.nextPosition(column),
|
|
accessInfo,
|
|
movedRef.get()
|
|
)
|
|
}
|
|
}
|
|
|
|
R.id.btnPersonalNotesEdit -> whoRef?.let { whoRef ->
|
|
val who = whoRef.get()
|
|
val relation = this.relation
|
|
val lastColumn = column
|
|
activity.launchAndShowError {
|
|
activity.showTextInputDialog(
|
|
title = daoAcctColor.getStringWithNickname(
|
|
activity,
|
|
R.string.personal_notes_of,
|
|
who.acct
|
|
),
|
|
initialText = relation?.note ?: "",
|
|
allowEmpty = true,
|
|
onEmptyText = {},
|
|
) { text ->
|
|
val result = activity.runApiTask(column.accessInfo) { client ->
|
|
when {
|
|
accessInfo.isPseudo ->
|
|
TootApiResult("Personal notes is not supported on pseudo account.")
|
|
accessInfo.isMisskey ->
|
|
TootApiResult("Personal notes is not supported on Misskey account.")
|
|
else ->
|
|
client.request(
|
|
"/api/v1/accounts/${who.id}/note",
|
|
buildJsonObject {
|
|
put("comment", text)
|
|
}.toPostRequestBuilder()
|
|
)
|
|
}
|
|
}
|
|
result ?: return@showTextInputDialog true
|
|
when (val error = result.error) {
|
|
null -> {
|
|
relation?.note = text
|
|
if (lastColumn == column) bindData(column)
|
|
true
|
|
}
|
|
else -> {
|
|
activity.showToast(true, error)
|
|
false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onLongClick(v: View): Boolean {
|
|
when (v.id) {
|
|
|
|
R.id.btnFollow -> {
|
|
activity.followFromAnotherAccount(
|
|
activity.nextPosition(column),
|
|
accessInfo,
|
|
whoRef?.get()
|
|
)
|
|
return true
|
|
}
|
|
|
|
R.id.btnMoved -> {
|
|
activity.followFromAnotherAccount(
|
|
activity.nextPosition(column),
|
|
accessInfo,
|
|
movedRef?.get()
|
|
)
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
private fun setAcct(tv: TextView, accessInfo: SavedAccount, who: TootAccount) {
|
|
val ac = daoAcctColor.load(accessInfo, who)
|
|
tv.text = when {
|
|
daoAcctColor.hasNickname(ac) -> ac.nickname
|
|
PrefB.bpShortAcctLocalUser.value -> "@${who.acct.pretty}"
|
|
else -> "@${ac.nickname}"
|
|
}
|
|
|
|
tv.textColor = ac.colorFg.notZero() ?: column.getAcctColor()
|
|
|
|
tv.setBackgroundColor(ac.colorBg) // may 0
|
|
tv.setPaddingRelative(activity.acctPadLr, 0, activity.acctPadLr, 0)
|
|
}
|
|
|
|
private fun formatFeaturedTags() = column.whoFeaturedTags?.notEmpty()?.let { tagList ->
|
|
SpannableStringBuilder().apply {
|
|
append(activity.getString(R.string.featured_hashtags))
|
|
append(":")
|
|
tagList.forEach { tag ->
|
|
append(" ")
|
|
val tagWithSharp = "#" + tag.name
|
|
val start = length
|
|
append(tagWithSharp)
|
|
val end = length
|
|
tag.url?.notEmpty()?.let { url ->
|
|
val span = MyClickableSpan(
|
|
LinkInfo(url = url, tag = tag.name, caption = tagWithSharp)
|
|
)
|
|
setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun encodeAcctText(who: TootAccount, whoDetail: TootAccount?) =
|
|
SpannableStringBuilder().apply {
|
|
append("@")
|
|
append(accessInfo.getFullAcct(who).pretty)
|
|
if (whoDetail?.locked ?: who.locked) {
|
|
append(" ")
|
|
val emoji = EmojiMap.shortNameMap["lock"]
|
|
when {
|
|
emoji == null ->
|
|
append("locked")
|
|
PrefB.bpUseTwemoji.value ->
|
|
appendSpan("locked", emoji.createSpan(activity))
|
|
else ->
|
|
append(emoji.unifiedCode)
|
|
}
|
|
}
|
|
|
|
if (who.bot) {
|
|
append(" ")
|
|
val emoji = EmojiMap.shortNameMap["robot_face"]
|
|
when {
|
|
emoji == null ->
|
|
append("bot")
|
|
PrefB.bpUseTwemoji.value ->
|
|
appendSpan("bot", emoji.createSpan(activity))
|
|
else ->
|
|
append(emoji.unifiedCode)
|
|
}
|
|
}
|
|
|
|
if (who.suspended) {
|
|
append(" ")
|
|
val emoji = EmojiMap.shortNameMap["cross_mark"]
|
|
when {
|
|
emoji == null ->
|
|
append("suspended")
|
|
PrefB.bpUseTwemoji.value ->
|
|
appendSpan("suspended", emoji.createSpan(activity))
|
|
else ->
|
|
append(emoji.unifiedCode)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun encodeMisskeyExtra(whoDetail: TootAccount?) = SpannableStringBuilder().apply {
|
|
var s = whoDetail?.location
|
|
if (s?.isNotEmpty() == true) {
|
|
if (isNotEmpty()) append('\n')
|
|
appendSpan(
|
|
activity.getString(R.string.location),
|
|
EmojiImageSpan(
|
|
activity,
|
|
R.drawable.ic_location,
|
|
useColorShader = true
|
|
)
|
|
)
|
|
append(' ')
|
|
append(s)
|
|
}
|
|
s = whoDetail?.birthday
|
|
if (s?.isNotEmpty() == true) {
|
|
if (isNotEmpty()) append('\n')
|
|
appendSpan(
|
|
activity.getString(R.string.birthday),
|
|
EmojiImageSpan(
|
|
activity,
|
|
R.drawable.ic_cake,
|
|
useColorShader = true
|
|
)
|
|
)
|
|
append(' ')
|
|
append(s)
|
|
}
|
|
}
|
|
|
|
private fun showFields(who: TootAccount, fields: List<TootAccount.Field>) {
|
|
views.llFields.visibility = View.VISIBLE
|
|
|
|
// fieldsのnameにはカスタム絵文字が適用されるようになった
|
|
// https://github.com/tootsuite/mastodon/pull/11350
|
|
// fieldsのvalueはMisskeyならMFM、MastodonならHTML
|
|
val fieldDecodeOptions = DecodeOptions(
|
|
context = activity,
|
|
decodeEmoji = true,
|
|
linkHelper = accessInfo,
|
|
short = true,
|
|
emojiMapCustom = who.custom_emojis,
|
|
emojiMapProfile = who.profile_emojis,
|
|
authorDomain = who,
|
|
emojiSizeMode = accessInfo.emojiSizeMode(),
|
|
enlargeCustomEmoji = DecodeOptions.emojiScaleUserName,
|
|
enlargeEmoji = DecodeOptions.emojiScaleUserName,
|
|
)
|
|
|
|
val nameTypeface = ActMain.timelineFontBold
|
|
val valueTypeface = ActMain.timelineFont
|
|
|
|
for (item in fields) {
|
|
|
|
//
|
|
val nameView = MyTextView(activity)
|
|
val nameLp = LinearLayout.LayoutParams(
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
)
|
|
val nameText = fieldDecodeOptions.decodeEmoji(item.name)
|
|
|
|
nameLp.topMargin = (density * 6f).toInt()
|
|
nameView.layoutParams = nameLp
|
|
nameView.setTextColor(colorTextContent)
|
|
nameView.typeface = nameTypeface
|
|
nameView.movementMethod = MyLinkMovementMethod
|
|
views.llFields.addView(nameView)
|
|
|
|
val nameInvalidator = NetworkEmojiInvalidator(activity.handler, nameView)
|
|
nameInvalidator.text = nameText
|
|
|
|
// 値の方はHTMLエンコードされている
|
|
val valueView = MyTextView(activity)
|
|
val valueLp = LinearLayout.LayoutParams(
|
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
)
|
|
|
|
val valueText = fieldDecodeOptions.decodeHTML(item.value)
|
|
if (item.verified_at > 0L) {
|
|
valueText.append('\n')
|
|
|
|
val start = valueText.length
|
|
valueText.append(activity.getString(R.string.verified_at))
|
|
valueText.append(": ")
|
|
valueText.append(TootStatus.formatTime(activity, item.verified_at, false))
|
|
val end = valueText.length
|
|
|
|
val linkFgColor = PrefI.ipVerifiedLinkFgColor.value.notZero()
|
|
?: (Color.BLACK or 0x7fbc99)
|
|
|
|
valueText.setSpan(
|
|
ForegroundColorSpan(linkFgColor),
|
|
start,
|
|
end,
|
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
)
|
|
}
|
|
|
|
|
|
valueLp.startMargin = (density * 32f).toInt()
|
|
valueView.layoutParams = valueLp
|
|
valueView.setTextColor(colorTextContent)
|
|
valueView.typeface = valueTypeface
|
|
valueView.movementMethod = MyLinkMovementMethod
|
|
|
|
val valueInvalidator = NetworkEmojiInvalidator(activity.handler, valueView)
|
|
valueInvalidator.text = valueText
|
|
|
|
if (item.verified_at > 0L) {
|
|
val linkBgColor = PrefI.ipVerifiedLinkBgColor.value.notZero()
|
|
?: (0x337fbc99)
|
|
|
|
valueView.setBackgroundColor(linkBgColor)
|
|
}
|
|
|
|
views.llFields.addView(valueView)
|
|
}
|
|
}
|
|
}
|