Spracherkennung für: .kt vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
package ch.threema.app.ui
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.WindowManager.BadTokenException
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.ViewCompat
import ch.threema.app.R
import ch.threema.app.cache.ThumbnailCache
import ch.threema.app.emojis.EmojiMarkupUtil
import ch.threema.app.preference.service.PreferenceService
import ch.threema.app.services.ContactService
import ch.threema.app.services.FileService
import ch.threema.app.services.UserService
import ch.threema.app.utils.ConfigUtils
import ch.threema.app.utils.MessageUtil
import ch.threema.app.utils.NameUtil
import ch.threema.app.utils.QuoteUtil
import ch.threema.domain.types.IdentityString
import ch.threema.storage.models.AbstractMessageModel
import com.google.android.material.card.MaterialCardView
import com.google.android.material.textfield.TextInputLayout
@SuppressLint("InflateParams")
class QuotePopup(
private val context: Context,
private val contactService: ContactService,
private val userService: UserService,
private val fileService: FileService,
private val preferenceService: PreferenceService,
private val thumbnailCache: ThumbnailCache<*>,
) : MovingPopupWindow(context) {
private val quoteTextView: TextView
private val quoteIdentityView: TextView
private val quoteThumbnail: ImageView
private val quoteTypeImage: ImageView
private val quoteBar: View
private val popupLayout: MaterialCardView
private var quotePopupListener: QuotePopupListener? = null
class QuoteInfo {
var quoteText: String? = null
var quoteIdentity: IdentityString? = null
var messageModel: AbstractMessageModel? = null
}
val quoteInfo = QuoteInfo()
init {
popupLayout = LayoutInflater.from(context).inflate(R.layout.popup_quote, null, false) as MaterialCardView
quoteTextView = popupLayout.findViewById(R.id.quote_text_view)
quoteIdentityView = popupLayout.findViewById(R.id.quote_id_view)
quoteBar = popupLayout.findViewById(R.id.quote_bar)
quoteThumbnail = popupLayout.findViewById(R.id.quote_thumbnail)
quoteTypeImage = popupLayout.findViewById(R.id.quote_type_image)
val quoteCloseButton = popupLayout.findViewById<ImageView>(R.id.quote_panel_close_button)
quoteCloseButton.setOnClickListener { dismiss() }
contentView = popupLayout
inputMethodMode = INPUT_METHOD_NEEDED
animationStyle = R.style.Threema_Animation_QuotePopup
isFocusable = false
isTouchable = true
isOutsideTouchable = false
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
@Suppress("DEPRECATION")
setWindowLayoutMode(0, ViewGroup.LayoutParams.WRAP_CONTENT)
height = 1
}
fun show(
activity: Activity,
editText: ComposeEditText,
textInputLayout: TextInputLayout,
messageModel: AbstractMessageModel,
identity: IdentityString?,
barColor: ColorStateList,
listener: QuotePopupListener?,
) {
this.quotePopupListener = listener
super.show(activity, textInputLayout)
popupLayout.setCardBackgroundColor(textInputLayout.boxBackgroundColor)
val coordinates = ConfigUtils.getPopupWindowPositionAboveAnchor(activity, textInputLayout)
val popupX = coordinates[0]
val popupY = coordinates[1]
val viewableSpaceHeight =
coordinates[2] - context.resources.getDimensionPixelSize(R.dimen.compose_bottom_panel_padding_bottom)
this.width = editText.width
this.height = viewableSpaceHeight
try {
showAtLocation(editText, Gravity.LEFT or Gravity.BOTTOM, popupX, popupY)
adjustCornersToOpenState(textInputLayout, 20)
contentView.viewTreeObserver.addOnGlobalLayoutListener(
object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
contentView?.viewTreeObserver?.removeOnGlobalLayoutListener(this)
listener?.onHeightSet(popupLayout.measuredHeight)
}
},
)
anchorView?.let {
ViewCompat.setWindowInsetsAnimationCallback(it, windowInsetsAnimationCallback)
it.addOnLayoutChangeListener(onLayoutChangeListener)
}
adjustCornersToOpenState(textInputLayout, 200)
} catch (_: BadTokenException) {
// Ignore
}
quoteInfo.messageModel = messageModel
quoteInfo.quoteText = QuoteUtil.getMessageBody(
quoteInfo.messageModel?.type,
quoteInfo.messageModel?.body,
quoteInfo.messageModel?.caption,
quoteInfo.messageModel?.isOutbox,
true,
preferenceService.getContactNameFormat(),
)
quoteInfo.quoteIdentity = identity
quoteIdentityView.text = NameUtil.getQuoteName(
quoteInfo.quoteIdentity,
contactService,
userService,
preferenceService.getContactNameFormat(),
)
quoteBar.backgroundTintList = barColor
quoteTextView.text = EmojiMarkupUtil.getInstance()
.addTextSpans(activity, quoteInfo.quoteText, quoteTextView, false, false)
quoteThumbnail.visibility = View.GONE
quoteTypeImage.visibility = View.GONE
try {
val thumbnail = fileService.getMessageThumbnailBitmap(
messageModel,
thumbnailCache,
)
if (thumbnail != null) {
quoteThumbnail.setImageBitmap(thumbnail)
quoteThumbnail.visibility = View.VISIBLE
}
} catch (_: Exception) {
// Ignore
}
val messageViewElement = MessageUtil.getViewElement(context, messageModel, preferenceService.getContactNameFormat())
if (messageViewElement.icon != null) {
quoteTypeImage.setImageResource(messageViewElement.icon)
quoteTypeImage.visibility = View.VISIBLE
}
quotePopupListener?.onPostVisibilityChange()
}
fun adjustCornersToOpenState(layout: TextInputLayout, delayMs: Long) {
layout.postDelayed(
{
layout.setBoxCornerRadiiResources(
R.dimen.compose_textinputlayout_radius_expanded,
R.dimen.compose_textinputlayout_radius_expanded,
R.dimen.compose_textinputlayout_radius,
R.dimen.compose_textinputlayout_radius,
)
},
delayMs,
)
}
override fun dismiss() {
anchorView?.let {
it.postDelayed(
{
it.setBoxCornerRadiiResources(
R.dimen.compose_textinputlayout_radius,
R.dimen.compose_textinputlayout_radius,
R.dimen.compose_textinputlayout_radius,
R.dimen.compose_textinputlayout_radius,
)
},
200,
)
it.removeOnLayoutChangeListener(onLayoutChangeListener)
ViewCompat.setWindowInsetsAnimationCallback(it, null)
}
quotePopupListener?.onDismiss()
super.dismiss()
quotePopupListener?.onPostVisibilityChange()
}
interface QuotePopupListener {
fun onHeightSet(height: Int)
fun onDismiss()
fun onPostVisibilityChange()
}
}