Merge remote-tracking branch 'upstream/ui' into ui

This commit is contained in:
jubb 2021-07-01 11:51:25 +10:00
commit c153ea2acf
4 changed files with 120 additions and 114 deletions

View File

@ -455,7 +455,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
if (thread.isClosedGroupRecipient) { if (thread.isClosedGroupRecipient) {
val group = DatabaseFactory.getGroupDatabase(this).getGroup(thread.address.toGroupString()).orNull() val group = DatabaseFactory.getGroupDatabase(this).getGroup(thread.address.toGroupString()).orNull()
val isActive = (group?.isActive == true) val isActive = (group?.isActive == true)
Log.d("Test", "isActive: $isActive")
inputBar.showInput = isActive inputBar.showInput = isActive
} else { } else {
inputBar.showInput = true inputBar.showInput = true
@ -735,7 +734,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
// `position` is the adapter position; not the visual position // `position` is the adapter position; not the visual position
private fun handleSwipeToReply(message: MessageRecord, position: Int) { private fun handleSwipeToReply(message: MessageRecord, position: Int) {
inputBar.draftQuote(message, glide) inputBar.draftQuote(thread, message, glide)
} }
// `position` is the adapter position; not the visual position // `position` is the adapter position; not the visual position
@ -1226,7 +1225,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
} }
override fun reply(messages: Set<MessageRecord>) { override fun reply(messages: Set<MessageRecord>) {
inputBar.draftQuote(messages.first(), glide) inputBar.draftQuote(thread, messages.first(), glide)
endActionMode() endActionMode()
} }

View File

@ -11,6 +11,8 @@ import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.view_input_bar.view.* import kotlinx.android.synthetic.main.view_input_bar.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.conversation.v2.components.LinkPreviewDraftView import org.thoughtcrime.securesms.conversation.v2.components.LinkPreviewDraftView
import org.thoughtcrime.securesms.conversation.v2.components.LinkPreviewDraftViewDelegate import org.thoughtcrime.securesms.conversation.v2.components.LinkPreviewDraftViewDelegate
import org.thoughtcrime.securesms.conversation.v2.messages.QuoteView import org.thoughtcrime.securesms.conversation.v2.messages.QuoteView
@ -105,7 +107,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li
// Drafting quotes and drafting link previews is mutually exclusive, i.e. you can't draft // Drafting quotes and drafting link previews is mutually exclusive, i.e. you can't draft
// a quote and a link preview at the same time. // a quote and a link preview at the same time.
fun draftQuote(message: MessageRecord, glide: GlideRequests) { fun draftQuote(thread: Recipient, message: MessageRecord, glide: GlideRequests) {
quote = message quote = message
linkPreview = null linkPreview = null
linkPreviewDraftView = null linkPreviewDraftView = null
@ -118,8 +120,9 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li
// quote view content area's start and end margins. This unfortunately has to be calculated manually // quote view content area's start and end margins. This unfortunately has to be calculated manually
// here to get the layout right. // here to get the layout right.
val maxContentWidth = (screenWidth - 2 * resources.getDimension(R.dimen.medium_spacing) - toPx(16, resources) - toPx(30, resources)).roundToInt() val maxContentWidth = (screenWidth - 2 * resources.getDimension(R.dimen.medium_spacing) - toPx(16, resources) - toPx(30, resources)).roundToInt()
quoteView.bind(message.individualRecipient.address.toString(), message.body, attachments, val sender = if (message.isOutgoing) TextSecurePreferences.getLocalNumber(context)!! else message.individualRecipient.address.serialize()
message.recipient, true, maxContentWidth, message.isOpenGroupInvitation, message.threadId, glide) quoteView.bind(sender, message.body, attachments,
thread, true, maxContentWidth, message.isOpenGroupInvitation, message.threadId, glide)
// The 6 DP below is the padding the quote view applies to itself, which isn't included in the // The 6 DP below is the padding the quote view applies to itself, which isn't included in the
// intrinsic height calculation. // intrinsic height calculation.
val quoteViewIntrinsicHeight = quoteView.getIntrinsicHeight(maxContentWidth) + toPx(6, resources) val quoteViewIntrinsicHeight = quoteView.getIntrinsicHeight(maxContentWidth) + toPx(6, resources)

View File

@ -3,10 +3,8 @@ package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Rect import android.graphics.Rect
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.AsyncTask
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@ -26,6 +24,7 @@ import org.session.libsignal.utilities.ThreadUtils
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
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.disableClipping
import org.thoughtcrime.securesms.loki.utilities.getColorWithID import org.thoughtcrime.securesms.loki.utilities.getColorWithID
import org.thoughtcrime.securesms.loki.utilities.toDp import org.thoughtcrime.securesms.loki.utilities.toDp
import org.thoughtcrime.securesms.loki.utilities.toPx import org.thoughtcrime.securesms.loki.utilities.toPx
@ -72,6 +71,8 @@ class VisibleMessageView : LinearLayout {
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
isHapticFeedbackEnabled = true isHapticFeedbackEnabled = true
setWillNotDraw(false) setWillNotDraw(false)
expirationTimerViewContainer.disableClipping()
messageContentContainer.disableClipping()
} }
// endregion // endregion
@ -114,20 +115,20 @@ class VisibleMessageView : LinearLayout {
// Timestamp // Timestamp
messageTimestampTextView.text = DateUtils.getExtendedRelativeTimeSpanString(context, Locale.getDefault(), message.timestamp) messageTimestampTextView.text = DateUtils.getExtendedRelativeTimeSpanString(context, Locale.getDefault(), message.timestamp)
// Margins // Margins
val messageContentContainerLayoutParams = messageContentContainer.layoutParams as LinearLayout.LayoutParams val startPadding: Int
if (isGroupThread) { if (isGroupThread) {
messageContentContainerLayoutParams.leftMargin = if (message.isOutgoing) resources.getDimension(R.dimen.very_large_spacing).toInt() else 0 startPadding = if (message.isOutgoing) resources.getDimension(R.dimen.very_large_spacing).toInt() else 0
} else { } else {
messageContentContainerLayoutParams.leftMargin = if (message.isOutgoing) resources.getDimension(R.dimen.very_large_spacing).toInt() startPadding = if (message.isOutgoing) resources.getDimension(R.dimen.very_large_spacing).toInt()
else resources.getDimension(R.dimen.medium_spacing).toInt() else resources.getDimension(R.dimen.medium_spacing).toInt()
} }
messageContentContainerLayoutParams.rightMargin = if (message.isOutgoing) resources.getDimension(R.dimen.medium_spacing).toInt() val endPadding = if (message.isOutgoing) resources.getDimension(R.dimen.medium_spacing).toInt()
else resources.getDimension(R.dimen.very_large_spacing).toInt() else resources.getDimension(R.dimen.very_large_spacing).toInt()
messageContentContainer.layoutParams = messageContentContainerLayoutParams messageContentContainer.setPaddingRelative(startPadding, 0, endPadding, 0)
// Set inter-message spacing // Set inter-message spacing
setMessageSpacing(isStartOfMessageCluster, isEndOfMessageCluster) setMessageSpacing(isStartOfMessageCluster, isEndOfMessageCluster)
// Gravity // Gravity
val gravity = if (message.isOutgoing) Gravity.RIGHT else Gravity.LEFT val gravity = if (message.isOutgoing) Gravity.END else Gravity.START
mainContainer.gravity = gravity or Gravity.BOTTOM mainContainer.gravity = gravity or Gravity.BOTTOM
// Message status indicator // Message status indicator
val (iconID, iconColor) = getMessageStatusImage(message) val (iconID, iconColor) = getMessageStatusImage(message)
@ -147,7 +148,7 @@ class VisibleMessageView : LinearLayout {
// Expiration timer // Expiration timer
updateExpirationTimer(message) updateExpirationTimer(message)
// Calculate max message bubble width // Calculate max message bubble width
var maxWidth = screenWidth - messageContentContainerLayoutParams.leftMargin - messageContentContainerLayoutParams.rightMargin var maxWidth = screenWidth - startPadding - endPadding
if (profilePictureContainer.visibility != View.GONE) { maxWidth -= profilePictureContainer.width } if (profilePictureContainer.visibility != View.GONE) { maxWidth -= profilePictureContainer.width }
// Populate content view // Populate content view
messageContentView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster, glide, maxWidth, thread, searchQuery) messageContentView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster, glide, maxWidth, thread, searchQuery)
@ -198,6 +199,9 @@ class VisibleMessageView : LinearLayout {
val ruleToRemove = if (message.isOutgoing) RelativeLayout.ALIGN_PARENT_END else RelativeLayout.ALIGN_PARENT_START val ruleToRemove = if (message.isOutgoing) RelativeLayout.ALIGN_PARENT_END else RelativeLayout.ALIGN_PARENT_START
expirationTimerViewLayoutParams.removeRule(ruleToRemove) expirationTimerViewLayoutParams.removeRule(ruleToRemove)
expirationTimerViewLayoutParams.addRule(ruleToAdd) expirationTimerViewLayoutParams.addRule(ruleToAdd)
val expirationTimerViewSize = toPx(12, resources)
expirationTimerViewLayoutParams.marginStart = -(messageContentContainer.paddingStart / 2 + expirationTimerViewSize / 2)
expirationTimerViewLayoutParams.marginEnd = -(messageContentContainer.paddingEnd / 2 + expirationTimerViewSize / 2)
expirationTimerView.layoutParams = expirationTimerViewLayoutParams expirationTimerView.layoutParams = expirationTimerViewLayoutParams
if (message.expiresIn > 0 && !message.isPending) { if (message.expiresIn > 0 && !message.isPending) {
expirationTimerView.setColorFilter(ResourcesCompat.getColor(resources, R.color.text, context.theme)) expirationTimerView.setColorFilter(ResourcesCompat.getColor(resources, R.color.text, context.theme))
@ -232,14 +236,14 @@ class VisibleMessageView : LinearLayout {
} }
override fun onDraw(canvas: Canvas) { override fun onDraw(canvas: Canvas) {
if (translationX < 0) { if (translationX < 0 && !expirationTimerView.isVisible) {
val spacing = context.resources.getDimensionPixelSize(R.dimen.small_spacing) val spacing = context.resources.getDimensionPixelSize(R.dimen.small_spacing)
val threshold = VisibleMessageView.swipeToReplyThreshold val threshold = VisibleMessageView.swipeToReplyThreshold
val iconSize = toPx(24, context.resources) val iconSize = toPx(24, context.resources)
val bottomVOffset = paddingBottom + messageStatusImageView.height + (messageContentView.height - iconSize) / 2 val bottomVOffset = paddingBottom + messageStatusImageView.height + (messageContentView.height - iconSize) / 2
swipeToReplyIconRect.left = messageContentContainer.right + spacing swipeToReplyIconRect.left = messageContentContainer.right - messageContentContainer.paddingEnd + spacing
swipeToReplyIconRect.top = height - bottomVOffset - iconSize swipeToReplyIconRect.top = height - bottomVOffset - iconSize
swipeToReplyIconRect.right = messageContentContainer.right + iconSize + spacing swipeToReplyIconRect.right = messageContentContainer.right - messageContentContainer.paddingEnd + iconSize + spacing
swipeToReplyIconRect.bottom = height - bottomVOffset swipeToReplyIconRect.bottom = height - bottomVOffset
swipeToReplyIcon.bounds = swipeToReplyIconRect swipeToReplyIcon.bounds = swipeToReplyIconRect
swipeToReplyIcon.alpha = (255.0f * (min(abs(translationX), threshold) / threshold)).roundToInt() swipeToReplyIcon.alpha = (255.0f * (min(abs(translationX), threshold) / threshold)).roundToInt()

View File

@ -1,126 +1,126 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <LinearLayout
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"
android:orientation="vertical">
<TextView
android:id="@+id/dateBreakTextView"
android:layout_width="match_parent"
android:layout_height="40dp"
android:textColor="@color/text"
android:textSize="@dimen/very_small_font_size"
android:textStyle="bold"
android:gravity="center" />
<LinearLayout <LinearLayout
android:id="@+id/mainContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="horizontal"
android:gravity="bottom">
<TextView
android:id="@+id/dateBreakTextView"
android:layout_width="match_parent"
android:layout_height="40dp"
android:textColor="@color/text"
android:textSize="@dimen/very_small_font_size"
android:textStyle="bold"
android:gravity="center" />
<LinearLayout <LinearLayout
android:id="@+id/mainContainer" android:id="@+id/profilePictureContainer"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal">
android:gravity="bottom">
<LinearLayout <View
android:id="@+id/profilePictureContainer" android:layout_width="12dp"
android:layout_height="0dp" />
<RelativeLayout
android:layout_width="26dp"
android:layout_height="32dp" >
<org.thoughtcrime.securesms.loki.views.ProfilePictureView
android:id="@+id/profilePictureView"
android:layout_width="@dimen/very_small_profile_picture_size"
android:layout_height="@dimen/very_small_profile_picture_size"
android:layout_marginTop="3dp" />
<ImageView
android:id="@+id/moderatorIconImageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_crown"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
<View
android:layout_width="12dp"
android:layout_height="0dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/messageContentContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/senderNameTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_marginBottom="4dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:textColor="@color/text"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end" />
<View <RelativeLayout
android:layout_width="12dp" android:id="@+id/expirationTimerViewContainer"
android:layout_height="0dp" />
<RelativeLayout
android:layout_width="26dp"
android:layout_height="32dp" >
<org.thoughtcrime.securesms.loki.views.ProfilePictureView
android:id="@+id/profilePictureView"
android:layout_width="@dimen/very_small_profile_picture_size"
android:layout_height="@dimen/very_small_profile_picture_size"
android:layout_marginTop="3dp" />
<ImageView
android:id="@+id/moderatorIconImageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_crown"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
<View
android:layout_width="12dp"
android:layout_height="0dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/messageContentContainer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:orientation="vertical">
<TextView
android:id="@+id/senderNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:textColor="@color/text"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end" />
<org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageContentView <org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageContentView
android:id="@+id/messageContentView" android:id="@+id/messageContentView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<RelativeLayout <org.thoughtcrime.securesms.conversation.v2.components.ExpirationTimerView
android:layout_width="match_parent" android:id="@+id/expirationTimerView"
android:layout_height="wrap_content"> android:layout_width="12dp"
android:layout_height="12dp"
android:layout_centerVertical="true" />
<TextView </RelativeLayout>
android:id="@+id/messageTimestampTextView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="2dp"
android:maxLines="1"
android:textSize="10dp" />
<ImageView <RelativeLayout
android:id="@+id/messageStatusImageView" android:layout_width="match_parent"
android:layout_width="16dp" android:layout_height="wrap_content">
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="2dp"
android:padding="2dp"
android:src="@drawable/ic_delivery_status_sent" />
</RelativeLayout> <TextView
android:id="@+id/messageTimestampTextView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="2dp"
android:maxLines="1"
android:textSize="10dp" />
</LinearLayout> <ImageView
android:id="@+id/messageStatusImageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="2dp"
android:padding="2dp"
android:src="@drawable/ic_delivery_status_sent" />
</RelativeLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<org.thoughtcrime.securesms.conversation.v2.components.ExpirationTimerView </LinearLayout>
android:id="@+id/expirationTimerView"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_marginHorizontal="@dimen/medium_spacing"
android:layout_centerVertical="true" />
</RelativeLayout>