mirror of
https://github.com/tateisu/SubwayTooter
synced 2025-02-05 21:23:26 +01:00
プロフカラムにfieldsの表を表示する
This commit is contained in:
parent
5a893d87a9
commit
7e2d94cc14
@ -459,11 +459,13 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
||||
internal fun getHttpCached(client : TootApiClient, url : String) : TootApiResult? {
|
||||
val result = TootApiResult.makeWithCaption(url)
|
||||
|
||||
val request = okhttp3.Request.Builder()
|
||||
.url(url)
|
||||
.cacheControl(App1.CACHE_5MIN)
|
||||
.build()
|
||||
|
||||
if(! client.sendRequest(result,cached = true) {
|
||||
okhttp3.Request.Builder()
|
||||
.url(url)
|
||||
.cacheControl(App1.CACHE_5MIN)
|
||||
.build()
|
||||
request
|
||||
}) return result
|
||||
|
||||
if(client.isApiCancelled) return null
|
||||
|
@ -104,21 +104,16 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
|
||||
internal val list_resize_max = intArrayOf(0, 640, 800, 1024, 1280, 1600, 2048)
|
||||
|
||||
internal val acceptable_mime_types : HashSet<String> by lazy {
|
||||
val v = HashSet<String>()
|
||||
|
||||
internal val acceptable_mime_types = HashSet<String>().apply {
|
||||
//
|
||||
v.add("image/*") // Android標準のギャラリーが image/* を出してくることがあるらしい
|
||||
v.add("video/*") // Android標準のギャラリーが image/* を出してくることがあるらしい
|
||||
add("image/*") // Android標準のギャラリーが image/* を出してくることがあるらしい
|
||||
add("video/*") // Android標準のギャラリーが image/* を出してくることがあるらしい
|
||||
//
|
||||
v.add("image/jpeg")
|
||||
v.add("image/png")
|
||||
v.add("image/gif")
|
||||
v.add("video/webm")
|
||||
v.add("video/mp4")
|
||||
|
||||
|
||||
v
|
||||
add("image/jpeg")
|
||||
add("image/png")
|
||||
add("image/gif")
|
||||
add("video/webm")
|
||||
add("video/mp4")
|
||||
}
|
||||
|
||||
// private void performCameraVideo(){
|
||||
|
@ -1,13 +1,15 @@
|
||||
package jp.juggler.subwaytooter
|
||||
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.ShapeDrawable
|
||||
import android.graphics.drawable.shapes.Shape
|
||||
import android.support.v4.view.ViewCompat
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.*
|
||||
import jp.juggler.emoji.EmojiMap201709
|
||||
|
||||
import jp.juggler.subwaytooter.action.Action_Follow
|
||||
@ -17,10 +19,13 @@ import jp.juggler.subwaytooter.api.entity.TootStatus
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
import jp.juggler.subwaytooter.util.NetworkEmojiInvalidator
|
||||
import jp.juggler.subwaytooter.util.intoStringResource
|
||||
import jp.juggler.subwaytooter.util.startMargin
|
||||
import jp.juggler.subwaytooter.view.MyLinkMovementMethod
|
||||
import jp.juggler.subwaytooter.view.MyNetworkImageView
|
||||
import jp.juggler.subwaytooter.view.MyTextView
|
||||
|
||||
internal class ViewHolderHeaderProfile(
|
||||
activity : ActMain,
|
||||
@ -42,6 +47,7 @@ internal class ViewHolderHeaderProfile(
|
||||
private val tvRemoteProfileWarning : TextView
|
||||
private val name_invalidator : NetworkEmojiInvalidator
|
||||
private val note_invalidator : NetworkEmojiInvalidator
|
||||
private val llFields : LinearLayout
|
||||
|
||||
private var who : TootAccount? = null
|
||||
|
||||
@ -56,6 +62,8 @@ internal class ViewHolderHeaderProfile(
|
||||
private val ivMovedBy : ImageView
|
||||
private val moved_caption_invalidator : NetworkEmojiInvalidator
|
||||
private val moved_name_invalidator : NetworkEmojiInvalidator
|
||||
private val default_color : Int
|
||||
private val density : Float
|
||||
|
||||
init {
|
||||
ivBackground = viewRoot.findViewById(R.id.ivBackground)
|
||||
@ -80,7 +88,10 @@ internal class ViewHolderHeaderProfile(
|
||||
tvMovedAcct = viewRoot.findViewById(R.id.tvMovedAcct)
|
||||
btnMoved = viewRoot.findViewById(R.id.btnMoved)
|
||||
ivMovedBy = viewRoot.findViewById(R.id.ivMovedBy)
|
||||
llFields = viewRoot.findViewById(R.id.llFields)
|
||||
|
||||
default_color = tvDisplayName.textColors.defaultColor
|
||||
density = tvDisplayName.resources.displayMetrics.density
|
||||
|
||||
ivBackground.setOnClickListener(this)
|
||||
btnFollowing.setOnClickListener(this)
|
||||
@ -136,6 +147,8 @@ internal class ViewHolderHeaderProfile(
|
||||
|
||||
llMoved.visibility = View.GONE
|
||||
tvMoved.visibility = View.GONE
|
||||
llFields.visibility = View.GONE
|
||||
llFields.removeAllViews()
|
||||
|
||||
if(who == null) {
|
||||
tvCreated.text = ""
|
||||
@ -209,6 +222,57 @@ internal class ViewHolderHeaderProfile(
|
||||
Styler.setFollowIcon(activity, btnFollow, ivFollowedBy, relation, who)
|
||||
|
||||
showMoved(who, who.moved)
|
||||
|
||||
if(who.fields != null) {
|
||||
|
||||
llFields.visibility = View.VISIBLE
|
||||
|
||||
val decodeOptions = DecodeOptions(
|
||||
context = activity,
|
||||
decodeEmoji = true,
|
||||
linkHelper = access_info,
|
||||
short = true
|
||||
)
|
||||
|
||||
val content_color = column.content_color
|
||||
val c = if(content_color != 0) content_color else default_color
|
||||
|
||||
val nameTypeface = activity.timeline_font_bold ?: Typeface.DEFAULT_BOLD
|
||||
val valueTypeface = activity.timeline_font ?: Typeface.DEFAULT
|
||||
|
||||
for(item in who.fields) {
|
||||
|
||||
//
|
||||
val nameView = MyTextView(activity)
|
||||
val nameLp = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
nameLp.topMargin = (density * 6f).toInt()
|
||||
nameView.layoutParams = nameLp
|
||||
nameView.text = decodeOptions.decodeEmoji(item.first)
|
||||
nameView.setTextColor(c)
|
||||
nameView.typeface = nameTypeface
|
||||
nameView.movementMethod = MyLinkMovementMethod
|
||||
llFields.addView(nameView)
|
||||
|
||||
//
|
||||
val valueView = MyTextView(activity)
|
||||
val valueLp = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
valueLp.startMargin = (density * 32f).toInt()
|
||||
valueView.layoutParams = valueLp
|
||||
valueView.text =
|
||||
decodeOptions.decodeHTML(item.second) // 値の方はHTML文字参照のエンコードが行われている
|
||||
valueView.setTextColor(c)
|
||||
valueView.typeface = valueTypeface
|
||||
valueView.movementMethod = MyLinkMovementMethod
|
||||
llFields.addView(valueView)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ class TootApiClient(
|
||||
)
|
||||
)
|
||||
|
||||
result.response = httpClient.getResponse(request,cached=cached)
|
||||
result.response = httpClient.getResponse(request, cached = cached)
|
||||
|
||||
null == result.error
|
||||
|
||||
|
@ -80,6 +80,8 @@ open class TootAccount(
|
||||
|
||||
val moved : TootAccount?
|
||||
|
||||
val fields : ArrayList<Pair<String, String>>?
|
||||
|
||||
init {
|
||||
var sv : String?
|
||||
|
||||
@ -110,6 +112,8 @@ open class TootAccount(
|
||||
src.optJSONObject("moved")?.let { TootAccount(parser, it) }
|
||||
this.locked = src.optBoolean("locked")
|
||||
|
||||
this.fields = parseFields(src.optJSONArray("fields"))
|
||||
|
||||
when(parser.serviceType) {
|
||||
ServiceType.MASTODON -> {
|
||||
|
||||
@ -265,5 +269,21 @@ open class TootAccount(
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun parseFields(src : JSONArray?) : ArrayList<Pair<String, String>>? {
|
||||
src ?: return null
|
||||
val dst = ArrayList<Pair<String, String>>()
|
||||
for(i in 0 until src.length()) {
|
||||
val item = src.optJSONObject(i) ?: continue
|
||||
val k = item.parseString("name") ?: continue
|
||||
val v = item.parseString("value") ?: continue
|
||||
dst.add(Pair(k, v))
|
||||
}
|
||||
return if( dst.isEmpty() ){
|
||||
null
|
||||
}else{
|
||||
dst
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import jp.juggler.subwaytooter.table.HighlightWord
|
||||
import java.util.HashMap
|
||||
|
||||
class DecodeOptions(
|
||||
val context: Context? = null,
|
||||
val context : Context? = null,
|
||||
var linkHelper : LinkHelper? = null,
|
||||
var short : Boolean = false,
|
||||
var decodeEmoji : Boolean = false,
|
||||
@ -22,7 +22,7 @@ class DecodeOptions(
|
||||
var highlightTrie : WordTrieTree? = null
|
||||
) {
|
||||
|
||||
internal fun isMediaAttachment( url : String? ) : Boolean {
|
||||
internal fun isMediaAttachment(url : String?) : Boolean {
|
||||
val list_attachment = attachmentList
|
||||
if(url == null || list_attachment == null) return false
|
||||
for(a in list_attachment) {
|
||||
@ -30,7 +30,6 @@ class DecodeOptions(
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// OUTPUT: true if found highlight
|
||||
var hasHighlight : Boolean = false
|
||||
@ -41,15 +40,12 @@ class DecodeOptions(
|
||||
////////////////////////
|
||||
// decoder
|
||||
|
||||
fun decodeHTML( html : String?) : SpannableStringBuilder {
|
||||
return HTMLDecoder.decodeHTML(this,html)
|
||||
fun decodeHTML(html : String?) : SpannableStringBuilder {
|
||||
return HTMLDecoder.decodeHTML(this, html)
|
||||
}
|
||||
|
||||
fun decodeEmoji( s : String?) : Spannable {
|
||||
return EmojiDecoder.decodeEmoji( this,s ?: "")
|
||||
fun decodeEmoji(s : String?) : Spannable {
|
||||
return EmojiDecoder.decodeEmoji(this, s ?: "")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ object EmojiDecoder {
|
||||
// }
|
||||
|
||||
private const val cpColon = ':'.toInt()
|
||||
|
||||
|
||||
fun canStartShortCode(s : CharSequence, index : Int) : Boolean {
|
||||
val cp = s.codePointBefore(index)
|
||||
return when(cp) {
|
||||
@ -114,19 +114,21 @@ object EmojiDecoder {
|
||||
}
|
||||
|
||||
internal fun addImageSpan(text : String?, @DrawableRes res_id : Int) {
|
||||
closeNormalText()
|
||||
val start = sb.length
|
||||
sb.append(text)
|
||||
val end = sb.length
|
||||
sb.setSpan(
|
||||
EmojiImageSpan(
|
||||
requireNotNull(options.context) { "decodeEmoji: missing context" },
|
||||
res_id
|
||||
),
|
||||
start,
|
||||
end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
val context = options.context
|
||||
if(context == null) {
|
||||
addUnicodeString("(missing context)")
|
||||
} else {
|
||||
closeNormalText()
|
||||
val start = sb.length
|
||||
sb.append(text)
|
||||
val end = sb.length
|
||||
sb.setSpan(
|
||||
EmojiImageSpan(context, res_id),
|
||||
start,
|
||||
end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun addUnicodeString(s : String) {
|
||||
@ -171,12 +173,14 @@ object EmojiDecoder {
|
||||
openNormalText()
|
||||
val length = Character.charCount(s.codePointAt(i))
|
||||
if(length == 1) {
|
||||
val c = s[i++]
|
||||
sb.append(when(c) {
|
||||
val c = s[i ++]
|
||||
sb.append(
|
||||
when(c) {
|
||||
// https://github.com/tateisu/SubwayTooter/issues/69
|
||||
'\u00AD' -> '-'
|
||||
else -> c
|
||||
})
|
||||
'\u00AD' -> '-'
|
||||
else -> c
|
||||
}
|
||||
)
|
||||
} else {
|
||||
sb.append(s.substring(i, i + length))
|
||||
i += length
|
||||
|
@ -164,6 +164,13 @@
|
||||
tools:text="説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 説明文 "
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/llFields"
|
||||
android:orientation="vertical"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
|
Loading…
x
Reference in New Issue
Block a user