mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-06 12:05:40 +00:00
Merge remote-tracking branch 'upstream/ui' into ui
# Conflicts: # app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java # app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt # app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt
This commit is contained in:
commit
b5f41b4383
@ -223,7 +223,7 @@
|
|||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/Theme.Session.DayNight.FlatActionBar" />
|
android:theme="@style/Theme.Session.DayNight.FlatActionBar" />
|
||||||
<activity
|
<activity
|
||||||
android:name="org.thoughtcrime.securesms.conversation.v2.OpenGroupGuidelinesActivity"
|
android:name="org.thoughtcrime.securesms.loki.activities.OpenGroupGuidelinesActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/Theme.TextSecure.DayNight" />
|
android:theme="@style/Theme.TextSecure.DayNight" />
|
||||||
<activity
|
<activity
|
||||||
|
@ -26,7 +26,7 @@ import android.widget.TextView;
|
|||||||
import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter;
|
import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter;
|
||||||
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.components.ThumbnailView;
|
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
|
||||||
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord;
|
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord;
|
||||||
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
|
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
@ -12,7 +12,7 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import network.loki.messenger.R;
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.components.v2.ThumbnailView;
|
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
|
@ -12,6 +12,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
|
@ -8,6 +8,7 @@ import android.util.AttributeSet;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.components.TypingIndicatorView;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.session.libsession.utilities.recipients.Recipient;
|
import org.session.libsession.utilities.recipients.Recipient;
|
||||||
import org.session.libsession.utilities.ThemeUtil;
|
import org.session.libsession.utilities.ThemeUtil;
|
||||||
|
@ -5,6 +5,7 @@ import android.graphics.Canvas;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import org.session.libsession.utilities.ThemeUtil;
|
import org.session.libsession.utilities.ThemeUtil;
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import android.util.AttributeSet;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
|
@ -11,7 +11,6 @@ import android.text.SpannableStringBuilder;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
import network.loki.messenger.R;
|
||||||
import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
|
import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
|
||||||
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
|
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
|
||||||
@ -19,9 +18,7 @@ import org.session.libsession.utilities.TextSecurePreferences;
|
|||||||
import org.session.libsession.utilities.Util;
|
import org.session.libsession.utilities.Util;
|
||||||
import org.session.libsignal.utilities.guava.Optional;
|
import org.session.libsignal.utilities.guava.Optional;
|
||||||
|
|
||||||
|
|
||||||
public class EmojiTextView extends AppCompatTextView {
|
public class EmojiTextView extends AppCompatTextView {
|
||||||
|
|
||||||
private final boolean scaleEmojis;
|
private final boolean scaleEmojis;
|
||||||
|
|
||||||
private static final char ELLIPSIS = '…';
|
private static final char ELLIPSIS = '…';
|
||||||
@ -46,14 +43,9 @@ public class EmojiTextView extends AppCompatTextView {
|
|||||||
public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
|
|
||||||
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EmojiTextView, 0, 0);
|
scaleEmojis = true;
|
||||||
scaleEmojis = a.getBoolean(R.styleable.EmojiTextView_scaleEmojis, false);
|
maxLength = 1000;
|
||||||
maxLength = a.getInteger(R.styleable.EmojiTextView_emoji_maxLength, -1);
|
originalFontSize = getResources().getDimension(R.dimen.small_font_size);
|
||||||
a.recycle();
|
|
||||||
|
|
||||||
a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.textSize});
|
|
||||||
originalFontSize = a.getDimensionPixelSize(0, 0);
|
|
||||||
a.recycle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setText(@Nullable CharSequence text, BufferType type) {
|
@Override public void setText(@Nullable CharSequence text, BufferType type) {
|
||||||
@ -182,8 +174,11 @@ public class EmojiTextView extends AppCompatTextView {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateDrawable(@NonNull Drawable drawable) {
|
public void invalidateDrawable(@NonNull Drawable drawable) {
|
||||||
if (drawable instanceof EmojiDrawable) invalidate();
|
if (drawable instanceof EmojiDrawable) {
|
||||||
else super.invalidateDrawable(drawable);
|
invalidate();
|
||||||
|
} else {
|
||||||
|
super.invalidateDrawable(drawable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,25 +5,35 @@ import android.animation.ValueAnimator
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import androidx.loader.app.LoaderManager
|
import androidx.loader.app.LoaderManager
|
||||||
import androidx.loader.content.Loader
|
import androidx.loader.content.Loader
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
||||||
import kotlinx.android.synthetic.main.activity_conversation_v2.view.*
|
import kotlinx.android.synthetic.main.activity_conversation_v2.view.*
|
||||||
import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.*
|
import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.*
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
|
import kotlinx.android.synthetic.main.view_conversation.view.*
|
||||||
import kotlinx.android.synthetic.main.view_input_bar.view.*
|
import kotlinx.android.synthetic.main.view_input_bar.view.*
|
||||||
import kotlinx.android.synthetic.main.view_input_bar_recording.*
|
import kotlinx.android.synthetic.main.view_input_bar_recording.*
|
||||||
import kotlinx.android.synthetic.main.view_input_bar_recording.view.*
|
import kotlinx.android.synthetic.main.view_input_bar_recording.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import nl.komponents.kovenant.ui.successUi
|
||||||
|
import org.session.libsession.messaging.contacts.Contact
|
||||||
import org.session.libsession.messaging.mentions.MentionsManager
|
import org.session.libsession.messaging.mentions.MentionsManager
|
||||||
|
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
||||||
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.dialogs.*
|
||||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton
|
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton
|
||||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate
|
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate
|
||||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarRecordingViewDelegate
|
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarRecordingViewDelegate
|
||||||
@ -35,8 +45,13 @@ import org.thoughtcrime.securesms.database.DatabaseFactory
|
|||||||
import org.thoughtcrime.securesms.database.DraftDatabase
|
import org.thoughtcrime.securesms.database.DraftDatabase
|
||||||
import org.thoughtcrime.securesms.database.DraftDatabase.Drafts
|
import org.thoughtcrime.securesms.database.DraftDatabase.Drafts
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository
|
||||||
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel
|
||||||
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState
|
||||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp
|
import org.thoughtcrime.securesms.mms.GlideApp
|
||||||
|
import org.thoughtcrime.securesms.util.DateUtils
|
||||||
|
import java.util.*
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDelegate,
|
class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDelegate,
|
||||||
@ -44,6 +59,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
private val scrollButtonFullVisibilityThreshold by lazy { toPx(120.0f, resources) }
|
private val scrollButtonFullVisibilityThreshold by lazy { toPx(120.0f, resources) }
|
||||||
private val scrollButtonNoVisibilityThreshold by lazy { toPx(20.0f, resources) }
|
private val scrollButtonNoVisibilityThreshold by lazy { toPx(20.0f, resources) }
|
||||||
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||||
|
private var linkPreviewViewModel: LinkPreviewViewModel? = null
|
||||||
private var threadID: Long = -1
|
private var threadID: Long = -1
|
||||||
private var actionMode: ActionMode? = null
|
private var actionMode: ActionMode? = null
|
||||||
private var isLockViewExpanded = false
|
private var isLockViewExpanded = false
|
||||||
@ -52,7 +68,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
|
|
||||||
// TODO: Selected message background color
|
// TODO: Selected message background color
|
||||||
// TODO: Overflow menu background + text color
|
// TODO: Overflow menu background + text color
|
||||||
// TODO: Typing indicators
|
|
||||||
|
|
||||||
private val adapter by lazy {
|
private val adapter by lazy {
|
||||||
val cursor = DatabaseFactory.getMmsSmsDatabase(this).getConversation(threadID)
|
val cursor = DatabaseFactory.getMmsSmsDatabase(this).getConversation(threadID)
|
||||||
@ -101,6 +116,12 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
restoreDraftIfNeeded()
|
restoreDraftIfNeeded()
|
||||||
addOpenGroupGuidelinesIfNeeded()
|
addOpenGroupGuidelinesIfNeeded()
|
||||||
scrollToBottomButton.setOnClickListener { conversationRecyclerView.smoothScrollToPosition(0) }
|
scrollToBottomButton.setOnClickListener { conversationRecyclerView.smoothScrollToPosition(0) }
|
||||||
|
updateUnreadCount()
|
||||||
|
setUpTypingObserver()
|
||||||
|
updateSubtitle()
|
||||||
|
getLatestOpenGroupInfoIfNeeded()
|
||||||
|
setUpBlockedBanner()
|
||||||
|
setUpLinkPreviewObserver()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@ -180,6 +201,47 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
conversationRecyclerView.layoutParams = recyclerViewLayoutParams
|
conversationRecyclerView.layoutParams = recyclerViewLayoutParams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setUpTypingObserver() {
|
||||||
|
ApplicationContext.getInstance(this).typingStatusRepository.getTypists(threadID).observe(this) { state ->
|
||||||
|
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 {
|
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
|
||||||
ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) }
|
ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) }
|
||||||
super.onPrepareOptionsMenu(menu)
|
super.onPrepareOptionsMenu(menu)
|
||||||
@ -194,9 +256,13 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
|
|
||||||
// region Updating & Animation
|
// region Updating & Animation
|
||||||
override fun inputBarHeightChanged(newValue: Int) {
|
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
|
// Recycler view
|
||||||
val recyclerViewLayoutParams = conversationRecyclerView.layoutParams as RelativeLayout.LayoutParams
|
val recyclerViewLayoutParams = conversationRecyclerView.layoutParams as RelativeLayout.LayoutParams
|
||||||
recyclerViewLayoutParams.bottomMargin = newValue + additionalContentContainer.height
|
recyclerViewLayoutParams.bottomMargin = newValue + additionalContentContainer.height + typingIndicatorHeight
|
||||||
conversationRecyclerView.layoutParams = recyclerViewLayoutParams
|
conversationRecyclerView.layoutParams = recyclerViewLayoutParams
|
||||||
// Additional content container
|
// Additional content container
|
||||||
val additionalContentContainerLayoutParams = additionalContentContainer.layoutParams as RelativeLayout.LayoutParams
|
val additionalContentContainerLayoutParams = additionalContentContainer.layoutParams as RelativeLayout.LayoutParams
|
||||||
@ -216,6 +282,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun inputBarEditTextContentChanged(newContent: CharSequence) {
|
override fun inputBarEditTextContentChanged(newContent: CharSequence) {
|
||||||
|
linkPreviewViewModel?.onTextChanged(this, inputBar.text, 0, 0)
|
||||||
// TODO: Implement the full mention show/hide logic
|
// TODO: Implement the full mention show/hide logic
|
||||||
if (newContent.contains("@")) {
|
if (newContent.contains("@")) {
|
||||||
showMentionCandidates()
|
showMentionCandidates()
|
||||||
@ -330,6 +397,35 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
(scrollButtonFullVisibilityThreshold - scrollButtonNoVisibilityThreshold)
|
(scrollButtonFullVisibilityThreshold - scrollButtonNoVisibilityThreshold)
|
||||||
val alpha = max(min(rawAlpha, 1.0f), 0.0f)
|
val alpha = max(min(rawAlpha, 1.0f), 0.0f)
|
||||||
scrollToBottomButton.alpha = alpha
|
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
|
// endregion
|
||||||
|
|
||||||
@ -351,6 +447,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
this.actionMode = null
|
this.actionMode = null
|
||||||
}
|
}
|
||||||
} else {
|
} 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()
|
view.onContentClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -432,6 +532,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
lockViewLocation[0] + lockView.width + lockViewHitMargin, lockViewLocation[1] + lockView.height)
|
lockViewLocation[0] + lockView.width + lockViewHitMargin, lockViewLocation[1] + lockView.height)
|
||||||
return hitRect.contains(x, y)
|
return hitRect.contains(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun unblock() {
|
||||||
|
// TODO: Implement
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region General
|
// region General
|
||||||
|
@ -5,6 +5,7 @@ import android.util.AttributeSet
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.VelocityTracker
|
import android.view.VelocityTracker
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
||||||
import org.thoughtcrime.securesms.loki.utilities.disableClipping
|
import org.thoughtcrime.securesms.loki.utilities.disableClipping
|
||||||
|
@ -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
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.v2
|
package org.thoughtcrime.securesms.conversation.v2.components
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@ -7,6 +7,8 @@ import android.view.LayoutInflater
|
|||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import kotlinx.android.synthetic.main.view_open_group_guidelines.view.*
|
import kotlinx.android.synthetic.main.view_open_group_guidelines.view.*
|
||||||
import network.loki.messenger.R
|
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
|
import org.thoughtcrime.securesms.loki.utilities.push
|
||||||
|
|
||||||
class OpenGroupGuidelinesView : FrameLayout {
|
class OpenGroupGuidelinesView : FrameLayout {
|
@ -1,4 +1,4 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.conversation.v2.components;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
@ -13,18 +13,14 @@ import android.widget.LinearLayout;
|
|||||||
import network.loki.messenger.R;
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
public class TypingIndicatorView extends LinearLayout {
|
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 CYCLE_DURATION = 1500;
|
||||||
private static final long DOT_DURATION = 600;
|
private static final long DOT_DURATION = 600;
|
||||||
private static final float MIN_ALPHA = 0.4f;
|
private static final float MIN_ALPHA = 0.4f;
|
||||||
private static final float MIN_SCALE = 0.75f;
|
private static final float MIN_SCALE = 0.75f;
|
||||||
|
|
||||||
private boolean isActive;
|
|
||||||
private long startTime;
|
|
||||||
|
|
||||||
private View dot1;
|
private View dot1;
|
||||||
private View dot2;
|
private View dot2;
|
||||||
private View dot3;
|
private View dot3;
|
||||||
@ -40,7 +36,7 @@ public class TypingIndicatorView extends LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initialize(@Nullable AttributeSet attrs) {
|
private void initialize(@Nullable AttributeSet attrs) {
|
||||||
inflate(getContext(), R.layout.typing_indicator_view, this);
|
inflate(getContext(), R.layout.view_typing_indicator, this);
|
||||||
|
|
||||||
setWillNotDraw(false);
|
setWillNotDraw(false);
|
||||||
|
|
@ -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<Recipient>) {
|
||||||
|
if (typists.isEmpty()) { typingIndicator.stopAnimation(); return }
|
||||||
|
typingIndicator.startAnimation()
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -2,24 +2,23 @@ package org.thoughtcrime.securesms.conversation.v2.input_bar
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.text.Editable
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import kotlinx.android.synthetic.main.view_input_bar.view.*
|
import kotlinx.android.synthetic.main.view_input_bar.view.*
|
||||||
import kotlinx.android.synthetic.main.view_quote.view.*
|
import kotlinx.android.synthetic.main.view_quote.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
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.QuoteView
|
||||||
import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate
|
import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.loki.utilities.toDp
|
import org.thoughtcrime.securesms.loki.utilities.toDp
|
||||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||||
import org.thoughtcrime.securesms.mms.SlideDeck
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -27,6 +26,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate {
|
|||||||
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
private val screenWidth = Resources.getSystem().displayMetrics.widthPixels
|
||||||
private val vMargin by lazy { toDp(4, resources) }
|
private val vMargin by lazy { toDp(4, resources) }
|
||||||
private val minHeight by lazy { toPx(56, resources) }
|
private val minHeight by lazy { toPx(56, resources) }
|
||||||
|
private var linkPreviewDraftView: LinkPreviewDraftView? = null
|
||||||
var delegate: InputBarDelegate? = null
|
var delegate: InputBarDelegate? = null
|
||||||
var additionalContentHeight = 0
|
var additionalContentHeight = 0
|
||||||
|
|
||||||
@ -96,6 +96,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun draftQuote(message: MessageRecord) {
|
fun draftQuote(message: MessageRecord) {
|
||||||
|
linkPreviewDraftView = null
|
||||||
inputBarAdditionalContentContainer.removeAllViews()
|
inputBarAdditionalContentContainer.removeAllViews()
|
||||||
val quoteView = QuoteView(context, QuoteView.Mode.Draft)
|
val quoteView = QuoteView(context, QuoteView.Mode.Draft)
|
||||||
quoteView.delegate = this
|
quoteView.delegate = this
|
||||||
@ -121,6 +122,22 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate {
|
|||||||
additionalContentHeight = 0
|
additionalContentHeight = 0
|
||||||
setHeight(newHeight)
|
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
|
// endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.v2.messages
|
package org.thoughtcrime.securesms.conversation.v2.messages
|
||||||
|
|
||||||
import android.content.Context
|
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.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewOutlineProvider
|
import android.view.ViewOutlineProvider
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import androidx.core.content.res.ResourcesCompat
|
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.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities
|
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||||
|
import org.thoughtcrime.securesms.mms.ImageSlide
|
||||||
|
|
||||||
class LinkPreviewView : LinearLayout {
|
class LinkPreviewView : LinearLayout {
|
||||||
|
|
||||||
@ -39,10 +33,9 @@ class LinkPreviewView : LinearLayout {
|
|||||||
mainLinkPreviewContainer.clipToOutline = true
|
mainLinkPreviewContainer.clipToOutline = true
|
||||||
// Thumbnail
|
// Thumbnail
|
||||||
val linkPreview = message.linkPreviews.first()
|
val linkPreview = message.linkPreviews.first()
|
||||||
// TODO: Handle downloading state
|
if (linkPreview.getThumbnail().isPresent) {
|
||||||
val uri = linkPreview.thumbnail.get().dataUri ?: return
|
thumbnailImageView.setImageResource(glide, ImageSlide(context, linkPreview.getThumbnail().get()), false, false)
|
||||||
glide.load(uri).into(thumbnailImageView)
|
}
|
||||||
// TODO: Properly use glide and the actual thumbnail
|
|
||||||
// Title
|
// Title
|
||||||
titleTextView.text = linkPreview.title
|
titleTextView.text = linkPreview.title
|
||||||
val textColorID = if (message.isOutgoing && UiModeUtilities.isDayUiMode(context)) {
|
val textColorID = if (message.isOutgoing && UiModeUtilities.isDayUiMode(context)) {
|
||||||
|
@ -13,26 +13,24 @@ import androidx.annotation.DrawableRes
|
|||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.graphics.BlendModeColorFilterCompat
|
import androidx.core.graphics.BlendModeColorFilterCompat
|
||||||
import androidx.core.graphics.BlendModeCompat
|
import androidx.core.graphics.BlendModeCompat
|
||||||
|
import androidx.core.text.toSpannable
|
||||||
import kotlinx.android.synthetic.main.view_visible_message_content.view.*
|
import kotlinx.android.synthetic.main.view_visible_message_content.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.session.libsession.utilities.ThemeUtil
|
import org.session.libsession.utilities.ThemeUtil
|
||||||
import org.session.libsession.utilities.ViewUtil
|
import org.session.libsession.utilities.ViewUtil
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.components.v2.AlbumThumbnailView
|
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.MessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.loki.utilities.UiMode
|
import org.thoughtcrime.securesms.loki.utilities.*
|
||||||
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities
|
import org.thoughtcrime.securesms.loki.utilities.MentionUtilities.highlightMentions
|
||||||
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
|
|
||||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class VisibleMessageContentView : LinearLayout {
|
class VisibleMessageContentView : LinearLayout {
|
||||||
var onContentClick: (() -> Unit)? = null
|
var onContentClick: (() -> Unit)? = null
|
||||||
|
|
||||||
// TODO: Large emojis
|
|
||||||
|
|
||||||
// region Lifecycle
|
// region Lifecycle
|
||||||
constructor(context: Context) : super(context) { initialize() }
|
constructor(context: Context) : super(context) { initialize() }
|
||||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
|
||||||
@ -124,16 +122,18 @@ class VisibleMessageContentView : LinearLayout {
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun getBodyTextView(context: Context, message: MessageRecord): TextView {
|
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 vPadding = context.resources.getDimension(R.dimen.small_spacing).toInt()
|
||||||
val hPadding = toPx(12, context.resources)
|
val hPadding = toPx(12, context.resources)
|
||||||
result.setPadding(hPadding, vPadding, hPadding, vPadding)
|
result.setPadding(hPadding, vPadding, hPadding, vPadding)
|
||||||
result.text = message.body
|
|
||||||
result.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.resources.getDimension(R.dimen.small_font_size))
|
result.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.resources.getDimension(R.dimen.small_font_size))
|
||||||
val color = getTextColor(context, message)
|
val color = getTextColor(context, message)
|
||||||
result.setTextColor(color)
|
result.setTextColor(color)
|
||||||
result.setLinkTextColor(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
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.conversation.v2.utilities;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
@ -24,6 +24,9 @@ import com.bumptech.glide.request.RequestOptions;
|
|||||||
|
|
||||||
import network.loki.messenger.R;
|
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.DecryptableStreamUriLoader.DecryptableUri;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequest;
|
import org.thoughtcrime.securesms.mms.GlideRequest;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
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[MAX_WIDTH] = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_maxWidth, 0);
|
||||||
bounds[MIN_HEIGHT] = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_minHeight, 0);
|
bounds[MIN_HEIGHT] = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_minHeight, 0);
|
||||||
bounds[MAX_HEIGHT] = typedArray.getDimensionPixelSize(R.styleable.ThumbnailView_maxHeight, 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();
|
typedArray.recycle();
|
||||||
} else {
|
} 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.slide = slide;
|
||||||
|
|
||||||
this.captionIcon.setVisibility(slide.getCaption().isPresent() ? VISIBLE : GONE);
|
this.captionIcon.setVisibility(GONE);
|
||||||
|
|
||||||
dimens[WIDTH] = naturalWidth;
|
dimens[WIDTH] = naturalWidth;
|
||||||
dimens[HEIGHT] = naturalHeight;
|
dimens[HEIGHT] = naturalHeight;
|
||||||
@ -398,6 +400,7 @@ public class ThumbnailView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ThumbnailClickDispatcher implements View.OnClickListener {
|
private class ThumbnailClickDispatcher implements View.OnClickListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (thumbnailClickListener != null &&
|
if (thumbnailClickListener != null &&
|
||||||
@ -413,9 +416,9 @@ public class ThumbnailView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class DownloadClickDispatcher implements View.OnClickListener {
|
private class DownloadClickDispatcher implements View.OnClickListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Log.i(TAG, "onClick() for download button");
|
|
||||||
if (downloadClickListener != null && slide != null) {
|
if (downloadClickListener != null && slide != null) {
|
||||||
downloadClickListener.onClick(view, Collections.singletonList(slide));
|
downloadClickListener.onClick(view, Collections.singletonList(slide));
|
||||||
} else {
|
} else {
|
@ -74,7 +74,7 @@ public class LinkPreviewViewModel extends ViewModel {
|
|||||||
activeRequest = null;
|
activeRequest = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!link.isPresent() || !isCursorPositionValid(text, link.get(), cursorStart, cursorEnd)) {
|
if (!link.isPresent()) {
|
||||||
activeUrl = null;
|
activeUrl = null;
|
||||||
linkPreviewState.setValue(LinkPreviewState.forEmpty());
|
linkPreviewState.setValue(LinkPreviewState.forEmpty());
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.v2
|
package org.thoughtcrime.securesms.loki.activities
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import kotlinx.android.synthetic.main.activity_open_group_guidelines.*
|
import kotlinx.android.synthetic.main.activity_open_group_guidelines.*
|
@ -12,18 +12,16 @@ import network.loki.messenger.R
|
|||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol
|
import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol
|
||||||
import org.session.libsession.utilities.KeyPairUtilities
|
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 {
|
override fun setContentView(builder: AlertDialog.Builder) {
|
||||||
val builder = AlertDialog.Builder(requireContext())
|
|
||||||
val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_clear_all_data, null)
|
val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_clear_all_data, null)
|
||||||
contentView.cancelButton.setOnClickListener { dismiss() }
|
contentView.cancelButton.setOnClickListener { dismiss() }
|
||||||
contentView.clearAllDataButton.setOnClickListener { clearAllData() }
|
contentView.clearAllDataButton.setOnClickListener { clearAllData() }
|
||||||
builder.setView(contentView)
|
builder.setView(contentView)
|
||||||
val result = builder.create()
|
|
||||||
result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearAllData() {
|
private fun clearAllData() {
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
package org.thoughtcrime.securesms.loki.dialogs
|
package org.thoughtcrime.securesms.loki.dialogs
|
||||||
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import kotlinx.android.synthetic.main.dialog_seed.view.*
|
import kotlinx.android.synthetic.main.dialog_seed.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.session.libsession.utilities.IdentityKeyUtil
|
import org.session.libsession.utilities.IdentityKeyUtil
|
||||||
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
|
import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities
|
||||||
import org.session.libsignal.crypto.MnemonicCodec
|
import org.session.libsignal.crypto.MnemonicCodec
|
||||||
import org.session.libsignal.utilities.hexEncodedPrivateKey
|
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 {
|
private val seed by lazy {
|
||||||
var hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED)
|
var hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED)
|
||||||
@ -31,16 +27,12 @@ class SeedDialog : DialogFragment() {
|
|||||||
MnemonicCodec(loadFileContents).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english)
|
MnemonicCodec(loadFileContents).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun setContentView(builder: AlertDialog.Builder) {
|
||||||
val builder = AlertDialog.Builder(requireContext())
|
|
||||||
val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_seed, null)
|
val contentView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_seed, null)
|
||||||
contentView.seedTextView.text = seed
|
contentView.seedTextView.text = seed
|
||||||
contentView.cancelButton.setOnClickListener { dismiss() }
|
contentView.cancelButton.setOnClickListener { dismiss() }
|
||||||
contentView.copyButton.setOnClickListener { copySeed() }
|
contentView.copyButton.setOnClickListener { copySeed() }
|
||||||
builder.setView(contentView)
|
builder.setView(contentView)
|
||||||
val result = builder.create()
|
|
||||||
result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copySeed() {
|
private fun copySeed() {
|
||||||
|
@ -7,6 +7,7 @@ import android.text.SpannableString
|
|||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.text.style.StyleSpan
|
import android.text.style.StyleSpan
|
||||||
import android.util.Range
|
import android.util.Range
|
||||||
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import nl.komponents.kovenant.combine.Tuple2
|
import nl.komponents.kovenant.combine.Tuple2
|
||||||
import org.session.libsession.messaging.contacts.Contact
|
import org.session.libsession.messaging.contacts.Contact
|
||||||
@ -23,7 +24,7 @@ object MentionUtilities {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun highlightMentions(text: CharSequence, isOutgoingMessage: Boolean, threadID: Long, context: Context): SpannableString {
|
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 threadDB = DatabaseFactory.getThreadDatabase(context)
|
||||||
val isOpenGroup = threadDB.getRecipientForThreadId(threadID)?.isOpenGroupRecipient ?: false
|
val isOpenGroup = threadDB.getRecipientForThreadId(threadID)?.isOpenGroupRecipient ?: false
|
||||||
val pattern = Pattern.compile("@[0-9a-fA-F]*")
|
val pattern = Pattern.compile("@[0-9a-fA-F]*")
|
||||||
@ -38,7 +39,7 @@ object MentionUtilities {
|
|||||||
TextSecurePreferences.getProfileName(context)
|
TextSecurePreferences.getProfileName(context)
|
||||||
} else {
|
} else {
|
||||||
val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey)
|
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)
|
contact?.displayName(context)
|
||||||
}
|
}
|
||||||
if (userDisplayName != null) {
|
if (userDisplayName != null) {
|
||||||
@ -54,10 +55,15 @@ object MentionUtilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val result = SpannableString(text)
|
val result = SpannableString(text)
|
||||||
for (mention in mentions) {
|
|
||||||
val isLightMode = UiModeUtilities.isDayUiMode(context)
|
val isLightMode = UiModeUtilities.isDayUiMode(context)
|
||||||
val colorID = if (isLightMode && isOutgoingMessage) R.color.black else R.color.accent
|
for (mention in mentions) {
|
||||||
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)
|
result.setSpan(StyleSpan(Typeface.BOLD), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@ -4,9 +4,11 @@ import android.content.Context
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlinx.android.synthetic.main.view_conversation.view.*
|
import kotlinx.android.synthetic.main.view_conversation.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
@ -37,13 +39,20 @@ class ConversationView : LinearLayout {
|
|||||||
fun bind(thread: ThreadRecord, isTyping: Boolean, glide: GlideRequests) {
|
fun bind(thread: ThreadRecord, isTyping: Boolean, glide: GlideRequests) {
|
||||||
this.thread = thread
|
this.thread = thread
|
||||||
populateUserPublicKeyCacheIfNeeded(thread.threadId, context) // FIXME: This is a bad place to do this
|
populateUserPublicKeyCacheIfNeeded(thread.threadId, context) // FIXME: This is a bad place to do this
|
||||||
|
val unreadCount = thread.unreadCount
|
||||||
if (thread.recipient.isBlocked) {
|
if (thread.recipient.isBlocked) {
|
||||||
accentView.setBackgroundResource(R.color.destructive)
|
accentView.setBackgroundResource(R.color.destructive)
|
||||||
accentView.visibility = View.VISIBLE
|
accentView.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
accentView.setBackgroundResource(R.color.accent)
|
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.glide = glide
|
||||||
profilePictureView.update(thread.recipient, thread.threadId)
|
profilePictureView.update(thread.recipient, thread.threadId)
|
||||||
val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString()
|
val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString()
|
||||||
@ -53,7 +62,7 @@ class ConversationView : LinearLayout {
|
|||||||
val rawSnippet = thread.getDisplayBody(context)
|
val rawSnippet = thread.getDisplayBody(context)
|
||||||
val snippet = highlightMentions(rawSnippet, thread.threadId, context)
|
val snippet = highlightMentions(rawSnippet, thread.threadId, context)
|
||||||
snippetTextView.text = snippet
|
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
|
snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE
|
||||||
if (isTyping) {
|
if (isTyping) {
|
||||||
typingIndicatorView.startAnimation()
|
typingIndicatorView.startAnimation()
|
||||||
|
@ -10,7 +10,7 @@ import android.view.ViewGroup;
|
|||||||
import network.loki.messenger.R;
|
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.mediasend.Media;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
import org.thoughtcrime.securesms.util.StableIdGenerator;
|
import org.thoughtcrime.securesms.util.StableIdGenerator;
|
||||||
|
@ -41,7 +41,7 @@ import org.thoughtcrime.securesms.MediaPreviewActivity;
|
|||||||
import org.thoughtcrime.securesms.loki.views.MessageAudioView;
|
import org.thoughtcrime.securesms.loki.views.MessageAudioView;
|
||||||
import org.thoughtcrime.securesms.components.DocumentView;
|
import org.thoughtcrime.securesms.components.DocumentView;
|
||||||
import org.thoughtcrime.securesms.components.RemovableEditableMediaView;
|
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.session.libsignal.utilities.NoExternalStorageException;
|
||||||
import org.thoughtcrime.securesms.giph.ui.GiphyActivity;
|
import org.thoughtcrime.securesms.giph.ui.GiphyActivity;
|
||||||
import org.session.libsignal.utilities.Log;
|
import org.session.libsignal.utilities.Log;
|
||||||
|
@ -7,5 +7,4 @@
|
|||||||
|
|
||||||
<corners android:radius="@dimen/dialog_corner_radius" />
|
<corners android:radius="@dimen/dialog_corner_radius" />
|
||||||
|
|
||||||
<!-- <stroke android:width="@dimen/border_thickness" android:color="@color/dialog_border" />-->
|
|
||||||
</shape>
|
</shape>
|
@ -2,6 +2,5 @@
|
|||||||
<inset
|
<inset
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:drawable="@drawable/default_dialog_background"
|
android:drawable="@drawable/default_dialog_background"
|
||||||
android:insetRight="@dimen/medium_spacing"
|
android:inset="@dimen/medium_spacing">
|
||||||
android:insetLeft="@dimen/medium_spacing">
|
|
||||||
</inset>
|
</inset>
|
9
app/src/main/res/drawable/ic_link.xml
Normal file
9
app/src/main/res/drawable/ic_link.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="512"
|
||||||
|
android:viewportHeight="512">
|
||||||
|
<path
|
||||||
|
android:pathData="M326.612,185.391c59.747,59.809 58.927,155.698 0.36,214.59 -0.11,0.12 -0.24,0.25 -0.36,0.37l-67.2,67.2c-59.27,59.27 -155.699,59.262 -214.96,0 -59.27,-59.26 -59.27,-155.7 0,-214.96l37.106,-37.106c9.84,-9.84 26.786,-3.3 27.294,10.606 0.648,17.722 3.826,35.527 9.69,52.721 1.986,5.822 0.567,12.262 -3.783,16.612l-13.087,13.087c-28.026,28.026 -28.905,73.66 -1.155,101.96 28.024,28.579 74.086,28.749 102.325,0.51l67.2,-67.19c28.191,-28.191 28.073,-73.757 0,-101.83 -3.701,-3.694 -7.429,-6.564 -10.341,-8.569a16.037,16.037 0,0 1,-6.947 -12.606c-0.396,-10.567 3.348,-21.456 11.698,-29.806l21.054,-21.055c5.521,-5.521 14.182,-6.199 20.584,-1.731a152.482,152.482 0,0 1,20.522 17.197zM467.547,44.449c-59.261,-59.262 -155.69,-59.27 -214.96,0l-67.2,67.2c-0.12,0.12 -0.25,0.25 -0.36,0.37 -58.566,58.892 -59.387,154.781 0.36,214.59a152.454,152.454 0,0 0,20.521 17.196c6.402,4.468 15.064,3.789 20.584,-1.731l21.054,-21.055c8.35,-8.35 12.094,-19.239 11.698,-29.806a16.037,16.037 0,0 0,-6.947 -12.606c-2.912,-2.005 -6.64,-4.875 -10.341,-8.569 -28.073,-28.073 -28.191,-73.639 0,-101.83l67.2,-67.19c28.239,-28.239 74.3,-28.069 102.325,0.51 27.75,28.3 26.872,73.934 -1.155,101.96l-13.087,13.087c-4.35,4.35 -5.769,10.79 -3.783,16.612 5.864,17.194 9.042,34.999 9.69,52.721 0.509,13.906 17.454,20.446 27.294,10.606l37.106,-37.106c59.271,-59.259 59.271,-155.699 0.001,-214.959z"
|
||||||
|
android:fillColor="@color/text"/>
|
||||||
|
</vector>
|
@ -1,12 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/contentView"
|
android:id="@+id/contentView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.conversation.v2.OpenGroupGuidelinesView
|
<org.thoughtcrime.securesms.conversation.v2.components.OpenGroupGuidelinesView
|
||||||
android:id="@+id/openGroupGuidelinesView"
|
android:id="@+id/openGroupGuidelinesView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -18,6 +20,14 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginBottom="@dimen/input_bar_height" />
|
android:layout_marginBottom="@dimen/input_bar_height" />
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.conversation.v2.components.TypingIndicatorViewContainer
|
||||||
|
android:id="@+id/typingIndicatorViewContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginBottom="@dimen/input_bar_height"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.conversation.v2.input_bar.InputBar
|
<org.thoughtcrime.securesms.conversation.v2.input_bar.InputBar
|
||||||
android:id="@+id/inputBar"
|
android:id="@+id/inputBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -73,12 +83,18 @@
|
|||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/scrollToBottomButton"
|
android:id="@+id/scrollToBottomButton"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="40dp"
|
android:layout_height="50dp"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_marginRight="12dp"
|
android:layout_marginRight="12dp"
|
||||||
android:layout_marginBottom="72dp"
|
android:layout_marginBottom="72dp"
|
||||||
android:alpha="0"
|
android:alpha="1">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
android:background="@drawable/view_scroll_to_bottom_button_background">
|
android:background="@drawable/view_scroll_to_bottom_button_background">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@ -91,6 +107,28 @@
|
|||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/unreadCountIndicator"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:background="@drawable/circle_tintable"
|
||||||
|
android:backgroundTint="@color/conversation_unread_count_indicator_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/unreadCountTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:textSize="@dimen/very_small_font_size"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:text="8" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarRecordingView
|
<org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarRecordingView
|
||||||
android:id="@+id/inputBarRecordingView"
|
android:id="@+id/inputBarRecordingView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -99,4 +137,26 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_alignParentBottom="true" />
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/blockedBanner"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/destructive"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/blockedBannerTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_margin="@dimen/medium_spacing"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="Elon is blocked. Unblock them?" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
@ -11,11 +12,18 @@
|
|||||||
android:layout_width="@dimen/small_profile_picture_size"
|
android:layout_width="@dimen/small_profile_picture_size"
|
||||||
android:layout_height="@dimen/small_profile_picture_size" />
|
android:layout_height="@dimen/small_profile_picture_size" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="-2dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/conversationTitleView"
|
android:id="@+id/conversationTitleView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginBottom="-4dp"
|
||||||
android:text="Elon"
|
android:text="Elon"
|
||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
@ -23,4 +31,38 @@
|
|||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:ellipsize="end" />
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/muteIconImageView"
|
||||||
|
android:layout_width="14dp"
|
||||||
|
android:layout_height="14dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/ic_outline_notifications_off_24"
|
||||||
|
app:tint="@color/text"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/conversationSubtitleView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Muted"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:textSize="@dimen/very_small_font_size"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -135,7 +135,7 @@
|
|||||||
android:background="?android:dividerHorizontal"
|
android:background="?android:dividerHorizontal"
|
||||||
android:elevation="1dp" />
|
android:elevation="1dp" />
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.conversation.v2.OpenGroupGuidelinesView
|
<org.thoughtcrime.securesms.conversation.v2.components.OpenGroupGuidelinesView
|
||||||
android:id="@+id/open_group_guidelines_view"
|
android:id="@+id/open_group_guidelines_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center">
|
android:layout_gravity="center">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||||
android:id="@+id/attachment_thumbnail"
|
android:id="@+id/attachment_thumbnail"
|
||||||
android:layout_width="230dp"
|
android:layout_width="230dp"
|
||||||
android:layout_height="150dp"
|
android:layout_height="150dp"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||||
android:id="@+id/conversation_thumbnail_image"
|
android:id="@+id/conversation_thumbnail_image"
|
||||||
android:layout_width="@dimen/media_bubble_default_dimens"
|
android:layout_width="@dimen/media_bubble_default_dimens"
|
||||||
android:layout_height="@dimen/media_bubble_default_dimens"
|
android:layout_height="@dimen/media_bubble_default_dimens"
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:background="@drawable/message_bubble_background">
|
android:background="@drawable/message_bubble_background">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.TypingIndicatorView
|
<org.thoughtcrime.securesms.conversation.v2.components.TypingIndicatorView
|
||||||
android:id="@+id/typing_indicator"
|
android:id="@+id/typing_indicator"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
57
app/src/main/res/layout/dialog_blocked.xml
Normal file
57
app/src/main/res/layout/dialog_blocked.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:padding="32dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/blockedTitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_blocked_title"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="@dimen/large_font_size" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/blockedExplanationTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="@string/dialog_blocked_explanation"
|
||||||
|
android:paddingHorizontal="@dimen/medium_spacing"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/cancel" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/unblockButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="@dimen/medium_spacing"
|
||||||
|
android:text="@string/ConversationActivity_unblock" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -6,10 +6,8 @@
|
|||||||
android:background="@drawable/default_dialog_background_inset"
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="32dp"
|
android:elevation="4dp"
|
||||||
android:paddingTop="@dimen/medium_spacing"
|
android:padding="32dp">
|
||||||
android:paddingRight="32dp"
|
|
||||||
android:paddingBottom="@dimen/medium_spacing">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
57
app/src/main/res/layout/dialog_download.xml
Normal file
57
app/src/main/res/layout/dialog_download.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:padding="32dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/downloadTitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_download_title"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="@dimen/large_font_size" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/downloadExplanationTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="@string/dialog_download_explanation"
|
||||||
|
android:paddingHorizontal="@dimen/medium_spacing"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/cancel" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/downloadButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="@dimen/medium_spacing"
|
||||||
|
android:text="@string/dialog_download_button_title" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
57
app/src/main/res/layout/dialog_join_open_group.xml
Normal file
57
app/src/main/res/layout/dialog_join_open_group.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:padding="32dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/joinOpenGroupTitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_join_open_group_title"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="@dimen/large_font_size" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/joinOpenGroupExplanationTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="@string/dialog_join_open_group_explanation"
|
||||||
|
android:paddingHorizontal="@dimen/medium_spacing"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/cancel" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/joinButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="@dimen/medium_spacing"
|
||||||
|
android:text="@string/open_group_invitation_view__join_accessibility_description" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
57
app/src/main/res/layout/dialog_link_preview.xml
Normal file
57
app/src/main/res/layout/dialog_link_preview.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:padding="32dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/linkPreviewDialogTitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_link_preview_title"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="@dimen/large_font_size" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/linkPreviewDialogExplanationTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="@string/dialog_link_preview_explanation"
|
||||||
|
android:paddingHorizontal="@dimen/medium_spacing"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/cancel" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/enableLinkPreviewsButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="@dimen/medium_spacing"
|
||||||
|
android:text="@string/dialog_link_preview_enable_button_title" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
57
app/src/main/res/layout/dialog_open_url.xml
Normal file
57
app/src/main/res/layout/dialog_open_url.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:padding="32dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/openURLTitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_open_url_title"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="@dimen/large_font_size" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/openURLExplanationTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="@string/dialog_open_url_explanation"
|
||||||
|
android:paddingHorizontal="@dimen/medium_spacing"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/cancel" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/Widget.Session.Button.Dialog.Unimportant"
|
||||||
|
android:id="@+id/openURLButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="@dimen/medium_spacing"
|
||||||
|
android:text="@string/open" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -6,10 +6,7 @@
|
|||||||
android:background="@drawable/default_dialog_background_inset"
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="32dp"
|
android:padding="32dp">
|
||||||
android:paddingTop="@dimen/medium_spacing"
|
|
||||||
android:paddingRight="32dp"
|
|
||||||
android:paddingBottom="@dimen/medium_spacing">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="2dp">
|
android:padding="2dp">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
android:layout_margin="2dp"
|
android:layout_margin="2dp"
|
||||||
android:animateLayoutChanges="true">
|
android:animateLayoutChanges="true">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||||
android:id="@+id/rail_item_image"
|
android:id="@+id/rail_item_image"
|
||||||
android:layout_width="56dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible"/>
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||||
android:id="@+id/sticker_thumbnail"
|
android:id="@+id/sticker_thumbnail"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -41,11 +41,17 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/conversationViewDisplayNameTextView"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/conversationViewDisplayNameTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
@ -54,6 +60,28 @@
|
|||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
tools:text="I'm a very long display name. What are you going to do about it?" />
|
tools:text="I'm a very long display name. What are you going to do about it?" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/unreadCountIndicator"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:background="@drawable/circle_tintable"
|
||||||
|
android:backgroundTint="@color/conversation_unread_count_indicator_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/unreadCountTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:textSize="@dimen/very_small_font_size"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="8" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/timestampTextView"
|
android:id="@+id/timestampTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -98,7 +126,7 @@
|
|||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
tools:text="Sorry, gotta go fight crime again" />
|
tools:text="Sorry, gotta go fight crime again" />
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.TypingIndicatorView
|
<org.thoughtcrime.securesms.conversation.v2.components.TypingIndicatorView
|
||||||
android:id="@+id/typingIndicatorView"
|
android:id="@+id/typingIndicatorView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="@dimen/medium_spacing"
|
||||||
|
android:paddingBottom="@dimen/small_spacing"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/typingIndicatorBubble"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:background="@drawable/message_bubble_background_received_alone"
|
||||||
|
android:backgroundTint="?message_received_background_color">
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.conversation.v2.components.TypingIndicatorView
|
||||||
|
android:id="@+id/typingIndicator"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:typingIndicator_tint="@color/text" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -1,11 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout android:id="@+id/mainLinkPreviewContainer"
|
||||||
android:id="@+id/mainLinkPreviewContainer"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -13,12 +13,25 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center">
|
android:gravity="center">
|
||||||
|
|
||||||
<ImageView
|
<RelativeLayout
|
||||||
android:id="@+id/thumbnailImageView"
|
|
||||||
android:layout_width="96dp"
|
android:layout_width="96dp"
|
||||||
android:layout_height="96dp"
|
android:layout_height="96dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:src="@drawable/ic_link"
|
||||||
|
app:tint="@color/text" />
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||||
|
android:id="@+id/thumbnailImageView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
android:scaleType="centerCrop" />
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/titleTextView"
|
android:id="@+id/titleTextView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
72
app/src/main/res/layout/view_link_preview_draft.xml
Normal file
72
app/src/main/res/layout/view_link_preview_draft.xml
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="88dp"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:paddingHorizontal="@dimen/medium_spacing">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/linkPreviewDraftContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="72dp"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:src="@drawable/ic_link"
|
||||||
|
app:tint="@color/text" />
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
||||||
|
android:id="@+id/thumbnailImageView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/linkPreviewDraftTitleTextView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingStart="80dp"
|
||||||
|
android:paddingEnd="30dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="The Day The Dinosaurs Died - Minute by Minute"
|
||||||
|
android:maxLines="3"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textColor="@color/text" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/linkPreviewDraftCancelButton"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:src="@drawable/ic_close_white_48dp"
|
||||||
|
app:tint="@color/text" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<com.github.ybq.android.spinkit.SpinKitView
|
||||||
|
android:id="@+id/linkPreviewDraftLoader"
|
||||||
|
style="@style/SpinKitView.Large.ThreeBounce"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:SpinKit_Color="@color/text"
|
||||||
|
android:layout_centerInParent="true" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -5,7 +5,7 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="org.thoughtcrime.securesms.components.TypingIndicatorView">
|
tools:context="org.thoughtcrime.securesms.conversation.v2.components.TypingIndicatorView">
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/typing_dot1"
|
android:id="@+id/typing_dot1"
|
@ -31,6 +31,7 @@
|
|||||||
<color name="link_preview_background">#0F000000</color>
|
<color name="link_preview_background">#0F000000</color>
|
||||||
<color name="scroll_to_bottom_button_background">#FCFCFC</color>
|
<color name="scroll_to_bottom_button_background">#FCFCFC</color>
|
||||||
<color name="scroll_to_bottom_button_border">#99000000</color>
|
<color name="scroll_to_bottom_button_border">#99000000</color>
|
||||||
|
<color name="conversation_unread_count_indicator_background">#E0E0E0</color>
|
||||||
|
|
||||||
<color name="default_background_start">#ffffff</color>
|
<color name="default_background_start">#ffffff</color>
|
||||||
<color name="default_background_end">#fcfcfc</color>
|
<color name="default_background_end">#fcfcfc</color>
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
<color name="link_preview_background">#000000</color>
|
<color name="link_preview_background">#000000</color>
|
||||||
<color name="scroll_to_bottom_button_background">#171717</color>
|
<color name="scroll_to_bottom_button_background">#171717</color>
|
||||||
<color name="scroll_to_bottom_button_border">#99FFFFFF</color>
|
<color name="scroll_to_bottom_button_border">#99FFFFFF</color>
|
||||||
|
<color name="conversation_unread_count_indicator_background">#303030</color>
|
||||||
|
|
||||||
<array name="profile_picture_placeholder_colors">
|
<array name="profile_picture_placeholder_colors">
|
||||||
<item>#5ff8b0</item>
|
<item>#5ff8b0</item>
|
||||||
|
@ -309,7 +309,7 @@
|
|||||||
<string name="MediaPreviewActivity_you">You</string>
|
<string name="MediaPreviewActivity_you">You</string>
|
||||||
<string name="MediaPreviewActivity_unssuported_media_type">Unsupported media type</string>
|
<string name="MediaPreviewActivity_unssuported_media_type">Unsupported media type</string>
|
||||||
<string name="MediaPreviewActivity_draft">Draft</string>
|
<string name="MediaPreviewActivity_draft">Draft</string>
|
||||||
<string name="MediaPreviewActivity_signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied">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\".</string>
|
<string name="MediaPreviewActivity_signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied">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\".</string>
|
||||||
<string name="MediaPreviewActivity_unable_to_write_to_external_storage_without_permission">Unable to save to external storage without permissions</string>
|
<string name="MediaPreviewActivity_unable_to_write_to_external_storage_without_permission">Unable to save to external storage without permissions</string>
|
||||||
<string name="MediaPreviewActivity_media_delete_confirmation_title">Delete message?</string>
|
<string name="MediaPreviewActivity_media_delete_confirmation_title">Delete message?</string>
|
||||||
<string name="MediaPreviewActivity_media_delete_confirmation_message">This will permanently delete this message.</string>
|
<string name="MediaPreviewActivity_media_delete_confirmation_message">This will permanently delete this message.</string>
|
||||||
@ -853,4 +853,23 @@
|
|||||||
|
|
||||||
<string name="document">Document</string>
|
<string name="document">Document</string>
|
||||||
|
|
||||||
|
<string name="dialog_blocked_title">Unblock %s?</string>
|
||||||
|
<string name="dialog_blocked_explanation">Are you sure you want to unblock %s?</string>
|
||||||
|
|
||||||
|
<string name="dialog_join_open_group_title">Join %s?</string>
|
||||||
|
<string name="dialog_join_open_group_explanation">Are you sure you want to join the %s open group?</string>
|
||||||
|
|
||||||
|
<string name="dialog_open_url_title">Open URL?</string>
|
||||||
|
<string name="dialog_open_url_explanation">Are you sure you want to open %s?</string>
|
||||||
|
<string name="open">Open</string>
|
||||||
|
|
||||||
|
<string name="dialog_link_preview_title">Enable Link Previews?</string>
|
||||||
|
<string name="dialog_link_preview_explanation">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.</string>
|
||||||
|
<string name="dialog_link_preview_enable_button_title">Enable</string>
|
||||||
|
|
||||||
|
<string name="dialog_download_title">Trust %s?</string>
|
||||||
|
<string name="dialog_download_explanation">Are you sure you want to download media sent by %s?</string>
|
||||||
|
<string name="dialog_download_button_title">Download</string>
|
||||||
|
|
||||||
|
<string name="activity_conversation_blocked_banner_text">%s is blocked. Unblock them?</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -280,4 +280,9 @@
|
|||||||
<item name="android:windowNoTitle">true</item>
|
<item name="android:windowNoTitle">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="Session.Dialog" parent="@android:style/Theme.Dialog">
|
||||||
|
<item name="android:windowBackground">#120000FF</item>
|
||||||
|
<item name="android:windowIsFloating">false</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user