2019-06-25 22:28:02 +02:00
|
|
|
package jp.juggler.subwaytooter.util
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.Intent
|
|
|
|
import jp.juggler.subwaytooter.ActText
|
|
|
|
import jp.juggler.subwaytooter.R
|
|
|
|
import jp.juggler.subwaytooter.api.entity.*
|
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
object TootTextEncoder {
|
2019-12-07 17:23:44 +01:00
|
|
|
private fun StringBuilder.addAfterLine(text : CharSequence) {
|
|
|
|
if(isNotEmpty() && this[length - 1] != '\n') {
|
2019-06-25 22:28:02 +02:00
|
|
|
append('\n')
|
|
|
|
}
|
|
|
|
append(text)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun addHeader(
|
|
|
|
context : Context,
|
|
|
|
sb : StringBuilder,
|
|
|
|
key_str_id : Int,
|
|
|
|
value : Any?
|
|
|
|
) {
|
|
|
|
if(sb.isNotEmpty() && sb[sb.length - 1] != '\n') {
|
|
|
|
sb.append('\n')
|
|
|
|
}
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine(context.getString(key_str_id))
|
2019-06-25 22:28:02 +02:00
|
|
|
sb.append(": ")
|
|
|
|
sb.append(value?.toString() ?: "(null)")
|
|
|
|
}
|
|
|
|
|
|
|
|
fun encodeStatus(
|
|
|
|
intent : Intent,
|
|
|
|
context : Context,
|
|
|
|
access_info : SavedAccount,
|
|
|
|
status : TootStatus
|
|
|
|
) {
|
|
|
|
val sb = StringBuilder()
|
|
|
|
|
|
|
|
addHeader(context, sb, R.string.send_header_url, status.url)
|
|
|
|
|
|
|
|
addHeader(
|
|
|
|
context,
|
|
|
|
sb,
|
|
|
|
R.string.send_header_date,
|
|
|
|
TootStatus.formatTime(context, status.time_created_at, false)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
addHeader(
|
|
|
|
context,
|
|
|
|
sb,
|
|
|
|
R.string.send_header_from_acct,
|
|
|
|
access_info.getFullAcct(status.account)
|
|
|
|
)
|
|
|
|
|
|
|
|
val sv : String? = status.spoiler_text
|
|
|
|
if(sv != null && sv.isNotEmpty()) {
|
|
|
|
addHeader(context, sb, R.string.send_header_content_warning, sv)
|
|
|
|
}
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine("\n")
|
2019-06-25 22:28:02 +02:00
|
|
|
|
|
|
|
intent.putExtra(ActText.EXTRA_CONTENT_START, sb.length)
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.append(
|
|
|
|
DecodeOptions(
|
|
|
|
context,
|
|
|
|
access_info,
|
|
|
|
mentions = status.mentions
|
|
|
|
).decodeHTML(status.content)
|
|
|
|
)
|
2019-06-25 22:28:02 +02:00
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
encodePolls(sb, context, status)
|
2019-06-25 22:28:02 +02:00
|
|
|
|
|
|
|
intent.putExtra(ActText.EXTRA_CONTENT_END, sb.length)
|
|
|
|
|
|
|
|
dumpAttachment(sb, status.media_attachments)
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine(String.format(Locale.JAPAN, "Status-Source: %s", status.json.toString(2)))
|
|
|
|
sb.addAfterLine("")
|
2019-06-25 22:28:02 +02:00
|
|
|
intent.putExtra(ActText.EXTRA_TEXT, sb.toString())
|
|
|
|
}
|
|
|
|
|
|
|
|
fun encodeStatusForTranslate(
|
|
|
|
context : Context,
|
|
|
|
access_info : SavedAccount,
|
|
|
|
status : TootStatus
|
2019-12-07 17:23:44 +01:00
|
|
|
) : String {
|
2019-06-25 22:28:02 +02:00
|
|
|
val sb = StringBuilder()
|
|
|
|
|
|
|
|
val sv : String? = status.spoiler_text
|
|
|
|
if(sv != null && sv.isNotEmpty()) {
|
|
|
|
sb.append(sv).append("\n\n")
|
|
|
|
}
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.append(
|
|
|
|
DecodeOptions(
|
|
|
|
context,
|
|
|
|
access_info,
|
|
|
|
mentions = status.mentions
|
|
|
|
).decodeHTML(status.content)
|
|
|
|
)
|
2019-06-25 22:28:02 +02:00
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
encodePolls(sb, context, status)
|
2019-06-25 22:28:02 +02:00
|
|
|
|
|
|
|
return sb.toString()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun dumpAttachment(sb : StringBuilder, src : ArrayList<TootAttachmentLike>?) {
|
|
|
|
if(src == null) return
|
|
|
|
var i = 0
|
|
|
|
for(ma in src) {
|
|
|
|
++ i
|
|
|
|
if(ma is TootAttachment) {
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine("\n")
|
|
|
|
sb.addAfterLine(String.format(Locale.JAPAN, "Media-%d-Url: %s", i, ma.url))
|
2019-06-25 22:28:02 +02:00
|
|
|
sb.addAfterLine(
|
|
|
|
String.format(Locale.JAPAN, "Media-%d-Remote-Url: %s", i, ma.remote_url)
|
|
|
|
)
|
|
|
|
sb.addAfterLine(
|
|
|
|
String.format(Locale.JAPAN, "Media-%d-Preview-Url: %s", i, ma.preview_url)
|
|
|
|
)
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine(
|
2019-06-25 22:28:02 +02:00
|
|
|
String.format(Locale.JAPAN, "Media-%d-Text-Url: %s", i, ma.text_url)
|
|
|
|
)
|
|
|
|
} else if(ma is TootAttachmentMSP) {
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine("\n")
|
|
|
|
sb.addAfterLine(
|
2019-06-25 22:28:02 +02:00
|
|
|
String.format(Locale.JAPAN, "Media-%d-Preview-Url: %s", i, ma.preview_url)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
private fun encodePolls(sb : StringBuilder, context : Context, status : TootStatus) {
|
2019-06-25 22:28:02 +02:00
|
|
|
val enquete = status.enquete ?: return
|
|
|
|
val items = enquete.items ?: return
|
|
|
|
val now = System.currentTimeMillis()
|
|
|
|
|
|
|
|
val canVote = when(enquete.pollType) {
|
|
|
|
|
|
|
|
// friends.nico の場合は本文に投票の選択肢が含まれるので
|
|
|
|
// アプリ側での文字列化は不要
|
|
|
|
TootPollsType.FriendsNico -> return
|
|
|
|
|
|
|
|
// MastodonとMisskeyは投票の選択肢が本文に含まれないので
|
|
|
|
// アプリ側で文字列化する
|
|
|
|
|
|
|
|
TootPollsType.Mastodon -> when {
|
|
|
|
enquete.expired -> false
|
|
|
|
now >= enquete.expired_at -> false
|
2019-09-22 20:25:00 +02:00
|
|
|
enquete.ownVoted -> false
|
2019-06-25 22:28:02 +02:00
|
|
|
else -> true
|
|
|
|
}
|
|
|
|
|
2019-09-22 20:25:00 +02:00
|
|
|
TootPollsType.Misskey -> enquete.ownVoted
|
2019-06-25 22:28:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sb.addAfterLine("\n")
|
|
|
|
|
2019-09-24 14:41:27 +02:00
|
|
|
items.forEach { choice ->
|
|
|
|
encodePollChoice(sb, context, enquete, canVote, choice)
|
2019-06-25 22:28:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
when(enquete.pollType) {
|
|
|
|
TootPollsType.Mastodon -> encodePollFooterMastodon(sb, context, enquete)
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
else -> {
|
|
|
|
}
|
2019-06-25 22:28:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun encodePollChoice(
|
|
|
|
sb : StringBuilder,
|
|
|
|
context : Context,
|
|
|
|
enquete : TootPolls,
|
|
|
|
canVote : Boolean,
|
|
|
|
item : TootPollsChoice
|
|
|
|
) {
|
|
|
|
|
|
|
|
val text = when(enquete.pollType) {
|
|
|
|
TootPollsType.Misskey -> {
|
|
|
|
val sb2 = StringBuilder().append(item.decoded_text)
|
2019-12-07 17:23:44 +01:00
|
|
|
if(enquete.ownVoted) {
|
2019-06-25 22:28:02 +02:00
|
|
|
sb2.append(" / ")
|
|
|
|
sb2.append(context.getString(R.string.vote_count_text, item.votes))
|
2019-12-07 17:23:44 +01:00
|
|
|
if(item.isVoted) sb2.append(' ').append(0x2713.toChar())
|
2019-06-25 22:28:02 +02:00
|
|
|
}
|
|
|
|
sb2
|
|
|
|
}
|
|
|
|
|
|
|
|
TootPollsType.FriendsNico -> {
|
|
|
|
item.decoded_text
|
|
|
|
}
|
|
|
|
|
|
|
|
TootPollsType.Mastodon -> if(canVote) {
|
|
|
|
item.decoded_text
|
|
|
|
} else {
|
|
|
|
val sb2 = StringBuilder().append(item.decoded_text)
|
|
|
|
if(! canVote) {
|
|
|
|
sb2.append(" / ")
|
|
|
|
sb2.append(
|
|
|
|
when(val v = item.votes) {
|
|
|
|
null -> context.getString(R.string.vote_count_unavailable)
|
|
|
|
else -> context.getString(R.string.vote_count_text, v)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
sb2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sb.addAfterLine(text)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun encodePollFooterMastodon(
|
|
|
|
sb : StringBuilder,
|
|
|
|
context : Context,
|
|
|
|
enquete : TootPolls
|
|
|
|
) {
|
|
|
|
val line = StringBuilder()
|
|
|
|
|
|
|
|
val votes_count = enquete.votes_count ?: 0
|
|
|
|
when {
|
|
|
|
votes_count == 1 -> line.append(context.getString(R.string.vote_1))
|
|
|
|
votes_count > 1 -> line.append(context.getString(R.string.vote_2, votes_count))
|
|
|
|
}
|
|
|
|
|
|
|
|
when(val t = enquete.expired_at) {
|
|
|
|
|
|
|
|
Long.MAX_VALUE -> {
|
|
|
|
}
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
if(line.isNotEmpty()) line.append(" ")
|
|
|
|
line.append(
|
|
|
|
context.getString(
|
|
|
|
R.string.vote_expire_at,
|
|
|
|
TootStatus.formatTime(context, t, false)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sb.addAfterLine(line)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun encodeAccount(
|
|
|
|
intent : Intent,
|
|
|
|
context : Context,
|
|
|
|
access_info : SavedAccount,
|
|
|
|
who : TootAccount
|
|
|
|
) {
|
|
|
|
val sb = StringBuilder()
|
|
|
|
|
|
|
|
intent.putExtra(ActText.EXTRA_CONTENT_START, sb.length)
|
|
|
|
sb.append(who.display_name)
|
|
|
|
sb.append("\n")
|
|
|
|
sb.append("@")
|
|
|
|
sb.append(access_info.getFullAcct(who))
|
|
|
|
sb.append("\n")
|
|
|
|
|
|
|
|
intent.putExtra(ActText.EXTRA_CONTENT_START, sb.length)
|
|
|
|
sb.append(who.url)
|
|
|
|
intent.putExtra(ActText.EXTRA_CONTENT_END, sb.length)
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine("\n")
|
2019-06-25 22:28:02 +02:00
|
|
|
|
|
|
|
sb.append(DecodeOptions(context, access_info).decodeHTML(who.note))
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine("\n")
|
2019-06-25 22:28:02 +02:00
|
|
|
|
|
|
|
addHeader(context, sb, R.string.send_header_account_name, who.display_name)
|
|
|
|
addHeader(context, sb, R.string.send_header_account_acct, access_info.getFullAcct(who))
|
|
|
|
addHeader(context, sb, R.string.send_header_account_url, who.url)
|
|
|
|
|
|
|
|
addHeader(context, sb, R.string.send_header_account_image_avatar, who.avatar)
|
|
|
|
addHeader(
|
|
|
|
context,
|
|
|
|
sb,
|
|
|
|
R.string.send_header_account_image_avatar_static,
|
|
|
|
who.avatar_static
|
|
|
|
)
|
|
|
|
addHeader(context, sb, R.string.send_header_account_image_header, who.header)
|
|
|
|
addHeader(
|
|
|
|
context,
|
|
|
|
sb,
|
|
|
|
R.string.send_header_account_image_header_static,
|
|
|
|
who.header_static
|
|
|
|
)
|
|
|
|
|
|
|
|
addHeader(context, sb, R.string.send_header_account_created_at, who.created_at)
|
|
|
|
addHeader(context, sb, R.string.send_header_account_statuses_count, who.statuses_count)
|
|
|
|
addHeader(
|
|
|
|
context,
|
|
|
|
sb,
|
|
|
|
R.string.send_header_account_followers_count,
|
|
|
|
who.followers_count
|
|
|
|
)
|
|
|
|
addHeader(
|
|
|
|
context,
|
|
|
|
sb,
|
|
|
|
R.string.send_header_account_following_count,
|
|
|
|
who.following_count
|
|
|
|
)
|
|
|
|
addHeader(context, sb, R.string.send_header_account_locked, who.locked)
|
|
|
|
|
2019-12-07 17:23:44 +01:00
|
|
|
sb.addAfterLine(String.format(Locale.JAPAN, "Account-Source: %s", who.json.toString(2)))
|
|
|
|
sb.addAfterLine("")
|
2019-12-06 09:04:33 +01:00
|
|
|
|
2019-06-25 22:28:02 +02:00
|
|
|
intent.putExtra(ActText.EXTRA_TEXT, sb.toString())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|