package jp.juggler.subwaytooter import android.content.Context import android.support.v4.content.ContextCompat import android.view.View import android.widget.ImageButton import android.widget.ImageView import android.widget.LinearLayout import android.widget.PopupWindow import com.google.android.flexbox.FlexWrap import com.google.android.flexbox.FlexboxLayout import com.google.android.flexbox.JustifyContent import jp.juggler.subwaytooter.action.Action_Follow import jp.juggler.subwaytooter.action.Action_Toot import jp.juggler.subwaytooter.action.NOT_CROSS_ACCOUNT import jp.juggler.subwaytooter.api.entity.TootNotification import jp.juggler.subwaytooter.api.entity.TootStatus import jp.juggler.subwaytooter.api.entity.TootVisibility import jp.juggler.subwaytooter.table.SavedAccount import jp.juggler.subwaytooter.table.UserRelation import jp.juggler.subwaytooter.util.startMargin import jp.juggler.subwaytooter.view.CountImageButton import jp.juggler.util.* import org.jetbrains.anko.* import org.jetbrains.anko.custom.customView internal class StatusButtons( private val activity : ActMain, private val column : Column, private val bSimpleList : Boolean, private val holder : StatusButtonsViewHolder, private val itemViewHolder : ItemViewHolder ) : View.OnClickListener, View.OnLongClickListener { companion object { val log = LogCategory("StatusButtons") } private val access_info : SavedAccount private var relation : UserRelation? = null private var status : TootStatus? = null private var notification : TootNotification? = null var close_window : PopupWindow? = null private val btnConversation = holder.btnConversation private val btnReply = holder.btnReply private val btnBoost = holder.btnBoost private val btnFavourite = holder.btnFavourite private val llFollow2 = holder.llFollow2 private val btnFollow2 = holder.btnFollow2 private val ivFollowedBy2 = holder.ivFollowedBy2 private val btnMore = holder.btnMore private val color_normal = column.getContentColor() private val color_accent : Int get() = getAttributeColor(activity, R.attr.colorImageButtonAccent) init { this.access_info = column.access_info btnBoost.setOnClickListener(this) btnBoost.setOnLongClickListener(this) btnFavourite.setOnClickListener(this) btnFavourite.setOnLongClickListener(this) btnFollow2.setOnClickListener(this) btnFollow2.setOnLongClickListener(this) btnMore.setOnClickListener(this) btnConversation.setOnClickListener(this) btnConversation.setOnLongClickListener(this) btnReply.setOnClickListener(this) btnReply.setOnLongClickListener(this) } fun hide() { holder.viewRoot.visibility = View.GONE } fun bind(status : TootStatus, notification : TootNotification?) { holder.viewRoot.visibility = View.VISIBLE this.status = status this.notification = notification val fav_icon_drawable = when { access_info.isNicoru(status.account) -> R.drawable.ic_nicoru else -> R.drawable.ic_star } val replies_count = status.replies_count setIconDrawableId( activity, btnConversation, R.drawable.ic_forum, color = color_normal, alphaMultiplier = Styler.boost_alpha ) setIconDrawableId( activity, btnMore, R.drawable.ic_more, color = color_normal, alphaMultiplier = Styler.boost_alpha ) // val a = (((color_normal ushr 24)/255f) * 0.7f) // setIconDrawableId で色を指定するとアルファ値も反映されるらしい // btnConversation.alpha = a // btnMore.alpha = a // // btnReply.alpha = a // btnBoost.alpha = a // btnFavourite.alpha = a // btnFollow2.alpha = a // ivFollowedBy2.alpha = a setButton( btnReply, true, color_normal, R.drawable.ic_reply, when(replies_count) { null -> "" else -> when(Pref.ipRepliesCount(activity.pref)) { Pref.RC_SIMPLE -> when { replies_count >= 2L -> "1+" replies_count == 1L -> "1" else -> "" } Pref.RC_ACTUAL -> replies_count.toString() else -> "" } }, activity.getString(R.string.reply) ) // ブーストボタン when { // マストドンではDirectはブーストできない (Misskeyはできる) (! access_info.isMisskey && status.visibility.order <= TootVisibility.DirectSpecified.order) -> setButton( btnBoost, false, color_accent, R.drawable.ic_repeat, "", activity.getString(R.string.boost) ) activity.app_state.isBusyBoost(access_info, status) -> setButton( btnBoost, false, color_normal, R.drawable.ic_refresh, "?", activity.getString(R.string.boost) ) else -> setButton( btnBoost, true, if(status.reblogged) color_accent else color_normal, R.drawable.ic_repeat, status.reblogs_count?.toString() ?: "", activity.getString(R.string.boost) ) } when { activity.app_state.isBusyFav(access_info, status) -> setButton( btnFavourite, false, color_normal, R.drawable.ic_refresh, "?", activity.getString(R.string.favourite) ) else -> setButton( btnFavourite, true, if(status.favourited) color_accent else color_normal, fav_icon_drawable, status.favourites_count?.toString() ?: "", activity.getString(R.string.favourite) ) } val account = status.account this.relation = if(! Pref.bpShowFollowButtonInButtonBar(activity.pref)) { llFollow2.visibility = View.GONE null } else { llFollow2.visibility = View.VISIBLE val relation = UserRelation.load(access_info.db_id, account.id) Styler.setFollowIcon( activity, btnFollow2, ivFollowedBy2, relation, account, color_normal, alphaMultiplier = Styler.boost_alpha ) relation } } private fun setButton( b : CountImageButton, enabled : Boolean, color : Int, drawableId : Int, count : String, contentDescription : String ) { val d = createColoredDrawable(activity, drawableId, color, alphaMultiplier = Styler.boost_alpha) b.setImageDrawable(d) b.setPaddingAndText(holder.paddingH, holder.paddingV, count, 14f, holder.compoundPaddingDp) b.setTextColor(color.applyAlphaMultiplier(Styler.boost_alpha)) b.contentDescription = contentDescription + count b.isEnabled = enabled } override fun onClick(v : View) { close_window?.dismiss() close_window = null val status = this.status ?: return when(v) { btnConversation -> { val cs = status.conversationSummary if(cs != null) { if(cs.unread) { cs.unread = false // 表示の更新 itemViewHolder.list_adapter.notifyChange( reason = "ConversationSummary reset unread", reset = true ) // 未読フラグのクリアをサーバに送る Action_Toot.clearConversationUnread(activity, access_info, cs) } } Action_Toot.conversation( activity, activity.nextPosition(column), access_info, status ) } btnReply -> if(! access_info.isPseudo) { Action_Toot.reply(activity, access_info, status) } else { Action_Toot.replyFromAnotherAccount(activity, access_info, status) } btnBoost -> { if(access_info.isPseudo) { Action_Toot.boostFromAnotherAccount(activity, access_info, status) } else { // トグル動作 val bSet = ! status.reblogged Action_Toot.boost( activity, access_info, status, access_info.getFullAcct(status.account), NOT_CROSS_ACCOUNT, when { ! bSimpleList -> null // 簡略表示なら結果をトースト表示 bSet -> activity.boost_complete_callback else -> activity.unboost_complete_callback }, bSet = bSet ) } } btnFavourite -> { if(access_info.isPseudo) { Action_Toot.favouriteFromAnotherAccount(activity, access_info, status) } else { // トグル動作 val bSet = ! status.favourited Action_Toot.favourite( activity, access_info, status, NOT_CROSS_ACCOUNT, when { ! bSimpleList -> null // 簡略表示なら結果をトースト表示 bSet -> activity.favourite_complete_callback else -> activity.unfavourite_complete_callback }, bSet = bSet ) } } btnFollow2 -> { val accountRef = status.accountRef val account = accountRef.get() val relation = this.relation ?: return when { access_info.isPseudo -> { // 別アカでフォロー Action_Follow.followFromAnotherAccount( activity, activity.nextPosition(column), access_info, account ) } relation.blocking || relation.muting -> { // 何もしない } access_info.isMisskey && relation.getRequested(account) && ! relation.getFollowing( account ) -> Action_Follow.deleteFollowRequest( activity, activity.nextPosition(column), access_info, accountRef, callback = activity.cancel_follow_request_complete_callback ) relation.getFollowing(account) || relation.getRequested(account) -> { // フォロー解除 Action_Follow.follow( activity, activity.nextPosition(column), access_info, accountRef, bFollow = false, callback = activity.unfollow_complete_callback ) } else -> { // フォロー Action_Follow.follow( activity, activity.nextPosition(column), access_info, accountRef, bFollow = true, callback = activity.follow_complete_callback ) } } } btnMore -> DlgContextMenu( activity, column, status.accountRef, status, notification, itemViewHolder.tvContent ).show() } } override fun onLongClick(v : View) : Boolean { close_window?.dismiss() close_window = null val status = this.status ?: return true when(v) { btnConversation -> Action_Toot.conversationOtherInstance( activity, activity.nextPosition(column), 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 ) } return true } } open class _FlexboxLayout(ctx : Context) : FlexboxLayout(ctx) { inline fun T.lparams( width : Int = android.view.ViewGroup.LayoutParams.WRAP_CONTENT, height : Int = android.view.ViewGroup.LayoutParams.WRAP_CONTENT, init : FlexboxLayout.LayoutParams.() -> Unit = {} ) : T { val layoutParams = FlexboxLayout.LayoutParams(width, height) layoutParams.init() this@lparams.layoutParams = layoutParams return this } } class StatusButtonsViewHolder( activity : ActMain , lpWidth : Int , topMarginDp : Float , @JustifyContent justifyContent : Int = JustifyContent.CENTER ) { private val buttonHeight = ActMain.boostButtonSize private val marginBetween = (ActMain.boostButtonSize.toFloat() * 0.05f + 0.5f).toInt() val paddingH = (buttonHeight.toFloat() * 0.1f + 0.5f).toInt() val paddingV = (buttonHeight.toFloat() * 0.1f + 0.5f).toInt() val compoundPaddingDp = 0f // ActMain.boostButtonSize.toFloat() * -0f / activity.resources.displayMetrics.density val viewRoot : FlexboxLayout lateinit var btnConversation : ImageButton lateinit var btnReply : CountImageButton lateinit var btnBoost : CountImageButton lateinit var btnFavourite : CountImageButton lateinit var llFollow2 : View lateinit var btnFollow2 : ImageButton lateinit var ivFollowedBy2 : ImageView lateinit var btnMore : ImageButton init { viewRoot = with(activity.UI {}) { customView<_FlexboxLayout> { // トップレベルのViewGroupのlparamsはイニシャライザ内部に置くしかないみたい layoutParams = LinearLayout.LayoutParams(lpWidth, wrapContent).apply { topMargin = dip(topMarginDp) } flexWrap = FlexWrap.WRAP this.justifyContent = justifyContent btnConversation = imageButton { background = ContextCompat.getDrawable( context, R.drawable.btn_bg_transparent ) contentDescription = context.getString(R.string.conversation_view) setPadding(paddingH, paddingV, paddingH, paddingV) scaleType = ImageView.ScaleType.FIT_CENTER imageResource = R.drawable.ic_forum }.lparams(buttonHeight, buttonHeight) btnReply = customView { background = ContextCompat.getDrawable( context, R.drawable.btn_bg_transparent ) setPadding(paddingH, paddingV, paddingH, paddingV) scaleType = ImageView.ScaleType.FIT_CENTER minimumWidth = buttonHeight }.lparams(wrapContent, buttonHeight) { startMargin = marginBetween } btnBoost = customView { background = ContextCompat.getDrawable( context, R.drawable.btn_bg_transparent ) setPadding(paddingH, paddingV, paddingH, paddingV) scaleType = ImageView.ScaleType.FIT_CENTER minimumWidth = buttonHeight }.lparams(wrapContent, buttonHeight) { startMargin = marginBetween } btnFavourite = customView { background = ContextCompat.getDrawable( context, R.drawable.btn_bg_transparent ) setPadding(paddingH, paddingV, paddingH, paddingV) scaleType = ImageView.ScaleType.FIT_CENTER minimumWidth = buttonHeight }.lparams(wrapContent, buttonHeight) { startMargin = marginBetween } llFollow2 = frameLayout { lparams(buttonHeight, buttonHeight) { startMargin = marginBetween } btnFollow2 = imageButton { background = ContextCompat.getDrawable( context, R.drawable.btn_bg_transparent ) setPadding(paddingH, paddingV, paddingH, paddingV) scaleType = ImageView.ScaleType.FIT_CENTER contentDescription = context.getString(R.string.follow) }.lparams(matchParent, matchParent) ivFollowedBy2 = imageView { setPadding(paddingH, paddingV, paddingH, paddingV) scaleType = ImageView.ScaleType.FIT_CENTER importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO }.lparams(matchParent, matchParent) } btnMore = imageButton { background = ContextCompat.getDrawable( context, R.drawable.btn_bg_transparent ) setPadding(paddingH, paddingV, paddingH, paddingV) scaleType = ImageView.ScaleType.FIT_CENTER contentDescription = context.getString(R.string.more) imageResource = R.drawable.ic_more }.lparams(buttonHeight, buttonHeight) { startMargin = marginBetween } } } } }