2018-01-04 19:52:25 +01:00
|
|
|
package jp.juggler.subwaytooter
|
|
|
|
|
|
|
|
import android.app.SearchManager
|
|
|
|
import android.content.ClipData
|
|
|
|
import android.content.ClipboardManager
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.Intent
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.support.v7.app.AppCompatActivity
|
|
|
|
import android.view.View
|
|
|
|
import android.widget.EditText
|
|
|
|
import jp.juggler.subwaytooter.api.entity.*
|
|
|
|
|
|
|
|
import java.util.Locale
|
|
|
|
|
|
|
|
import jp.juggler.subwaytooter.table.MutedWord
|
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
|
|
|
import jp.juggler.subwaytooter.util.DecodeOptions
|
|
|
|
import jp.juggler.subwaytooter.util.LogCategory
|
2018-01-21 13:46:36 +01:00
|
|
|
import jp.juggler.subwaytooter.util.showToast
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
class ActText : AppCompatActivity(), View.OnClickListener {
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
|
|
|
internal val log = LogCategory("ActText")
|
|
|
|
|
|
|
|
internal const val RESULT_SEARCH_MSP = RESULT_FIRST_USER + 1
|
|
|
|
internal const val RESULT_SEARCH_TS = RESULT_FIRST_USER + 2
|
|
|
|
|
|
|
|
internal const val EXTRA_TEXT = "text"
|
|
|
|
internal const val EXTRA_CONTENT_START = "content_start"
|
|
|
|
internal const val EXTRA_CONTENT_END = "content_end"
|
|
|
|
|
|
|
|
private fun addAfterLine(sb : StringBuilder, text : String) {
|
|
|
|
if(sb.isNotEmpty() && sb[sb.length - 1] != '\n') {
|
|
|
|
sb.append('\n')
|
|
|
|
}
|
|
|
|
sb.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')
|
|
|
|
}
|
|
|
|
addAfterLine(sb, context.getString(key_str_id))
|
|
|
|
sb.append(": ")
|
|
|
|
sb.append(value?.toString() ?: "(null)")
|
|
|
|
}
|
|
|
|
|
|
|
|
private 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)
|
|
|
|
}
|
|
|
|
|
|
|
|
addAfterLine(sb, "\n")
|
|
|
|
|
|
|
|
intent.putExtra(EXTRA_CONTENT_START, sb.length)
|
2018-01-21 17:47:13 +01:00
|
|
|
sb.append(DecodeOptions(context, access_info).decodeHTML( status.content))
|
2018-01-04 19:52:25 +01:00
|
|
|
intent.putExtra(EXTRA_CONTENT_END, sb.length)
|
|
|
|
|
|
|
|
dumpAttachment(sb, status.media_attachments)
|
|
|
|
|
|
|
|
addAfterLine(sb, String.format(Locale.JAPAN, "Status-Source: %s", status.json))
|
|
|
|
|
|
|
|
addAfterLine(sb, "")
|
|
|
|
intent.putExtra(EXTRA_TEXT, sb.toString())
|
|
|
|
}
|
|
|
|
|
2018-01-10 16:47:35 +01:00
|
|
|
private fun dumpAttachment(sb : StringBuilder, src : ArrayList<TootAttachmentLike> ?) {
|
2018-01-04 19:52:25 +01:00
|
|
|
if(src == null) return
|
|
|
|
var i = 0
|
|
|
|
for(ma in src) {
|
|
|
|
++ i
|
|
|
|
if( ma is TootAttachment ) {
|
|
|
|
addAfterLine(sb, "\n")
|
|
|
|
addAfterLine(sb, String.format(Locale.JAPAN, "Media-%d-Url: %s", i, ma.url))
|
|
|
|
addAfterLine(sb, String.format(Locale.JAPAN, "Media-%d-Remote-Url: %s", i, ma.remote_url))
|
|
|
|
addAfterLine(sb, String.format(Locale.JAPAN, "Media-%d-Preview-Url: %s", i, ma.preview_url))
|
|
|
|
addAfterLine(sb, String.format(Locale.JAPAN, "Media-%d-Text-Url: %s", i, ma.text_url))
|
|
|
|
}else if( ma is TootAttachmentMSP){
|
|
|
|
addAfterLine(sb, "\n")
|
|
|
|
addAfterLine(sb, String.format(Locale.JAPAN, "Media-%d-Preview-Url: %s", i, ma.preview_url))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun encodeAccount(intent : Intent, context : Context, access_info : SavedAccount, who : TootAccount) {
|
|
|
|
val sb = StringBuilder()
|
|
|
|
|
|
|
|
intent.putExtra(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(EXTRA_CONTENT_START, sb.length)
|
|
|
|
sb.append(who.url)
|
|
|
|
intent.putExtra(EXTRA_CONTENT_END, sb.length)
|
|
|
|
|
|
|
|
addAfterLine(sb, "\n")
|
|
|
|
|
2018-01-21 17:47:13 +01:00
|
|
|
sb.append(DecodeOptions(context, access_info).decodeHTML( who.note))
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
addAfterLine(sb, "\n")
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
addAfterLine(sb, "")
|
|
|
|
intent.putExtra(EXTRA_TEXT, sb.toString())
|
|
|
|
}
|
|
|
|
|
|
|
|
fun open(activity : ActMain, request_code : Int, access_info : SavedAccount, status : TootStatus) {
|
|
|
|
val intent = Intent(activity, ActText::class.java)
|
|
|
|
encodeStatus(intent, activity, access_info, status)
|
|
|
|
|
|
|
|
activity.startActivityForResult(intent, request_code)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun open(activity : ActMain, request_code : Int, access_info : SavedAccount, who : TootAccount) {
|
|
|
|
val intent = Intent(activity, ActText::class.java)
|
|
|
|
encodeAccount(intent, activity, access_info, who)
|
|
|
|
|
|
|
|
activity.startActivityForResult(intent, request_code)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private lateinit var etText : EditText
|
|
|
|
|
|
|
|
private val selection : String
|
|
|
|
get() {
|
|
|
|
val s = etText.selectionStart
|
|
|
|
val e = etText.selectionEnd
|
|
|
|
val text = etText.text.toString()
|
|
|
|
return if(s == e) {
|
|
|
|
text
|
|
|
|
} else {
|
|
|
|
text.substring(s, e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreate(savedInstanceState : Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
App1.setActivityTheme(this, false)
|
|
|
|
initUI()
|
|
|
|
|
|
|
|
if(savedInstanceState == null) {
|
|
|
|
val intent = intent
|
|
|
|
val sv = intent.getStringExtra(EXTRA_TEXT)
|
|
|
|
val content_start = intent.getIntExtra(EXTRA_CONTENT_START, 0)
|
|
|
|
val content_end = intent.getIntExtra(EXTRA_CONTENT_END, sv.length)
|
|
|
|
etText.setText(sv)
|
|
|
|
etText.setSelection(content_start, content_end)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun initUI() {
|
|
|
|
setContentView(R.layout.act_text)
|
|
|
|
|
|
|
|
Styler.fixHorizontalMargin(findViewById(R.id.svFooterBar))
|
|
|
|
Styler.fixHorizontalMargin(findViewById(R.id.svContent))
|
|
|
|
|
|
|
|
etText = findViewById(R.id.etText)
|
|
|
|
|
|
|
|
findViewById<View>(R.id.btnCopy).setOnClickListener(this)
|
|
|
|
findViewById<View>(R.id.btnSearch).setOnClickListener(this)
|
|
|
|
findViewById<View>(R.id.btnSend).setOnClickListener(this)
|
|
|
|
findViewById<View>(R.id.btnMuteWord).setOnClickListener(this)
|
|
|
|
findViewById<View>(R.id.btnSearchMSP).setOnClickListener(this)
|
|
|
|
findViewById<View>(R.id.btnSearchTS).setOnClickListener(this)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onClick(v : View) {
|
|
|
|
when(v.id) {
|
|
|
|
|
|
|
|
R.id.btnCopy -> copy()
|
|
|
|
|
|
|
|
R.id.btnSearch -> search()
|
|
|
|
|
|
|
|
R.id.btnSend -> send()
|
|
|
|
|
|
|
|
R.id.btnMuteWord -> muteWord()
|
|
|
|
|
|
|
|
R.id.btnSearchMSP -> searchToot(RESULT_SEARCH_MSP)
|
|
|
|
|
|
|
|
R.id.btnSearchTS -> searchToot(RESULT_SEARCH_TS)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun copy() {
|
|
|
|
try {
|
|
|
|
// Gets a handle to the clipboard service.
|
2018-01-10 16:47:35 +01:00
|
|
|
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
|
2018-01-04 19:52:25 +01:00
|
|
|
?: throw NotImplementedError("missing ClipboardManager system service")
|
|
|
|
|
|
|
|
// Creates a new text clip to put on the clipboard
|
|
|
|
val clip = ClipData.newPlainText("text", selection)
|
|
|
|
|
|
|
|
// Set the clipboard's primary clip.
|
|
|
|
|
|
|
|
clipboard.primaryClip = clip
|
|
|
|
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, false, R.string.copy_complete)
|
2018-01-04 19:52:25 +01:00
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, ex, "copy failed.")
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun send() {
|
|
|
|
try {
|
|
|
|
|
|
|
|
val intent = Intent()
|
|
|
|
intent.action = Intent.ACTION_SEND
|
|
|
|
intent.type = "text/plain"
|
|
|
|
intent.putExtra(Intent.EXTRA_TEXT, selection)
|
|
|
|
startActivity(intent)
|
|
|
|
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, ex, "send failed.")
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun search() {
|
|
|
|
val sv = selection
|
2018-01-10 16:47:35 +01:00
|
|
|
if( sv.isEmpty() ) {
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, false, "please select search keyword")
|
2018-01-04 19:52:25 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
val intent = Intent(Intent.ACTION_WEB_SEARCH)
|
|
|
|
intent.putExtra(SearchManager.QUERY, sv)
|
|
|
|
if(intent.resolveActivity(packageManager) != null) {
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, ex, "search failed.")
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun searchToot(resultCode : Int) {
|
|
|
|
val sv = selection
|
2018-01-10 16:47:35 +01:00
|
|
|
if(sv.isEmpty() ) {
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, false, "please select search keyword")
|
2018-01-04 19:52:25 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
val data = Intent()
|
|
|
|
data.putExtra(Intent.EXTRA_TEXT, sv)
|
|
|
|
setResult(resultCode, data)
|
|
|
|
finish()
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun muteWord() {
|
|
|
|
try {
|
|
|
|
MutedWord.save(selection)
|
|
|
|
for(column in App1.getAppState(this).column_list) {
|
|
|
|
column.onMuteAppUpdated()
|
|
|
|
}
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, false, R.string.word_was_muted)
|
2018-01-04 19:52:25 +01:00
|
|
|
} catch(ex : Throwable) {
|
|
|
|
log.trace(ex)
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(this, ex, "muteWord failed.")
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|