-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SES-2021] Optimise XML loading #1512
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,8 +11,10 @@ import android.os.Looper | |
import android.util.AttributeSet | ||
import android.view.Gravity | ||
import android.view.HapticFeedbackConstants | ||
import android.view.LayoutInflater | ||
import android.view.MotionEvent | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.widget.FrameLayout | ||
import android.widget.LinearLayout | ||
import androidx.annotation.ColorInt | ||
|
@@ -26,17 +28,17 @@ import androidx.core.view.isVisible | |
import androidx.core.view.marginBottom | ||
import dagger.hilt.android.AndroidEntryPoint | ||
import network.loki.messenger.R | ||
import network.loki.messenger.databinding.ViewEmojiReactionsBinding | ||
import network.loki.messenger.databinding.ViewVisibleMessageBinding | ||
import network.loki.messenger.databinding.ViewstubVisibleMessageMarkerContainerBinding | ||
import org.session.libsession.messaging.contacts.Contact | ||
import org.session.libsession.messaging.contacts.Contact.ContactContext | ||
import org.session.libsession.messaging.open_groups.OpenGroupApi | ||
import org.session.libsession.utilities.Address | ||
import org.session.libsession.utilities.TextSecurePreferences | ||
import org.session.libsession.utilities.ViewUtil | ||
import org.session.libsession.utilities.getColorFromAttr | ||
import org.session.libsession.utilities.modifyLayoutParams | ||
import org.session.libsignal.utilities.IdPrefix | ||
import org.session.libsignal.utilities.Log | ||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 | ||
import org.thoughtcrime.securesms.database.LastSentTimestampCache | ||
import org.thoughtcrime.securesms.database.LokiAPIDatabase | ||
|
@@ -65,7 +67,7 @@ import kotlin.math.sqrt | |
private const val TAG = "VisibleMessageView" | ||
|
||
@AndroidEntryPoint | ||
class VisibleMessageView : LinearLayout { | ||
class VisibleMessageView : FrameLayout { | ||
private var replyDisabled: Boolean = false | ||
@Inject lateinit var threadDb: ThreadDatabase | ||
@Inject lateinit var lokiThreadDb: LokiThreadDatabase | ||
|
@@ -75,7 +77,16 @@ class VisibleMessageView : LinearLayout { | |
@Inject lateinit var mmsDb: MmsDatabase | ||
@Inject lateinit var lastSentTimestampCache: LastSentTimestampCache | ||
|
||
private val binding by lazy { ViewVisibleMessageBinding.bind(this) } | ||
private val binding = ViewVisibleMessageBinding.inflate(LayoutInflater.from(context), this, true) | ||
|
||
private val markerContainerBinding = lazy(LazyThreadSafetyMode.NONE) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you have to add the LazyThreadSafetyMode.NONE to those two bindings? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find it wasteful to have a thread safe lazy for UI components where you only access through main thread. |
||
ViewstubVisibleMessageMarkerContainerBinding.bind(binding.unreadMarkerContainerStub.inflate()) | ||
} | ||
|
||
private val emojiReactionsBinding = lazy(LazyThreadSafetyMode.NONE) { | ||
ViewEmojiReactionsBinding.bind(binding.emojiReactionsView.inflate()) | ||
} | ||
|
||
private val swipeToReplyIcon = ContextCompat.getDrawable(context, R.drawable.ic_baseline_reply_24)!!.mutate() | ||
private val swipeToReplyIconRect = Rect() | ||
private var dx = 0.0f | ||
|
@@ -94,7 +105,7 @@ class VisibleMessageView : LinearLayout { | |
var onPress: ((event: MotionEvent) -> Unit)? = null | ||
var onSwipeToReply: (() -> Unit)? = null | ||
var onLongPress: (() -> Unit)? = null | ||
val messageContentView: VisibleMessageContentView by lazy { binding.messageContentView.root } | ||
val messageContentView: VisibleMessageContentView get() = binding.messageContentView.root | ||
|
||
companion object { | ||
const val swipeToReplyThreshold = 64.0f // dp | ||
|
@@ -108,20 +119,19 @@ class VisibleMessageView : LinearLayout { | |
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) | ||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) | ||
|
||
override fun onFinishInflate() { | ||
super.onFinishInflate() | ||
initialize() | ||
} | ||
|
||
private fun initialize() { | ||
init { | ||
isHapticFeedbackEnabled = true | ||
setWillNotDraw(false) | ||
binding.root.disableClipping() | ||
binding.mainContainer.disableClipping() | ||
binding.messageInnerContainer.disableClipping() | ||
binding.messageInnerLayout.disableClipping() | ||
binding.messageContentView.root.disableClipping() | ||
|
||
// Default layout params | ||
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) | ||
} | ||
|
||
// endregion | ||
|
||
// region Updating | ||
|
@@ -203,7 +213,13 @@ class VisibleMessageView : LinearLayout { | |
binding.senderNameTextView.text = contact?.displayName(contactContext) ?: senderSessionID | ||
|
||
// Unread marker | ||
binding.unreadMarkerContainer.isVisible = lastSeen != -1L && message.timestamp > lastSeen && (previous == null || previous.timestamp <= lastSeen) && !message.isOutgoing | ||
val shouldShowUnreadMarker = lastSeen != -1L && message.timestamp > lastSeen && (previous == null || previous.timestamp <= lastSeen) && !message.isOutgoing | ||
if (shouldShowUnreadMarker) { | ||
markerContainerBinding.value.root.isVisible = true | ||
} else if (markerContainerBinding.isInitialized()) { | ||
// Only need to hide the binding when the binding is inflated. (default is gone) | ||
markerContainerBinding.value.root.isVisible = false | ||
} | ||
|
||
// Date break | ||
val showDateBreak = isStartOfMessageCluster || snIsSelected | ||
|
@@ -214,21 +230,22 @@ class VisibleMessageView : LinearLayout { | |
showStatusMessage(message) | ||
|
||
// Emoji Reactions | ||
val emojiLayoutParams = binding.emojiReactionsView.root.layoutParams as ConstraintLayout.LayoutParams | ||
emojiLayoutParams.horizontalBias = if (message.isOutgoing) 1f else 0f | ||
binding.emojiReactionsView.root.layoutParams = emojiLayoutParams | ||
|
||
if (message.reactions.isNotEmpty()) { | ||
val capabilities = lokiThreadDb.getOpenGroupChat(threadID)?.server?.let { lokiApiDb.getServerCapabilities(it) } | ||
if (capabilities.isNullOrEmpty() || capabilities.contains(OpenGroupApi.Capability.REACTIONS.name.lowercase())) { | ||
binding.emojiReactionsView.root.setReactions(message.id, message.reactions, message.isOutgoing, delegate) | ||
binding.emojiReactionsView.root.isVisible = true | ||
} else { | ||
binding.emojiReactionsView.root.isVisible = false | ||
emojiReactionsBinding.value.root.let { root -> | ||
root.setReactions(message.id, message.reactions, message.isOutgoing, delegate) | ||
root.isVisible = true | ||
(root.layoutParams as ConstraintLayout.LayoutParams).apply { | ||
horizontalBias = if (message.isOutgoing) 1f else 0f | ||
} | ||
} | ||
} else if (emojiReactionsBinding.isInitialized()) { | ||
emojiReactionsBinding.value.root.isVisible = false | ||
} | ||
} | ||
else { | ||
binding.emojiReactionsView.root.isVisible = false | ||
else if (emojiReactionsBinding.isInitialized()) { | ||
emojiReactionsBinding.value.root.isVisible = false | ||
} | ||
|
||
// Populate content view | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested this? The audio message plays without using that existing binding that was removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I have tested.
The binding has been moved into the custom view itself