内蔵メディアビューアはリモートURLでダメなら自タンスのURLを試す。TL中項目のビューをXMLからAnko Layoutに変更。
@ -11,8 +11,10 @@ android {
|
|||||||
applicationId "jp.juggler.subwaytooter"
|
applicationId "jp.juggler.subwaytooter"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 201
|
|
||||||
versionName "2.0.1"
|
versionCode 202
|
||||||
|
versionName "2.0.2"
|
||||||
|
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/47791227/java-lang-illegalstateexception-dex-archives-setting-dex-extension-only-for
|
// https://stackoverflow.com/questions/47791227/java-lang-illegalstateexception-dex-archives-setting-dex-extension-only-for
|
||||||
@ -105,6 +107,15 @@ dependencies {
|
|||||||
|
|
||||||
|
|
||||||
implementation 'com.google.android.exoplayer:exoplayer:r2.5.4'
|
implementation 'com.google.android.exoplayer:exoplayer:r2.5.4'
|
||||||
|
|
||||||
|
compile "org.jetbrains.anko:anko:$anko_version"
|
||||||
|
// Anko Layouts
|
||||||
|
compile "org.jetbrains.anko:anko-sdk25:$anko_version" // sdk15, sdk19, sdk21, sdk23 are also available
|
||||||
|
compile "org.jetbrains.anko:anko-appcompat-v7:$anko_version"
|
||||||
|
|
||||||
|
// Coroutine listeners for Anko Layouts
|
||||||
|
compile "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version"
|
||||||
|
compile "org.jetbrains.anko:anko-appcompat-v7-coroutines:$anko_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package jp.juggler.subwaytooter.util
|
||||||
|
|
||||||
|
import android.support.test.runner.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@Suppress("MemberVisibilityCanPrivate")
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class TestBucketList {
|
||||||
|
@Test fun test1(){
|
||||||
|
val list = BucketList<String>(bucketCapacity=2)
|
||||||
|
assertEquals(true,list.isEmpty())
|
||||||
|
list.addAll( listOf("A","B","C"))
|
||||||
|
list.addAll( 3, listOf("a","b","c"))
|
||||||
|
list.addAll( 1, listOf("a","b","c"))
|
||||||
|
list.removeAt(7)
|
||||||
|
assertEquals(8,list.size)
|
||||||
|
listOf("A","a","b","c","B","C","a","c").forEachIndexed { i,v->
|
||||||
|
assertEquals( v,list[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -52,7 +52,6 @@ import jp.juggler.subwaytooter.util.LogCategory
|
|||||||
import jp.juggler.subwaytooter.util.ProgressResponseBody
|
import jp.juggler.subwaytooter.util.ProgressResponseBody
|
||||||
import jp.juggler.subwaytooter.util.Utils
|
import jp.juggler.subwaytooter.util.Utils
|
||||||
import jp.juggler.subwaytooter.view.PinchBitmapView
|
import jp.juggler.subwaytooter.view.PinchBitmapView
|
||||||
import okhttp3.Response
|
|
||||||
|
|
||||||
class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
||||||
|
|
||||||
@ -316,8 +315,8 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak") private fun loadBitmap(ta : TootAttachment) {
|
@SuppressLint("StaticFieldLeak") private fun loadBitmap(ta : TootAttachment) {
|
||||||
val url = ta.getLargeUrl(App1.pref)
|
val urlList = ta.getLargeUrlList(App1.pref)
|
||||||
if(url == null) {
|
if(urlList.isEmpty() ) {
|
||||||
showError("missing media attachment url.")
|
showError("missing media attachment url.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -332,7 +331,6 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||||||
|
|
||||||
private val options = BitmapFactory.Options()
|
private val options = BitmapFactory.Options()
|
||||||
|
|
||||||
internal var data : ByteArray? = null
|
|
||||||
internal var bitmap : Bitmap? = null
|
internal var bitmap : Bitmap? = null
|
||||||
|
|
||||||
private fun decodeBitmap(data : ByteArray, pixel_max : Int) : Bitmap? {
|
private fun decodeBitmap(data : ByteArray, pixel_max : Int) : Bitmap? {
|
||||||
@ -359,50 +357,53 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||||||
return BitmapFactory.decodeByteArray(data, 0, data.size, options)
|
return BitmapFactory.decodeByteArray(data, 0, data.size, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getHttpCached(client : TootApiClient, url : String) : TootApiResult {
|
internal fun getHttpCached(client : TootApiClient, url : String) : TootApiResult? {
|
||||||
val response : Response
|
val result = TootApiResult.makeWithCaption(url)
|
||||||
|
|
||||||
try {
|
if(!client.sendRequest(result){
|
||||||
val request = okhttp3.Request.Builder()
|
okhttp3.Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.cacheControl(App1.CACHE_5MIN)
|
.cacheControl(App1.CACHE_5MIN)
|
||||||
.build()
|
.build()
|
||||||
|
}) return result
|
||||||
client.publishApiProgress(getString(R.string.request_api, request.method(), url))
|
|
||||||
val call = App1.ok_http_client2.newCall(request)
|
|
||||||
response = call.execute()
|
|
||||||
} catch(ex : Throwable) {
|
|
||||||
return TootApiResult(Utils.formatError(ex, "network error."))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if( client.isApiCancelled ) return null
|
||||||
|
val response = requireNotNull(result.response)
|
||||||
if(! response.isSuccessful) {
|
if(! response.isSuccessful) {
|
||||||
return TootApiResult(TootApiClient.formatResponse(response, "response error"))
|
return result.setError( TootApiClient.formatResponse(response,result.caption))
|
||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
try {
|
||||||
|
result.data = ProgressResponseBody.bytes(response) { bytesRead, bytesTotal ->
|
||||||
data = ProgressResponseBody.bytes(response) { bytesRead, bytesTotal ->
|
|
||||||
// 50MB以上のデータはキャンセルする
|
// 50MB以上のデータはキャンセルする
|
||||||
if(Math.max(bytesRead, bytesTotal) >= 50000000) {
|
if(Math.max(bytesRead, bytesTotal) >= 50000000) {
|
||||||
throw RuntimeException("media attachment is larger than 50000000")
|
throw RuntimeException("media attachment is larger than 50000000")
|
||||||
}
|
}
|
||||||
client.publishApiProgressRatio(bytesRead.toInt(), bytesTotal.toInt())
|
client.publishApiProgressRatio(bytesRead.toInt(), bytesTotal.toInt())
|
||||||
}
|
}
|
||||||
|
if( client.isApiCancelled ) return null
|
||||||
TootApiResult("")
|
|
||||||
} catch(ex : Throwable) {
|
} catch(ex : Throwable) {
|
||||||
TootApiResult(Utils.formatError(ex, "content error."))
|
result.setError( TootApiClient.formatResponse(response,result.caption,"?"))
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun background(client : TootApiClient) : TootApiResult {
|
override fun background(client : TootApiClient) : TootApiResult? {
|
||||||
val result = getHttpCached(client, url)
|
if( urlList.isEmpty()) return TootApiResult("missing url")
|
||||||
val data = this.data ?: return result
|
var result : TootApiResult? = null
|
||||||
client.publishApiProgress("decoding image…")
|
for(url in urlList) {
|
||||||
val bitmap = decodeBitmap(data, 2048)
|
result = getHttpCached(client, url)
|
||||||
this.bitmap = bitmap
|
val data = result?.data as? ByteArray
|
||||||
return if(bitmap != null) result else TootApiResult("image decode failed.")
|
if(data != null) {
|
||||||
|
client.publishApiProgress("decoding image…")
|
||||||
|
val bitmap = decodeBitmap(data, 2048)
|
||||||
|
if( bitmap != null ) {
|
||||||
|
this.bitmap = bitmap
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleResult(result : TootApiResult?) {
|
override fun handleResult(result : TootApiResult?) {
|
||||||
|
@ -291,6 +291,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
R.id.btnRemoveReply -> removeReply()
|
R.id.btnRemoveReply -> removeReply()
|
||||||
R.id.btnMore -> performMore()
|
R.id.btnMore -> performMore()
|
||||||
R.id.btnPlugin -> openMushroom()
|
R.id.btnPlugin -> openMushroom()
|
||||||
|
R.id.btnEmojiPicker -> post_helper.openEmojiPickerFromMore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,7 +753,8 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
btnRemoveReply.setOnClickListener(this)
|
btnRemoveReply.setOnClickListener(this)
|
||||||
|
|
||||||
findViewById<View>(R.id.btnPlugin).setOnClickListener(this)
|
findViewById<View>(R.id.btnPlugin).setOnClickListener(this)
|
||||||
|
findViewById<View>(R.id.btnEmojiPicker).setOnClickListener(this)
|
||||||
|
|
||||||
for(iv in ivMedia) {
|
for(iv in ivMedia) {
|
||||||
iv.setOnClickListener(this)
|
iv.setOnClickListener(this)
|
||||||
iv.setDefaultImageResId(Styler.getAttributeResourceId(this, R.attr.ic_loading))
|
iv.setDefaultImageResId(Styler.getAttributeResourceId(this, R.attr.ic_loading))
|
||||||
@ -1569,6 +1571,7 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
|||||||
dialog.show(this, null)
|
dialog.show(this, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
// post
|
// post
|
||||||
|
|
||||||
|
@ -60,8 +60,8 @@ internal class ItemListAdapter(private val activity : ActMain, private val colum
|
|||||||
val holder : ItemViewHolder
|
val holder : ItemViewHolder
|
||||||
val view : View
|
val view : View
|
||||||
if(viewOld == null) {
|
if(viewOld == null) {
|
||||||
view = activity.layoutInflater.inflate(if(bSimpleList) R.layout.lv_status_simple else R.layout.lv_status, parent, false)
|
holder = ItemViewHolder(activity, column, this, bSimpleList)
|
||||||
holder = ItemViewHolder(activity, column, this, view, bSimpleList)
|
view = holder.viewRoot
|
||||||
view.tag = holder
|
view.tag = holder
|
||||||
} else {
|
} else {
|
||||||
view = viewOld
|
view = viewOld
|
||||||
|
@ -3,17 +3,17 @@ package jp.juggler.subwaytooter
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.support.v4.content.ContextCompat
|
||||||
import android.support.v4.view.ViewCompat
|
import android.support.v4.view.ViewCompat
|
||||||
import android.support.v7.app.AlertDialog
|
import android.support.v7.app.AlertDialog
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageButton
|
import android.widget.*
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.TextView
|
|
||||||
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
@ -35,79 +35,88 @@ import jp.juggler.subwaytooter.table.ContentWarning
|
|||||||
import jp.juggler.subwaytooter.table.MediaShown
|
import jp.juggler.subwaytooter.table.MediaShown
|
||||||
import jp.juggler.subwaytooter.table.SavedAccount
|
import jp.juggler.subwaytooter.table.SavedAccount
|
||||||
import jp.juggler.subwaytooter.table.UserRelation
|
import jp.juggler.subwaytooter.table.UserRelation
|
||||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
|
||||||
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
import jp.juggler.subwaytooter.span.EmojiImageSpan
|
||||||
import jp.juggler.subwaytooter.util.HTMLDecoder
|
import jp.juggler.subwaytooter.util.*
|
||||||
import jp.juggler.subwaytooter.util.LogCategory
|
|
||||||
import jp.juggler.subwaytooter.util.NetworkEmojiInvalidator
|
|
||||||
import jp.juggler.subwaytooter.util.Utils
|
|
||||||
import jp.juggler.subwaytooter.view.*
|
import jp.juggler.subwaytooter.view.*
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
|
import org.jetbrains.anko.*
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
internal class ItemViewHolder(
|
internal class ItemViewHolder(
|
||||||
val activity : ActMain,
|
val activity : ActMain,
|
||||||
val column : Column,
|
val column : Column,
|
||||||
private val list_adapter : ItemListAdapter,
|
private val list_adapter : ItemListAdapter,
|
||||||
view : View,
|
|
||||||
private val bSimpleList : Boolean
|
private val bSimpleList : Boolean
|
||||||
) : View.OnClickListener, View.OnLongClickListener {
|
) : View.OnClickListener, View.OnLongClickListener {
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = LogCategory("ItemViewHolder")
|
private val log = LogCategory("ItemViewHolder")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var viewRoot : View
|
||||||
|
|
||||||
|
private lateinit var llBoosted : View
|
||||||
|
private lateinit var ivBoosted : ImageView
|
||||||
|
private lateinit var tvBoosted : TextView
|
||||||
|
private lateinit var tvBoostedAcct : TextView
|
||||||
|
private lateinit var tvBoostedTime : TextView
|
||||||
|
|
||||||
|
private lateinit var llFollow : View
|
||||||
|
private lateinit var ivFollow : MyNetworkImageView
|
||||||
|
private lateinit var tvFollowerName : TextView
|
||||||
|
private lateinit var tvFollowerAcct : TextView
|
||||||
|
private lateinit var btnFollow : ImageButton
|
||||||
|
private lateinit var ivFollowedBy : ImageView
|
||||||
|
|
||||||
|
private lateinit var llStatus : View
|
||||||
|
private lateinit var ivThumbnail : MyNetworkImageView
|
||||||
|
private lateinit var tvName : TextView
|
||||||
|
private lateinit var tvTime : TextView
|
||||||
|
private lateinit var tvAcct : TextView
|
||||||
|
|
||||||
|
private lateinit var llContentWarning : View
|
||||||
|
private lateinit var tvContentWarning : MyTextView
|
||||||
|
private lateinit var btnContentWarning : Button
|
||||||
|
|
||||||
|
private lateinit var llContents : View
|
||||||
|
private lateinit var tvMentions : MyTextView
|
||||||
|
private lateinit var tvContent : MyTextView
|
||||||
|
|
||||||
|
private lateinit var flMedia : View
|
||||||
|
private lateinit var btnShowMedia : TextView
|
||||||
|
private lateinit var ivMedia1 : MyNetworkImageView
|
||||||
|
private lateinit var ivMedia2 : MyNetworkImageView
|
||||||
|
private lateinit var ivMedia3 : MyNetworkImageView
|
||||||
|
private lateinit var ivMedia4 : MyNetworkImageView
|
||||||
|
private lateinit var btnHideMedia : View
|
||||||
|
|
||||||
|
private lateinit var llButtonBar : View
|
||||||
|
private lateinit var btnConversation : ImageButton
|
||||||
|
private lateinit var btnReply : ImageButton
|
||||||
|
private lateinit var btnBoost : Button
|
||||||
|
private lateinit var btnFavourite : Button
|
||||||
|
private lateinit var llFollow2 : View
|
||||||
|
private lateinit var btnFollow2 : ImageButton
|
||||||
|
private lateinit var ivFollowedBy2 : ImageView
|
||||||
|
private lateinit var btnMore : ImageButton
|
||||||
|
|
||||||
|
private lateinit var llSearchTag : View
|
||||||
|
private lateinit var btnSearchTag : Button
|
||||||
|
|
||||||
|
private lateinit var llList : View
|
||||||
|
private lateinit var btnListTL : Button
|
||||||
|
private lateinit var btnListMore : ImageButton
|
||||||
|
|
||||||
|
private lateinit var llExtra : LinearLayout
|
||||||
|
|
||||||
|
private lateinit var tvApplication : TextView
|
||||||
|
|
||||||
|
|
||||||
private val access_info : SavedAccount
|
private val access_info : SavedAccount
|
||||||
|
|
||||||
private val llBoosted : View
|
|
||||||
private val ivBoosted : ImageView
|
|
||||||
private val tvBoosted : TextView
|
|
||||||
private val tvBoostedAcct : TextView
|
|
||||||
private val tvBoostedTime : TextView
|
|
||||||
|
|
||||||
private val llFollow : View
|
|
||||||
private val ivFollow : MyNetworkImageView
|
|
||||||
private val tvFollowerName : TextView
|
|
||||||
private val tvFollowerAcct : TextView
|
|
||||||
private val btnFollow : ImageButton
|
|
||||||
private val ivFollowedBy : ImageView
|
|
||||||
|
|
||||||
private val llStatus : View
|
|
||||||
private val ivThumbnail : MyNetworkImageView
|
|
||||||
private val tvName : TextView
|
|
||||||
private val tvTime : TextView
|
|
||||||
private val tvAcct : TextView
|
|
||||||
|
|
||||||
private val llContentWarning : View
|
|
||||||
private val tvContentWarning : MyTextView
|
|
||||||
private val btnContentWarning : Button
|
|
||||||
|
|
||||||
private val llContents : View
|
|
||||||
private val tvMentions : MyTextView
|
|
||||||
private val tvContent : MyTextView
|
|
||||||
|
|
||||||
private val flMedia : View
|
|
||||||
private val btnShowMedia : TextView
|
|
||||||
|
|
||||||
private val ivMedia1 : MyNetworkImageView
|
|
||||||
private val ivMedia2 : MyNetworkImageView
|
|
||||||
private val ivMedia3 : MyNetworkImageView
|
|
||||||
private val ivMedia4 : MyNetworkImageView
|
|
||||||
|
|
||||||
private val buttons_for_status : StatusButtons?
|
private val buttons_for_status : StatusButtons?
|
||||||
|
|
||||||
private val llSearchTag : View
|
|
||||||
private val btnSearchTag : Button
|
|
||||||
|
|
||||||
private val llList : View
|
|
||||||
private val btnListTL : Button
|
|
||||||
|
|
||||||
private val llExtra : LinearLayout
|
|
||||||
|
|
||||||
private val tvApplication : TextView?
|
|
||||||
|
|
||||||
private var item : Any? = null
|
private var item : Any? = null
|
||||||
|
|
||||||
private var status__showing : TootStatus? = null
|
private var status__showing : TootStatus? = null
|
||||||
@ -126,22 +135,17 @@ internal class ItemViewHolder(
|
|||||||
private val extra_invalidator_list = ArrayList<NetworkEmojiInvalidator>()
|
private val extra_invalidator_list = ArrayList<NetworkEmojiInvalidator>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
this.viewRoot = inflate(activity.UI {})
|
||||||
this.access_info = column.access_info
|
this.access_info = column.access_info
|
||||||
|
|
||||||
this.tvName = view.findViewById(R.id.tvName)
|
|
||||||
this.tvFollowerName = view.findViewById(R.id.tvFollowerName)
|
|
||||||
this.tvBoosted = view.findViewById(R.id.tvBoosted)
|
|
||||||
|
|
||||||
if(activity.timeline_font != null || activity.timeline_font_bold != null) {
|
if(activity.timeline_font != null || activity.timeline_font_bold != null) {
|
||||||
Utils.scanView(view) { v ->
|
Utils.scanView(this.viewRoot) { v ->
|
||||||
try {
|
try {
|
||||||
if(v is Button) {
|
if(v is Button) {
|
||||||
// ボタンは太字なので触らない
|
// ボタンは太字なので触らない
|
||||||
} else if(v is TextView) {
|
} else if(v is TextView) {
|
||||||
val typeface = when(v.getId()) {
|
val typeface = when {
|
||||||
R.id.tvName,
|
v === tvName || v === tvFollowerName || v === tvBoosted -> activity.timeline_font_bold ?: activity.timeline_font
|
||||||
R.id.tvFollowerName,
|
|
||||||
R.id.tvBoosted -> activity.timeline_font_bold ?: activity.timeline_font
|
|
||||||
else -> activity.timeline_font ?: activity.timeline_font_bold
|
else -> activity.timeline_font ?: activity.timeline_font_bold
|
||||||
}
|
}
|
||||||
if(typeface != null) v.typeface = typeface
|
if(typeface != null) v.typeface = typeface
|
||||||
@ -156,49 +160,27 @@ internal class ItemViewHolder(
|
|||||||
tvBoosted.typeface = Typeface.DEFAULT_BOLD
|
tvBoosted.typeface = Typeface.DEFAULT_BOLD
|
||||||
}
|
}
|
||||||
|
|
||||||
this.llBoosted = view.findViewById(R.id.llBoosted)
|
if(bSimpleList) {
|
||||||
this.ivBoosted = view.findViewById(R.id.ivBoosted)
|
llButtonBar.visibility = View.GONE
|
||||||
this.tvBoostedTime = view.findViewById(R.id.tvBoostedTime)
|
this.buttons_for_status = null
|
||||||
this.tvBoostedAcct = view.findViewById(R.id.tvBoostedAcct)
|
} else {
|
||||||
|
llButtonBar.visibility = View.VISIBLE
|
||||||
this.llFollow = view.findViewById(R.id.llFollow)
|
this.buttons_for_status = StatusButtons(
|
||||||
this.ivFollow = view.findViewById(R.id.ivFollow)
|
activity,
|
||||||
this.tvFollowerAcct = view.findViewById(R.id.tvFollowerAcct)
|
column,
|
||||||
this.btnFollow = view.findViewById(R.id.btnFollow)
|
false,
|
||||||
this.ivFollowedBy = view.findViewById(R.id.ivFollowedBy)
|
|
||||||
|
btnConversation = btnConversation,
|
||||||
this.llStatus = view.findViewById(R.id.llStatus)
|
btnReply = btnReply,
|
||||||
|
btnBoost = btnBoost,
|
||||||
this.ivThumbnail = view.findViewById(R.id.ivThumbnail)
|
btnFavourite = btnFavourite,
|
||||||
this.tvTime = view.findViewById(R.id.tvTime)
|
llFollow2 = llFollow2,
|
||||||
this.tvAcct = view.findViewById(R.id.tvAcct)
|
btnFollow2 = btnFollow2,
|
||||||
|
ivFollowedBy2 = ivFollowedBy2,
|
||||||
this.llContentWarning = view.findViewById(R.id.llContentWarning)
|
btnMore = btnMore
|
||||||
this.tvContentWarning = view.findViewById(R.id.tvContentWarning)
|
|
||||||
this.btnContentWarning = view.findViewById(R.id.btnContentWarning)
|
)
|
||||||
|
}
|
||||||
this.llContents = view.findViewById(R.id.llContents)
|
|
||||||
this.tvContent = view.findViewById(R.id.tvContent)
|
|
||||||
this.tvMentions = view.findViewById(R.id.tvMentions)
|
|
||||||
|
|
||||||
this.llExtra = view.findViewById(R.id.llExtra)
|
|
||||||
|
|
||||||
this.buttons_for_status = if(bSimpleList) null else StatusButtons(activity, column, view, false)
|
|
||||||
|
|
||||||
this.flMedia = view.findViewById(R.id.flMedia)
|
|
||||||
this.btnShowMedia = view.findViewById(R.id.btnShowMedia)
|
|
||||||
this.ivMedia1 = view.findViewById(R.id.ivMedia1)
|
|
||||||
this.ivMedia2 = view.findViewById(R.id.ivMedia2)
|
|
||||||
this.ivMedia3 = view.findViewById(R.id.ivMedia3)
|
|
||||||
this.ivMedia4 = view.findViewById(R.id.ivMedia4)
|
|
||||||
|
|
||||||
this.llSearchTag = view.findViewById(R.id.llSearchTag)
|
|
||||||
this.btnSearchTag = view.findViewById(R.id.btnSearchTag)
|
|
||||||
this.tvApplication = view.findViewById(R.id.tvApplication)
|
|
||||||
|
|
||||||
this.llList = view.findViewById(R.id.llList)
|
|
||||||
this.btnListTL = view.findViewById(R.id.btnListTL)
|
|
||||||
val btnListMore = view.findViewById<View>(R.id.btnListMore)
|
|
||||||
|
|
||||||
btnListTL.setOnClickListener(this)
|
btnListTL.setOnClickListener(this)
|
||||||
btnListMore.setOnClickListener(this)
|
btnListMore.setOnClickListener(this)
|
||||||
@ -230,10 +212,7 @@ internal class ItemViewHolder(
|
|||||||
tvMentions.movementMethod = MyLinkMovementMethod
|
tvMentions.movementMethod = MyLinkMovementMethod
|
||||||
tvContentWarning.movementMethod = MyLinkMovementMethod
|
tvContentWarning.movementMethod = MyLinkMovementMethod
|
||||||
|
|
||||||
val v : View
|
btnHideMedia.setOnClickListener(this)
|
||||||
//
|
|
||||||
v = view.findViewById(R.id.btnHideMedia)
|
|
||||||
v.setOnClickListener(this)
|
|
||||||
|
|
||||||
val lp = flMedia.layoutParams
|
val lp = flMedia.layoutParams
|
||||||
lp.height = activity.app_state.media_thumb_height
|
lp.height = activity.app_state.media_thumb_height
|
||||||
@ -248,9 +227,7 @@ internal class ItemViewHolder(
|
|||||||
tvContentWarning.textSize = activity.timeline_font_size_sp
|
tvContentWarning.textSize = activity.timeline_font_size_sp
|
||||||
tvContent.textSize = activity.timeline_font_size_sp
|
tvContent.textSize = activity.timeline_font_size_sp
|
||||||
btnShowMedia.textSize = activity.timeline_font_size_sp
|
btnShowMedia.textSize = activity.timeline_font_size_sp
|
||||||
if(tvApplication != null) {
|
tvApplication.textSize = activity.timeline_font_size_sp
|
||||||
tvApplication.textSize = activity.timeline_font_size_sp
|
|
||||||
}
|
|
||||||
btnListTL.textSize = activity.timeline_font_size_sp
|
btnListTL.textSize = activity.timeline_font_size_sp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,9 +265,11 @@ internal class ItemViewHolder(
|
|||||||
llList.visibility = View.GONE
|
llList.visibility = View.GONE
|
||||||
llExtra.removeAllViews()
|
llExtra.removeAllViews()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(item == null) return
|
if(item == null) return
|
||||||
|
|
||||||
var c: Int
|
var c : Int
|
||||||
|
|
||||||
c = if(column.content_color != 0) column.content_color else content_color_default
|
c = if(column.content_color != 0) column.content_color else content_color_default
|
||||||
tvBoosted.setTextColor(c)
|
tvBoosted.setTextColor(c)
|
||||||
@ -300,15 +279,15 @@ internal class ItemViewHolder(
|
|||||||
tvContentWarning.setTextColor(c)
|
tvContentWarning.setTextColor(c)
|
||||||
tvContent.setTextColor(c)
|
tvContent.setTextColor(c)
|
||||||
//NSFWは文字色固定 btnShowMedia.setTextColor( c );
|
//NSFWは文字色固定 btnShowMedia.setTextColor( c );
|
||||||
tvApplication?.setTextColor(c)
|
tvApplication.setTextColor(c)
|
||||||
|
|
||||||
c =if(column.acct_color != 0) column.acct_color else Styler.getAttributeColor(activity, R.attr.colorTimeSmall)
|
c = if(column.acct_color != 0) column.acct_color else Styler.getAttributeColor(activity, R.attr.colorTimeSmall)
|
||||||
this.acct_color = c
|
this.acct_color = c
|
||||||
tvBoostedTime.setTextColor(c)
|
tvBoostedTime.setTextColor(c)
|
||||||
tvTime.setTextColor(c)
|
tvTime.setTextColor(c)
|
||||||
// tvBoostedAcct.setTextColor( c );
|
// tvBoostedAcct.setTextColor( c );
|
||||||
// tvFollowerAcct.setTextColor( c );
|
// tvFollowerAcct.setTextColor( c );
|
||||||
// tvAcct.setTextColor( c );
|
// tvAcct.setTextColor( c );
|
||||||
|
|
||||||
this.item = item
|
this.item = item
|
||||||
when(item) {
|
when(item) {
|
||||||
@ -563,18 +542,16 @@ internal class ItemViewHolder(
|
|||||||
|
|
||||||
buttons_for_status?.bind(status, (item as? TootNotification))
|
buttons_for_status?.bind(status, (item as? TootNotification))
|
||||||
|
|
||||||
if(tvApplication != null) {
|
val application = status.application
|
||||||
val application = status.application
|
when(column.column_type) {
|
||||||
when(column.column_type) {
|
|
||||||
|
Column.TYPE_CONVERSATION -> if(application == null) {
|
||||||
Column.TYPE_CONVERSATION -> if(application == null) {
|
tvApplication.visibility = View.GONE
|
||||||
tvApplication.visibility = View.GONE
|
} else {
|
||||||
} else {
|
tvApplication.visibility = View.VISIBLE
|
||||||
tvApplication.visibility = View.VISIBLE
|
tvApplication.text = activity.getString(R.string.application_is, application.name ?: "")
|
||||||
tvApplication.text = activity.getString(R.string.application_is, application.name ?: "")
|
|
||||||
}
|
|
||||||
else -> tvApplication.visibility = View.GONE
|
|
||||||
}
|
}
|
||||||
|
else -> tvApplication.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,7 +574,7 @@ internal class ItemViewHolder(
|
|||||||
val start = sb.length
|
val start = sb.length
|
||||||
sb.append(status.visibility)
|
sb.append(status.visibility)
|
||||||
val end = sb.length
|
val end = sb.length
|
||||||
val iconResId = Styler.getAttributeResourceId(activity,visIconAttrId )
|
val iconResId = Styler.getAttributeResourceId(activity, visIconAttrId)
|
||||||
sb.setSpan(EmojiImageSpan(activity, iconResId), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
sb.setSpan(EmojiImageSpan(activity, iconResId), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,34 +677,30 @@ internal class ItemViewHolder(
|
|||||||
val pos = activity.nextPosition(column)
|
val pos = activity.nextPosition(column)
|
||||||
val item = this.item
|
val item = this.item
|
||||||
val notification = (item as? TootNotification)
|
val notification = (item as? TootNotification)
|
||||||
when(v.id) {
|
when(v) {
|
||||||
|
|
||||||
R.id.btnHideMedia -> status__showing?.let { status ->
|
btnHideMedia -> status__showing?.let { status ->
|
||||||
MediaShown.save(status, false)
|
MediaShown.save(status, false)
|
||||||
btnShowMedia.visibility = View.VISIBLE
|
btnShowMedia.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnShowMedia -> status__showing?.let { status ->
|
btnShowMedia -> status__showing?.let { status ->
|
||||||
MediaShown.save(status, true)
|
MediaShown.save(status, true)
|
||||||
btnShowMedia.visibility = View.GONE
|
btnShowMedia.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.ivMedia1 -> clickMedia(0)
|
ivMedia1 -> clickMedia(0)
|
||||||
R.id.ivMedia2 -> clickMedia(1)
|
ivMedia2 -> clickMedia(1)
|
||||||
R.id.ivMedia3 -> clickMedia(2)
|
ivMedia3 -> clickMedia(2)
|
||||||
R.id.ivMedia4 -> clickMedia(3)
|
ivMedia4 -> clickMedia(3)
|
||||||
|
|
||||||
R.id.ivCardThumbnail -> status__showing?.card?.url?.let { url ->
|
btnContentWarning -> status__showing?.let { status ->
|
||||||
if(url.isNotEmpty()) App1.openCustomTab(activity, url)
|
|
||||||
}
|
|
||||||
|
|
||||||
R.id.btnContentWarning -> status__showing?.let { status ->
|
|
||||||
val new_shown = llContents.visibility == View.GONE
|
val new_shown = llContents.visibility == View.GONE
|
||||||
ContentWarning.save(status, new_shown)
|
ContentWarning.save(status, new_shown)
|
||||||
list_adapter.notifyDataSetChanged()
|
list_adapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.ivThumbnail -> status_account?.let { who ->
|
ivThumbnail -> status_account?.let { who ->
|
||||||
if(access_info.isPseudo) {
|
if(access_info.isPseudo) {
|
||||||
DlgContextMenu(activity, column, who, null, notification).show()
|
DlgContextMenu(activity, column, who, null, notification).show()
|
||||||
} else {
|
} else {
|
||||||
@ -735,7 +708,7 @@ internal class ItemViewHolder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.llBoosted -> boost_account?.let { who ->
|
llBoosted -> boost_account?.let { who ->
|
||||||
if(access_info.isPseudo) {
|
if(access_info.isPseudo) {
|
||||||
DlgContextMenu(activity, column, who, null, notification).show()
|
DlgContextMenu(activity, column, who, null, notification).show()
|
||||||
} else {
|
} else {
|
||||||
@ -743,18 +716,18 @@ internal class ItemViewHolder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.llFollow -> follow_account?.let { who ->
|
llFollow -> follow_account?.let { who ->
|
||||||
if(access_info.isPseudo) {
|
if(access_info.isPseudo) {
|
||||||
DlgContextMenu(activity, column, who, null, notification).show()
|
DlgContextMenu(activity, column, who, null, notification).show()
|
||||||
} else {
|
} else {
|
||||||
Action_User.profileLocal(activity, pos, access_info, who)
|
Action_User.profileLocal(activity, pos, access_info, who)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
R.id.btnFollow -> follow_account?.let { who ->
|
btnFollow -> follow_account?.let { who ->
|
||||||
DlgContextMenu(activity, column, who, null, notification).show()
|
DlgContextMenu(activity, column, who, null, notification).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnSearchTag -> when(item) {
|
btnSearchTag -> when(item) {
|
||||||
is TootGap -> column.startGap(item)
|
is TootGap -> column.startGap(item)
|
||||||
|
|
||||||
is TootDomainBlock -> {
|
is TootDomainBlock -> {
|
||||||
@ -772,11 +745,11 @@ internal class ItemViewHolder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnListTL -> if(item is TootList) {
|
btnListTL -> if(item is TootList) {
|
||||||
activity.addColumn(pos, access_info, Column.TYPE_LIST_TL, item.id)
|
activity.addColumn(pos, access_info, Column.TYPE_LIST_TL, item.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnListMore -> if(item is TootList) {
|
btnListMore -> if(item is TootList) {
|
||||||
ActionsDialog()
|
ActionsDialog()
|
||||||
.addAction(activity.getString(R.string.list_timeline)) {
|
.addAction(activity.getString(R.string.list_timeline)) {
|
||||||
activity.addColumn(pos, access_info, Column.TYPE_LIST_TL, item.id)
|
activity.addColumn(pos, access_info, Column.TYPE_LIST_TL, item.id)
|
||||||
@ -794,6 +767,13 @@ internal class ItemViewHolder(
|
|||||||
}
|
}
|
||||||
.show(activity, item.title)
|
.show(activity, item.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else -> when(v.id) {
|
||||||
|
R.id.ivCardThumbnail -> status__showing?.card?.url?.let { url ->
|
||||||
|
if(url.isNotEmpty()) App1.openCustomTab(activity, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,41 +781,41 @@ internal class ItemViewHolder(
|
|||||||
|
|
||||||
val notification = (item as? TootNotification)
|
val notification = (item as? TootNotification)
|
||||||
|
|
||||||
when(v.id) {
|
when(v) {
|
||||||
|
|
||||||
R.id.ivThumbnail -> {
|
ivThumbnail -> {
|
||||||
status_account?.let { who -> DlgContextMenu(activity, column, who, null, notification).show() }
|
status_account?.let { who -> DlgContextMenu(activity, column, who, null, notification).show() }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.llBoosted -> {
|
llBoosted -> {
|
||||||
boost_account?.let { who -> DlgContextMenu(activity, column, who, null, notification).show() }
|
boost_account?.let { who -> DlgContextMenu(activity, column, who, null, notification).show() }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.llFollow -> {
|
llFollow -> {
|
||||||
follow_account?.let { who -> DlgContextMenu(activity, column, who, null, notification).show() }
|
follow_account?.let { who -> DlgContextMenu(activity, column, who, null, notification).show() }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnFollow -> {
|
btnFollow -> {
|
||||||
follow_account?.let { who -> Action_Follow.followFromAnotherAccount(activity, activity.nextPosition(column), access_info, who) }
|
follow_account?.let { who -> Action_Follow.followFromAnotherAccount(activity, activity.nextPosition(column), access_info, who) }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnSearchTag -> {
|
btnSearchTag -> {
|
||||||
val item = this.item
|
val item = this.item
|
||||||
when(item) {
|
when(item) {
|
||||||
// is TootGap -> column.startGap(item)
|
// is TootGap -> column.startGap(item)
|
||||||
//
|
//
|
||||||
// is TootDomainBlock -> {
|
// is TootDomainBlock -> {
|
||||||
// val domain = item.domain
|
// val domain = item.domain
|
||||||
// AlertDialog.Builder(activity)
|
// AlertDialog.Builder(activity)
|
||||||
// .setMessage(activity.getString(R.string.confirm_unblock_domain, domain))
|
// .setMessage(activity.getString(R.string.confirm_unblock_domain, domain))
|
||||||
// .setNegativeButton(R.string.cancel, null)
|
// .setNegativeButton(R.string.cancel, null)
|
||||||
// .setPositiveButton(R.string.ok) { _, _ -> Action_Instance.blockDomain(activity, access_info, domain, false) }
|
// .setPositiveButton(R.string.ok) { _, _ -> Action_Instance.blockDomain(activity, access_info, domain, false) }
|
||||||
// .show()
|
// .show()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
is String -> {
|
is String -> {
|
||||||
// search_tag は#を含まない
|
// search_tag は#を含まない
|
||||||
@ -843,10 +823,10 @@ internal class ItemViewHolder(
|
|||||||
val host = access_info.host
|
val host = access_info.host
|
||||||
val url = "https://$host/tags/$tagEncoded"
|
val url = "https://$host/tags/$tagEncoded"
|
||||||
Action_HashTag.timelineOtherInstance(
|
Action_HashTag.timelineOtherInstance(
|
||||||
activity =activity,
|
activity = activity,
|
||||||
pos =activity.nextPosition(column),
|
pos = activity.nextPosition(column),
|
||||||
url =url,
|
url = url,
|
||||||
host =host,
|
host = host,
|
||||||
tag_without_sharp = item
|
tag_without_sharp = item
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -918,7 +898,7 @@ internal class ItemViewHolder(
|
|||||||
addLinkAndCaption(sb, activity.getString(R.string.card_header_provider), card.provider_url, card.provider_name)
|
addLinkAndCaption(sb, activity.getString(R.string.card_header_provider), card.provider_url, card.provider_name)
|
||||||
|
|
||||||
val description = card.description
|
val description = card.description
|
||||||
if( description != null && description.isNotEmpty() ) {
|
if(description != null && description.isNotEmpty()) {
|
||||||
if(sb.isNotEmpty()) sb.append("<br>")
|
if(sb.isNotEmpty()) sb.append("<br>")
|
||||||
sb.append(HTMLDecoder.encodeEntity(description))
|
sb.append(HTMLDecoder.encodeEntity(description))
|
||||||
}
|
}
|
||||||
@ -928,7 +908,7 @@ internal class ItemViewHolder(
|
|||||||
llExtra.addView(tv)
|
llExtra.addView(tv)
|
||||||
|
|
||||||
val image = card.image
|
val image = card.image
|
||||||
if( image != null && image.isNotEmpty()) {
|
if(image != null && image.isNotEmpty()) {
|
||||||
lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, activity.app_state.media_thumb_height)
|
lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, activity.app_state.media_thumb_height)
|
||||||
lp.topMargin = (0.5f + llExtra.resources.displayMetrics.density * 3f).toInt()
|
lp.topMargin = (0.5f + llExtra.resources.displayMetrics.density * 3f).toInt()
|
||||||
val iv = MyNetworkImageView(activity)
|
val iv = MyNetworkImageView(activity)
|
||||||
@ -1027,7 +1007,7 @@ internal class ItemViewHolder(
|
|||||||
try {
|
try {
|
||||||
form.put("item_index", Integer.toString(idx))
|
form.put("item_index", Integer.toString(idx))
|
||||||
} catch(ex : Throwable) {
|
} catch(ex : Throwable) {
|
||||||
log.e(ex,"json encode failed.")
|
log.e(ex, "json encode failed.")
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1056,6 +1036,414 @@ internal class ItemViewHolder(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun inflate(ui : AnkoContext<Context>) = with(ui) {
|
||||||
|
verticalLayout {
|
||||||
|
// トップレベルのViewGroupのlparamsはイニシャライザ内部に置くしかないみたい
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
topPadding = dip(3)
|
||||||
|
bottomPadding = dip(3)
|
||||||
|
descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS
|
||||||
|
|
||||||
|
llBoosted = linearLayout {
|
||||||
|
lparams(matchParent, wrapContent) {
|
||||||
|
bottomMargin = dip(6)
|
||||||
|
}
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
|
||||||
|
ivBoosted = imageView {
|
||||||
|
scaleType = ImageView.ScaleType.FIT_END
|
||||||
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
||||||
|
}.lparams(dip(48), dip(32)) {
|
||||||
|
endMargin = dip(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalLayout {
|
||||||
|
lparams(dip(0), wrapContent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
linearLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
tvBoostedAcct = textView {
|
||||||
|
ellipsize = TextUtils.TruncateAt.END
|
||||||
|
gravity = Gravity.END
|
||||||
|
maxLines = 1
|
||||||
|
textColor = Styler.getAttributeColor(context, R.attr.colorTimeSmall)
|
||||||
|
textSize = 12f // textSize の単位はSP
|
||||||
|
// tools:text ="who@hoge"
|
||||||
|
}.lparams(dip(0), wrapContent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
tvBoostedTime = textView {
|
||||||
|
|
||||||
|
startPadding = dip(2)
|
||||||
|
|
||||||
|
gravity = Gravity.END
|
||||||
|
textColor = Styler.getAttributeColor(context, R.attr.colorTimeSmall)
|
||||||
|
textSize = 12f // textSize の単位はSP
|
||||||
|
// tools:ignore="RtlSymmetry"
|
||||||
|
// tools:text="2017-04-16 09:37:14"
|
||||||
|
}.lparams(wrapContent, wrapContent)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tvBoosted = textView {
|
||||||
|
// tools:text = "~にブーストされました"
|
||||||
|
}.lparams(matchParent, wrapContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
llFollow = linearLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
|
||||||
|
ivFollow = myNetworkImageView {
|
||||||
|
contentDescription = context.getString(R.string.thumbnail)
|
||||||
|
scaleType = ImageView.ScaleType.FIT_END
|
||||||
|
}.lparams(dip(48), dip(40)) {
|
||||||
|
endMargin = dip(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalLayout {
|
||||||
|
|
||||||
|
lparams(dip(0), wrapContent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
tvFollowerName = textView {
|
||||||
|
// tools:text="Follower Name"
|
||||||
|
}.lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
tvFollowerAcct = textView {
|
||||||
|
setPaddingStartEnd(dip(4), dip(4))
|
||||||
|
textColor = Styler.getAttributeColor(context, R.attr.colorTimeSmall)
|
||||||
|
textSize = 12f // SP
|
||||||
|
// tools:text="aaaaaaaaaaaaaaaa"
|
||||||
|
}.lparams(matchParent, wrapContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
frameLayout {
|
||||||
|
lparams(dip(40), dip(40)) {
|
||||||
|
startMargin = dip(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
btnFollow = imageButton {
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
contentDescription = context.getString(R.string.follow)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER
|
||||||
|
// tools:src="?attr/ic_follow_plus"
|
||||||
|
}.lparams(matchParent, matchParent)
|
||||||
|
|
||||||
|
ivFollowedBy = imageView {
|
||||||
|
scaleType = ImageView.ScaleType.CENTER
|
||||||
|
// tools:src="?attr/ic_followed_by"
|
||||||
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
||||||
|
}.lparams(matchParent, matchParent)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
llStatus = verticalLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
linearLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
tvAcct = textView {
|
||||||
|
ellipsize = TextUtils.TruncateAt.END
|
||||||
|
gravity = Gravity.END
|
||||||
|
maxLines = 1
|
||||||
|
textColor = Styler.getAttributeColor(context, R.attr.colorTimeSmall)
|
||||||
|
textSize = 12f // SP
|
||||||
|
// tools:text="who@hoge"
|
||||||
|
}.lparams(dip(0), wrapContent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
tvTime = textView {
|
||||||
|
gravity = Gravity.END
|
||||||
|
startPadding = dip(2)
|
||||||
|
textColor = Styler.getAttributeColor(context, R.attr.colorTimeSmall)
|
||||||
|
textSize = 12f // SP
|
||||||
|
// tools:ignore="RtlSymmetry"
|
||||||
|
// tools:text="2017-04-16 09:37:14"
|
||||||
|
}.lparams(wrapContent, wrapContent)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
linearLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
ivThumbnail = myNetworkImageView {
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
contentDescription = context.getString(R.string.thumbnail)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
}.lparams(dip(48), dip(48)) {
|
||||||
|
topMargin = dip(4)
|
||||||
|
endMargin = dip(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalLayout {
|
||||||
|
lparams(dip(0), wrapContent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
tvName = textView {
|
||||||
|
|
||||||
|
// tools:text="Displayname"
|
||||||
|
}.lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
llContentWarning = linearLayout {
|
||||||
|
lparams(matchParent, wrapContent) {
|
||||||
|
topMargin = dip(3)
|
||||||
|
isBaselineAligned = false
|
||||||
|
}
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
|
||||||
|
btnContentWarning = button {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_ddd)
|
||||||
|
minWidthCompat = dip(40)
|
||||||
|
padding = dip(4)
|
||||||
|
//tools:text="見る"
|
||||||
|
}.lparams(wrapContent, dip(40)) {
|
||||||
|
endMargin = dip(8)
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalLayout {
|
||||||
|
lparams(dip(0), wrapContent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
tvMentions = myTextView {
|
||||||
|
}.lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
tvContentWarning = myTextView {
|
||||||
|
}.lparams(matchParent, wrapContent) {
|
||||||
|
topMargin = dip(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
llContents = verticalLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
tvContent = myTextView {
|
||||||
|
setLineSpacing(lineSpacingExtra, 1.1f)
|
||||||
|
// tools:text="Contents\nContents"
|
||||||
|
}.lparams(matchParent, wrapContent) {
|
||||||
|
topMargin = dip(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
flMedia = frameLayout {
|
||||||
|
lparams(matchParent, dip(64)) {
|
||||||
|
topMargin = dip(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
linearLayout {
|
||||||
|
lparams(matchParent, matchParent)
|
||||||
|
|
||||||
|
ivMedia1 = myNetworkImageView {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_ddd)
|
||||||
|
contentDescription = context.getString(R.string.thumbnail)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
|
||||||
|
}.lparams(0, matchParent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
ivMedia2 = myNetworkImageView {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_ddd)
|
||||||
|
contentDescription = context.getString(R.string.thumbnail)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
|
||||||
|
}.lparams(0, matchParent) {
|
||||||
|
startMargin = dip(8)
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
ivMedia3 = myNetworkImageView {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_ddd)
|
||||||
|
contentDescription = context.getString(R.string.thumbnail)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
|
||||||
|
}.lparams(0, matchParent) {
|
||||||
|
startMargin = dip(8)
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
ivMedia4 = myNetworkImageView {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_ddd)
|
||||||
|
contentDescription = context.getString(R.string.thumbnail)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
|
||||||
|
}.lparams(0, matchParent) {
|
||||||
|
startMargin = dip(8)
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
btnHideMedia = imageButton {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
contentDescription = "@string/hide"
|
||||||
|
imageResource = Styler.getAttributeResourceId(context, R.attr.btn_close)
|
||||||
|
}.lparams(dip(32), matchParent) {
|
||||||
|
startMargin = dip(8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btnShowMedia = textView {
|
||||||
|
|
||||||
|
backgroundColor = Styler.getAttributeColor(context, R.attr.colorShowMediaBackground)
|
||||||
|
gravity = Gravity.CENTER
|
||||||
|
text = context.getString(R.string.tap_to_show)
|
||||||
|
textColor = Styler.getAttributeColor(context, R.attr.colorShowMediaText)
|
||||||
|
|
||||||
|
}.lparams(matchParent, matchParent)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
llExtra = verticalLayout {
|
||||||
|
lparams(matchParent, wrapContent) {
|
||||||
|
topMargin = dip(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// button bar
|
||||||
|
llButtonBar = linearLayout {
|
||||||
|
lparams(wrapContent, dip(40)) {
|
||||||
|
topMargin = dip(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
btnConversation = imageButton {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
contentDescription = context.getString(R.string.conversation_view)
|
||||||
|
minimumWidth = dip(40)
|
||||||
|
imageResource = Styler.getAttributeResourceId(context, R.attr.ic_conversation)
|
||||||
|
}.lparams(wrapContent, matchParent)
|
||||||
|
|
||||||
|
btnReply = imageButton {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
contentDescription = context.getString(R.string.reply)
|
||||||
|
minimumWidth = dip(40)
|
||||||
|
imageResource = Styler.getAttributeResourceId(context, R.attr.btn_reply)
|
||||||
|
|
||||||
|
}.lparams(wrapContent, matchParent) {
|
||||||
|
startMargin = dip(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
btnBoost = button {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
compoundDrawablePadding = dip(4)
|
||||||
|
|
||||||
|
minWidthCompat = dip(48)
|
||||||
|
setPaddingStartEnd(dip(4), dip(4))
|
||||||
|
}.lparams(wrapContent, matchParent) {
|
||||||
|
startMargin = dip(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
btnFavourite = button {
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
compoundDrawablePadding = dip(4)
|
||||||
|
minWidthCompat = dip(48)
|
||||||
|
setPaddingStartEnd(dip(4), dip(4))
|
||||||
|
|
||||||
|
}.lparams(wrapContent, matchParent) {
|
||||||
|
startMargin = dip(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
llFollow2 = frameLayout {
|
||||||
|
lparams(dip(40), dip(40)) {
|
||||||
|
startMargin = dip(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
btnFollow2 = imageButton {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
contentDescription = context.getString(R.string.follow)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER
|
||||||
|
// tools:src="?attr/ic_follow_plus"
|
||||||
|
minimumWidth = dip(40)
|
||||||
|
|
||||||
|
}.lparams(matchParent, matchParent)
|
||||||
|
|
||||||
|
ivFollowedBy2 = imageView {
|
||||||
|
|
||||||
|
scaleType = ImageView.ScaleType.CENTER
|
||||||
|
imageResource = Styler.getAttributeResourceId(context, R.attr.ic_followed_by)
|
||||||
|
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
||||||
|
}.lparams(matchParent, matchParent)
|
||||||
|
}
|
||||||
|
|
||||||
|
btnMore = imageButton {
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
contentDescription = context.getString(R.string.more)
|
||||||
|
imageResource = Styler.getAttributeResourceId(context, R.attr.btn_more)
|
||||||
|
minimumWidth = dip(40)
|
||||||
|
}.lparams(wrapContent, matchParent) {
|
||||||
|
startMargin = dip(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tvApplication = textView {
|
||||||
|
gravity = Gravity.END
|
||||||
|
}.lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
llSearchTag = linearLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
btnSearchTag = button {
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
allCaps = false
|
||||||
|
}.lparams(matchParent, wrapContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
llList = linearLayout {
|
||||||
|
lparams(matchParent, wrapContent)
|
||||||
|
|
||||||
|
btnListTL = button {
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
allCaps = false
|
||||||
|
}.lparams(0, wrapContent) {
|
||||||
|
weight = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
btnListMore = imageButton {
|
||||||
|
|
||||||
|
background = ContextCompat.getDrawable(context, R.drawable.btn_bg_transparent)
|
||||||
|
imageResource = Styler.getAttributeResourceId(context, R.attr.btn_more)
|
||||||
|
contentDescription = context.getString(R.string.more)
|
||||||
|
}.lparams(dip(40), dip(40)) {
|
||||||
|
startMargin = dip(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,20 +19,23 @@ import jp.juggler.subwaytooter.util.LogCategory
|
|||||||
internal class StatusButtons(
|
internal class StatusButtons(
|
||||||
private val activity : ActMain,
|
private val activity : ActMain,
|
||||||
private val column : Column,
|
private val column : Column,
|
||||||
viewRoot : View,
|
private val bSimpleList : Boolean,
|
||||||
private val bSimpleList : Boolean
|
|
||||||
|
private val btnConversation : ImageButton,
|
||||||
|
private val btnReply : ImageButton,
|
||||||
|
private val btnBoost : Button,
|
||||||
|
private val btnFavourite : Button,
|
||||||
|
private val llFollow2 : View,
|
||||||
|
private val btnFollow2 : ImageButton,
|
||||||
|
private val ivFollowedBy2 : ImageView,
|
||||||
|
private val btnMore : ImageButton
|
||||||
|
|
||||||
) : View.OnClickListener, View.OnLongClickListener {
|
) : View.OnClickListener, View.OnLongClickListener {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val log = LogCategory("StatusButtons")
|
val log = LogCategory("StatusButtons")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val btnBoost : Button
|
|
||||||
private val btnFavourite : Button
|
|
||||||
private val btnFollow2 : ImageButton
|
|
||||||
private val ivFollowedBy2 : ImageView
|
|
||||||
private val llFollow2 : View
|
|
||||||
|
|
||||||
private val access_info : SavedAccount
|
private val access_info : SavedAccount
|
||||||
private var relation : UserRelation? = null
|
private var relation : UserRelation? = null
|
||||||
private var status : TootStatus? = null
|
private var status : TootStatus? = null
|
||||||
@ -43,12 +46,6 @@ internal class StatusButtons(
|
|||||||
init {
|
init {
|
||||||
this.access_info = column.access_info
|
this.access_info = column.access_info
|
||||||
|
|
||||||
btnBoost = viewRoot.findViewById(R.id.btnBoost)
|
|
||||||
btnFavourite = viewRoot.findViewById(R.id.btnFavourite)
|
|
||||||
btnFollow2 = viewRoot.findViewById(R.id.btnFollow2)
|
|
||||||
ivFollowedBy2 = viewRoot.findViewById(R.id.ivFollowedBy2)
|
|
||||||
llFollow2 = viewRoot.findViewById(R.id.llFollow2)
|
|
||||||
|
|
||||||
val listener = this
|
val listener = this
|
||||||
|
|
||||||
btnBoost.setOnClickListener(listener)
|
btnBoost.setOnClickListener(listener)
|
||||||
@ -57,20 +54,12 @@ internal class StatusButtons(
|
|||||||
btnFavourite.setOnLongClickListener(listener)
|
btnFavourite.setOnLongClickListener(listener)
|
||||||
btnFollow2.setOnClickListener(listener)
|
btnFollow2.setOnClickListener(listener)
|
||||||
btnFollow2.setOnLongClickListener(listener)
|
btnFollow2.setOnLongClickListener(listener)
|
||||||
|
btnMore.setOnClickListener(listener)
|
||||||
|
btnConversation.setOnClickListener(listener)
|
||||||
|
btnConversation.setOnLongClickListener(listener)
|
||||||
|
btnReply.setOnClickListener(listener)
|
||||||
|
btnReply.setOnLongClickListener(listener)
|
||||||
|
|
||||||
with(viewRoot.findViewById<View>(R.id.btnMore)) {
|
|
||||||
setOnClickListener(listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
with(viewRoot.findViewById<View>(R.id.btnConversation)) {
|
|
||||||
setOnClickListener(listener)
|
|
||||||
setOnLongClickListener(listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
with(viewRoot.findViewById<View>(R.id.btnReply)) {
|
|
||||||
setOnClickListener(listener)
|
|
||||||
setOnLongClickListener(listener)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bind(status : TootStatus, notification : TootNotification?) {
|
fun bind(status : TootStatus, notification : TootNotification?) {
|
||||||
@ -81,6 +70,7 @@ internal class StatusButtons(
|
|||||||
val color_accent = Styler.getAttributeColor(activity, R.attr.colorImageButtonAccent)
|
val color_accent = Styler.getAttributeColor(activity, R.attr.colorImageButtonAccent)
|
||||||
val fav_icon_attr = if(access_info.isNicoru(status.account)) R.attr.ic_nicoru else R.attr.btn_favourite
|
val fav_icon_attr = if(access_info.isNicoru(status.account)) R.attr.ic_nicoru else R.attr.btn_favourite
|
||||||
|
|
||||||
|
// ブーストボタン
|
||||||
when {
|
when {
|
||||||
TootStatus.VISIBILITY_DIRECT == status.visibility -> setButton(btnBoost, false, color_accent, R.attr.ic_mail, "")
|
TootStatus.VISIBILITY_DIRECT == status.visibility -> setButton(btnBoost, false, color_accent, R.attr.ic_mail, "")
|
||||||
TootStatus.VISIBILITY_PRIVATE == status.visibility -> setButton(btnBoost, false, color_accent, R.attr.ic_lock, "")
|
TootStatus.VISIBILITY_PRIVATE == status.visibility -> setButton(btnBoost, false, color_accent, R.attr.ic_lock, "")
|
||||||
@ -131,66 +121,70 @@ internal class StatusButtons(
|
|||||||
|
|
||||||
val status = this.status ?: return
|
val status = this.status ?: return
|
||||||
|
|
||||||
when(v.id) {
|
when(v) {
|
||||||
|
|
||||||
R.id.btnConversation -> Action_Toot.conversation(activity, activity.nextPosition(column), access_info, status)
|
btnConversation -> Action_Toot.conversation(activity, activity.nextPosition(column), access_info, status)
|
||||||
|
|
||||||
R.id.btnReply -> if( ! access_info.isPseudo) {
|
btnReply -> if( ! access_info.isPseudo) {
|
||||||
Action_Toot.reply(activity, access_info, status)
|
Action_Toot.reply(activity, access_info, status)
|
||||||
} else {
|
} else {
|
||||||
Action_Toot.replyFromAnotherAccount(activity, access_info, status)
|
Action_Toot.replyFromAnotherAccount(activity, access_info, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnBoost -> if(access_info.isPseudo) {
|
btnBoost -> {
|
||||||
Action_Toot.boostFromAnotherAccount(activity, access_info, status)
|
if(access_info.isPseudo) {
|
||||||
} else {
|
Action_Toot.boostFromAnotherAccount(activity, access_info, status)
|
||||||
|
} else {
|
||||||
// トグル動作
|
|
||||||
val willRoost = ! status.reblogged
|
// トグル動作
|
||||||
|
val willRoost = ! status.reblogged
|
||||||
// 簡略表示なら結果をトースト表示
|
|
||||||
val callback = when {
|
// 簡略表示なら結果をトースト表示
|
||||||
! bSimpleList -> null
|
val callback = when {
|
||||||
willRoost -> activity.boost_complete_callback
|
! bSimpleList -> null
|
||||||
else -> activity.unboost_complete_callback
|
willRoost -> activity.boost_complete_callback
|
||||||
|
else -> activity.unboost_complete_callback
|
||||||
|
}
|
||||||
|
|
||||||
|
Action_Toot.boost(
|
||||||
|
activity,
|
||||||
|
access_info,
|
||||||
|
status,
|
||||||
|
NOT_CROSS_ACCOUNT,
|
||||||
|
willRoost,
|
||||||
|
false,
|
||||||
|
callback
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Action_Toot.boost(
|
|
||||||
activity,
|
|
||||||
access_info,
|
|
||||||
status,
|
|
||||||
NOT_CROSS_ACCOUNT,
|
|
||||||
willRoost,
|
|
||||||
false,
|
|
||||||
callback
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnFavourite -> if(access_info.isPseudo) {
|
btnFavourite -> {
|
||||||
Action_Toot.favouriteFromAnotherAccount(activity, access_info, status)
|
if(access_info.isPseudo) {
|
||||||
} else {
|
Action_Toot.favouriteFromAnotherAccount(activity, access_info, status)
|
||||||
|
} else {
|
||||||
// トグル動作
|
|
||||||
val willFavourite = ! status.favourited
|
// トグル動作
|
||||||
|
val willFavourite = ! status.favourited
|
||||||
// 簡略表示なら結果をトースト表示
|
|
||||||
val callback = when {
|
// 簡略表示なら結果をトースト表示
|
||||||
! bSimpleList -> null
|
val callback = when {
|
||||||
status.favourited -> activity.unfavourite_complete_callback
|
! bSimpleList -> null
|
||||||
else -> activity.favourite_complete_callback
|
status.favourited -> activity.unfavourite_complete_callback
|
||||||
|
else -> activity.favourite_complete_callback
|
||||||
|
}
|
||||||
|
|
||||||
|
Action_Toot.favourite(
|
||||||
|
activity,
|
||||||
|
access_info,
|
||||||
|
status,
|
||||||
|
NOT_CROSS_ACCOUNT,
|
||||||
|
willFavourite,
|
||||||
|
callback
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Action_Toot.favourite(
|
|
||||||
activity,
|
|
||||||
access_info,
|
|
||||||
status,
|
|
||||||
NOT_CROSS_ACCOUNT,
|
|
||||||
willFavourite,
|
|
||||||
callback
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnFollow2 -> {
|
btnFollow2 -> {
|
||||||
val account = status.account
|
val account = status.account
|
||||||
val relation = this.relation ?: return
|
val relation = this.relation ?: return
|
||||||
|
|
||||||
@ -235,7 +229,7 @@ internal class StatusButtons(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.btnMore -> DlgContextMenu(activity, column, status.account, status, notification).show()
|
btnMore -> DlgContextMenu(activity, column, status.account, status, notification).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,15 +240,22 @@ internal class StatusButtons(
|
|||||||
|
|
||||||
val status = this.status ?: return true
|
val status = this.status ?: return true
|
||||||
|
|
||||||
when(v.id) {
|
when(v) {
|
||||||
R.id.btnConversation -> Action_Toot.conversationOtherInstance(activity, activity.nextPosition(column), status)
|
btnConversation -> Action_Toot.conversationOtherInstance(
|
||||||
R.id.btnBoost -> Action_Toot.boostFromAnotherAccount(activity, access_info, status)
|
activity, activity.nextPosition(column), status)
|
||||||
R.id.btnFavourite -> Action_Toot.favouriteFromAnotherAccount(activity, access_info, status)
|
|
||||||
R.id.btnReply -> Action_Toot.replyFromAnotherAccount(activity, access_info, status)
|
btnBoost -> Action_Toot.boostFromAnotherAccount(
|
||||||
|
activity, access_info, status)
|
||||||
|
|
||||||
|
btnFavourite -> Action_Toot.favouriteFromAnotherAccount(
|
||||||
|
activity, access_info, status)
|
||||||
|
|
||||||
|
btnReply -> Action_Toot.replyFromAnotherAccount(
|
||||||
|
activity, access_info, status)
|
||||||
|
|
||||||
|
btnFollow2 -> Action_Follow.followFromAnotherAccount(
|
||||||
|
activity, activity.nextPosition(column), access_info, status.account)
|
||||||
|
|
||||||
R.id.btnFollow2 -> {
|
|
||||||
Action_Follow.followFromAnotherAccount(activity, activity.nextPosition(column), access_info, status.account)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,19 @@ class StatusButtonsPopup(
|
|||||||
init {
|
init {
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
this.viewRoot = activity.layoutInflater.inflate(R.layout.list_item_popup, null, false)
|
this.viewRoot = activity.layoutInflater.inflate(R.layout.list_item_popup, null, false)
|
||||||
this.buttons_for_status = StatusButtons(activity, column, viewRoot, bSimpleList)
|
this.buttons_for_status = StatusButtons(
|
||||||
|
activity,
|
||||||
|
column,
|
||||||
|
bSimpleList,
|
||||||
|
btnConversation =viewRoot.findViewById(R.id.btnConversation),
|
||||||
|
btnReply = viewRoot.findViewById(R.id.btnReply),
|
||||||
|
btnBoost = viewRoot.findViewById(R.id.btnBoost),
|
||||||
|
btnFavourite = viewRoot.findViewById(R.id.btnFavourite),
|
||||||
|
llFollow2 = viewRoot.findViewById(R.id.llFollow2),
|
||||||
|
btnFollow2 = viewRoot.findViewById(R.id.btnFollow2),
|
||||||
|
ivFollowedBy2 = viewRoot.findViewById(R.id.ivFollowedBy2),
|
||||||
|
btnMore = viewRoot.findViewById(R.id.btnMore)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dismiss() {
|
fun dismiss() {
|
||||||
|
@ -63,7 +63,17 @@ class TootAttachment(src : JSONObject) : TootAttachmentLike {
|
|||||||
if( remote_url?.isNotEmpty() == true ) remote_url else url
|
if( remote_url?.isNotEmpty() == true ) remote_url else url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun getLargeUrlList(pref : SharedPreferences) : ArrayList<String> {
|
||||||
|
val result = ArrayList<String>()
|
||||||
|
if( pref.getBoolean(Pref.KEY_PRIOR_LOCAL_URL, false) ){
|
||||||
|
if( url?.isNotEmpty() ==true) result.add(url)
|
||||||
|
if( remote_url?.isNotEmpty()==true) result.add( remote_url)
|
||||||
|
} else {
|
||||||
|
if( remote_url?.isNotEmpty()==true) result.add( remote_url)
|
||||||
|
if( url?.isNotEmpty() ==true) result.add(url)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// v1.3 から 添付ファイルの画像のピクセルサイズが取得できるようになった
|
// v1.3 から 添付ファイルの画像のピクセルサイズが取得できるようになった
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package jp.juggler.subwaytooter.util
|
||||||
|
|
||||||
|
import android.view.ViewManager
|
||||||
|
import jp.juggler.subwaytooter.view.MyNetworkImageView
|
||||||
|
import jp.juggler.subwaytooter.view.MyTextView
|
||||||
|
import org.jetbrains.anko.custom.ankoView
|
||||||
|
|
||||||
|
// Anko Layout中にカスタムビューを指定する為に拡張関数を定義する
|
||||||
|
|
||||||
|
inline fun ViewManager.myNetworkImageView(init: MyNetworkImageView.() -> Unit): MyNetworkImageView {
|
||||||
|
return ankoView({ MyNetworkImageView(it) }, theme = 0, init = init)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun ViewManager.myTextView(init: MyTextView.() -> Unit): MyTextView {
|
||||||
|
return ankoView({ MyTextView(it) }, theme = 0, init = init)
|
||||||
|
}
|
||||||
|
|
49
app/src/main/java/jp/juggler/subwaytooter/util/AnkoHelper.kt
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package jp.juggler.subwaytooter.util
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
|
||||||
|
// marginStart,marginEnd と leftMargin,topMargin の表記ゆれの対策
|
||||||
|
var ViewGroup.MarginLayoutParams.startMargin : Int
|
||||||
|
get() = marginStart
|
||||||
|
set(start) {
|
||||||
|
marginStart = start
|
||||||
|
}
|
||||||
|
|
||||||
|
// marginStart,marginEnd と leftMargin,topMargin の表記ゆれの対策
|
||||||
|
var ViewGroup.MarginLayoutParams.endMargin : Int
|
||||||
|
get() = marginEnd
|
||||||
|
set(end) {
|
||||||
|
marginEnd = end
|
||||||
|
}
|
||||||
|
|
||||||
|
// paddingStart,paddingEndにはsetterが提供されてない問題の対策
|
||||||
|
// 表記もtopPadding,bottomPaddingと揃えてある
|
||||||
|
var View.startPadding : Int
|
||||||
|
get() = paddingStart
|
||||||
|
set(start) {
|
||||||
|
setPaddingRelative(start, paddingTop, paddingEnd, paddingBottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
// paddingStart,paddingEndにはsetterが提供されてない問題の対策
|
||||||
|
// 表記もtopPadding,bottomPaddingと揃えてある
|
||||||
|
var View.endPadding : Int
|
||||||
|
get() = paddingEnd
|
||||||
|
set(end) {
|
||||||
|
setPaddingRelative(paddingStart, paddingTop, end, paddingBottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
// paddingStart,paddingEndにはsetterが提供されてない問題の対策
|
||||||
|
fun View.setPaddingStartEnd(start : Int, end : Int) {
|
||||||
|
setPaddingRelative(start, paddingTop, end, paddingBottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
// XMLのandroid:minWidthと同じことをしたい場合、View#setMinimumWidthとTextView#setMinWidthの両方を呼び出す必要がある
|
||||||
|
// http://www.thekingsmuseum.info/entry/2015/12/01/233134
|
||||||
|
var TextView.minWidthCompat : Int
|
||||||
|
get() = minWidth
|
||||||
|
set(value) {
|
||||||
|
minimumWidth = value
|
||||||
|
minWidth = value
|
||||||
|
}
|
@ -5,10 +5,11 @@ import java.util.ArrayList
|
|||||||
import java.util.NoSuchElementException
|
import java.util.NoSuchElementException
|
||||||
import java.util.RandomAccess
|
import java.util.RandomAccess
|
||||||
|
|
||||||
class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : AbstractList<E>(), MutableIterable<E>, RandomAccess {
|
class BucketList<E> constructor(
|
||||||
|
val bucketCapacity : Int = 1024
|
||||||
|
) : AbstractList<E>(), MutableIterable<E>, RandomAccess {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val pos_internal = object : ThreadLocal<BucketPos>() {
|
private val pos_internal = object : ThreadLocal<BucketPos>() {
|
||||||
override fun initialValue() : BucketPos {
|
override fun initialValue() : BucketPos {
|
||||||
return BucketPos()
|
return BucketPos()
|
||||||
@ -22,10 +23,11 @@ class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : Abstr
|
|||||||
return 0 == size
|
return 0 == size
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Bucket<E> internal constructor(capacity : Int) : ArrayList<E>(capacity) {
|
private class Bucket<E>(
|
||||||
internal var total_start : Int = 0
|
capacity : Int,
|
||||||
internal var total_end : Int = 0
|
var total_start : Int = 0,
|
||||||
}
|
var total_end : Int = 0
|
||||||
|
) : ArrayList<E>(capacity)
|
||||||
|
|
||||||
private val groups = ArrayList<Bucket<E>>()
|
private val groups = ArrayList<Bucket<E>>()
|
||||||
|
|
||||||
@ -44,8 +46,11 @@ class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : Abstr
|
|||||||
size = n
|
size = n
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BucketPos(var group_index : Int = 0, var bucket_index : Int = 0) {
|
internal class BucketPos(
|
||||||
internal fun update(group_index : Int, bucket_index : Int) : BucketPos {
|
var group_index : Int = 0,
|
||||||
|
var bucket_index : Int = 0
|
||||||
|
) {
|
||||||
|
internal fun set(group_index : Int, bucket_index : Int) : BucketPos {
|
||||||
this.group_index = group_index
|
this.group_index = group_index
|
||||||
this.bucket_index = bucket_index
|
this.bucket_index = bucket_index
|
||||||
return this
|
return this
|
||||||
@ -53,15 +58,18 @@ class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : Abstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocalted を指定しない場合は BucketPosを生成します
|
// allocalted を指定しない場合は BucketPosを生成します
|
||||||
private fun findPos(total_index : Int, allocated : BucketPos? = pos_internal.get()) : BucketPos {
|
private fun findPos(
|
||||||
|
total_index : Int,
|
||||||
|
result : BucketPos = pos_internal.get()
|
||||||
|
) : BucketPos {
|
||||||
|
|
||||||
if(total_index < 0 || total_index >= size) {
|
if(total_index < 0 || total_index >= size) {
|
||||||
throw IndexOutOfBoundsException("findPos: bad index=$total_index, size=$size")
|
throw IndexOutOfBoundsException("findPos: bad index=$total_index, size=$size")
|
||||||
}
|
}
|
||||||
|
|
||||||
// binary search
|
// binary search
|
||||||
val groups_size = groups.size
|
|
||||||
var gs = 0
|
var gs = 0
|
||||||
var ge = groups_size
|
var ge = groups.size
|
||||||
while(true) {
|
while(true) {
|
||||||
val gi = (gs + ge) shr 1
|
val gi = (gs + ge) shr 1
|
||||||
val group = groups[gi]
|
val group = groups[gi]
|
||||||
@ -69,8 +77,7 @@ class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : Abstr
|
|||||||
total_index < group.total_start -> ge = gi
|
total_index < group.total_start -> ge = gi
|
||||||
total_index >= group.total_end -> gs = gi + 1
|
total_index >= group.total_end -> gs = gi + 1
|
||||||
else -> {
|
else -> {
|
||||||
return (allocated ?: BucketPos())
|
return result.set(gi, total_index - group.total_start)
|
||||||
.update(gi, total_index - group.total_start)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,9 +94,9 @@ class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : Abstr
|
|||||||
if(c_size == 0) return false
|
if(c_size == 0) return false
|
||||||
|
|
||||||
// 最後のバケツに収まるなら、最後のバケツの中に追加する
|
// 最後のバケツに収まるなら、最後のバケツの中に追加する
|
||||||
if(groups.size > 0) {
|
if( groups.isNotEmpty() ) {
|
||||||
val bucket = groups[groups.size - 1]
|
val bucket = groups[groups.size -1]
|
||||||
if(bucket.size + c_size <= bucketCapacity) {
|
if( bucket.size + c_size <= bucketCapacity) {
|
||||||
bucket.addAll(elements)
|
bucket.addAll(elements)
|
||||||
bucket.total_end += c_size
|
bucket.total_end += c_size
|
||||||
size += c_size
|
size += c_size
|
||||||
@ -111,7 +118,7 @@ class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : Abstr
|
|||||||
|
|
||||||
// indexが終端なら、終端に追加する
|
// indexが終端なら、終端に追加する
|
||||||
// バケツがカラの場合もここ
|
// バケツがカラの場合もここ
|
||||||
if(index == size) {
|
if(index >= size) {
|
||||||
return addAll(elements)
|
return addAll(elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,5 +200,4 @@ class BucketList<E> constructor(private val bucketCapacity : Int = 1024) : Abstr
|
|||||||
override fun iterator() : MutableIterator<E> {
|
override fun iterator() : MutableIterator<E> {
|
||||||
return MyIterator()
|
return MyIterator()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
BIN
app/src/main/res/drawable-hdpi/ic_face.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-hdpi/ic_face_dark.png
Normal file
After Width: | Height: | Size: 1003 B |
BIN
app/src/main/res/drawable-mdpi/ic_face.png
Normal file
After Width: | Height: | Size: 712 B |
BIN
app/src/main/res/drawable-mdpi/ic_face_dark.png
Normal file
After Width: | Height: | Size: 625 B |
BIN
app/src/main/res/drawable-xhdpi/ic_face.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_face_dark.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_face.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_face_dark.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
@ -189,12 +189,29 @@
|
|||||||
/>
|
/>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:baselineAligned="false"
|
||||||
android:text="@string/status"
|
android:orientation="horizontal"
|
||||||
/>
|
>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/status"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
/>
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btnEmojiPicker"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:background="@drawable/btn_bg_transparent"
|
||||||
|
android:contentDescription="@string/open_picker_emoji"
|
||||||
|
android:src="?attr/ic_face"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -375,7 +375,7 @@
|
|||||||
<string name="text_to_speech_initialize_failed">TextToSpeech initializing failed. status=%1$s</string>
|
<string name="text_to_speech_initialize_failed">TextToSpeech initializing failed. status=%1$s</string>
|
||||||
<string name="text_to_speech_shutdown">TextToSpeech shutdown…</string>
|
<string name="text_to_speech_shutdown">TextToSpeech shutdown…</string>
|
||||||
<string name="show_post_button_bar_top">Show buttons bar at the top of posting screen</string>
|
<string name="show_post_button_bar_top">Show buttons bar at the top of posting screen</string>
|
||||||
<string name="client_name">Client name (access token update required)</string>
|
<string name="client_name">Client name (access token set required)</string>
|
||||||
<string name="toot_search">Toot search</string>
|
<string name="toot_search">Toot search</string>
|
||||||
<string name="mastodon_search_portal">MSP(JP)</string>
|
<string name="mastodon_search_portal">MSP(JP)</string>
|
||||||
<string name="search_desc_mastodon_api">Account/Hashtag search using Mastodon API.</string>
|
<string name="search_desc_mastodon_api">Account/Hashtag search using Mastodon API.</string>
|
||||||
@ -519,7 +519,7 @@
|
|||||||
<string name="card_header_card">Card</string>
|
<string name="card_header_card">Card</string>
|
||||||
<string name="card_header_author">Author</string>
|
<string name="card_header_author">Author</string>
|
||||||
<string name="card_header_provider">Provider</string>
|
<string name="card_header_provider">Provider</string>
|
||||||
<string name="allow_non_space_before_emoji_code">Allow non-space character before emoji shortcode (Affect to display and post. to update display, please restart app and reload column. The emojis converted at posting can\'t be restored to shortcode.)</string>
|
<string name="allow_non_space_before_emoji_code">Allow non-space character before emoji shortcode (Affect to display and post. to set display, please restart app and reload column. The emojis converted at posting can\'t be restored to shortcode.)</string>
|
||||||
<string name="emoji">Emoji</string>
|
<string name="emoji">Emoji</string>
|
||||||
<string name="not_blocked">Not blocked.</string>
|
<string name="not_blocked">Not blocked.</string>
|
||||||
<string name="not_muted">Not muted.</string>
|
<string name="not_muted">Not muted.</string>
|
||||||
@ -594,7 +594,7 @@
|
|||||||
<string name="new_item">New item…</string>
|
<string name="new_item">New item…</string>
|
||||||
<string name="word_empty">Please input keyword.</string>
|
<string name="word_empty">Please input keyword.</string>
|
||||||
<string name="already_exist">already exist.</string>
|
<string name="already_exist">already exist.</string>
|
||||||
<string name="highlight_desc">Swipe to delete. You may need reload column to check update.</string>
|
<string name="highlight_desc">Swipe to delete. You may need reload column to check set.</string>
|
||||||
<string name="check_sound">Check sound</string>
|
<string name="check_sound">Check sound</string>
|
||||||
<string name="keyword">Keyword</string>
|
<string name="keyword">Keyword</string>
|
||||||
<string name="domain_block_from_pseudo">Can\'t use domain block from pseudo account.</string>
|
<string name="domain_block_from_pseudo">Can\'t use domain block from pseudo account.</string>
|
||||||
|
@ -134,5 +134,6 @@
|
|||||||
<attr name="ic_left" format="reference" />
|
<attr name="ic_left" format="reference" />
|
||||||
<attr name="ic_right" format="reference" />
|
<attr name="ic_right" format="reference" />
|
||||||
<attr name="ic_volume_up" format="reference" />
|
<attr name="ic_volume_up" format="reference" />
|
||||||
|
<attr name="ic_face" format="reference" />
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -24,7 +24,7 @@
|
|||||||
<string name="home">Home</string>
|
<string name="home">Home</string>
|
||||||
<string name="local_timeline">Local timeline</string>
|
<string name="local_timeline">Local timeline</string>
|
||||||
<string name="federate_timeline">Federated timeline</string>
|
<string name="federate_timeline">Federated timeline</string>
|
||||||
<string name="login_required">Please update your access token from the account setting.</string>
|
<string name="login_required">Please set your access token from the account setting.</string>
|
||||||
<string name="cancelled">Cancelled</string>
|
<string name="cancelled">Cancelled</string>
|
||||||
<string name="account_pick">Select an account</string>
|
<string name="account_pick">Select an account</string>
|
||||||
<string name="account_confirmed">Account confirmed.</string>
|
<string name="account_confirmed">Account confirmed.</string>
|
||||||
@ -367,7 +367,7 @@
|
|||||||
<string name="text_to_speech_initialize_failed">TextToSpeech initializing failed. status=%1$s</string>
|
<string name="text_to_speech_initialize_failed">TextToSpeech initializing failed. status=%1$s</string>
|
||||||
<string name="text_to_speech_shutdown">TextToSpeech shutdown…</string>
|
<string name="text_to_speech_shutdown">TextToSpeech shutdown…</string>
|
||||||
<string name="show_post_button_bar_top">Show buttons bar at the top of posting screen</string>
|
<string name="show_post_button_bar_top">Show buttons bar at the top of posting screen</string>
|
||||||
<string name="client_name">Client name (access token update required)</string>
|
<string name="client_name">Client name (access token set required)</string>
|
||||||
<string name="toot_search">Toot search</string>
|
<string name="toot_search">Toot search</string>
|
||||||
<string name="toot_search_msp">Toot search(MSP)</string>
|
<string name="toot_search_msp">Toot search(MSP)</string>
|
||||||
<string name="toot_search_ts">Toot search(ts)</string>
|
<string name="toot_search_ts">Toot search(ts)</string>
|
||||||
@ -514,7 +514,7 @@
|
|||||||
<string name="card_header_card">Card</string>
|
<string name="card_header_card">Card</string>
|
||||||
<string name="card_header_author">Author</string>
|
<string name="card_header_author">Author</string>
|
||||||
<string name="card_header_provider">Provider</string>
|
<string name="card_header_provider">Provider</string>
|
||||||
<string name="allow_non_space_before_emoji_code">Allow non-space character before emoji shortcode (Affect to display and post. to update display, please restart app and reload column. The emojis converted at posting can\'t be restored to shortcode.)</string>
|
<string name="allow_non_space_before_emoji_code">Allow non-space character before emoji shortcode (Affect to display and post. to set display, please restart app and reload column. The emojis converted at posting can\'t be restored to shortcode.)</string>
|
||||||
<string name="emoji">Emoji</string>
|
<string name="emoji">Emoji</string>
|
||||||
<string name="not_blocked">Not blocked.</string>
|
<string name="not_blocked">Not blocked.</string>
|
||||||
<string name="not_muted">Not muted.</string>
|
<string name="not_muted">Not muted.</string>
|
||||||
@ -583,7 +583,7 @@
|
|||||||
<string name="new_item">New item…</string>
|
<string name="new_item">New item…</string>
|
||||||
<string name="word_empty">Please input keyword.</string>
|
<string name="word_empty">Please input keyword.</string>
|
||||||
<string name="already_exist">already exist.</string>
|
<string name="already_exist">already exist.</string>
|
||||||
<string name="highlight_desc">Swipe to delete. You may need reload column to check update.</string>
|
<string name="highlight_desc">Swipe to delete. You may need reload column to check set.</string>
|
||||||
<string name="check_sound">Check sound</string>
|
<string name="check_sound">Check sound</string>
|
||||||
<string name="keyword">Keyword</string>
|
<string name="keyword">Keyword</string>
|
||||||
<string name="domain_block_from_pseudo">Can\'t use domain block from pseudo account.</string>
|
<string name="domain_block_from_pseudo">Can\'t use domain block from pseudo account.</string>
|
||||||
|
@ -107,6 +107,7 @@
|
|||||||
<item name="ic_left">@drawable/ic_left</item>
|
<item name="ic_left">@drawable/ic_left</item>
|
||||||
<item name="ic_right">@drawable/ic_right</item>
|
<item name="ic_right">@drawable/ic_right</item>
|
||||||
<item name="ic_volume_up">@drawable/ic_volume_up</item>
|
<item name="ic_volume_up">@drawable/ic_volume_up</item>
|
||||||
|
<item name="ic_face">@drawable/ic_face</item>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -217,7 +218,7 @@
|
|||||||
<item name="ic_left">@drawable/ic_left_dark</item>
|
<item name="ic_left">@drawable/ic_left_dark</item>
|
||||||
<item name="ic_right">@drawable/ic_right_dark</item>
|
<item name="ic_right">@drawable/ic_right_dark</item>
|
||||||
<item name="ic_volume_up">@drawable/ic_volume_up_dark</item>
|
<item name="ic_volume_up">@drawable/ic_volume_up_dark</item>
|
||||||
|
<item name="ic_face">@drawable/ic_face_dark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.Dark.NoActionBar" parent="AppTheme.Dark">
|
<style name="AppTheme.Dark.NoActionBar" parent="AppTheme.Dark">
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
|
|
||||||
ext.kotlin_version = '1.2.10'
|
ext.kotlin_version = '1.2.10'
|
||||||
|
ext.anko_version='0.10.4'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
|