diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e61edbe7e0..32869dd1f1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -223,7 +223,7 @@ android:screenOrientation="portrait" android:theme="@style/Theme.Session.DayNight.FlatActionBar" /> + val recipients = if (state != null) state.typists else listOf() + typingIndicatorViewContainer.isVisible = recipients.isNotEmpty() + typingIndicatorViewContainer.setTypists(recipients) + inputBarHeightChanged(inputBar.height) + } + } + + private fun getLatestOpenGroupInfoIfNeeded() { + val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) ?: return + OpenGroupAPIV2.getMemberCount(openGroup.room, openGroup.server).successUi { updateSubtitle() } + } + + private fun setUpBlockedBanner() { + if (thread.isGroupRecipient) { return } + val contactDB = DatabaseFactory.getSessionContactDatabase(this) + val sessionID = thread.address.toString() + val contact = contactDB.getContactWithSessionID(sessionID) + val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID + blockedBannerTextView.text = resources.getString(R.string.activity_conversation_blocked_banner_text, name) + blockedBanner.isVisible = thread.isBlocked + blockedBanner.setOnClickListener { unblock() } + } + + private fun setUpLinkPreviewObserver() { + val linkPreviewViewModel = ViewModelProviders.of(this, LinkPreviewViewModel.Factory(LinkPreviewRepository(this)))[LinkPreviewViewModel::class.java] + this.linkPreviewViewModel = linkPreviewViewModel + if (!TextSecurePreferences.isLinkPreviewsEnabled(this)) { + linkPreviewViewModel.onUserCancel(); return + } + linkPreviewViewModel.linkPreviewState.observe(this, { previewState: LinkPreviewState? -> + if (previewState == null) return@observe + if (previewState.isLoading) { + inputBar.draftLinkPreview() + } else { + inputBar.updateLinkPreviewDraft(glide, previewState.linkPreview.get()) + } + }) + } + override fun onPrepareOptionsMenu(menu: Menu): Boolean { ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) } super.onPrepareOptionsMenu(menu) @@ -194,9 +256,13 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe // region Updating & Animation override fun inputBarHeightChanged(newValue: Int) { + @Suppress("NAME_SHADOWING") val newValue = max(newValue, resources.getDimension(R.dimen.input_bar_height).roundToInt()) + // 36 DP is the exact height of the typing indicator view. It's also exactly 18 * 2, and 18 is the large message + // corner radius. This makes 36 DP look "correct" in the context of other messages on the screen. + val typingIndicatorHeight = if (typingIndicatorViewContainer.isVisible) toPx(36, resources) else 0 // Recycler view val recyclerViewLayoutParams = conversationRecyclerView.layoutParams as RelativeLayout.LayoutParams - recyclerViewLayoutParams.bottomMargin = newValue + additionalContentContainer.height + recyclerViewLayoutParams.bottomMargin = newValue + additionalContentContainer.height + typingIndicatorHeight conversationRecyclerView.layoutParams = recyclerViewLayoutParams // Additional content container val additionalContentContainerLayoutParams = additionalContentContainer.layoutParams as RelativeLayout.LayoutParams @@ -216,6 +282,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } override fun inputBarEditTextContentChanged(newContent: CharSequence) { + linkPreviewViewModel?.onTextChanged(this, inputBar.text, 0, 0) // TODO: Implement the full mention show/hide logic if (newContent.contains("@")) { showMentionCandidates() @@ -330,6 +397,35 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe (scrollButtonFullVisibilityThreshold - scrollButtonNoVisibilityThreshold) val alpha = max(min(rawAlpha, 1.0f), 0.0f) scrollToBottomButton.alpha = alpha + updateUnreadCount() + } + + private fun updateUnreadCount() { + val unreadCount = DatabaseFactory.getMmsSmsDatabase(this).getUnreadCount(threadID) + val formattedUnreadCount = if (unreadCount < 100) unreadCount.toString() else "99+" + unreadCountTextView.text = formattedUnreadCount + val textSize = if (unreadCount < 100) 12.0f else 9.0f + unreadCountTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize) + unreadCountTextView.setTypeface(Typeface.DEFAULT, if (unreadCount < 100) Typeface.BOLD else Typeface.NORMAL) + unreadCountIndicator.isVisible = (unreadCount != 0) + } + + private fun updateSubtitle() { + muteIconImageView.isVisible = thread.isMuted + conversationSubtitleView.isVisible = true + if (thread.isMuted) { + conversationSubtitleView.text = getString(R.string.ConversationActivity_muted_until_date, DateUtils.getFormattedDateTime(thread.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault())) + } else if (thread.isGroupRecipient) { + val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) + if (openGroup != null) { + val userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(openGroup.room, openGroup.server) ?: 0 + conversationSubtitleView.text = getString(R.string.ConversationActivity_member_count, userCount) + } else { + conversationSubtitleView.isVisible = false + } + } else { + conversationSubtitleView.isVisible = false + } } // endregion @@ -351,6 +447,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe this.actionMode = null } } else { + // NOTE: + // We have to use onContentClick (rather than a click listener directly on + // the view) so as to not interfere with all the other gestures. Do not add + // onClickListeners directly to message content views. view.onContentClick() } } @@ -432,6 +532,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe lockViewLocation[0] + lockView.width + lockViewHitMargin, lockViewLocation[1] + lockView.height) return hitRect.contains(x, y) } + + private fun unblock() { + // TODO: Implement + } // endregion // region General diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRecyclerView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRecyclerView.kt index e2d37c0fca..7d8957a065 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRecyclerView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationRecyclerView.kt @@ -5,6 +5,7 @@ import android.util.AttributeSet import android.util.Log import android.view.MotionEvent import android.view.VelocityTracker +import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.activity_conversation_v2.* import org.thoughtcrime.securesms.loki.utilities.disableClipping diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/LinkPreviewDraftView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/LinkPreviewDraftView.kt new file mode 100644 index 0000000000..23158acf0f --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/LinkPreviewDraftView.kt @@ -0,0 +1,38 @@ +package org.thoughtcrime.securesms.conversation.v2.components + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.LinearLayout +import androidx.core.view.isVisible +import kotlinx.android.synthetic.main.view_link_preview_draft.view.* +import network.loki.messenger.R +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview +import org.thoughtcrime.securesms.mms.GlideRequests +import org.thoughtcrime.securesms.mms.ImageSlide + +class LinkPreviewDraftView : LinearLayout { + + // region Lifecycle + constructor(context: Context) : super(context) { initialize() } + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() } + + private fun initialize() { + LayoutInflater.from(context).inflate(R.layout.view_link_preview_draft, this) + linkPreviewDraftContainer.isVisible = false + thumbnailImageView.clipToOutline = true + } + // endregion + + // region Updating + fun update(glide: GlideRequests, linkPreview: LinkPreview) { + linkPreviewDraftContainer.isVisible = true + linkPreviewDraftLoader.isVisible = false + if (linkPreview.getThumbnail().isPresent) { + thumbnailImageView.setImageResource(glide, ImageSlide(context, linkPreview.getThumbnail().get()), false, false) + } + linkPreviewDraftTitleTextView.text = linkPreview.title + } + // endregion +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/OpenGroupGuidelinesView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/OpenGroupGuidelinesView.kt similarity index 84% rename from app/src/main/java/org/thoughtcrime/securesms/conversation/v2/OpenGroupGuidelinesView.kt rename to app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/OpenGroupGuidelinesView.kt index 4040c9fa3d..e4d7e4a3b6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/OpenGroupGuidelinesView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/OpenGroupGuidelinesView.kt @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.conversation.v2 +package org.thoughtcrime.securesms.conversation.v2.components import android.content.Context import android.content.Intent @@ -7,6 +7,8 @@ import android.view.LayoutInflater import android.widget.FrameLayout import kotlinx.android.synthetic.main.view_open_group_guidelines.view.* import network.loki.messenger.R +import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 +import org.thoughtcrime.securesms.loki.activities.OpenGroupGuidelinesActivity import org.thoughtcrime.securesms.loki.utilities.push class OpenGroupGuidelinesView : FrameLayout { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/TypingIndicatorView.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/TypingIndicatorView.java similarity index 93% rename from app/src/main/java/org/thoughtcrime/securesms/components/TypingIndicatorView.java rename to app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/TypingIndicatorView.java index 477776a9dd..826cfe7b3a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/TypingIndicatorView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/TypingIndicatorView.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.components; +package org.thoughtcrime.securesms.conversation.v2.components; import android.content.Context; import android.content.res.TypedArray; @@ -13,18 +13,14 @@ import android.widget.LinearLayout; import network.loki.messenger.R; public class TypingIndicatorView extends LinearLayout { + private boolean isActive; + private long startTime; - private static final long DURATION = 300; - private static final long PRE_DELAY = 500; - private static final long POST_DELAY = 500; private static final long CYCLE_DURATION = 1500; private static final long DOT_DURATION = 600; private static final float MIN_ALPHA = 0.4f; private static final float MIN_SCALE = 0.75f; - private boolean isActive; - private long startTime; - private View dot1; private View dot2; private View dot3; @@ -40,7 +36,7 @@ public class TypingIndicatorView extends LinearLayout { } private void initialize(@Nullable AttributeSet attrs) { - inflate(getContext(), R.layout.typing_indicator_view, this); + inflate(getContext(), R.layout.view_typing_indicator, this); setWillNotDraw(false); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/TypingIndicatorViewContainer.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/TypingIndicatorViewContainer.kt new file mode 100644 index 0000000000..0628b63b78 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/TypingIndicatorViewContainer.kt @@ -0,0 +1,25 @@ +package org.thoughtcrime.securesms.conversation.v2.components + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.widget.LinearLayout +import kotlinx.android.synthetic.main.view_conversation_typing_container.view.* +import network.loki.messenger.R +import org.session.libsession.utilities.recipients.Recipient + +class TypingIndicatorViewContainer : LinearLayout { + + constructor(context: Context) : super(context) { initialize() } + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() } + + private fun initialize() { + LayoutInflater.from(context).inflate(R.layout.view_conversation_typing_container, this) + } + + fun setTypists(typists: List) { + if (typists.isEmpty()) { typingIndicator.stopAnimation(); return } + typingIndicator.startAnimation() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt new file mode 100644 index 0000000000..51c927fbba --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt @@ -0,0 +1,40 @@ +package org.thoughtcrime.securesms.conversation.v2.dialogs + +import android.graphics.Typeface +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.style.StyleSpan +import android.view.LayoutInflater +import androidx.appcompat.app.AlertDialog +import kotlinx.android.synthetic.main.dialog_blocked.view.* +import kotlinx.android.synthetic.main.dialog_blocked.view.cancelButton +import network.loki.messenger.R +import org.session.libsession.messaging.contacts.Contact +import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog +import org.thoughtcrime.securesms.database.DatabaseFactory + +class BlockedDialog(private val recipient: Recipient) : BaseDialog() { + + override fun setContentView(builder: AlertDialog.Builder) { + val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_blocked, null) + val contactDB = DatabaseFactory.getSessionContactDatabase(requireContext()) + val sessionID = recipient.address.toString() + val contact = contactDB.getContactWithSessionID(sessionID) + val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID + val title = resources.getString(R.string.dialog_blocked_title, name) + contentView.blockedTitleTextView.text = title + val explanation = resources.getString(R.string.dialog_blocked_explanation, name) + val spannable = SpannableStringBuilder(explanation) + val startIndex = explanation.indexOf(name) + spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + contentView.blockedExplanationTextView.text = spannable + contentView.cancelButton.setOnClickListener { dismiss() } + contentView.unblockButton.setOnClickListener { unblock() } + builder.setView(contentView) + } + + private fun unblock() { + // TODO: Implement + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt new file mode 100644 index 0000000000..74f835ec22 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt @@ -0,0 +1,39 @@ +package org.thoughtcrime.securesms.conversation.v2.dialogs + +import android.graphics.Typeface +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.style.StyleSpan +import android.view.LayoutInflater +import androidx.appcompat.app.AlertDialog +import kotlinx.android.synthetic.main.dialog_download.view.* +import network.loki.messenger.R +import org.session.libsession.messaging.contacts.Contact +import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog +import org.thoughtcrime.securesms.database.DatabaseFactory + +class DownloadDialog(private val recipient: Recipient) : BaseDialog() { + + override fun setContentView(builder: AlertDialog.Builder) { + val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_download, null) + val contactDB = DatabaseFactory.getSessionContactDatabase(requireContext()) + val sessionID = recipient.address.toString() + val contact = contactDB.getContactWithSessionID(sessionID) + val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID + val title = resources.getString(R.string.dialog_download_title, name) + contentView.downloadTitleTextView.text = title + val explanation = resources.getString(R.string.dialog_download_explanation, name) + val spannable = SpannableStringBuilder(explanation) + val startIndex = explanation.indexOf(name) + spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + contentView.downloadExplanationTextView.text = spannable + contentView.cancelButton.setOnClickListener { dismiss() } + contentView.downloadButton.setOnClickListener { trust() } + builder.setView(contentView) + } + + private fun trust() { + // TODO: Implement + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/JoinOpenGroupDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/JoinOpenGroupDialog.kt new file mode 100644 index 0000000000..22a896d34d --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/JoinOpenGroupDialog.kt @@ -0,0 +1,34 @@ +package org.thoughtcrime.securesms.conversation.v2.dialogs + +import android.graphics.Typeface +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.style.StyleSpan +import android.view.LayoutInflater +import androidx.appcompat.app.AlertDialog +import kotlinx.android.synthetic.main.dialog_join_open_group.view.* +import network.loki.messenger.R +import org.session.libsession.messaging.open_groups.OpenGroupV2 +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog + +class JoinOpenGroupDialog(private val openGroup: OpenGroupV2) : BaseDialog() { + + override fun setContentView(builder: AlertDialog.Builder) { + val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_join_open_group, null) + val name = openGroup.name + val title = resources.getString(R.string.dialog_join_open_group_title, name) + contentView.joinOpenGroupTitleTextView.text = title + val explanation = resources.getString(R.string.dialog_join_open_group_explanation, name) + val spannable = SpannableStringBuilder(explanation) + val startIndex = explanation.indexOf(name) + spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + contentView.joinOpenGroupExplanationTextView.text = spannable + contentView.cancelButton.setOnClickListener { dismiss() } + contentView.joinButton.setOnClickListener { join() } + builder.setView(contentView) + } + + private fun join() { + // TODO: Implement + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/LinkPreviewDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/LinkPreviewDialog.kt new file mode 100644 index 0000000000..04dd5fe03e --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/LinkPreviewDialog.kt @@ -0,0 +1,21 @@ +package org.thoughtcrime.securesms.conversation.v2.dialogs + +import android.view.LayoutInflater +import androidx.appcompat.app.AlertDialog +import kotlinx.android.synthetic.main.dialog_link_preview.view.* +import network.loki.messenger.R +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog + +class LinkPreviewDialog() : BaseDialog() { + + override fun setContentView(builder: AlertDialog.Builder) { + val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_link_preview, null) + contentView.cancelButton.setOnClickListener { dismiss() } + contentView.enableLinkPreviewsButton.setOnClickListener { enable() } + builder.setView(contentView) + } + + private fun enable() { + // TODO: Implement + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/OpenURLDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/OpenURLDialog.kt new file mode 100644 index 0000000000..eedd33731b --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/OpenURLDialog.kt @@ -0,0 +1,30 @@ +package org.thoughtcrime.securesms.conversation.v2.dialogs + +import android.graphics.Typeface +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.style.StyleSpan +import android.view.LayoutInflater +import androidx.appcompat.app.AlertDialog +import kotlinx.android.synthetic.main.dialog_open_url.view.* +import network.loki.messenger.R +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog + +class OpenURLDialog(private val url: String) : BaseDialog() { + + override fun setContentView(builder: AlertDialog.Builder) { + val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_open_url, null) + val explanation = resources.getString(R.string.dialog_open_url_explanation, url) + val spannable = SpannableStringBuilder(explanation) + val startIndex = explanation.indexOf(url) + spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + url.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + contentView.openURLExplanationTextView.text = spannable + contentView.cancelButton.setOnClickListener { dismiss() } + contentView.openURLButton.setOnClickListener { open() } + builder.setView(contentView) + } + + private fun open() { + // TODO: Implement + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt index e5bab6373e..65965a2177 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt @@ -2,24 +2,23 @@ package org.thoughtcrime.securesms.conversation.v2.input_bar import android.content.Context import android.content.res.Resources -import android.text.Editable import android.util.AttributeSet -import android.util.Log import android.view.LayoutInflater import android.view.MotionEvent -import android.widget.LinearLayout import android.widget.RelativeLayout import androidx.core.view.isVisible import kotlinx.android.synthetic.main.view_input_bar.view.* import kotlinx.android.synthetic.main.view_quote.view.* import network.loki.messenger.R +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview +import org.thoughtcrime.securesms.conversation.v2.components.LinkPreviewDraftView import org.thoughtcrime.securesms.conversation.v2.messages.QuoteView import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.loki.utilities.toDp import org.thoughtcrime.securesms.loki.utilities.toPx -import org.thoughtcrime.securesms.mms.SlideDeck +import org.thoughtcrime.securesms.mms.GlideRequests import kotlin.math.max import kotlin.math.roundToInt @@ -27,6 +26,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate { private val screenWidth = Resources.getSystem().displayMetrics.widthPixels private val vMargin by lazy { toDp(4, resources) } private val minHeight by lazy { toPx(56, resources) } + private var linkPreviewDraftView: LinkPreviewDraftView? = null var delegate: InputBarDelegate? = null var additionalContentHeight = 0 @@ -96,6 +96,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate { } fun draftQuote(message: MessageRecord) { + linkPreviewDraftView = null inputBarAdditionalContentContainer.removeAllViews() val quoteView = QuoteView(context, QuoteView.Mode.Draft) quoteView.delegate = this @@ -121,6 +122,22 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate { additionalContentHeight = 0 setHeight(newHeight) } + + fun draftLinkPreview() { + val linkPreviewDraftHeight = toPx(88, resources) + inputBarAdditionalContentContainer.removeAllViews() + val linkPreviewDraftView = LinkPreviewDraftView(context) + this.linkPreviewDraftView = linkPreviewDraftView + inputBarAdditionalContentContainer.addView(linkPreviewDraftView) + val newHeight = max(inputBarEditText.height + 2 * vMargin, minHeight) + linkPreviewDraftHeight + additionalContentHeight = linkPreviewDraftHeight + setHeight(newHeight) + } + + fun updateLinkPreviewDraft(glide: GlideRequests, linkPreview: LinkPreview) { + val linkPreviewDraftView = this.linkPreviewDraftView ?: return + linkPreviewDraftView.update(glide, linkPreview) + } // endregion } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt index 356745328a..6219077dad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt @@ -1,16 +1,9 @@ package org.thoughtcrime.securesms.conversation.v2.messages import android.content.Context -import android.graphics.Canvas -import android.graphics.Outline -import android.graphics.Path -import android.graphics.RectF import android.graphics.drawable.Drawable -import android.os.Build import android.util.AttributeSet -import android.util.Log import android.view.LayoutInflater -import android.view.View import android.view.ViewOutlineProvider import android.widget.LinearLayout import androidx.core.content.res.ResourcesCompat @@ -19,6 +12,7 @@ import network.loki.messenger.R import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities import org.thoughtcrime.securesms.mms.GlideRequests +import org.thoughtcrime.securesms.mms.ImageSlide class LinkPreviewView : LinearLayout { @@ -39,10 +33,9 @@ class LinkPreviewView : LinearLayout { mainLinkPreviewContainer.clipToOutline = true // Thumbnail val linkPreview = message.linkPreviews.first() - // TODO: Handle downloading state - val uri = linkPreview.thumbnail.get().dataUri ?: return - glide.load(uri).into(thumbnailImageView) - // TODO: Properly use glide and the actual thumbnail + if (linkPreview.getThumbnail().isPresent) { + thumbnailImageView.setImageResource(glide, ImageSlide(context, linkPreview.getThumbnail().get()), false, false) + } // Title titleTextView.text = linkPreview.title val textColorID = if (message.isOutgoing && UiModeUtilities.isDayUiMode(context)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index c40599630c..c949163a7c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -13,26 +13,24 @@ import androidx.annotation.DrawableRes import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.BlendModeColorFilterCompat import androidx.core.graphics.BlendModeCompat +import androidx.core.text.toSpannable import kotlinx.android.synthetic.main.view_visible_message_content.view.* import network.loki.messenger.R import org.session.libsession.utilities.ThemeUtil import org.session.libsession.utilities.ViewUtil import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.components.v2.AlbumThumbnailView +import org.thoughtcrime.securesms.components.emoji.EmojiTextView import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord -import org.thoughtcrime.securesms.loki.utilities.UiMode -import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities -import org.thoughtcrime.securesms.loki.utilities.getColorWithID -import org.thoughtcrime.securesms.loki.utilities.toPx +import org.thoughtcrime.securesms.loki.utilities.* +import org.thoughtcrime.securesms.loki.utilities.MentionUtilities.highlightMentions import org.thoughtcrime.securesms.mms.GlideRequests import kotlin.math.roundToInt class VisibleMessageContentView : LinearLayout { var onContentClick: (() -> Unit)? = null - // TODO: Large emojis - // region Lifecycle constructor(context: Context) : super(context) { initialize() } constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() } @@ -124,16 +122,18 @@ class VisibleMessageContentView : LinearLayout { companion object { fun getBodyTextView(context: Context, message: MessageRecord): TextView { - val result = TextView(context) + val result = EmojiTextView(context) val vPadding = context.resources.getDimension(R.dimen.small_spacing).toInt() val hPadding = toPx(12, context.resources) result.setPadding(hPadding, vPadding, hPadding, vPadding) - result.text = message.body result.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.resources.getDimension(R.dimen.small_font_size)) val color = getTextColor(context, message) result.setTextColor(color) result.setLinkTextColor(color) - Linkify.addLinks(result, Linkify.WEB_URLS) + var body = message.body.toSpannable() + Linkify.addLinks(body, Linkify.WEB_URLS) + body = MentionUtilities.highlightMentions(body, message.isOutgoing, message.threadId, context); + result.text = body return result } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/BaseDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/BaseDialog.kt new file mode 100644 index 0000000000..79bb1405a7 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/BaseDialog.kt @@ -0,0 +1,26 @@ +package org.thoughtcrime.securesms.conversation.v2.utilities + +import android.app.Dialog +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities + +open class BaseDialog : DialogFragment() { + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val builder = AlertDialog.Builder(requireContext()) + setContentView(builder) + val result = builder.create() + result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + val isLightMode = UiModeUtilities.isDayUiMode(requireContext()) + result.window?.setDimAmount(if (isLightMode) 0.1f else 0.75f) + return result + } + + open fun setContentView(builder: AlertDialog.Builder) { + // To be overridden by subclasses + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ThumbnailView.java similarity index 97% rename from app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java rename to app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ThumbnailView.java index 106fa45096..b2fe05b54a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ThumbnailView.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.components; +package org.thoughtcrime.securesms.conversation.v2.utilities; import android.content.Context; import android.content.res.TypedArray; @@ -24,6 +24,9 @@ import com.bumptech.glide.request.RequestOptions; import network.loki.messenger.R; +import org.thoughtcrime.securesms.components.GlideBitmapListeningTarget; +import org.thoughtcrime.securesms.components.GlideDrawableListeningTarget; +import org.thoughtcrime.securesms.components.TransferControlView; import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri; import org.thoughtcrime.securesms.mms.GlideRequest; import org.thoughtcrime.securesms.mms.GlideRequests; @@ -94,10 +97,9 @@ public class ThumbnailView extends FrameLayout { bounds[MAX_WIDTH] = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_maxWidth, 0); bounds[MIN_HEIGHT] = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_minHeight, 0); bounds[MAX_HEIGHT] = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_maxHeight, 0); - radius = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_thumbnail_radius, getResources().getDimensionPixelSize(R.dimen.thumbnail_default_radius)); typedArray.recycle(); } else { - radius = getResources().getDimensionPixelSize(R.dimen.message_corner_collapse_radius); + radius = 0; } } @@ -275,7 +277,7 @@ public class ThumbnailView extends FrameLayout { this.slide = slide; - this.captionIcon.setVisibility(slide.getCaption().isPresent() ? VISIBLE : GONE); + this.captionIcon.setVisibility(GONE); dimens[WIDTH] = naturalWidth; dimens[HEIGHT] = naturalHeight; @@ -398,6 +400,7 @@ public class ThumbnailView extends FrameLayout { } private class ThumbnailClickDispatcher implements View.OnClickListener { + @Override public void onClick(View view) { if (thumbnailClickListener != null && @@ -413,9 +416,9 @@ public class ThumbnailView extends FrameLayout { } private class DownloadClickDispatcher implements View.OnClickListener { + @Override public void onClick(View view) { - Log.i(TAG, "onClick() for download button"); if (downloadClickListener != null && slide != null) { downloadClickListener.onClick(view, Collections.singletonList(slide)); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index a6f4c801fb..dd2bd7735d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -95,7 +95,7 @@ public class LinkPreviewRepository implements InjectableType { private @NonNull RequestController fetchMetadata(@NonNull String url, Callback callback) { Call call = client.newCall(new Request.Builder().url(url).removeHeader("User-Agent").addHeader("User-Agent", - "WhatsApp").cacheControl(NO_CACHE).build()); + "WhatsApp").cacheControl(NO_CACHE).build()); call.enqueue(new okhttp3.Callback() { @Override @@ -186,18 +186,18 @@ public class LinkPreviewRepository implements InjectableType { byte[] bytes = baos.toByteArray(); Uri uri = BlobProvider.getInstance().forData(bytes).createForSingleSessionInMemory(); - return Optional.of(new UriAttachment(uri, - uri, - contentType, - AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED, - bytes.length, - bitmap.getWidth(), - bitmap.getHeight(), - null, - null, - false, - false, - null)); + return Optional.of(new UriAttachment(uri, + uri, + contentType, + AttachmentTransferProgress.TRANSFER_PROGRESS_STARTED, + bytes.length, + bitmap.getWidth(), + bitmap.getHeight(), + null, + null, + false, + false, + null)); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java index dbf8c4bf66..8556c232a0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java @@ -74,7 +74,7 @@ public class LinkPreviewViewModel extends ViewModel { activeRequest = null; } - if (!link.isPresent() || !isCursorPositionValid(text, link.get(), cursorStart, cursorEnd)) { + if (!link.isPresent()) { activeUrl = null; linkPreviewState.setValue(LinkPreviewState.forEmpty()); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/OpenGroupGuidelinesActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/OpenGroupGuidelinesActivity.kt similarity index 97% rename from app/src/main/java/org/thoughtcrime/securesms/conversation/v2/OpenGroupGuidelinesActivity.kt rename to app/src/main/java/org/thoughtcrime/securesms/loki/activities/OpenGroupGuidelinesActivity.kt index 4e0f42d215..9c714b6eff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/OpenGroupGuidelinesActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/OpenGroupGuidelinesActivity.kt @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.conversation.v2 +package org.thoughtcrime.securesms.loki.activities import android.os.Bundle import kotlinx.android.synthetic.main.activity_open_group_guidelines.* diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt index cb1bf22566..9db4533c9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt @@ -12,18 +12,16 @@ import network.loki.messenger.R import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol import org.session.libsession.utilities.KeyPairUtilities +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog +import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities -class ClearAllDataDialog : DialogFragment() { +class ClearAllDataDialog : BaseDialog() { - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(requireContext()) + override fun setContentView(builder: AlertDialog.Builder) { val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_clear_all_data, null) contentView.cancelButton.setOnClickListener { dismiss() } contentView.clearAllDataButton.setOnClickListener { clearAllData() } builder.setView(contentView) - val result = builder.create() - result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) - return result } private fun clearAllData() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt index 2bd9595b22..ab847ec2c1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt @@ -1,24 +1,20 @@ package org.thoughtcrime.securesms.loki.dialogs -import android.app.Dialog import android.content.ClipData import android.content.ClipboardManager import android.content.Context -import android.graphics.Color -import android.graphics.drawable.ColorDrawable -import android.os.Bundle import android.view.LayoutInflater import android.widget.Toast import androidx.appcompat.app.AlertDialog -import androidx.fragment.app.DialogFragment import kotlinx.android.synthetic.main.dialog_seed.view.* import network.loki.messenger.R import org.session.libsession.utilities.IdentityKeyUtil import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities import org.session.libsignal.crypto.MnemonicCodec import org.session.libsignal.utilities.hexEncodedPrivateKey +import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog -class SeedDialog : DialogFragment() { +class SeedDialog : BaseDialog() { private val seed by lazy { var hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED) @@ -31,16 +27,12 @@ class SeedDialog : DialogFragment() { MnemonicCodec(loadFileContents).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english) } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(requireContext()) + override fun setContentView(builder: AlertDialog.Builder) { val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_seed, null) contentView.seedTextView.text = seed contentView.cancelButton.setOnClickListener { dismiss() } contentView.copyButton.setOnClickListener { copySeed() } builder.setView(contentView) - val result = builder.create() - result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) - return result } private fun copySeed() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt index 45fda301d8..d54d19f0ee 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt @@ -7,6 +7,7 @@ import android.text.SpannableString import android.text.style.ForegroundColorSpan import android.text.style.StyleSpan import android.util.Range +import androidx.core.content.res.ResourcesCompat import network.loki.messenger.R import nl.komponents.kovenant.combine.Tuple2 import org.session.libsession.messaging.contacts.Contact @@ -23,7 +24,7 @@ object MentionUtilities { @JvmStatic fun highlightMentions(text: CharSequence, isOutgoingMessage: Boolean, threadID: Long, context: Context): SpannableString { - var text = text + @Suppress("NAME_SHADOWING") var text = text val threadDB = DatabaseFactory.getThreadDatabase(context) val isOpenGroup = threadDB.getRecipientForThreadId(threadID)?.isOpenGroupRecipient ?: false val pattern = Pattern.compile("@[0-9a-fA-F]*") @@ -38,7 +39,7 @@ object MentionUtilities { TextSecurePreferences.getProfileName(context) } else { val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey) - val context = if (isOpenGroup) Contact.ContactContext.OPEN_GROUP else Contact.ContactContext.REGULAR + @Suppress("NAME_SHADOWING") val context = if (isOpenGroup) Contact.ContactContext.OPEN_GROUP else Contact.ContactContext.REGULAR contact?.displayName(context) } if (userDisplayName != null) { @@ -54,10 +55,15 @@ object MentionUtilities { } } val result = SpannableString(text) + val isLightMode = UiModeUtilities.isDayUiMode(context) for (mention in mentions) { - val isLightMode = UiModeUtilities.isDayUiMode(context) - val colorID = if (isLightMode && isOutgoingMessage) R.color.black else R.color.accent - result.setSpan(ForegroundColorSpan(context.resources.getColorWithID(colorID, context.theme)), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + val colorID = if (isOutgoingMessage) { + if (isLightMode) R.color.white else R.color.black + } else { + R.color.accent + } + val color = ResourcesCompat.getColor(context.resources, colorID, context.theme) + result.setSpan(ForegroundColorSpan(color), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) result.setSpan(StyleSpan(Typeface.BOLD), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) } return result diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt index 5fa8967d95..cff2096de7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt @@ -4,9 +4,11 @@ import android.content.Context import android.content.res.Resources import android.graphics.Typeface import android.util.AttributeSet +import android.util.TypedValue import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout +import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.view_conversation.view.* import network.loki.messenger.R @@ -37,13 +39,20 @@ class ConversationView : LinearLayout { fun bind(thread: ThreadRecord, isTyping: Boolean, glide: GlideRequests) { this.thread = thread populateUserPublicKeyCacheIfNeeded(thread.threadId, context) // FIXME: This is a bad place to do this + val unreadCount = thread.unreadCount if (thread.recipient.isBlocked) { accentView.setBackgroundResource(R.color.destructive) accentView.visibility = View.VISIBLE } else { accentView.setBackgroundResource(R.color.accent) - accentView.visibility = if (thread.unreadCount > 0) View.VISIBLE else View.INVISIBLE + accentView.visibility = if (unreadCount > 0) View.VISIBLE else View.INVISIBLE } + val formattedUnreadCount = if (unreadCount < 100) unreadCount.toString() else "99+" + unreadCountTextView.text = formattedUnreadCount + val textSize = if (unreadCount < 100) 12.0f else 9.0f + unreadCountTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize) + unreadCountTextView.setTypeface(Typeface.DEFAULT, if (unreadCount < 100) Typeface.BOLD else Typeface.NORMAL) + unreadCountIndicator.isVisible = (unreadCount != 0) profilePictureView.glide = glide profilePictureView.update(thread.recipient, thread.threadId) val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString() @@ -53,7 +62,7 @@ class ConversationView : LinearLayout { val rawSnippet = thread.getDisplayBody(context) val snippet = highlightMentions(rawSnippet, thread.threadId, context) snippetTextView.text = snippet - snippetTextView.typeface = if (thread.unreadCount > 0) Typeface.DEFAULT_BOLD else Typeface.DEFAULT + snippetTextView.typeface = if (unreadCount > 0) Typeface.DEFAULT_BOLD else Typeface.DEFAULT snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE if (isTyping) { typingIndicatorView.startAnimation() diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaRailAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaRailAdapter.java index 7767d0d7ea..dd27c42502 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaRailAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaRailAdapter.java @@ -10,7 +10,7 @@ import android.view.ViewGroup; import network.loki.messenger.R; -import org.thoughtcrime.securesms.components.ThumbnailView; +import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView; import org.thoughtcrime.securesms.mediasend.Media; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.util.StableIdGenerator; diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java b/app/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java index dcac22909c..e2b7980ab6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java @@ -41,7 +41,7 @@ import org.thoughtcrime.securesms.MediaPreviewActivity; import org.thoughtcrime.securesms.loki.views.MessageAudioView; import org.thoughtcrime.securesms.components.DocumentView; import org.thoughtcrime.securesms.components.RemovableEditableMediaView; -import org.thoughtcrime.securesms.components.ThumbnailView; +import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView; import org.session.libsignal.utilities.NoExternalStorageException; import org.thoughtcrime.securesms.giph.ui.GiphyActivity; import org.session.libsignal.utilities.Log; diff --git a/app/src/main/res/drawable/default_dialog_background.xml b/app/src/main/res/drawable/default_dialog_background.xml index fff764ebd5..4cd206aca8 100644 --- a/app/src/main/res/drawable/default_dialog_background.xml +++ b/app/src/main/res/drawable/default_dialog_background.xml @@ -7,5 +7,4 @@ - \ No newline at end of file diff --git a/app/src/main/res/drawable/default_dialog_background_inset.xml b/app/src/main/res/drawable/default_dialog_background_inset.xml index b67cfb0b73..0ff315ebd3 100644 --- a/app/src/main/res/drawable/default_dialog_background_inset.xml +++ b/app/src/main/res/drawable/default_dialog_background_inset.xml @@ -2,6 +2,5 @@ + android:inset="@dimen/medium_spacing"> \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_link.xml b/app/src/main/res/drawable/ic_link.xml new file mode 100644 index 0000000000..56b2c2168c --- /dev/null +++ b/app/src/main/res/drawable/ic_link.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_conversation_v2.xml b/app/src/main/res/layout/activity_conversation_v2.xml index a975516701..66d71f5cce 100644 --- a/app/src/main/res/layout/activity_conversation_v2.xml +++ b/app/src/main/res/layout/activity_conversation_v2.xml @@ -1,12 +1,14 @@ - - + + + android:alpha="1"> - + + + + + + + + + + + @@ -99,4 +137,26 @@ android:visibility="gone" android:layout_alignParentBottom="true" /> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_conversation_v2_action_bar.xml b/app/src/main/res/layout/activity_conversation_v2_action_bar.xml index 4716171f50..294e75564c 100644 --- a/app/src/main/res/layout/activity_conversation_v2_action_bar.xml +++ b/app/src/main/res/layout/activity_conversation_v2_action_bar.xml @@ -1,8 +1,9 @@ - @@ -11,16 +12,57 @@ android:layout_width="@dimen/small_profile_picture_size" android:layout_height="@dimen/small_profile_picture_size" /> - + android:layout_marginTop="-2dp" + android:orientation="vertical"> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/conversation_activity.xml b/app/src/main/res/layout/conversation_activity.xml index d5859631fc..814d7d6943 100644 --- a/app/src/main/res/layout/conversation_activity.xml +++ b/app/src/main/res/layout/conversation_activity.xml @@ -135,7 +135,7 @@ android:background="?android:dividerHorizontal" android:elevation="1dp" /> - - - - diff --git a/app/src/main/res/layout/dialog_blocked.xml b/app/src/main/res/layout/dialog_blocked.xml new file mode 100644 index 0000000000..38b13c3da5 --- /dev/null +++ b/app/src/main/res/layout/dialog_blocked.xml @@ -0,0 +1,57 @@ + + + + + + + + + +