Twidere-App-Android-Twitter.../twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/ParcelableStatusExtensions.kt

214 lines
7.4 KiB
Kotlin

package org.mariotaku.twidere.extension.model
import org.mariotaku.ktextension.addAllTo
import org.mariotaku.ktextension.toLongOr
import org.mariotaku.microblog.library.mastodon.annotation.StatusVisibility
import org.mariotaku.twidere.TwidereConstants.USER_TYPE_FANFOU_COM
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.util.HtmlEscapeHelper
import org.mariotaku.twidere.util.UriUtils
import org.mariotaku.twidere.util.Utils
inline val ParcelableStatus.originalId: String
get() = if (is_retweet) (retweet_id ?: id) else id
val ParcelableStatus.media_type: Int
get() = media?.firstOrNull()?.type ?: 0
val ParcelableStatus.user: ParcelableUser
get() = ParcelableUser(account_key, user_key, user_name, user_screen_name, user_profile_image_url)
val ParcelableStatus.referencedUsers: Array<ParcelableUser>
get() {
val resultList = mutableSetOf(user)
if (quoted_user_key != null) {
resultList.add(ParcelableUser(account_key, quoted_user_key, quoted_user_name,
quoted_user_screen_name, quoted_user_profile_image))
}
if (retweeted_by_user_key != null) {
resultList.add(ParcelableUser(account_key, retweeted_by_user_key, retweeted_by_user_name,
retweeted_by_user_screen_name, retweeted_by_user_profile_image))
}
mentions?.forEach { mention ->
resultList.add(ParcelableUser(account_key, mention.key, mention.name,
mention.screen_name, null))
}
return resultList.toTypedArray()
}
val ParcelableStatus.replyMentions: Array<ParcelableUserMention>
get() {
val result = ArrayList<ParcelableUserMention>()
result.add(parcelableUserMention(user_key, user_name, user_screen_name))
if (is_retweet) retweeted_by_user_key?.let { key ->
result.add(parcelableUserMention(key, retweeted_by_user_name,
retweeted_by_user_screen_name))
}
mentions?.addAllTo(result)
return result.toTypedArray()
}
inline val ParcelableStatus.user_acct: String
get() = if (account_key.host == user_key.host) {
user_screen_name
} else {
"$user_screen_name@${user_key.host}"
}
inline val ParcelableStatus.retweeted_by_user_acct: String?
get() = if (account_key.host == retweeted_by_user_key?.host) {
retweeted_by_user_screen_name
} else {
"$retweeted_by_user_screen_name@${retweeted_by_user_key?.host}"
}
inline val ParcelableStatus.quoted_user_acct: String?
get() = if (account_key.host == quoted_user_key?.host) {
quoted_user_screen_name
} else {
"$quoted_user_screen_name@${quoted_user_key?.host}"
}
inline val ParcelableStatus.is_my_retweet: Boolean
get() = Utils.isMyRetweet(account_key, retweeted_by_user_key, my_retweet_id)
inline val ParcelableStatus.can_retweet: Boolean
get() {
if (user_key.host == USER_TYPE_FANFOU_COM) return true
val visibility = extras?.visibility ?: return !user_is_protected
return when (visibility) {
StatusVisibility.PRIVATE -> false
StatusVisibility.DIRECT -> false
else -> true
}
}
val ParcelableStatus.quoted: ParcelableStatus?
get() {
val obj = ParcelableStatus()
obj.account_key = account_key
obj.id = quoted_id ?: return null
obj.timestamp = quoted_timestamp
obj.user_key = quoted_user_key ?: return null
obj.user_name = quoted_user_name ?: return null
obj.user_screen_name = quoted_user_screen_name ?: return null
obj.user_profile_image_url = quoted_user_profile_image ?: return null
obj.user_is_protected = quoted_user_is_protected
obj.user_is_verified = quoted_user_is_verified
obj.text_plain = quoted_text_plain
obj.text_unescaped = quoted_text_unescaped
obj.source = quoted_source
obj.spans = quoted_spans
obj.media = quoted_media
return obj
}
val ParcelableStatus.retweet_sort_id: Long
get() {
if (!is_retweet) return -1
return retweet_id.toLongOr(timestamp)
}
fun ParcelableStatus.toSummaryLine(): ParcelableActivity.SummaryLine {
val result = ParcelableActivity.SummaryLine()
result.key = user_key
result.name = user_name
result.screen_name = user_screen_name
result.content = text_unescaped
return result
}
fun ParcelableStatus.extractFanfouHashtags(): List<String> {
return spans?.filter { span ->
var link = span.link
if (link.startsWith("/")) {
link = "http://fanfou.com$link"
}
if (UriUtils.getAuthority(link) != "fanfou.com") {
return@filter false
}
if (span.start <= 0 || span.end > text_unescaped.lastIndex) return@filter false
if (text_unescaped[span.start - 1] == '#' && text_unescaped[span.end] == '#') {
return@filter true
}
return@filter false
}?.map { text_unescaped.substring(it.start, it.end) }.orEmpty()
}
fun ParcelableStatus.makeOriginal() {
if (!is_retweet) return
id = retweet_id
retweeted_by_user_key = null
retweeted_by_user_name = null
retweeted_by_user_screen_name = null
retweeted_by_user_profile_image = null
retweet_timestamp = -1
retweet_id = null
is_retweet = false
sort_id = id.toLongOr(timestamp)
}
fun ParcelableStatus.addFilterFlag(@ParcelableStatus.FilterFlags flags: Long) {
filter_flags = filter_flags or flags
}
fun ParcelableStatus.updateFilterInfo(descriptions: Collection<String?>?) {
updateContentFilterInfo()
filter_users = setOf(user_key, quoted_user_key, retweeted_by_user_key).filterNotNull().toTypedArray()
filter_names = setOf(user_name, quoted_user_name, retweeted_by_user_name).filterNotNull().toTypedArray()
filter_descriptions = descriptions?.filterNotNull()?.joinToString("\n")
}
fun ParcelableStatus.updateContentFilterInfo() {
filter_links = generateFilterLinks()
filter_texts = generateFilterTexts()
filter_sources = setOf(source?.plainText, quoted_source?.plainText).filterNotNull().toTypedArray()
}
fun ParcelableStatus.generateFilterTexts(): String {
val texts = StringBuilder()
texts.appendNonEmptyLine(text_unescaped)
texts.appendNonEmptyLine(quoted_text_unescaped)
media?.forEach { item ->
texts.appendNonEmptyLine(item.alt_text)
}
quoted_media?.forEach { item ->
texts.appendNonEmptyLine(item.alt_text)
}
return texts.toString()
}
fun ParcelableStatus.generateFilterLinks(): Array<String> {
val links = mutableSetOf<String>()
spans?.mapNotNullTo(links) { span ->
if (span.type != SpanItem.SpanType.LINK) return@mapNotNullTo null
return@mapNotNullTo span.link
}
quoted_spans?.mapNotNullTo(links) { span ->
if (span.type != SpanItem.SpanType.LINK) return@mapNotNullTo null
return@mapNotNullTo span.link
}
return links.toTypedArray()
}
fun ParcelableStatus.updateExtraInformation(details: AccountDetails) {
account_color = details.color
}
internal inline val String.plainText: String get() = HtmlEscapeHelper.toPlainText(this)
private fun parcelableUserMention(key: UserKey, name: String, screenName: String) = ParcelableUserMention().also {
it.key = key
it.name = name
it.screen_name = screenName
}
private fun StringBuilder.appendNonEmptyLine(line: CharSequence?) {
if (line.isNullOrEmpty()) return
append(line)
append('\n')
}