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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_clear_all_data.xml b/app/src/main/res/layout/dialog_clear_all_data.xml
index a4c94c2e84..9d82d0bbad 100644
--- a/app/src/main/res/layout/dialog_clear_all_data.xml
+++ b/app/src/main/res/layout/dialog_clear_all_data.xml
@@ -6,10 +6,8 @@
android:background="@drawable/default_dialog_background_inset"
android:gravity="center_horizontal"
android:orientation="vertical"
- android:paddingLeft="32dp"
- android:paddingTop="@dimen/medium_spacing"
- android:paddingRight="32dp"
- android:paddingBottom="@dimen/medium_spacing">
+ android:elevation="4dp"
+ android:padding="32dp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_join_open_group.xml b/app/src/main/res/layout/dialog_join_open_group.xml
new file mode 100644
index 0000000000..a84a4101cd
--- /dev/null
+++ b/app/src/main/res/layout/dialog_join_open_group.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_link_preview.xml b/app/src/main/res/layout/dialog_link_preview.xml
new file mode 100644
index 0000000000..67fb381e04
--- /dev/null
+++ b/app/src/main/res/layout/dialog_link_preview.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_open_url.xml b/app/src/main/res/layout/dialog_open_url.xml
new file mode 100644
index 0000000000..05cd2b5f1c
--- /dev/null
+++ b/app/src/main/res/layout/dialog_open_url.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_seed.xml b/app/src/main/res/layout/dialog_seed.xml
index 5ecc7982a4..dd4c2d32b2 100644
--- a/app/src/main/res/layout/dialog_seed.xml
+++ b/app/src/main/res/layout/dialog_seed.xml
@@ -6,10 +6,7 @@
android:background="@drawable/default_dialog_background_inset"
android:gravity="center_horizontal"
android:orientation="vertical"
- android:paddingLeft="32dp"
- android:paddingTop="@dimen/medium_spacing"
- android:paddingRight="32dp"
- android:paddingBottom="@dimen/medium_spacing">
+ android:padding="32dp">
-
-
-
-
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_link_preview.xml b/app/src/main/res/layout/view_link_preview.xml
index 38e0ef00cf..41997eaf64 100644
--- a/app/src/main/res/layout/view_link_preview.xml
+++ b/app/src/main/res/layout/view_link_preview.xml
@@ -1,11 +1,11 @@
-
+ android:orientation="vertical"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
-
+ android:layout_height="96dp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/typing_indicator_view.xml b/app/src/main/res/layout/view_typing_indicator.xml
similarity index 92%
rename from app/src/main/res/layout/typing_indicator_view.xml
rename to app/src/main/res/layout/view_typing_indicator.xml
index 23a4cf19ef..b48c554476 100644
--- a/app/src/main/res/layout/typing_indicator_view.xml
+++ b/app/src/main/res/layout/view_typing_indicator.xml
@@ -5,7 +5,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context="org.thoughtcrime.securesms.components.TypingIndicatorView">
+ tools:context="org.thoughtcrime.securesms.conversation.v2.components.TypingIndicatorView">
#0F000000
#FCFCFC
#99000000
+ #E0E0E0
#ffffff
#fcfcfc
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index fa24a3ecee..5f8fa46a6b 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -38,6 +38,7 @@
#000000
#171717
#99FFFFFF
+ #303030
- #5ff8b0
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b4fd882fe7..27203d0863 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -309,7 +309,7 @@
You
Unsupported media type
Draft
- Session needs the Storage permission in order to save to external storage, but it has been permanently denied. Please continue to app settings, select \"Permissions\", and enable \"Storage\".
+ Session needs storage access in order to save to external storage, but it has been permanently denied. Please continue to app settings, select \"Permissions\", and enable \"Storage\".
Unable to save to external storage without permissions
Delete message?
This will permanently delete this message.
@@ -853,4 +853,23 @@
Document
+ Unblock %s?
+ Are you sure you want to unblock %s?
+
+ Join %s?
+ Are you sure you want to join the %s open group?
+
+ Open URL?
+ Are you sure you want to open %s?
+ Open
+
+ Enable Link Previews?
+ Enabling link previews will show previews for URLs you send and receive. This can be useful, but Session will need to contact linked websites to generate previews. You can always disable link previews in Session\'s settings.
+ Enable
+
+ Trust %s?
+ Are you sure you want to download media sent by %s?
+ Download
+
+ %s is blocked. Unblock them?
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 202f171816..5928d5687f 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -280,4 +280,9 @@
- true
+
+