- (Misskey)返信のかわりに引用Renoteを作成できる(タンス側のバグがなければ)。
- (Misskey)返信と引用Renoteの際に元投稿をプレビューカードとして表示する。 - プレビューカードの表示にボーダー枠を追加。
This commit is contained in:
parent
0a7d2c68bd
commit
25cd2e201b
@ -200,7 +200,7 @@ class ActMain : AppCompatActivity()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private val link_click_listener : MyClickableSpanClickCallback = { viewClicked, span ->
|
||||
internal val link_click_listener : MyClickableSpanClickCallback = { viewClicked, span ->
|
||||
|
||||
var view = viewClicked
|
||||
var column : Column? = null
|
||||
@ -353,8 +353,8 @@ class ActMain : AppCompatActivity()
|
||||
// (カラム一覧画面のデフォルト選択位置に使われる)
|
||||
val currentColumn : Int
|
||||
get() = phoneTab(
|
||||
{ pe -> pe.pager.currentItem },
|
||||
{ _ -> - 1 }
|
||||
{ it.pager.currentItem },
|
||||
{ - 1 }
|
||||
)
|
||||
|
||||
// 新しいカラムをどこに挿入するか
|
||||
@ -369,8 +369,8 @@ class ActMain : AppCompatActivity()
|
||||
// 新しいカラムをどこに挿入するか
|
||||
private val defaultInsertPosition : Int
|
||||
get() = phoneTab(
|
||||
{ pe -> pe.pager.currentItem + 1 },
|
||||
{ _ -> Integer.MAX_VALUE }
|
||||
{ it.pager.currentItem + 1 },
|
||||
{ Integer.MAX_VALUE }
|
||||
)
|
||||
|
||||
private fun validateFloat(fv : Float) : Float {
|
||||
@ -684,7 +684,7 @@ class ActMain : AppCompatActivity()
|
||||
message = getString(R.string.account_picker_toot)
|
||||
) { ai -> performQuickPost(ai) }
|
||||
}
|
||||
}, { _ ->
|
||||
}, {
|
||||
// アカウント選択してやり直し
|
||||
AccountPicker.pick(
|
||||
this,
|
||||
@ -702,7 +702,8 @@ class ActMain : AppCompatActivity()
|
||||
post_helper.bNSFW = false
|
||||
post_helper.in_reply_to_id = null
|
||||
post_helper.attachment_list = null
|
||||
post_helper.emojiMapCustom = App1.custom_emoji_lister.getMap(account.host,account.isMisskey)
|
||||
post_helper.emojiMapCustom =
|
||||
App1.custom_emoji_lister.getMap(account.host, account.isMisskey)
|
||||
|
||||
|
||||
etQuickToot.hideKeyboard()
|
||||
@ -1324,7 +1325,6 @@ class ActMain : AppCompatActivity()
|
||||
env.tablet_pager.layoutManager = env.tablet_layout_manager
|
||||
env.tablet_pager.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
|
||||
|
||||
override fun onScrollStateChanged(recyclerView : RecyclerView, newState : Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
|
||||
@ -2031,7 +2031,7 @@ class ActMain : AppCompatActivity()
|
||||
}
|
||||
}
|
||||
|
||||
}, { _ ->
|
||||
}, {
|
||||
removeColumn(column)
|
||||
|
||||
if(! app_state.column_list.isEmpty() && page_delete > 0) {
|
||||
@ -2061,8 +2061,8 @@ class ActMain : AppCompatActivity()
|
||||
|
||||
var lastColumnIndex = when(_lastColumnIndex) {
|
||||
- 1 -> phoneTab(
|
||||
{ pe -> pe.pager.currentItem },
|
||||
{ _ -> 0 }
|
||||
{ it.pager.currentItem },
|
||||
{ 0 }
|
||||
)
|
||||
else -> _lastColumnIndex
|
||||
}
|
||||
@ -2774,7 +2774,6 @@ class ActMain : AppCompatActivity()
|
||||
// 既に表示中かもしれない
|
||||
if(dlgPrivacyPolicy?.get()?.isShowing == true) return
|
||||
|
||||
|
||||
val res_id = when(getString(R.string.language_code)) {
|
||||
"ja" -> R.raw.privacy_policy_ja
|
||||
"fr" -> R.raw.privacy_policy_fr
|
||||
@ -2795,7 +2794,7 @@ class ActMain : AppCompatActivity()
|
||||
.setNegativeButton(R.string.cancel) { _, _ ->
|
||||
finish()
|
||||
}
|
||||
.setOnCancelListener{_->
|
||||
.setOnCancelListener {
|
||||
finish()
|
||||
}
|
||||
.setPositiveButton(R.string.agree) { _, _ ->
|
||||
@ -2806,6 +2805,4 @@ class ActMain : AppCompatActivity()
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
internal const val DRAFT_REPLY_URL = "reply_url"
|
||||
internal const val DRAFT_IS_ENQUETE = "is_enquete"
|
||||
internal const val DRAFT_ENQUETE_ITEMS = "enquete_items"
|
||||
internal const val DRAFT_QUOTED_RENOTE = "quotedRenote"
|
||||
|
||||
private const val STATE_MUSHROOM_INPUT = "mushroom_input"
|
||||
private const val STATE_MUSHROOM_START = "mushroom_start"
|
||||
@ -223,6 +224,8 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
internal lateinit var etContentWarning : MyEditText
|
||||
internal lateinit var etContent : MyEditText
|
||||
|
||||
internal lateinit var cbQuoteRenote : CheckBox
|
||||
|
||||
internal lateinit var cbEnquete : CheckBox
|
||||
private lateinit var llEnquete : View
|
||||
internal lateinit var list_etChoice : List<MyEditText>
|
||||
@ -703,14 +706,17 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
selectAccount(null)
|
||||
}
|
||||
|
||||
|
||||
updateContentWarning()
|
||||
showMediaAttachment()
|
||||
showVisibility()
|
||||
updateTextCount()
|
||||
showReplyTo()
|
||||
showEnquete()
|
||||
showQuotedRenote()
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
post_helper.onDestroy()
|
||||
|
||||
@ -765,6 +771,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
updateTextCount()
|
||||
showReplyTo()
|
||||
showEnquete()
|
||||
showQuotedRenote()
|
||||
}
|
||||
|
||||
private fun appendContentText(
|
||||
@ -853,6 +860,8 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
etContentWarning = findViewById(R.id.etContentWarning)
|
||||
etContent = findViewById(R.id.etContent)
|
||||
|
||||
cbQuoteRenote= findViewById(R.id.cbQuoteRenote)
|
||||
|
||||
cbEnquete = findViewById(R.id.cbEnquete)
|
||||
llEnquete = findViewById(R.id.llEnquete)
|
||||
|
||||
@ -1128,6 +1137,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
log.trace(ex)
|
||||
}
|
||||
showVisibility()
|
||||
showQuotedRenote()
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
@ -1974,6 +1984,8 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
|
||||
post_helper.redraft_status_id = redraft_status_id
|
||||
|
||||
post_helper.useQuotedRenote = cbQuoteRenote.isChecked
|
||||
|
||||
post_helper.post(account) { target_account, status ->
|
||||
val data = Intent()
|
||||
data.putExtra(EXTRA_POSTED_ACCT, target_account.acct)
|
||||
@ -1986,6 +1998,12 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
}
|
||||
}
|
||||
|
||||
private fun showQuotedRenote() {
|
||||
val isReply = in_reply_to_id != null
|
||||
val isMisskey = account?.isMisskey == true
|
||||
cbQuoteRenote.visibility = if( isReply && isMisskey ) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
internal fun showReplyTo() {
|
||||
if(in_reply_to_id == null) {
|
||||
llReply.visibility = View.GONE
|
||||
@ -2008,6 +2026,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
in_reply_to_image = null
|
||||
in_reply_to_url = null
|
||||
showReplyTo()
|
||||
showQuotedRenote()
|
||||
}
|
||||
|
||||
private fun saveDraft() {
|
||||
@ -2054,7 +2073,9 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
json.put(DRAFT_REPLY_IMAGE, in_reply_to_image)
|
||||
json.put(DRAFT_REPLY_URL, in_reply_to_url)
|
||||
|
||||
json.put(DRAFT_QUOTED_RENOTE,cbQuoteRenote.isChecked)
|
||||
json.put(DRAFT_IS_ENQUETE, isEnquete)
|
||||
|
||||
val array = JSONArray()
|
||||
for(s in str_choice) {
|
||||
array.put(s)
|
||||
@ -2206,6 +2227,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
val draft_visibility = TootVisibility
|
||||
.parseSavedVisibility(draft.parseString(DRAFT_VISIBILITY))
|
||||
|
||||
|
||||
val evEmoji = DecodeOptions(this@ActPost, decodeEmoji = true).decodeEmoji(content)
|
||||
etContent.setText(evEmoji)
|
||||
etContent.setSelection(evEmoji.length)
|
||||
@ -2215,6 +2237,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
cbNSFW.isChecked = nsfw_checked
|
||||
if(draft_visibility != null) this@ActPost.visibility = draft_visibility
|
||||
|
||||
cbQuoteRenote.isChecked = draft.optBoolean(DRAFT_QUOTED_RENOTE)
|
||||
cbEnquete.isChecked = draft.optBoolean(DRAFT_IS_ENQUETE, false)
|
||||
val array = draft.optJSONArray(DRAFT_ENQUETE_ITEMS)
|
||||
if(array != null) {
|
||||
@ -2255,12 +2278,14 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
in_reply_to_url = reply_url
|
||||
}
|
||||
|
||||
|
||||
updateContentWarning()
|
||||
showMediaAttachment()
|
||||
showVisibility()
|
||||
updateTextCount()
|
||||
showReplyTo()
|
||||
showEnquete()
|
||||
showQuotedRenote()
|
||||
|
||||
if(! list_warning.isEmpty()) {
|
||||
val sb = StringBuilder()
|
||||
|
@ -26,6 +26,7 @@ import jp.juggler.subwaytooter.api.TootTaskRunner
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
import jp.juggler.subwaytooter.dialog.ActionsDialog
|
||||
import jp.juggler.subwaytooter.dialog.DlgConfirm
|
||||
import jp.juggler.subwaytooter.drawable.PreviewCardBorder
|
||||
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
||||
import jp.juggler.subwaytooter.span.MyClickableSpan
|
||||
import jp.juggler.subwaytooter.table.*
|
||||
@ -120,12 +121,13 @@ internal class ItemViewHolder(
|
||||
private lateinit var tvFilterDetail : TextView
|
||||
|
||||
private lateinit var tvMediaDescription : TextView
|
||||
|
||||
private lateinit var llCardOuter : View
|
||||
private lateinit var tvCardText : TextView
|
||||
private lateinit var ivCardImage : MyNetworkImageView
|
||||
|
||||
private lateinit var llExtra : LinearLayout
|
||||
|
||||
|
||||
private lateinit var llConversationIcons : View
|
||||
private lateinit var ivConversationIcon1 : MyNetworkImageView
|
||||
private lateinit var ivConversationIcon2 : MyNetworkImageView
|
||||
@ -134,8 +136,6 @@ internal class ItemViewHolder(
|
||||
private lateinit var tvConversationIconsMore : TextView
|
||||
private lateinit var tvConversationParticipants : TextView
|
||||
|
||||
|
||||
|
||||
private lateinit var tvApplication : TextView
|
||||
|
||||
private lateinit var tvMessageHolder : TextView
|
||||
@ -181,7 +181,8 @@ internal class ItemViewHolder(
|
||||
btnFollow.setOnClickListener(this)
|
||||
btnFollow.setOnLongClickListener(this)
|
||||
|
||||
ivCardImage.setOnClickListener(this)
|
||||
llCardOuter.setOnClickListener(this)
|
||||
llCardOuter.setOnLongClickListener(this)
|
||||
|
||||
ivThumbnail.setOnClickListener(this)
|
||||
|
||||
@ -263,6 +264,13 @@ internal class ItemViewHolder(
|
||||
this.reply_invalidator = NetworkEmojiInvalidator(activity.handler, tvReply)
|
||||
this.follow_invalidator = NetworkEmojiInvalidator(activity.handler, tvFollowerName)
|
||||
this.name_invalidator = NetworkEmojiInvalidator(activity.handler, tvName)
|
||||
|
||||
val cardBackground = llCardOuter.background
|
||||
if(cardBackground is PreviewCardBorder) {
|
||||
val density = activity.density
|
||||
cardBackground.round = (density * 8f)
|
||||
cardBackground.width = (density * 1f)
|
||||
}
|
||||
}
|
||||
|
||||
fun onViewRecycled() {
|
||||
@ -375,6 +383,7 @@ internal class ItemViewHolder(
|
||||
llTrendTag.visibility = View.GONE
|
||||
llFilter.visibility = View.GONE
|
||||
tvMediaDescription.visibility = View.GONE
|
||||
llCardOuter.visibility = View.GONE
|
||||
tvCardText.visibility = View.GONE
|
||||
ivCardImage.visibility = View.GONE
|
||||
llConversationIcons.visibility = View.GONE
|
||||
@ -402,6 +411,12 @@ internal class ItemViewHolder(
|
||||
tvConversationIconsMore.setTextColor(c)
|
||||
tvConversationParticipants.setTextColor(c)
|
||||
|
||||
val cardBackground = llCardOuter.background
|
||||
if(cardBackground is PreviewCardBorder) {
|
||||
cardBackground.color = c
|
||||
}
|
||||
|
||||
|
||||
c = if(column.acct_color != 0) column.acct_color else Styler.getAttributeColor(
|
||||
activity,
|
||||
R.attr.colorTimeSmall
|
||||
@ -484,12 +499,10 @@ internal class ItemViewHolder(
|
||||
}
|
||||
extra_invalidator_list.clear()
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun showConversationIcons(cs : TootConversationSummary) {
|
||||
|
||||
val accounts = cs.accounts
|
||||
val last_account_id = cs.last_status.account.id
|
||||
|
||||
val accountsOther = cs.accounts.filter { it.get().id != last_account_id }
|
||||
@ -958,10 +971,7 @@ internal class ItemViewHolder(
|
||||
}
|
||||
|
||||
// カードの表示(会話ビューのみ)
|
||||
val card = status.card
|
||||
if(card != null) {
|
||||
showPreviewCard(activity, card)
|
||||
}
|
||||
showPreviewCard(activity, status)
|
||||
|
||||
// if( status.decoded_tags == null ){
|
||||
// tvTags.setVisibility( View.GONE );
|
||||
@ -1328,7 +1338,8 @@ internal class ItemViewHolder(
|
||||
|
||||
if(ta.description?.isNotEmpty() == true) {
|
||||
if(sbDesc.isNotEmpty()) sbDesc.append("\n")
|
||||
val desc = activity.getString(R.string.media_description, idx + 1, ta.description)
|
||||
val desc =
|
||||
activity.getString(R.string.media_description, idx + 1, ta.description)
|
||||
sbDesc.append(desc)
|
||||
}
|
||||
}
|
||||
@ -1353,8 +1364,6 @@ internal class ItemViewHolder(
|
||||
}
|
||||
private var boostedAction : () -> Unit = defaultBoostedAction
|
||||
|
||||
|
||||
|
||||
override fun onClick(v : View) {
|
||||
|
||||
val pos = activity.nextPosition(column)
|
||||
@ -1516,8 +1525,26 @@ internal class ItemViewHolder(
|
||||
openFilterMenu(item)
|
||||
}
|
||||
|
||||
ivCardImage-> status_showing?.card?.url?.let { url ->
|
||||
if(url.isNotEmpty()) App1.openCustomTab(activity, url)
|
||||
llCardOuter -> status_showing?.card?.let { card ->
|
||||
val originalStatus = card.originalStatus
|
||||
if(originalStatus != null) {
|
||||
Action_Toot.conversation(
|
||||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
originalStatus
|
||||
)
|
||||
} else {
|
||||
val url = card.url
|
||||
if(url?.isNotEmpty() == true) {
|
||||
ChromeTabOpener(
|
||||
activity,
|
||||
pos,
|
||||
url,
|
||||
accessInfo = access_info
|
||||
).open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llConversationIcons -> openConversationSummary()
|
||||
@ -1593,6 +1620,12 @@ internal class ItemViewHolder(
|
||||
return true
|
||||
}
|
||||
|
||||
llCardOuter -> Action_Toot.conversationOtherInstance(
|
||||
activity,
|
||||
activity.nextPosition(column),
|
||||
status_showing?.card?.originalStatus
|
||||
)
|
||||
|
||||
btnSearchTag, llTrendTag -> {
|
||||
val item = this.item
|
||||
when(item) {
|
||||
@ -1666,15 +1699,35 @@ internal class ItemViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
private fun showPreviewCard(activity : ActMain, card : TootCard) {
|
||||
private fun showPreviewCard(activity : ActMain, status : TootStatus) {
|
||||
val card = status.card ?: return
|
||||
|
||||
// 会話カラムで返信ステータスなら捏造したカードを表示しない
|
||||
if(column.column_type == Column.TYPE_CONVERSATION
|
||||
&& card.originalStatus != null
|
||||
&& status.reply != null
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
llCardOuter.visibility = View.VISIBLE
|
||||
|
||||
val sb = StringBuilder()
|
||||
addLinkAndCaption(sb, activity.getString(R.string.card_header_card), card.url, card.title)
|
||||
|
||||
addLinkAndCaption(
|
||||
sb,
|
||||
activity.getString(R.string.card_header_card),
|
||||
card.url,
|
||||
card.title
|
||||
)
|
||||
|
||||
addLinkAndCaption(
|
||||
sb,
|
||||
activity.getString(R.string.card_header_author),
|
||||
card.author_url,
|
||||
card.author_name
|
||||
)
|
||||
|
||||
addLinkAndCaption(
|
||||
sb,
|
||||
activity.getString(R.string.card_header_provider),
|
||||
@ -1688,11 +1741,19 @@ internal class ItemViewHolder(
|
||||
|
||||
val limit = Pref.spCardDescriptionLength.toInt(activity.pref)
|
||||
|
||||
sb.append(HTMLDecoder.encodeEntity(ellipsize(description,if( limit <= 0 ) 64 else limit)))
|
||||
sb.append(
|
||||
HTMLDecoder.encodeEntity(
|
||||
ellipsize(
|
||||
description,
|
||||
if(limit <= 0) 64 else limit
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if(sb.isNotEmpty()) {
|
||||
val text = DecodeOptions(activity, access_info).decodeHTML(sb.toString())
|
||||
val text =
|
||||
DecodeOptions(activity, access_info, forceHtml = true).decodeHTML(sb.toString())
|
||||
if(text.isNotEmpty()) {
|
||||
tvCardText.visibility = View.VISIBLE
|
||||
tvCardText.text = text
|
||||
@ -2028,7 +2089,6 @@ internal class ItemViewHolder(
|
||||
list_adapter.notifyChange(reason = "onClickEnqueteChoice", reset = true)
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
val message = data.parseString("message") ?: "?"
|
||||
val valid = data.optBoolean("valid")
|
||||
@ -2501,10 +2561,19 @@ internal class ItemViewHolder(
|
||||
|
||||
tvMediaDescription = textView {}.lparams(matchParent, wrapContent)
|
||||
|
||||
tvCardText = textView{
|
||||
|
||||
}.lparams(matchParent, wrapContent){
|
||||
llCardOuter = verticalLayout {
|
||||
lparams(matchParent, wrapContent) {
|
||||
topMargin = dip(3)
|
||||
startMargin = dip(12)
|
||||
endMargin = dip(6)
|
||||
}
|
||||
padding = dip(3)
|
||||
bottomPadding = dip(6)
|
||||
|
||||
background = PreviewCardBorder()
|
||||
|
||||
tvCardText = textView {
|
||||
}.lparams(matchParent, wrapContent) {
|
||||
}
|
||||
|
||||
ivCardImage = myNetworkImageView {
|
||||
@ -2519,6 +2588,7 @@ internal class ItemViewHolder(
|
||||
}.lparams(matchParent, activity.app_state.media_thumb_height) {
|
||||
topMargin = dip(3)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
llExtra = verticalLayout {
|
||||
@ -2526,7 +2596,6 @@ internal class ItemViewHolder(
|
||||
topMargin = dip(0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// button bar
|
||||
|
@ -179,7 +179,7 @@ internal class ViewHolderHeaderProfile(
|
||||
btnFollow.setImageDrawable(null)
|
||||
tvRemoteProfileWarning.visibility = View.GONE
|
||||
} else {
|
||||
tvCreated.text = TootStatus.formatTime(tvCreated.context, who.time_created_at, true)
|
||||
tvCreated.text = TootStatus.formatTime(tvCreated.context, (whoDetail?:who).time_created_at, true)
|
||||
ivBackground.setImageUrl(
|
||||
activity.pref,
|
||||
0f,
|
||||
|
@ -181,7 +181,6 @@ object Action_Follow {
|
||||
override fun background(client : TootApiClient) : TootApiResult? {
|
||||
var result : TootApiResult?
|
||||
|
||||
val parser = TootParser(activity, access_info)
|
||||
|
||||
if(access_info.isMisskey) {
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
import jp.juggler.subwaytooter.api.TootParser
|
||||
import jp.juggler.subwaytooter.util.HTMLDecoder
|
||||
import jp.juggler.subwaytooter.util.filterNotEmpty
|
||||
import jp.juggler.subwaytooter.util.parseString
|
||||
import org.json.JSONObject
|
||||
|
||||
class TootCard(
|
||||
|
||||
@ -19,10 +21,12 @@ class TootCard(
|
||||
val image : String?,
|
||||
|
||||
val type : String?,
|
||||
val author_name : String?,
|
||||
val author_url : String?,
|
||||
val provider_name : String?,
|
||||
val provider_url : String?
|
||||
val author_name : String? =null,
|
||||
val author_url : String? =null,
|
||||
val provider_name : String? =null,
|
||||
val provider_url : String? =null,
|
||||
|
||||
val originalStatus :TootStatus? =null
|
||||
) {
|
||||
|
||||
constructor(src : JSONObject) : this(
|
||||
@ -38,4 +42,17 @@ class TootCard(
|
||||
provider_url = src.parseString("provider_url")
|
||||
|
||||
)
|
||||
|
||||
constructor(parser: TootParser, src:TootStatus) :this(
|
||||
originalStatus = src,
|
||||
url = src.url,
|
||||
title = "${src.account.display_name} @${parser.linkHelper .getFullAcct(src.account.acct)}",
|
||||
description = if( parser.serviceType==ServiceType.MISSKEY){
|
||||
src.spoiler_text.filterNotEmpty() ?: src.content
|
||||
}else{
|
||||
src.spoiler_text.filterNotEmpty() ?: HTMLDecoder.encodeEntity( src.content ?: "")
|
||||
},
|
||||
image = src.media_attachments ?. firstOrNull() ?. urlForThumbnail ?: src.account.avatar_static,
|
||||
type = "photo"
|
||||
)
|
||||
}
|
||||
|
@ -312,6 +312,18 @@ class TootStatus(parser : TootParser, src : JSONObject) : TimelineItem() {
|
||||
|
||||
this.deletedAt = src.parseString("deletedAt")
|
||||
this.time_deleted_at = parseTime(deletedAt)
|
||||
|
||||
if( card == null) {
|
||||
|
||||
if(reblog != null && hasAnyContent() ) {
|
||||
// 引用Renoteにプレビューカードをでっちあげる
|
||||
card = TootCard(parser, reblog)
|
||||
} else if(reply != null ) {
|
||||
// 返信にプレビューカードをでっちあげる
|
||||
card = TootCard(parser, reply!! )
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
misskeyVisibleIds = null
|
||||
reply = null
|
||||
|
@ -0,0 +1,39 @@
|
||||
package jp.juggler.subwaytooter.drawable
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.ColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.drawable.Drawable
|
||||
|
||||
class PreviewCardBorder : Drawable() {
|
||||
|
||||
var color = 0
|
||||
var round = 0f
|
||||
var width = 1f
|
||||
|
||||
private val paint = Paint()
|
||||
|
||||
override fun draw(canvas : Canvas) {
|
||||
paint.isAntiAlias = true
|
||||
paint.color = color
|
||||
paint.style = Paint.Style.STROKE
|
||||
paint.strokeWidth = width
|
||||
|
||||
val bounds = this.bounds
|
||||
val left = bounds.left + width/2
|
||||
val right = bounds.right -width/2
|
||||
val top = bounds.top + width/2
|
||||
val bottom = bounds.bottom -width/2
|
||||
|
||||
canvas.drawRoundRect( left,top,right,bottom,round,round,paint )
|
||||
}
|
||||
|
||||
override fun getOpacity() : Int = PixelFormat.TRANSLUCENT
|
||||
|
||||
override fun setAlpha(alpha : Int) =Unit
|
||||
|
||||
override fun setColorFilter(colorFilter : ColorFilter?) =Unit
|
||||
|
||||
|
||||
}
|
@ -21,7 +21,8 @@ class DecodeOptions(
|
||||
var emojiMapProfile : HashMap<String, NicoProfileEmoji>? = null,
|
||||
var highlightTrie : WordTrieTree? = null,
|
||||
var unwrapEmojiImageTag :Boolean = false,
|
||||
var enlargeCustomEmoji :Float = 1f
|
||||
var enlargeCustomEmoji :Float = 1f,
|
||||
var forceHtml : Boolean = false // force use HTML instead of Misskey Markdown
|
||||
) {
|
||||
|
||||
internal fun isMediaAttachment(url : String?) : Boolean {
|
||||
|
@ -468,7 +468,7 @@ object HTMLDecoder {
|
||||
|
||||
fun decodeHTML(options : DecodeOptions, src : String?) : SpannableStringBuilder {
|
||||
|
||||
if( options.linkHelper?.isMisskey == true){
|
||||
if( options.linkHelper?.isMisskey == true && !options.forceHtml ){
|
||||
return MisskeyMarkdownDecoder.decodeMarkdown(options,src)
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ class PostHelper(
|
||||
var enquete_items : ArrayList<String>? = null
|
||||
var emojiMapCustom : HashMap<String, CustomEmoji>? = null
|
||||
var redraft_status_id : EntityId? = null
|
||||
var useQuotedRenote : Boolean = false
|
||||
|
||||
private var last_post_tapped : Long = 0L
|
||||
|
||||
@ -358,8 +359,12 @@ class PostHelper(
|
||||
}
|
||||
|
||||
if(in_reply_to_id != null) {
|
||||
if( useQuotedRenote){
|
||||
json.put("renoteId", in_reply_to_id.toString())
|
||||
}else{
|
||||
json.put("replyId", in_reply_to_id.toString())
|
||||
}
|
||||
}
|
||||
|
||||
json.put("viaMobile", true)
|
||||
|
||||
@ -470,8 +475,9 @@ class PostHelper(
|
||||
}
|
||||
|
||||
result = if(isMisskey) {
|
||||
log.d("misskey json %s",body_string)
|
||||
|
||||
client.request("/api/notes/create", request_builder)
|
||||
// TODO {"error":{}} が返ってきた時にどう扱えばいい?
|
||||
} else {
|
||||
client.request("/api/v1/statuses", request_builder)
|
||||
}
|
||||
@ -549,7 +555,7 @@ class PostHelper(
|
||||
private var isMisskey = false
|
||||
|
||||
private val onEmojiListLoad : (list : ArrayList<CustomEmoji>) -> Unit =
|
||||
{ _ : ArrayList<CustomEmoji> ->
|
||||
{
|
||||
val popup = this@PostHelper.popup
|
||||
if(popup?.isShowing == true) proc_text_changed.run()
|
||||
}
|
||||
@ -740,9 +746,9 @@ class PostHelper(
|
||||
val remain = limit - code_list.size
|
||||
if(remain > 0) {
|
||||
val s = src.substring(last_colon + 1, end).toLowerCase().replace('-', '_')
|
||||
val src = EmojiDecoder.searchShortCode(activity, s, remain)
|
||||
log.d("checkEmoji: search for %s, result=%d", s, src.size)
|
||||
code_list.addAll(src)
|
||||
val matches = EmojiDecoder.searchShortCode(activity, s, remain)
|
||||
log.d("checkEmoji: search for %s, result=%d", s, matches.size)
|
||||
code_list.addAll(matches)
|
||||
|
||||
}
|
||||
|
||||
|
@ -488,6 +488,12 @@ fun String?.optInt() : Int? {
|
||||
}
|
||||
}
|
||||
|
||||
fun String?.filterNotEmpty() :String? = when{
|
||||
this==null -> null
|
||||
this.isEmpty() -> null
|
||||
else->this
|
||||
}
|
||||
|
||||
//fun String.ellipsize(max : Int) = if(this.length > max) this.substring(0, max - 1) + "…" else this
|
||||
//
|
||||
//fun String.toCamelCase() : String {
|
||||
|
@ -83,6 +83,14 @@
|
||||
android:src="?attr/btn_close"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbQuoteRenote"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/make_quote_renote"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -217,6 +225,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPostFormBackground"
|
||||
android:layout_marginBottom="32dp"
|
||||
>
|
||||
|
||||
<jp.juggler.subwaytooter.view.MyEditText
|
||||
@ -231,11 +240,12 @@
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbEnquete"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="@string/make_enquete"
|
||||
/>
|
||||
|
||||
|
@ -784,5 +784,6 @@
|
||||
<string name="participants">会話の参加者:</string>
|
||||
<string name="participants_and_more">…他</string>
|
||||
<string name="conversation_to">送り先:</string>
|
||||
<string name="make_quote_renote">引用Renoteにする</string>
|
||||
|
||||
</resources>
|
||||
|
@ -803,5 +803,6 @@
|
||||
<string name="participants">Conversation participants:</string>
|
||||
<string name="participants_and_more">… and more</string>
|
||||
<string name="conversation_to">To:</string>
|
||||
<string name="make_quote_renote">Use \"Quoted Renote\"</string>
|
||||
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user