mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-21 15:05:19 +00:00
Moved into libsession for ease of access to control message view creation
This commit is contained in:
parent
b908a54a44
commit
3c576053a3
@ -227,7 +227,6 @@ dependencies {
|
|||||||
ksp("com.google.dagger:hilt-compiler:$daggerHiltVersion")
|
ksp("com.google.dagger:hilt-compiler:$daggerHiltVersion")
|
||||||
ksp("com.github.bumptech.glide:ksp:$glideVersion")
|
ksp("com.github.bumptech.glide:ksp:$glideVersion")
|
||||||
|
|
||||||
implementation 'androidx.compose.material3:material3-android:1.2.1'
|
|
||||||
implementation("com.google.dagger:hilt-android:$daggerHiltVersion")
|
implementation("com.google.dagger:hilt-android:$daggerHiltVersion")
|
||||||
implementation "androidx.appcompat:appcompat:$appcompatVersion"
|
implementation "androidx.appcompat:appcompat:$appcompatVersion"
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||||
|
@ -1072,24 +1072,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
updateUnreadCountIndicator()
|
updateUnreadCountIndicator()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method that takes a char sequence that contains one or more elements surrounded in bold tags
|
|
||||||
// like "Hello <b>world</b>" and returns a SpannableString that will display the appropriate
|
|
||||||
// elements in bold. If there are no such <b> or </b> elements then the original string is returned
|
|
||||||
// as a SpannableString without any bold highlighting.
|
|
||||||
private fun makeBoldBetweenTags(input: CharSequence): SpannableString {
|
|
||||||
val spannable = SpannableString(input)
|
|
||||||
var startIndex = 0
|
|
||||||
while (true) {
|
|
||||||
startIndex = input.indexOf("<b>", startIndex)
|
|
||||||
if (startIndex == -1) break
|
|
||||||
val endIndex = input.indexOf("</b>", startIndex + 3)
|
|
||||||
if (endIndex == -1) break
|
|
||||||
spannable.setSpan(StyleSpan(Typeface.BOLD),startIndex + 3, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
||||||
startIndex = endIndex + 4
|
|
||||||
}
|
|
||||||
return spannable
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update placeholder / control messages in a conversation
|
// Update placeholder / control messages in a conversation
|
||||||
private fun updatePlaceholder() {
|
private fun updatePlaceholder() {
|
||||||
val recipient = viewModel.recipient ?: return Log.w("Loki", "recipient was null in placeholder update")
|
val recipient = viewModel.recipient ?: return Log.w("Loki", "recipient was null in placeholder update")
|
||||||
@ -1134,7 +1116,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
binding.placeholderText.isVisible = showPlaceholder
|
binding.placeholderText.isVisible = showPlaceholder
|
||||||
if (showPlaceholder) {
|
if (showPlaceholder) {
|
||||||
if (!isNoteToSelf) {
|
if (!isNoteToSelf) {
|
||||||
binding.placeholderText.text = makeBoldBetweenTags(txtCS)
|
binding.placeholderText.text = org.session.libsession.utilities.Util.makeBoldBetweenTags(txtCS)
|
||||||
} else {
|
} else {
|
||||||
binding.placeholderText.text = txtCS
|
binding.placeholderText.text = txtCS
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.v2.utilities
|
package org.thoughtcrime.securesms.conversation.v2.utilities
|
||||||
|
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.text.Layout
|
import android.text.Layout
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.text.Spanned
|
||||||
import android.text.StaticLayout
|
import android.text.StaticLayout
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
|
import android.text.style.StyleSpan
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.text.getSpans
|
import androidx.core.text.getSpans
|
||||||
|
@ -78,7 +78,7 @@ class SaveAttachmentTask @JvmOverloads constructor(context: Context, count: Int
|
|||||||
// for unknown reasons it provides us with an empty filename when saving files.
|
// for unknown reasons it provides us with an empty filename when saving files.
|
||||||
// TODO: Further investigation into root cause and fix!
|
// TODO: Further investigation into root cause and fix!
|
||||||
if (fileName.isNullOrEmpty()) fileName = generateOutputFileName(contentType, attachment.date)
|
if (fileName.isNullOrEmpty()) fileName = generateOutputFileName(contentType, attachment.date)
|
||||||
|
|
||||||
fileName = sanitizeOutputFileName(fileName)
|
fileName = sanitizeOutputFileName(fileName)
|
||||||
val outputUri: Uri = getMediaStoreContentUriForType(contentType)
|
val outputUri: Uri = getMediaStoreContentUriForType(contentType)
|
||||||
val mediaUri = createOutputUri(context, outputUri, contentType, fileName)
|
val mediaUri = createOutputUri(context, outputUri, contentType, fileName)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.session.libsession.messaging.utilities
|
package org.session.libsession.messaging.utilities
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.text.SpannableString
|
||||||
import com.squareup.phrase.Phrase
|
import com.squareup.phrase.Phrase
|
||||||
import org.session.libsession.R
|
import org.session.libsession.R
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
@ -23,6 +24,7 @@ import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_K
|
|||||||
import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY
|
import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY
|
||||||
import org.session.libsession.utilities.StringSubstitutionConstants.OTHER_NAME_KEY
|
import org.session.libsession.utilities.StringSubstitutionConstants.OTHER_NAME_KEY
|
||||||
import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY
|
import org.session.libsession.utilities.StringSubstitutionConstants.TIME_KEY
|
||||||
|
import org.session.libsession.utilities.Util
|
||||||
|
|
||||||
object UpdateMessageBuilder {
|
object UpdateMessageBuilder {
|
||||||
const val TAG = "libsession"
|
const val TAG = "libsession"
|
||||||
@ -33,29 +35,34 @@ object UpdateMessageBuilder {
|
|||||||
?.displayName(Contact.ContactContext.REGULAR)
|
?.displayName(Contact.ContactContext.REGULAR)
|
||||||
?: truncateIdForDisplay(senderId)
|
?: truncateIdForDisplay(senderId)
|
||||||
|
|
||||||
fun buildGroupUpdateMessage(context: Context, updateMessageData: UpdateMessageData, senderId: String? = null, isOutgoing: Boolean = false): String {
|
//@RequiresApi(Build.VERSION_CODES.P)
|
||||||
|
fun buildGroupUpdateMessage(context: Context, updateMessageData: UpdateMessageData, senderId: String? = null, isOutgoing: Boolean = false): CharSequence {
|
||||||
val updateData = updateMessageData.kind
|
val updateData = updateMessageData.kind
|
||||||
if (updateData == null || !isOutgoing && senderId == null) return ""
|
if (updateData == null || !isOutgoing && senderId == null) return ""
|
||||||
val senderName: String = if (isOutgoing) context.getString(R.string.you) else getSenderName(senderId!!)
|
|
||||||
|
|
||||||
return when (updateData) {
|
return when (updateData) {
|
||||||
// --- Group created or joined ---
|
// --- Group created or joined ---
|
||||||
is UpdateMessageData.Kind.GroupCreation -> {
|
is UpdateMessageData.Kind.GroupCreation -> {
|
||||||
if (!isOutgoing) context.getString(R.string.groupInviteYou)
|
if (!isOutgoing) {
|
||||||
else "" // We no longer add a string like `disappearingMessagesNewGroup` ("You created a new group") and leave the group with its default empty state
|
Util.makeBoldBetweenTags(SpannableString(context.getString(R.string.groupInviteYou)))
|
||||||
|
} else {
|
||||||
|
"" // We no longer add a string like `disappearingMessagesNewGroup` ("You created a new group") and leave the group with its default empty state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Group name changed ---
|
// --- Group name changed ---
|
||||||
is UpdateMessageData.Kind.GroupNameChange -> {
|
is UpdateMessageData.Kind.GroupNameChange -> {
|
||||||
if (isOutgoing) {
|
if (isOutgoing) {
|
||||||
Phrase.from(context, R.string.groupNameNew)
|
val cs = Phrase.from(context, R.string.groupNameNew)
|
||||||
.put(GROUP_NAME_KEY, updateData.name)
|
.put(GROUP_NAME_KEY, updateData.name)
|
||||||
.format().toString()
|
.format()
|
||||||
|
Util.makeBoldBetweenTags(cs)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Phrase.from(context, R.string.groupNameNew)
|
val cs = Phrase.from(context, R.string.groupNameNew)
|
||||||
.put(GROUP_NAME_KEY, updateData.name)
|
.put(GROUP_NAME_KEY, updateData.name)
|
||||||
.format().toString()
|
.format()
|
||||||
|
Util.makeBoldBetweenTags(cs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,20 +81,20 @@ object UpdateMessageBuilder {
|
|||||||
1 -> {
|
1 -> {
|
||||||
Phrase.from(context, R.string.groupMemberNew)
|
Phrase.from(context, R.string.groupMemberNew)
|
||||||
.put(NAME_KEY, updateData.updatedMembers.elementAtOrNull(0))
|
.put(NAME_KEY, updateData.updatedMembers.elementAtOrNull(0))
|
||||||
.format().toString()
|
.format()
|
||||||
}
|
}
|
||||||
2 -> {
|
2 -> {
|
||||||
Phrase.from(context, R.string.groupMemberTwoNew)
|
Phrase.from(context, R.string.groupMemberTwoNew)
|
||||||
.put(NAME_KEY, updateData.updatedMembers.elementAtOrNull(0))
|
.put(NAME_KEY, updateData.updatedMembers.elementAtOrNull(0))
|
||||||
.put(OTHER_NAME_KEY, updateData.updatedMembers.elementAtOrNull(1))
|
.put(OTHER_NAME_KEY, updateData.updatedMembers.elementAtOrNull(1))
|
||||||
.format().toString()
|
.format()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val newMemberCountMinusOne = newMemberCount - 1
|
val newMemberCountMinusOne = newMemberCount - 1
|
||||||
Phrase.from(context, R.string.groupMemberMoreNew)
|
Phrase.from(context, R.string.groupMemberMoreNew)
|
||||||
.put(NAME_KEY, updateData.updatedMembers.elementAtOrNull(0))
|
.put(NAME_KEY, updateData.updatedMembers.elementAtOrNull(0))
|
||||||
.put(COUNT_KEY, newMemberCountMinusOne)
|
.put(COUNT_KEY, newMemberCountMinusOne)
|
||||||
.format().toString()
|
.format()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,15 +105,13 @@ object UpdateMessageBuilder {
|
|||||||
|
|
||||||
// 1st case: you are part of the removed members
|
// 1st case: you are part of the removed members
|
||||||
return if (userPublicKey in updateData.updatedMembers) {
|
return if (userPublicKey in updateData.updatedMembers) {
|
||||||
if (isOutgoing) context.getString(R.string.groupMemberYouLeft) // You chose to leave
|
if (isOutgoing) context.getString(R.string.groupMemberYouLeft) // You chose to leave
|
||||||
else Phrase.from(context, R.string.groupRemovedYou) // You were forced to leave
|
else Phrase.from(context, R.string.groupRemovedYou) // You were forced to leave
|
||||||
.put(GROUP_NAME_KEY, updateData.groupName)
|
.put(GROUP_NAME_KEY, updateData.groupName)
|
||||||
.format().toString()
|
.format()
|
||||||
}
|
}
|
||||||
else // 2nd case: you are not part of the removed members
|
else // 2nd case: you are not part of the removed members
|
||||||
{
|
{
|
||||||
val members = updateData.updatedMembers.joinToString(", ", transform = ::getSenderName)
|
|
||||||
|
|
||||||
// a.) You are the person doing the removing of one or more members
|
// a.) You are the person doing the removing of one or more members
|
||||||
if (isOutgoing) {
|
if (isOutgoing) {
|
||||||
when (updateData.updatedMembers.size) {
|
when (updateData.updatedMembers.size) {
|
||||||
@ -116,15 +121,15 @@ object UpdateMessageBuilder {
|
|||||||
}
|
}
|
||||||
1 -> Phrase.from(context, R.string.groupRemoved)
|
1 -> Phrase.from(context, R.string.groupRemoved)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.format().toString()
|
.format()
|
||||||
2 -> Phrase.from(context, R.string.groupRemovedTwo)
|
2 -> Phrase.from(context, R.string.groupRemovedTwo)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.put(OTHER_NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(1)))
|
.put(OTHER_NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(1)))
|
||||||
.format().toString()
|
.format()
|
||||||
else -> Phrase.from(context, R.string.groupRemovedMore)
|
else -> Phrase.from(context, R.string.groupRemovedMore)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.put(COUNT_KEY, updateData.updatedMembers.size - 1)
|
.put(COUNT_KEY, updateData.updatedMembers.size - 1)
|
||||||
.format().toString()
|
.format()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // b.) Someone else is the person doing the removing of one or more members
|
else // b.) Someone else is the person doing the removing of one or more members
|
||||||
@ -140,15 +145,15 @@ object UpdateMessageBuilder {
|
|||||||
}
|
}
|
||||||
1 -> Phrase.from(context, R.string.groupRemoved)
|
1 -> Phrase.from(context, R.string.groupRemoved)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.format().toString()
|
.format()
|
||||||
2 -> Phrase.from(context, R.string.groupRemovedTwo)
|
2 -> Phrase.from(context, R.string.groupRemovedTwo)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.put(OTHER_NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(1)))
|
.put(OTHER_NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(1)))
|
||||||
.format().toString()
|
.format()
|
||||||
else -> Phrase.from(context, R.string.groupRemovedMore)
|
else -> Phrase.from(context, R.string.groupRemovedMore)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.put(COUNT_KEY, updateData.updatedMembers.size - 1)
|
.put(COUNT_KEY, updateData.updatedMembers.size - 1)
|
||||||
.format().toString()
|
.format()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,15 +170,15 @@ object UpdateMessageBuilder {
|
|||||||
}
|
}
|
||||||
1 -> Phrase.from(context, R.string.groupMemberLeft)
|
1 -> Phrase.from(context, R.string.groupMemberLeft)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.format().toString()
|
.format()
|
||||||
2 -> Phrase.from(context, R.string.groupMemberLeftTwo)
|
2 -> Phrase.from(context, R.string.groupMemberLeftTwo)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.put(OTHER_NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(1)))
|
.put(OTHER_NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(1)))
|
||||||
.format().toString()
|
.format()
|
||||||
else -> Phrase.from(context, R.string.groupMemberLeftMore)
|
else -> Phrase.from(context, R.string.groupMemberLeftMore)
|
||||||
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
.put(NAME_KEY, getSenderName(updateData.updatedMembers.elementAt(0)))
|
||||||
.put(COUNT_KEY, updateData.updatedMembers.size - 1)
|
.put(COUNT_KEY, updateData.updatedMembers.size - 1)
|
||||||
.format().toString()
|
.format()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import android.os.Looper
|
|||||||
import android.provider.Telephony
|
import android.provider.Telephony
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
|
import android.text.Spanned
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.text.style.StyleSpan
|
import android.text.style.StyleSpan
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
@ -358,6 +359,25 @@ object Util {
|
|||||||
val digitGroups = (Math.log10(sizeBytes.toDouble()) / Math.log10(1024.0)).toInt()
|
val digitGroups = (Math.log10(sizeBytes.toDouble()) / Math.log10(1024.0)).toInt()
|
||||||
return DecimalFormat("#,##0.#").format(sizeBytes / Math.pow(1024.0, digitGroups.toDouble())) + " " + units[digitGroups]
|
return DecimalFormat("#,##0.#").format(sizeBytes / Math.pow(1024.0, digitGroups.toDouble())) + " " + units[digitGroups]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method that takes a char sequence that contains one or more elements surrounded in bold tags
|
||||||
|
// like "Hello <b>world</b>" and returns a SpannableString that will display the appropriate
|
||||||
|
// elements in bold. If there are no such <b> or </b> elements then the original string is returned
|
||||||
|
// as a SpannableString without any bold highlighting.
|
||||||
|
@JvmStatic
|
||||||
|
fun makeBoldBetweenTags(input: CharSequence): SpannableString {
|
||||||
|
val spannable = SpannableString(input)
|
||||||
|
var startIndex = 0
|
||||||
|
while (true) {
|
||||||
|
startIndex = input.indexOf("<b>", startIndex)
|
||||||
|
if (startIndex == -1) break
|
||||||
|
val endIndex = input.indexOf("</b>", startIndex + 3)
|
||||||
|
if (endIndex == -1) break
|
||||||
|
spannable.setSpan(StyleSpan(Typeface.BOLD),startIndex + 3, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
startIndex = endIndex + 4
|
||||||
|
}
|
||||||
|
return spannable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T, R> T.runIf(condition: Boolean, block: T.() -> R): R where T: R = if (condition) block() else this
|
fun <T, R> T.runIf(condition: Boolean, block: T.() -> R): R where T: R = if (condition) block() else this
|
||||||
|
Loading…
Reference in New Issue
Block a user