mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Merge branch 'dev' into fix-dialog-button
This commit is contained in:
commit
c28eba313a
@ -39,15 +39,20 @@ public abstract class BaseActionBarActivity extends AppCompatActivity {
|
|||||||
public int getDesiredTheme() {
|
public int getDesiredTheme() {
|
||||||
ThemeState themeState = ActivityUtilitiesKt.themeState(getPreferences());
|
ThemeState themeState = ActivityUtilitiesKt.themeState(getPreferences());
|
||||||
int userSelectedTheme = themeState.getTheme();
|
int userSelectedTheme = themeState.getTheme();
|
||||||
|
|
||||||
|
// If the user has configured Session to follow the system light/dark theme mode then do so..
|
||||||
if (themeState.getFollowSystem()) {
|
if (themeState.getFollowSystem()) {
|
||||||
// do light or dark based on the selected theme
|
|
||||||
|
// Use light or dark versions of the user's theme based on light-mode / dark-mode settings
|
||||||
boolean isDayUi = UiModeUtilities.isDayUiMode(this);
|
boolean isDayUi = UiModeUtilities.isDayUiMode(this);
|
||||||
if (userSelectedTheme == R.style.Ocean_Dark || userSelectedTheme == R.style.Ocean_Light) {
|
if (userSelectedTheme == R.style.Ocean_Dark || userSelectedTheme == R.style.Ocean_Light) {
|
||||||
return isDayUi ? R.style.Ocean_Light : R.style.Ocean_Dark;
|
return isDayUi ? R.style.Ocean_Light : R.style.Ocean_Dark;
|
||||||
} else {
|
} else {
|
||||||
return isDayUi ? R.style.Classic_Light : R.style.Classic_Dark;
|
return isDayUi ? R.style.Classic_Light : R.style.Classic_Dark;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else // ..otherwise just return their selected theme.
|
||||||
|
{
|
||||||
return userSelectedTheme;
|
return userSelectedTheme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,14 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
|||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.LinearLayout.VERTICAL
|
import android.widget.LinearLayout.VERTICAL
|
||||||
|
import android.widget.Space
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.annotation.StyleRes
|
import androidx.annotation.StyleRes
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.setPadding
|
import androidx.core.view.setMargins
|
||||||
import androidx.core.view.updateMargins
|
import androidx.core.view.updateMargins
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
@ -36,7 +37,9 @@ class SessionDialogBuilder(val context: Context) {
|
|||||||
private var dialog: AlertDialog? = null
|
private var dialog: AlertDialog? = null
|
||||||
private fun dismiss() = dialog?.dismiss()
|
private fun dismiss() = dialog?.dismiss()
|
||||||
|
|
||||||
private val topView = LinearLayout(context).apply { orientation = VERTICAL }
|
private val topView = LinearLayout(context)
|
||||||
|
.apply { setPadding(0, dp20, 0, 0) }
|
||||||
|
.apply { orientation = VERTICAL }
|
||||||
.also(dialogBuilder::setCustomTitle)
|
.also(dialogBuilder::setCustomTitle)
|
||||||
private val contentView = LinearLayout(context).apply { orientation = VERTICAL }
|
private val contentView = LinearLayout(context).apply { orientation = VERTICAL }
|
||||||
private val buttonLayout = LinearLayout(context)
|
private val buttonLayout = LinearLayout(context)
|
||||||
@ -52,14 +55,14 @@ class SessionDialogBuilder(val context: Context) {
|
|||||||
|
|
||||||
fun title(text: CharSequence?) = title(text?.toString())
|
fun title(text: CharSequence?) = title(text?.toString())
|
||||||
fun title(text: String?) {
|
fun title(text: String?) {
|
||||||
text(text, R.style.TextAppearance_AppCompat_Title) { setPadding(dp20) }
|
text(text, R.style.TextAppearance_AppCompat_Title) { setPadding(dp20, 0, dp20, 0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun text(@StringRes id: Int, style: Int = 0) = text(context.getString(id), style)
|
fun text(@StringRes id: Int, style: Int = 0) = text(context.getString(id), style)
|
||||||
fun text(text: CharSequence?, @StyleRes style: Int = 0) {
|
fun text(text: CharSequence?, @StyleRes style: Int = 0) {
|
||||||
text(text, style) {
|
text(text, style) {
|
||||||
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
||||||
.apply { updateMargins(dp40, 0, dp40, dp20) }
|
.apply { updateMargins(dp40, 0, dp40, 0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +74,10 @@ class SessionDialogBuilder(val context: Context) {
|
|||||||
textAlignment = View.TEXT_ALIGNMENT_CENTER
|
textAlignment = View.TEXT_ALIGNMENT_CENTER
|
||||||
modify()
|
modify()
|
||||||
}.let(topView::addView)
|
}.let(topView::addView)
|
||||||
|
|
||||||
|
Space(context).apply {
|
||||||
|
layoutParams = LinearLayout.LayoutParams(0, dp20)
|
||||||
|
}.let(topView::addView)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun view(view: View) = contentView.addView(view)
|
fun view(view: View) = contentView.addView(view)
|
||||||
@ -123,7 +130,8 @@ class SessionDialogBuilder(val context: Context) {
|
|||||||
) = Button(context, null, 0, style).apply {
|
) = Button(context, null, 0, style).apply {
|
||||||
setText(text)
|
setText(text)
|
||||||
contentDescription = resources.getString(contentDescriptionRes)
|
contentDescription = resources.getString(contentDescriptionRes)
|
||||||
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, dp60, 1f)
|
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, dp60, 1f)
|
||||||
|
.apply { setMargins(dp20) }
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
listener.invoke()
|
listener.invoke()
|
||||||
if (dismiss) dismiss()
|
if (dismiss) dismiss()
|
||||||
|
@ -17,6 +17,7 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import org.session.libsession.utilities.getColorFromAttr
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingModel
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingModel
|
||||||
@ -84,7 +85,7 @@ class ContextMenuList(recyclerView: RecyclerView, onItemClick: () -> Unit) {
|
|||||||
context.theme.resolveAttribute(item.iconRes, typedValue, true)
|
context.theme.resolveAttribute(item.iconRes, typedValue, true)
|
||||||
icon.setImageDrawable(ContextCompat.getDrawable(context, typedValue.resourceId))
|
icon.setImageDrawable(ContextCompat.getDrawable(context, typedValue.resourceId))
|
||||||
|
|
||||||
icon.imageTintList = color?.let(ColorStateList::valueOf)
|
icon.imageTintList = ColorStateList.valueOf(color ?: context.getColorFromAttr(android.R.attr.textColor))
|
||||||
}
|
}
|
||||||
item.contentDescription?.let(context.resources::getString)?.let { itemView.contentDescription = it }
|
item.contentDescription?.let(context.resources::getString)?.let { itemView.contentDescription = it }
|
||||||
title.setText(item.title)
|
title.setText(item.title)
|
||||||
|
@ -140,6 +140,8 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun draftQuote(thread: Recipient, message: MessageRecord, glide: GlideRequests) {
|
fun draftQuote(thread: Recipient, message: MessageRecord, glide: GlideRequests) {
|
||||||
|
quoteView?.let(binding.inputBarAdditionalContentContainer::removeView)
|
||||||
|
|
||||||
quote = message
|
quote = message
|
||||||
|
|
||||||
// If we already have a link preview View then clear the 'additional content' layout so that
|
// If we already have a link preview View then clear the 'additional content' layout so that
|
||||||
|
@ -4,18 +4,24 @@ import android.content.Context
|
|||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
|
import android.text.style.BackgroundColorSpan
|
||||||
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.appcompat.widget.ThemeUtils
|
||||||
import androidx.core.content.res.ResourcesCompat
|
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
|
||||||
import org.session.libsession.messaging.utilities.SodiumUtilities
|
import org.session.libsession.messaging.utilities.SodiumUtilities
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
|
import org.session.libsession.utilities.ThemeUtil
|
||||||
|
import org.session.libsignal.utilities.Log
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||||
import org.thoughtcrime.securesms.util.UiModeUtilities
|
import org.thoughtcrime.securesms.util.UiModeUtilities
|
||||||
import org.thoughtcrime.securesms.util.getAccentColor
|
import org.thoughtcrime.securesms.util.getAccentColor
|
||||||
|
import org.thoughtcrime.securesms.util.getColorResourceIdFromAttr
|
||||||
|
import org.thoughtcrime.securesms.util.getMessageTextColourAttr
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
object MentionUtilities {
|
object MentionUtilities {
|
||||||
@ -58,15 +64,37 @@ object MentionUtilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val result = SpannableString(text)
|
val result = SpannableString(text)
|
||||||
val isLightMode = UiModeUtilities.isDayUiMode(context)
|
|
||||||
val color = if (isOutgoingMessage) {
|
var mentionTextColour: Int? = null
|
||||||
ResourcesCompat.getColor(context.resources, if (isLightMode) R.color.white else R.color.black, context.theme)
|
// In dark themes..
|
||||||
} else {
|
if (ThemeUtil.isDarkTheme(context)) {
|
||||||
context.getAccentColor()
|
// ..we use the standard outgoing message colour for outgoing messages..
|
||||||
|
if (isOutgoingMessage) {
|
||||||
|
val mentionTextColourAttributeId = getMessageTextColourAttr(true)
|
||||||
|
val mentionTextColourResourceId = getColorResourceIdFromAttr(context, mentionTextColourAttributeId)
|
||||||
|
mentionTextColour = ResourcesCompat.getColor(context.resources, mentionTextColourResourceId, context.theme)
|
||||||
|
}
|
||||||
|
else // ..but we use the accent colour for incoming messages (i.e., someone mentioning us)..
|
||||||
|
{
|
||||||
|
mentionTextColour = context.getAccentColor()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else // ..while in light themes we always just use the incoming or outgoing message text colour for mentions.
|
||||||
|
{
|
||||||
|
val mentionTextColourAttributeId = getMessageTextColourAttr(isOutgoingMessage)
|
||||||
|
val mentionTextColourResourceId = getColorResourceIdFromAttr(context, mentionTextColourAttributeId)
|
||||||
|
mentionTextColour = ResourcesCompat.getColor(context.resources, mentionTextColourResourceId, context.theme)
|
||||||
|
}
|
||||||
|
|
||||||
for (mention in mentions) {
|
for (mention in mentions) {
|
||||||
result.setSpan(ForegroundColorSpan(color), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
result.setSpan(ForegroundColorSpan(mentionTextColour), 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)
|
||||||
|
|
||||||
|
// If we're using a light theme then we change the background colour of the mention to be the accent colour
|
||||||
|
if (ThemeUtil.isLightTheme(context)) {
|
||||||
|
val backgroundColour = context.getAccentColor();
|
||||||
|
result.setSpan(BackgroundColorSpan(backgroundColour), mention.first.lower, mention.first.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -320,6 +320,19 @@ public class MmsSmsDatabase extends Database {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getLastMessageTimestamp(long threadId) {
|
||||||
|
String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC";
|
||||||
|
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
|
||||||
|
|
||||||
|
try (Cursor cursor = queryTables(PROJECTION, selection, order, "1")) {
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
return cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.NORMALIZED_DATE_SENT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public Cursor getUnread() {
|
public Cursor getUnread() {
|
||||||
String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " ASC";
|
String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " ASC";
|
||||||
String selection = "(" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1) AND " + MmsSmsColumns.NOTIFIED + " = 0";
|
String selection = "(" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1) AND " + MmsSmsColumns.NOTIFIED + " = 0";
|
||||||
|
@ -934,7 +934,17 @@ public class ThreadDatabase extends Database {
|
|||||||
readReceiptCount = 0;
|
readReceiptCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ThreadRecord(body, snippetUri, recipient, date, count,
|
MessageRecord lastMessage = null;
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
MmsSmsDatabase mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase();
|
||||||
|
long messageTimestamp = mmsSmsDatabase.getLastMessageTimestamp(threadId);
|
||||||
|
if (messageTimestamp > 0) {
|
||||||
|
lastMessage = mmsSmsDatabase.getMessageForTimestamp(messageTimestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ThreadRecord(body, snippetUri, lastMessage, recipient, date, count,
|
||||||
unreadCount, unreadMentionCount, threadId, deliveryReceiptCount, status, type,
|
unreadCount, unreadMentionCount, threadId, deliveryReceiptCount, status, type,
|
||||||
distributionType, archived, expiresIn, lastSeen, readReceiptCount, pinned);
|
distributionType, archived, expiresIn, lastSeen, readReceiptCount, pinned);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ import network.loki.messenger.R;
|
|||||||
public class ThreadRecord extends DisplayRecord {
|
public class ThreadRecord extends DisplayRecord {
|
||||||
|
|
||||||
private @Nullable final Uri snippetUri;
|
private @Nullable final Uri snippetUri;
|
||||||
|
public @Nullable final MessageRecord lastMessage;
|
||||||
private final long count;
|
private final long count;
|
||||||
private final int unreadCount;
|
private final int unreadCount;
|
||||||
private final int unreadMentionCount;
|
private final int unreadMentionCount;
|
||||||
@ -54,13 +55,14 @@ public class ThreadRecord extends DisplayRecord {
|
|||||||
private final int initialRecipientHash;
|
private final int initialRecipientHash;
|
||||||
|
|
||||||
public ThreadRecord(@NonNull String body, @Nullable Uri snippetUri,
|
public ThreadRecord(@NonNull String body, @Nullable Uri snippetUri,
|
||||||
@NonNull Recipient recipient, long date, long count, int unreadCount,
|
@Nullable MessageRecord lastMessage, @NonNull Recipient recipient, long date, long count, int unreadCount,
|
||||||
int unreadMentionCount, long threadId, int deliveryReceiptCount, int status,
|
int unreadMentionCount, long threadId, int deliveryReceiptCount, int status,
|
||||||
long snippetType, int distributionType, boolean archived, long expiresIn,
|
long snippetType, int distributionType, boolean archived, long expiresIn,
|
||||||
long lastSeen, int readReceiptCount, boolean pinned)
|
long lastSeen, int readReceiptCount, boolean pinned)
|
||||||
{
|
{
|
||||||
super(body, recipient, date, date, threadId, status, deliveryReceiptCount, snippetType, readReceiptCount);
|
super(body, recipient, date, date, threadId, status, deliveryReceiptCount, snippetType, readReceiptCount);
|
||||||
this.snippetUri = snippetUri;
|
this.snippetUri = snippetUri;
|
||||||
|
this.lastMessage = lastMessage;
|
||||||
this.count = count;
|
this.count = count;
|
||||||
this.unreadCount = unreadCount;
|
this.unreadCount = unreadCount;
|
||||||
this.unreadMentionCount = unreadMentionCount;
|
this.unreadMentionCount = unreadMentionCount;
|
||||||
|
@ -4,6 +4,8 @@ import android.content.Context
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.text.TextUtils
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -89,7 +91,7 @@ class ConversationView : LinearLayout {
|
|||||||
|| (configFactory.convoVolatile?.getConversationUnread(thread) == true)
|
|| (configFactory.convoVolatile?.getConversationUnread(thread) == true)
|
||||||
binding.unreadMentionTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize)
|
binding.unreadMentionTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize)
|
||||||
binding.unreadMentionIndicator.isVisible = (thread.unreadMentionCount != 0 && thread.recipient.address.isGroup)
|
binding.unreadMentionIndicator.isVisible = (thread.unreadMentionCount != 0 && thread.recipient.address.isGroup)
|
||||||
val senderDisplayName = getUserDisplayName(thread.recipient)
|
val senderDisplayName = getTitle(thread.recipient)
|
||||||
?: thread.recipient.address.toString()
|
?: thread.recipient.address.toString()
|
||||||
binding.conversationViewDisplayNameTextView.text = senderDisplayName
|
binding.conversationViewDisplayNameTextView.text = senderDisplayName
|
||||||
binding.timestampTextView.text = thread.date.takeIf { it != 0L }?.let { DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), it) }
|
binding.timestampTextView.text = thread.date.takeIf { it != 0L }?.let { DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), it) }
|
||||||
@ -101,9 +103,7 @@ class ConversationView : LinearLayout {
|
|||||||
R.drawable.ic_notifications_mentions
|
R.drawable.ic_notifications_mentions
|
||||||
}
|
}
|
||||||
binding.muteIndicatorImageView.setImageResource(drawableRes)
|
binding.muteIndicatorImageView.setImageResource(drawableRes)
|
||||||
val rawSnippet = thread.getDisplayBody(context)
|
binding.snippetTextView.text = highlightMentions(thread.getSnippet(), thread.threadId, context)
|
||||||
val snippet = highlightMentions(rawSnippet, thread.threadId, context)
|
|
||||||
binding.snippetTextView.text = snippet
|
|
||||||
binding.snippetTextView.typeface = if (unreadCount > 0 && !thread.isRead) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
|
binding.snippetTextView.typeface = if (unreadCount > 0 && !thread.isRead) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
|
||||||
binding.snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE
|
binding.snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE
|
||||||
if (isTyping) {
|
if (isTyping) {
|
||||||
@ -131,12 +131,21 @@ class ConversationView : LinearLayout {
|
|||||||
binding.profilePictureView.recycle()
|
binding.profilePictureView.recycle()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUserDisplayName(recipient: Recipient): String? {
|
private fun getTitle(recipient: Recipient): String? = when {
|
||||||
return if (recipient.isLocalNumber) {
|
recipient.isLocalNumber -> context.getString(R.string.note_to_self)
|
||||||
context.getString(R.string.note_to_self)
|
else -> recipient.toShortString() // Internally uses the Contact API
|
||||||
} else {
|
}
|
||||||
recipient.toShortString() // Internally uses the Contact API
|
|
||||||
}
|
private fun ThreadRecord.getSnippet(): CharSequence =
|
||||||
|
concatSnippet(getSnippetPrefix(), getDisplayBody(context))
|
||||||
|
|
||||||
|
private fun concatSnippet(prefix: CharSequence?, body: CharSequence): CharSequence =
|
||||||
|
prefix?.let { TextUtils.concat(it, ": ", body) } ?: body
|
||||||
|
|
||||||
|
private fun ThreadRecord.getSnippetPrefix(): CharSequence? = when {
|
||||||
|
recipient.isLocalNumber || lastMessage?.isControlMessage == true -> null
|
||||||
|
lastMessage?.isOutgoing == true -> resources.getString(R.string.MessageRecord_you)
|
||||||
|
else -> lastMessage?.individualRecipient?.toShortString()
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,15 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.PointF
|
import android.graphics.PointF
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.util.Size
|
import android.util.Size
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.DimenRes
|
import androidx.annotation.DimenRes
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.session.libsession.utilities.getColorFromAttr
|
import org.session.libsession.utilities.getColorFromAttr
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import androidx.annotation.AttrRes
|
||||||
|
import androidx.annotation.ColorRes
|
||||||
import androidx.core.graphics.applyCanvas
|
import androidx.core.graphics.applyCanvas
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -32,6 +35,20 @@ val View.hitRect: Rect
|
|||||||
@ColorInt
|
@ColorInt
|
||||||
fun Context.getAccentColor() = getColorFromAttr(R.attr.colorAccent)
|
fun Context.getAccentColor() = getColorFromAttr(R.attr.colorAccent)
|
||||||
|
|
||||||
|
// Method to grab the appropriate attribute for a message colour.
|
||||||
|
// Note: This is an attribute, NOT a resource Id - see `getColorResourceIdFromAttr` for that.
|
||||||
|
@AttrRes
|
||||||
|
fun getMessageTextColourAttr(messageIsOutgoing: Boolean): Int =
|
||||||
|
if (messageIsOutgoing) R.attr.message_sent_text_color else R.attr.message_received_text_color
|
||||||
|
|
||||||
|
// Method to get an actual R.id.<SOME_COLOUR> resource Id from an attribute such as R.attr.message_sent_text_color etc.
|
||||||
|
@ColorRes
|
||||||
|
fun getColorResourceIdFromAttr(context: Context, attr: Int): Int {
|
||||||
|
val typedValue = TypedValue()
|
||||||
|
context.theme.resolveAttribute(attr, typedValue, true)
|
||||||
|
return typedValue.resourceId
|
||||||
|
}
|
||||||
|
|
||||||
fun View.animateSizeChange(@DimenRes startSizeID: Int, @DimenRes endSizeID: Int, animationDuration: Long = 250) {
|
fun View.animateSizeChange(@DimenRes startSizeID: Int, @DimenRes endSizeID: Int, animationDuration: Long = 250) {
|
||||||
val startSize = resources.getDimension(startSizeID)
|
val startSize = resources.getDimension(startSizeID)
|
||||||
val endSize = resources.getDimension(endSizeID)
|
val endSize = resources.getDimension(endSizeID)
|
||||||
@ -70,7 +87,6 @@ fun View.hideKeyboard() {
|
|||||||
imm.hideSoftInputFromWindow(this.windowToken, 0)
|
imm.hideSoftInputFromWindow(this.windowToken, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun View.drawToBitmap(config: Bitmap.Config = Bitmap.Config.ARGB_8888, longestWidth: Int = 2000): Bitmap {
|
fun View.drawToBitmap(config: Bitmap.Config = Bitmap.Config.ARGB_8888, longestWidth: Int = 2000): Bitmap {
|
||||||
val size = Size(measuredWidth, measuredHeight).coerceAtMost(longestWidth)
|
val size = Size(measuredWidth, measuredHeight).coerceAtMost(longestWidth)
|
||||||
val scale = size.width / measuredWidth.toFloat()
|
val scale = size.width / measuredWidth.toFloat()
|
||||||
|
@ -2,7 +2,7 @@ package org.session.libsession.messaging.mentions
|
|||||||
|
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsession.messaging.contacts.Contact
|
import org.session.libsession.messaging.contacts.Contact
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
|
|
||||||
object MentionsManager {
|
object MentionsManager {
|
||||||
var userPublicKeyCache = mutableMapOf<Long, Set<String>>() // Thread ID to set of user hex encoded public keys
|
var userPublicKeyCache = mutableMapOf<Long, Set<String>>() // Thread ID to set of user hex encoded public keys
|
||||||
|
@ -27,6 +27,10 @@ public class ThemeUtil {
|
|||||||
return getAttributeText(context, R.attr.theme_type, "light").equals("dark");
|
return getAttributeText(context, R.attr.theme_type, "light").equals("dark");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isLightTheme(@NonNull Context context) {
|
||||||
|
return getAttributeText(context, R.attr.theme_type, "light").equals("light");
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean getThemedBoolean(@NonNull Context context, @AttrRes int attr) {
|
public static boolean getThemedBoolean(@NonNull Context context, @AttrRes int attr) {
|
||||||
TypedValue typedValue = new TypedValue();
|
TypedValue typedValue = new TypedValue();
|
||||||
Resources.Theme theme = context.getTheme();
|
Resources.Theme theme = context.getTheme();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user