Adapt quote view for use in messages

This commit is contained in:
Niels Andriesse 2021-06-21 10:53:52 +10:00
parent 84fa6cdcb6
commit ce5f923b25
4 changed files with 65 additions and 10 deletions

View File

@ -85,10 +85,10 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate {
fun draftQuote(message: MessageRecord) { fun draftQuote(message: MessageRecord) {
inputBarAdditionalContentContainer.removeAllViews() inputBarAdditionalContentContainer.removeAllViews()
val quoteView = QuoteView(context) val quoteView = QuoteView(context, QuoteView.Mode.Draft)
quoteView.delegate = this quoteView.delegate = this
inputBarAdditionalContentContainer.addView(quoteView) inputBarAdditionalContentContainer.addView(quoteView)
quoteView.bind(message.individualRecipient.address.toString(), message.body, null, message.recipient) quoteView.bind(message.individualRecipient.address.toString(), message.body, null, message.recipient, true)
val quoteViewIntrinsicHeight = quoteView.getIntrinsicHeight() val quoteViewIntrinsicHeight = quoteView.getIntrinsicHeight()
val newHeight = max(inputBarEditText.height + 2 * vMargin, toPx(56, resources)) + quoteViewIntrinsicHeight val newHeight = max(inputBarEditText.height + 2 * vMargin, toPx(56, resources)) + quoteViewIntrinsicHeight
additionalContentHeight = quoteViewIntrinsicHeight additionalContentHeight = quoteViewIntrinsicHeight

View File

@ -6,6 +6,8 @@ import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.RelativeLayout import android.widget.RelativeLayout
import androidx.annotation.ColorInt
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.view_quote.view.* import kotlinx.android.synthetic.main.view_quote.view.*
import network.loki.messenger.R import network.loki.messenger.R
@ -14,12 +16,16 @@ import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.loki.utilities.UiMode
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities
import org.thoughtcrime.securesms.loki.utilities.toPx import org.thoughtcrime.securesms.loki.utilities.toPx
import org.thoughtcrime.securesms.mms.SlideDeck import org.thoughtcrime.securesms.mms.SlideDeck
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import kotlin.math.roundToInt
class QuoteView : LinearLayout { class QuoteView : LinearLayout {
private lateinit var mode: Mode
private val screenWidth by lazy { Resources.getSystem().displayMetrics.widthPixels } private val screenWidth by lazy { Resources.getSystem().displayMetrics.widthPixels }
private val vPadding by lazy { toPx(6, resources) } private val vPadding by lazy { toPx(6, resources) }
var delegate: QuoteViewDelegate? = null var delegate: QuoteViewDelegate? = null
@ -27,13 +33,25 @@ class QuoteView : LinearLayout {
enum class Mode { Regular, Draft } enum class Mode { Regular, Draft }
// region Lifecycle // region Lifecycle
constructor(context: Context) : super(context) { initialize() } constructor(context: Context) : super(context) { throw IllegalAccessError("Use QuoteView(context:mode:) instead.") }
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() } constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { throw IllegalAccessError("Use QuoteView(context:mode:) instead.") }
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() } constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { throw IllegalAccessError("Use QuoteView(context:mode:) instead.") }
private fun initialize() { constructor(context: Context, mode: Mode) : super(context) {
this.mode = mode
LayoutInflater.from(context).inflate(R.layout.view_quote, this) LayoutInflater.from(context).inflate(R.layout.view_quote, this)
quoteViewCancelButton.setOnClickListener { delegate?.cancelQuoteDraft() } when (mode) {
Mode.Draft -> quoteViewCancelButton.setOnClickListener { delegate?.cancelQuoteDraft() }
Mode.Regular -> {
quoteViewCancelButton.isVisible = false
mainQuoteViewContainer.setBackgroundColor(ResourcesCompat.getColor(resources, R.color.transparent, context.theme))
val hPadding = resources.getDimension(R.dimen.medium_spacing).roundToInt()
mainQuoteViewContainer.setPadding(hPadding, toPx(12, resources), hPadding, toPx(0, resources))
val quoteViewMainContentContainerLayoutParams = quoteViewMainContentContainer.layoutParams as RelativeLayout.LayoutParams
quoteViewMainContentContainerLayoutParams.marginEnd = resources.getDimension(R.dimen.medium_spacing).roundToInt()
quoteViewMainContentContainer.layoutParams = quoteViewMainContentContainerLayoutParams
}
}
} }
// endregion // endregion
@ -60,21 +78,51 @@ class QuoteView : LinearLayout {
// endregion // endregion
// region Updating // region Updating
fun bind(authorPublicKey: String, body: String, attachments: SlideDeck?, thread: Recipient) { fun bind(authorPublicKey: String, body: String?, attachments: SlideDeck?, thread: Recipient, isOutgoingMessage: Boolean) {
val contactDB = DatabaseFactory.getSessionContactDatabase(context) val contactDB = DatabaseFactory.getSessionContactDatabase(context)
// Author // Author
if (thread.isGroupRecipient) { if (thread.isGroupRecipient) {
val author = contactDB.getContactWithSessionID(authorPublicKey) val author = contactDB.getContactWithSessionID(authorPublicKey)
val authorDisplayName = author?.displayName(Contact.contextForRecipient(thread)) ?: authorPublicKey val authorDisplayName = author?.displayName(Contact.contextForRecipient(thread)) ?: authorPublicKey
quoteViewAuthorTextView.text = authorDisplayName quoteViewAuthorTextView.text = authorDisplayName
quoteViewAuthorTextView.setTextColor(getTextColor(isOutgoingMessage))
} }
quoteViewAuthorTextView.isVisible = thread.isGroupRecipient quoteViewAuthorTextView.isVisible = thread.isGroupRecipient
// Body // Body
quoteViewBodyTextView.text = body quoteViewBodyTextView.text = body
quoteViewBodyTextView.setTextColor(getTextColor(isOutgoingMessage))
// Accent line // Accent line
val accentLineLayoutParams = quoteViewAccentLine.layoutParams as RelativeLayout.LayoutParams val accentLineLayoutParams = quoteViewAccentLine.layoutParams as RelativeLayout.LayoutParams
accentLineLayoutParams.height = getIntrinsicContentHeight() accentLineLayoutParams.height = getIntrinsicContentHeight()
quoteViewAccentLine.layoutParams = accentLineLayoutParams quoteViewAccentLine.layoutParams = accentLineLayoutParams
quoteViewAccentLine.setBackgroundColor(getLineColor(isOutgoingMessage))
}
// endregion
// region Convenience
@ColorInt private fun getLineColor(isOutgoingMessage: Boolean): Int {
val isLightMode = UiModeUtilities.isDayUiMode(context)
if ((mode == Mode.Regular && isLightMode) || (mode == Mode.Draft && isLightMode)) {
return ResourcesCompat.getColor(resources, R.color.black, context.theme)
} else if (mode == Mode.Regular && !isLightMode) {
if (isOutgoingMessage) {
return ResourcesCompat.getColor(resources, R.color.black, context.theme)
} else {
return ResourcesCompat.getColor(resources, R.color.accent, context.theme)
}
} else { // Draft & dark mode
return ResourcesCompat.getColor(resources, R.color.accent, context.theme)
}
}
@ColorInt private fun getTextColor(isOutgoingMessage: Boolean): Int {
if (mode == Mode.Draft) { return ResourcesCompat.getColor(resources, R.color.text, context.theme) }
val isLightMode = UiModeUtilities.isDayUiMode(context)
if ((isOutgoingMessage && !isLightMode) || (!isOutgoingMessage && isLightMode)) {
return ResourcesCompat.getColor(resources, R.color.black, context.theme)
} else {
return ResourcesCompat.getColor(resources, R.color.white, context.theme)
}
} }
// endregion // endregion
} }

View File

@ -14,6 +14,7 @@ import androidx.core.graphics.BlendModeCompat
import kotlinx.android.synthetic.main.view_visible_message_content.view.* import kotlinx.android.synthetic.main.view_visible_message_content.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.utilities.ThemeUtil import org.session.libsession.utilities.ThemeUtil
import org.session.libsession.utilities.ViewUtil
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.loki.utilities.UiMode import org.thoughtcrime.securesms.loki.utilities.UiMode
@ -52,9 +53,13 @@ class VisibleMessageContentView : LinearLayout {
linkPreviewView.bind(message) linkPreviewView.bind(message)
mainContainer.addView(linkPreviewView) mainContainer.addView(linkPreviewView)
} else if (message is MmsMessageRecord && message.quote != null) { } else if (message is MmsMessageRecord && message.quote != null) {
val quoteView = QuoteView(context) val quote = message.quote!!
quoteView.bind(message.individualRecipient.address.toString(), "iuasfhiausfh", null, message.recipient) val quoteView = QuoteView(context, QuoteView.Mode.Regular)
quoteView.bind(quote.author.toString(), quote.text, quote.attachment, message.recipient, message.isOutgoing)
mainContainer.addView(quoteView) mainContainer.addView(quoteView)
val bodyTextView = getBodyTextView(message)
ViewUtil.setPaddingTop(bodyTextView, 0)
mainContainer.addView(bodyTextView)
} else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) { } else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) {
val voiceMessageView = VoiceMessageView(context) val voiceMessageView = VoiceMessageView(context)
voiceMessageView.bind(message) voiceMessageView.bind(message)

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout
android:id="@+id/mainQuoteViewContainer"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -20,6 +21,7 @@
<!-- The start margin below is the accent line thickness (4 dp) + 12 dp --> <!-- The start margin below is the accent line thickness (4 dp) + 12 dp -->
<LinearLayout <LinearLayout
android:id="@+id/quoteViewMainContentContainer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"