(misskey)返信と引用Renoteの表示

This commit is contained in:
tateisu 2018-08-23 12:46:14 +09:00
parent 979e2d0447
commit 9a0ac5f8ef
5 changed files with 201 additions and 31 deletions

View File

@ -52,12 +52,17 @@ internal class ItemViewHolder(
lateinit var column : Column lateinit var column : Column
private lateinit var list_adapter : ItemListAdapter private lateinit var list_adapter : ItemListAdapter
private lateinit var llBoosted : View private lateinit var llBoosted : View
private lateinit var ivBoosted : ImageView private lateinit var ivBoosted : ImageView
private lateinit var tvBoosted : TextView private lateinit var tvBoosted : TextView
private lateinit var tvBoostedAcct : TextView private lateinit var tvBoostedAcct : TextView
private lateinit var tvBoostedTime : 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 llFollow : View
private lateinit var ivFollow : MyNetworkImageView private lateinit var ivFollow : MyNetworkImageView
private lateinit var tvFollowerName : TextView private lateinit var tvFollowerName : TextView
@ -123,6 +128,7 @@ internal class ItemViewHolder(
private var item : TimelineItem? = null private var item : TimelineItem? = null
private var status_showing : TootStatus? = null private var status_showing : TootStatus? = null
private var status_reply : TootStatus? = null
private var status_account : TootAccountRef? = null private var status_account : TootAccountRef? = null
private var boost_account : TootAccountRef? = null private var boost_account : TootAccountRef? = null
private var follow_account : TootAccountRef? = null private var follow_account : TootAccountRef? = null
@ -133,6 +139,7 @@ internal class ItemViewHolder(
private var acct_color : Int = 0 private var acct_color : Int = 0
private val boost_invalidator : NetworkEmojiInvalidator private val boost_invalidator : NetworkEmojiInvalidator
private val reply_invalidator : NetworkEmojiInvalidator
private val follow_invalidator : NetworkEmojiInvalidator private val follow_invalidator : NetworkEmojiInvalidator
private val name_invalidator : NetworkEmojiInvalidator private val name_invalidator : NetworkEmojiInvalidator
private val content_invalidator : NetworkEmojiInvalidator private val content_invalidator : NetworkEmojiInvalidator
@ -157,12 +164,18 @@ internal class ItemViewHolder(
btnFollow.setOnLongClickListener(this) btnFollow.setOnLongClickListener(this)
ivThumbnail.setOnClickListener(this) ivThumbnail.setOnClickListener(this)
// ここを個別タップにすると邪魔すぎる tvName.setOnClickListener( this );
llBoosted.setOnClickListener(this) llBoosted.setOnClickListener(this)
llBoosted.setOnLongClickListener(this) llBoosted.setOnLongClickListener(this)
llReply.setOnClickListener(this)
llReply.setOnLongClickListener(this)
llFollow.setOnClickListener(this) llFollow.setOnClickListener(this)
llFollow.setOnLongClickListener(this) llFollow.setOnLongClickListener(this)
btnFollow.setOnClickListener(this) btnFollow.setOnClickListener(this)
btnFollowRequestAccept.setOnClickListener(this) btnFollowRequestAccept.setOnClickListener(this)
btnFollowRequestDeny.setOnClickListener(this) btnFollowRequestDeny.setOnClickListener(this)
@ -200,6 +213,7 @@ internal class ItemViewHolder(
} }
if(! activity.notification_tl_font_size_sp.isNaN()) { if(! activity.notification_tl_font_size_sp.isNaN()) {
tvBoosted.textSize = activity.notification_tl_font_size_sp tvBoosted.textSize = activity.notification_tl_font_size_sp
tvReply.textSize = activity.notification_tl_font_size_sp
} }
if(! activity.acct_font_size_sp.isNaN()) { if(! activity.acct_font_size_sp.isNaN()) {
@ -221,6 +235,7 @@ internal class ItemViewHolder(
this.content_invalidator = NetworkEmojiInvalidator(activity.handler, tvContent) this.content_invalidator = NetworkEmojiInvalidator(activity.handler, tvContent)
this.spoiler_invalidator = NetworkEmojiInvalidator(activity.handler, tvContentWarning) this.spoiler_invalidator = NetworkEmojiInvalidator(activity.handler, tvContentWarning)
this.boost_invalidator = NetworkEmojiInvalidator(activity.handler, tvBoosted) this.boost_invalidator = NetworkEmojiInvalidator(activity.handler, tvBoosted)
this.reply_invalidator = NetworkEmojiInvalidator(activity.handler, tvReply)
this.follow_invalidator = NetworkEmojiInvalidator(activity.handler, tvFollowerName) this.follow_invalidator = NetworkEmojiInvalidator(activity.handler, tvFollowerName)
this.name_invalidator = NetworkEmojiInvalidator(activity.handler, tvName) this.name_invalidator = NetworkEmojiInvalidator(activity.handler, tvName)
} }
@ -258,6 +273,7 @@ internal class ItemViewHolder(
v === tvName || v === tvName ||
v === tvFollowerName || v === tvFollowerName ||
v === tvBoosted || v === tvBoosted ||
v === tvReply ||
v === tvTrendTagCount || v === tvTrendTagCount ||
v === tvTrendTagName || v === tvTrendTagName ||
v === tvFilterPhrase -> font_bold v === tvFilterPhrase -> font_bold
@ -311,6 +327,7 @@ internal class ItemViewHolder(
} }
this.status_showing = null this.status_showing = null
this.status_reply = null
this.status_account = null this.status_account = null
this.boost_account = null this.boost_account = null
this.follow_account = null this.follow_account = null
@ -319,6 +336,7 @@ internal class ItemViewHolder(
this.boostedAction = defaultBoostedAction this.boostedAction = defaultBoostedAction
llBoosted.visibility = View.GONE llBoosted.visibility = View.GONE
llReply.visibility = View.GONE
llFollow.visibility = View.GONE llFollow.visibility = View.GONE
llStatus.visibility = View.GONE llStatus.visibility = View.GONE
llSearchTag.visibility = View.GONE llSearchTag.visibility = View.GONE
@ -332,6 +350,7 @@ internal class ItemViewHolder(
var c : Int var c : Int
c = if(column.content_color != 0) column.content_color else content_color_default c = if(column.content_color != 0) column.content_color else content_color_default
tvBoosted.setTextColor(c) tvBoosted.setTextColor(c)
tvReply.setTextColor(c)
tvFollowerName.setTextColor(c) tvFollowerName.setTextColor(c)
tvName.setTextColor(c) tvName.setTextColor(c)
tvMentions.setTextColor(c) tvMentions.setTextColor(c)
@ -362,16 +381,27 @@ internal class ItemViewHolder(
when(item) { when(item) {
is TootStatus -> { is TootStatus -> {
val reblog = item.reblog val reblog = item.reblog
if(reblog != null) { when{
showBoost( reblog == null -> showStatusOrReply(item)
item.accountRef, item.hasAnyContent() -> {
item.time_created_at, // 引用Renote
R.attr.btn_boost, showReply(
R.string.display_name_boosted_by reblog,
) R.attr.btn_boost,
showStatus(activity, reblog) R.string.renote_to
} else { )
showStatus(activity, item) showStatus(activity, item)
}
else ->{
// 引用なしブースト
showBoost(
item.accountRef,
item.time_created_at,
R.attr.btn_boost,
R.string.display_name_boosted_by
)
showStatusOrReply(item.reblog)
}
} }
} }
@ -396,6 +426,21 @@ internal class ItemViewHolder(
} }
} }
private fun showStatusOrReply(item:TootStatus){
val reply = item.reply
if( reply != null) {
// 返信
showReply(
reply,
R.attr.btn_reply,
R.string.reply_to
)
showStatus(activity, item)
}else{
showStatus(activity, item)
}
}
private fun showTrendTag(item : TootTrendTag) { private fun showTrendTag(item : TootTrendTag) {
llTrendTag.visibility = View.VISIBLE llTrendTag.visibility = View.VISIBLE
tvTrendTagName.text = "#${item.name}" tvTrendTagName.text = "#${item.name}"
@ -411,10 +456,30 @@ internal class ItemViewHolder(
tvMessageHolder.gravity = item.gravity tvMessageHolder.gravity = item.gravity
} }
private fun showNotification(n : TootNotification) { private fun showNotification(n : TootNotification) {
val n_status = n.status val n_status = n.status
val n_accountRef = n.accountRef val n_accountRef = n.accountRef
val n_account = n_accountRef?.get() val n_account = n_accountRef?.get()
fun showNotificationStatus(item :TootStatus){
val reblog = item.reblog
when{
reblog == null -> showStatusOrReply(item)
!item.hasAnyContent() ->showStatusOrReply(reblog) // ブースト表示は通知イベントと被るのでしない
else -> {
// 引用Renote
showReply(
reblog,
R.attr.btn_boost,
R.string.renote_to
)
showStatus(activity, item)
}
}
}
when(n.type) { when(n.type) {
TootNotification.TYPE_FAVOURITE -> { TootNotification.TYPE_FAVOURITE -> {
@ -424,7 +489,9 @@ internal class ItemViewHolder(
if(access_info.isNicoru(n_account)) R.attr.ic_nicoru else R.attr.btn_favourite, if(access_info.isNicoru(n_account)) R.attr.ic_nicoru else R.attr.btn_favourite,
R.string.display_name_favourited_by R.string.display_name_favourited_by
) )
if(n_status != null) showStatus(activity, n_status) if(n_status != null){
showNotificationStatus(n_status)
}
} }
TootNotification.TYPE_REBLOG -> { TootNotification.TYPE_REBLOG -> {
@ -434,7 +501,9 @@ internal class ItemViewHolder(
R.attr.btn_boost, R.attr.btn_boost,
R.string.display_name_boosted_by R.string.display_name_boosted_by
) )
if(n_status != null) showStatus(activity, n_status) if(n_status != null){
showNotificationStatus(n_status)
}
} }
@ -446,8 +515,8 @@ internal class ItemViewHolder(
R.attr.btn_boost, R.attr.btn_boost,
R.string.display_name_boosted_by R.string.display_name_boosted_by
) )
if(n_status != null) { if(n_status != null){
showStatus(activity, n_status.reblog ?: n_status) showNotificationStatus(n_status)
} }
} }
@ -464,9 +533,7 @@ internal class ItemViewHolder(
} }
TootNotification.TYPE_MENTION, TootNotification.TYPE_REPLY -> { TootNotification.TYPE_MENTION, TootNotification.TYPE_REPLY -> {
// ミスキーは返信にメンションがないので説明文がないとなぜ通知にでるのか分からない if(! bSimpleList && ! access_info.isMisskey) {
// 感力表示オフでも説明文を表示する
if(! bSimpleList || ! access_info.isMisskey) {
if(n_account != null) showBoost( if(n_account != null) showBoost(
n_accountRef, n_accountRef,
n.time_created_at, n.time_created_at,
@ -474,8 +541,9 @@ internal class ItemViewHolder(
R.string.display_name_replied_by R.string.display_name_replied_by
) )
} }
if(n_status != null) showStatus(activity, n_status) if(n_status != null){
showNotificationStatus(n_status)
}
} }
TootNotification.TYPE_REACTION -> { TootNotification.TYPE_REACTION -> {
@ -487,8 +555,9 @@ internal class ItemViewHolder(
R.string.display_name_reaction_by R.string.display_name_reaction_by
, reaction?.btnDrawableId , reaction?.btnDrawableId
) )
if(n_status != null) showStatus(activity, n_status) if(n_status != null){
showNotificationStatus(n_status)
}
} }
TootNotification.TYPE_QUOTE -> { TootNotification.TYPE_QUOTE -> {
@ -498,7 +567,9 @@ internal class ItemViewHolder(
R.attr.btn_boost, R.attr.btn_boost,
R.string.display_name_quoted_by R.string.display_name_quoted_by
) )
if(n_status != null) showStatus(activity, n_status) if(n_status != null){
showNotificationStatus(n_status)
}
} }
TootNotification.TYPE_VOTE -> { TootNotification.TYPE_VOTE -> {
@ -508,7 +579,9 @@ internal class ItemViewHolder(
R.attr.ic_vote, R.attr.ic_vote,
R.string.display_name_voted_by R.string.display_name_voted_by
) )
if(n_status != null) showStatus(activity, n_status) if(n_status != null){
showNotificationStatus(n_status)
}
} }
TootNotification.TYPE_FOLLOW_REQUEST -> { TootNotification.TYPE_FOLLOW_REQUEST -> {
@ -534,7 +607,9 @@ internal class ItemViewHolder(
R.attr.ic_question, R.attr.ic_question,
R.string.unknown_notification_from R.string.unknown_notification_from
) )
if(n_status != null) showStatus(activity, n_status) if(n_status != null){
showNotificationStatus(n_status)
}
tvMessageHolder.visibility = View.VISIBLE tvMessageHolder.visibility = View.VISIBLE
tvMessageHolder.text = "notification type is ${n.type}" tvMessageHolder.text = "notification type is ${n.type}"
tvMessageHolder.gravity = Gravity.CENTER tvMessageHolder.gravity = Gravity.CENTER
@ -590,6 +665,26 @@ internal class ItemViewHolder(
btnSearchTag.text = activity.getString(R.string.read_gap) btnSearchTag.text = activity.getString(R.string.read_gap)
} }
private fun showReply(
reply : TootStatus,
iconAttrId : Int,
stringId : Int
) {
status_reply = reply
llReply.visibility = View.VISIBLE
// val who = reply.account
// showStatusTime(activity, tvReplyTime, who, time = reply.time_created_at)
// setAcct(tvReplyAcct, access_info.getFullAcct(who), who.acct)
ivReply.setImageResource(Styler.getAttributeResourceId(activity, iconAttrId))
val text = reply.accountRef.decoded_display_name.intoStringResource(activity, stringId)
tvReply.text = text
reply_invalidator.register(text)
}
private fun showBoost( private fun showBoost(
whoRef : TootAccountRef, whoRef : TootAccountRef,
time : Long, time : Long,
@ -731,6 +826,14 @@ internal class ItemViewHolder(
tvMentions.text = status.decoded_mentions tvMentions.text = status.decoded_mentions
} }
if( status.time_deleted_at > 0L){
val s = SpannableStringBuilder()
.append('(')
.append(activity.getString(R.string.deleted_at,TootStatus.formatTime(activity,status.time_deleted_at,true)))
.append(')')
content= s
}
tvContent.text = content tvContent.text = content
content_invalidator.register(content) content_invalidator.register(content)
@ -1114,6 +1217,12 @@ internal class ItemViewHolder(
llBoosted -> boostedAction() llBoosted -> boostedAction()
llReply ->{
status_reply?.let { s ->
Action_Toot.conversation(activity,pos,access_info,s)
}
}
llFollow -> follow_account?.let { whoRef -> llFollow -> follow_account?.let { whoRef ->
if(access_info.isPseudo) { if(access_info.isPseudo) {
DlgContextMenu(activity, column, whoRef, null, notification).show() DlgContextMenu(activity, column, whoRef, null, notification).show()
@ -1257,6 +1366,18 @@ internal class ItemViewHolder(
return true return true
} }
llReply ->{
status_reply?.let { s ->
DlgContextMenu(
activity,
column,
s.accountRef,
s,
notification
).show()
}
}
llFollow -> { llFollow -> {
follow_account?.let { whoRef -> follow_account?.let { whoRef ->
DlgContextMenu( DlgContextMenu(
@ -1831,6 +1952,8 @@ internal class ItemViewHolder(
} }
} }
llStatus = verticalLayout { llStatus = verticalLayout {
lparams(matchParent, wrapContent) lparams(matchParent, wrapContent)
@ -1878,10 +2001,29 @@ internal class ItemViewHolder(
} }
tvName = textView { tvName = textView {
// tools:text="Displayname"
}.lparams(matchParent, wrapContent) }.lparams(matchParent, wrapContent)
llReply = linearLayout {
lparams(matchParent, wrapContent) {
bottomMargin = dip(3)
}
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
gravity = Gravity.CENTER_VERTICAL
ivReply = imageView {
scaleType = ImageView.ScaleType.FIT_END
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
}.lparams(dip(32), dip(32)) {
endMargin = dip(4)
}
tvReply = textView {
}.lparams(dip(0), wrapContent) {
weight = 1f
}
}
llContentWarning = linearLayout { llContentWarning = linearLayout {
lparams(matchParent, wrapContent) { lparams(matchParent, wrapContent) {
topMargin = dip(3) topMargin = dip(3)

View File

@ -54,9 +54,6 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
override fun getOrderId() = _orderId override fun getOrderId() = _orderId
// val isMisskey :Boolean
// get()= id is EntityIdString
// The TootAccount which posted the status // The TootAccount which posted the status
val accountRef : TootAccountRef val accountRef : TootAccountRef
@ -146,6 +143,11 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
var renoteReply : String? = null var renoteReply : String? = null
val serviceType :ServiceType
val deletedAt : String?
val time_deleted_at : Long
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// 以下はentityから取得したデータではなく、アプリ内部で使う // 以下はentityから取得したデータではなく、アプリ内部で使う
@ -172,6 +174,7 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
init { init {
this.json = src this.json = src
this.serviceType = parser.serviceType
if(parser.serviceType == ServiceType.MISSKEY) { if(parser.serviceType == ServiceType.MISSKEY) {
val instance = parser.linkHelper.host val instance = parser.linkHelper.host
@ -298,9 +301,13 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
this.reblog = parser.status(src.optJSONObject("renote")) this.reblog = parser.status(src.optJSONObject("renote"))
this.reply = parser.status(src.optJSONObject("reply")) this.reply = parser.status(src.optJSONObject("reply"))
this.deletedAt = src.parseString("deletedAt")
this.time_deleted_at = parseTime(deletedAt)
} else { } else {
misskeyVisibleIds = null misskeyVisibleIds = null
reply = null reply = null
deletedAt = null
time_deleted_at =0L
this.uri = src.parseString("uri") // MSPだとuriは提供されない this.uri = src.parseString("uri") // MSPだとuriは提供されない
this.url = src.parseString("url") // 頻繁にnullになる this.url = src.parseString("url") // 頻繁にnullになる
@ -512,6 +519,16 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
return false return false
} }
fun hasAnyContent() =when{
reblog == null -> true // reblog以外はオリジナルコンテンツがあると見なす
serviceType != ServiceType.MISSKEY -> false // misskey以外のreblogはコンテンツがないと見なす
content?.isNotEmpty()== true
|| spoiler_text?.isNotEmpty()== true
|| media_attachments?.isNotEmpty()== true
|| enquete != null -> true
else-> false
}
companion object { companion object {
internal val log = LogCategory("TootStatus") internal val log = LogCategory("TootStatus")

View File

@ -768,7 +768,11 @@
<string name="end">End</string> <string name="end">End</string>
<string name="misskey_hybrid_timeline">Social timeline</string> <string name="misskey_hybrid_timeline">Social timeline</string>
<string name="misskey_hybrid_timeline_long">Social TL (Misskey)</string> <string name="misskey_hybrid_timeline_long">Social TL (Misskey)</string>
<!--<string name="abc_action_bar_home_description">Revenir à l\'accueil</string>--> <string name="renote_to">Renote to %1$s</string>
<string name="reply_to">Reply to %1$s</string>
<string name="deleted_at">deleted at %1$s</string>
<!--<string name="abc_action_bar_home_description">Revenir à l\'accueil</string>-->
<!--<string name="abc_action_bar_home_description_format">%1$s, %2$s</string>--> <!--<string name="abc_action_bar_home_description_format">%1$s, %2$s</string>-->
<!--<string name="abc_action_bar_home_subtitle_description_format">%1$s, %2$s, %3$s</string>--> <!--<string name="abc_action_bar_home_subtitle_description_format">%1$s, %2$s, %3$s</string>-->
<!--<string name="abc_action_bar_up_description">Revenir en haut de la page</string>--> <!--<string name="abc_action_bar_up_description">Revenir en haut de la page</string>-->

View File

@ -1045,5 +1045,8 @@
<string name="end">終端</string> <string name="end">終端</string>
<string name="misskey_hybrid_timeline_long">ソーシャルTL(Misskey)</string> <string name="misskey_hybrid_timeline_long">ソーシャルTL(Misskey)</string>
<string name="misskey_hybrid_timeline">ソーシャルTL</string> <string name="misskey_hybrid_timeline">ソーシャルTL</string>
<string name="renote_to">%1$sへのリート</string>
<string name="reply_to">%1$sへの返信</string>
<string name="deleted_at">%1$sに削除されました</string>
</resources> </resources>

View File

@ -753,4 +753,8 @@
<string name="end">End</string> <string name="end">End</string>
<string name="misskey_hybrid_timeline">Social timeline</string> <string name="misskey_hybrid_timeline">Social timeline</string>
<string name="misskey_hybrid_timeline_long">Social TL (Misskey)</string> <string name="misskey_hybrid_timeline_long">Social TL (Misskey)</string>
<string name="renote_to">Renote to %1$s</string>
<string name="reply_to">Reply to %1$s</string>
<string name="deleted_at">deleted at %1$s</string>
</resources> </resources>