diff --git a/app/build.gradle b/app/build.gradle index afd8952dbd..4cd08255d6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -322,6 +322,7 @@ dependencies { implementation "com.google.protobuf:protobuf-java:$protobufVersion" implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonDatabindVersion" implementation "com.squareup.okhttp3:okhttp:$okhttpVersion" + implementation "com.squareup.phrase:phrase:$phraseVersion" implementation 'app.cash.copper:copper-flow:1.0.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" diff --git a/app/src/androidTest/java/network/loki/messenger/SodiumUtilitiesTest.kt b/app/src/androidTest/java/network/loki/messenger/SodiumUtilitiesTest.kt index ac62ecea24..028a76a33f 100644 --- a/app/src/androidTest/java/network/loki/messenger/SodiumUtilitiesTest.kt +++ b/app/src/androidTest/java/network/loki/messenger/SodiumUtilitiesTest.kt @@ -136,29 +136,29 @@ class SodiumUtilitiesTest { } @Test - fun sessionIdSuccess() { - val result = SodiumUtilities.sessionId("05$publicKey", "15$blindedPublicKey", serverPublicKey) + fun accountIdSuccess() { + val result = SodiumUtilities.accountId("05$publicKey", "15$blindedPublicKey", serverPublicKey) assertTrue(result) } @Test - fun sessionIdFailureInvalidAccountId() { - val result = SodiumUtilities.sessionId("AB$publicKey", "15$blindedPublicKey", serverPublicKey) + fun accountIdFailureInvalidAccountId() { + val result = SodiumUtilities.accountId("AB$publicKey", "15$blindedPublicKey", serverPublicKey) assertFalse(result) } @Test - fun sessionIdFailureInvalidBlindedId() { - val result = SodiumUtilities.sessionId("05$publicKey", "AB$blindedPublicKey", serverPublicKey) + fun accountIdFailureInvalidBlindedId() { + val result = SodiumUtilities.accountId("05$publicKey", "AB$blindedPublicKey", serverPublicKey) assertFalse(result) } @Test - fun sessionIdFailureBlindingFactor() { - val result = SodiumUtilities.sessionId("05$publicKey", "15$blindedPublicKey", "Test") + fun accountIdFailureBlindingFactor() { + val result = SodiumUtilities.accountId("05$publicKey", "15$blindedPublicKey", "Test") assertFalse(result) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index bbf494cce3..023ec6b660 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -156,8 +156,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO private volatile boolean isAppVisible; - public boolean newAccount = false; - @Override public Object getSystemService(String name) { if (MessagingModuleConfiguration.MESSAGING_MODULE_SERVICE.equals(name)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt index d9ebe449a4..050f58278b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt @@ -18,6 +18,7 @@ import org.session.libsession.utilities.Address import org.session.libsession.utilities.AppTextSecurePreferences import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.recipients.Recipient +import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.mms.GlideApp import org.thoughtcrime.securesms.mms.GlideRequests @@ -25,6 +26,8 @@ import org.thoughtcrime.securesms.mms.GlideRequests class ProfilePictureView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null ) : RelativeLayout(context, attrs) { + private val TAG = "ProfilePictureView" + private val binding = ViewProfilePictureBinding.inflate(LayoutInflater.from(context), this) private val glide: GlideRequests = GlideApp.with(this) private val prefs = AppTextSecurePreferences(context) @@ -91,7 +94,7 @@ class ProfilePictureView @JvmOverloads constructor( } fun update() { - val publicKey = publicKey ?: return + val publicKey = publicKey ?: return Log.w(TAG, "Could not find public key to update profile picture") val additionalPublicKey = additionalPublicKey if (additionalPublicKey != null) { setProfilePictureIfNeeded(binding.doubleModeImageView1, publicKey, displayName) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt index 510d666c49..97740b2a26 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt @@ -89,8 +89,8 @@ private fun EnterAccountId( SessionOutlinedTextField( text = state.newMessageIdOrOns, modifier = Modifier - .padding(horizontal = LocalDimensions.current.spacing) - .contentDescription("Session id input box"), + .padding(horizontal = LocalDimensions.current.spacing), + contentDescription = "Session id input box", placeholder = stringResource(R.string.accountIdOrOnsEnter), onChange = callbacks::onChange, onContinue = callbacks::onContinue, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageFragment.kt index a0a3df84eb..8c383fe1a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageFragment.kt @@ -45,7 +45,7 @@ class NewMessageFragment : Fragment() { viewModel, onClose = { delegate.onDialogClosePressed() }, onBack = { delegate.onDialogBackPressed() }, - onHelp = { requireContext().openUrl("https://sessionapp.zendesk.com/hc/en-us/articles/4439132747033-How-do-Session-ID-usernames-work") } + onHelp = { requireContext().openUrl("https://sessionapp.zendesk.com/hc/en-us/articles/4439132747033-How-do-Account-ID-usernames-work") } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 060da324d0..62ea2e52d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -239,12 +239,12 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe intent.getParcelableExtra
(ADDRESS)?.let { it -> threadId = threadDb.getThreadIdIfExistsFor(it.serialize()) if (threadId == -1L) { - val sessionId = AccountId(it.serialize()) + val accountId = AccountId(it.serialize()) val openGroup = lokiThreadDb.getOpenGroupChat(intent.getLongExtra(FROM_GROUP_THREAD_ID, -1)) - val address = if (sessionId.prefix == IdPrefix.BLINDED && openGroup != null) { - storage.getOrCreateBlindedIdMapping(sessionId.hexString, openGroup.server, openGroup.publicKey).sessionId?.let { + val address = if (accountId.prefix == IdPrefix.BLINDED && openGroup != null) { + storage.getOrCreateBlindedIdMapping(accountId.hexString, openGroup.server, openGroup.publicKey).accountId?.let { fromSerialized(it) - } ?: GroupUtil.getEncodedOpenGroupInboxID(openGroup, sessionId) + } ?: GroupUtil.getEncodedOpenGroupInboxID(openGroup, accountId) } else { it } @@ -1131,8 +1131,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } } - override fun copyAccountID(sessionId: String) { - val clip = ClipData.newPlainText("Account ID", sessionId) + override fun copyAccountID(accountId: String) { + val clip = ClipData.newPlainText("Account ID", accountId) val manager = getSystemService(PassphraseRequiredActionBarActivity.CLIPBOARD_SERVICE) as ClipboardManager manager.setPrimaryClip(clip) Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt index 052dcb69c4..8e38c7d38e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt @@ -2,19 +2,16 @@ package org.thoughtcrime.securesms.conversation.v2.input_bar import android.annotation.SuppressLint import android.content.Context -import android.content.res.Resources import android.graphics.PointF import android.net.Uri import android.text.Editable import android.text.InputType -import android.text.TextWatcher import android.util.AttributeSet import android.view.KeyEvent import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.inputmethod.EditorInfo -import android.widget.EditText import android.widget.RelativeLayout import android.widget.TextView import androidx.core.view.isGone @@ -31,11 +28,8 @@ import org.thoughtcrime.securesms.conversation.v2.messages.QuoteViewDelegate import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.mms.GlideRequests -import org.thoughtcrime.securesms.util.SimpleTextWatcher import org.thoughtcrime.securesms.util.addTextChangedListener import org.thoughtcrime.securesms.util.contains -import org.thoughtcrime.securesms.util.toDp -import org.thoughtcrime.securesms.util.toPx // Enums to keep track of the state of our voice recording mechanism as the user can // manipulate the UI faster than we can setup & teardown. @@ -46,16 +40,24 @@ enum class VoiceRecorderState { ShuttingDownAfterRecord } -class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, LinkPreviewDraftViewDelegate, +@SuppressLint("ClickableViewAccessibility") +class InputBar @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : RelativeLayout( + context, + attrs, + defStyleAttr +), InputBarEditTextDelegate, + QuoteViewDelegate, + LinkPreviewDraftViewDelegate, TextView.OnEditorActionListener { - private lateinit var binding: ViewInputBarBinding - private val screenWidth = Resources.getSystem().displayMetrics.widthPixels - private val vMargin by lazy { toDp(4, resources) } - private val minHeight by lazy { toPx(56, resources) } + + private var binding: ViewInputBarBinding = ViewInputBarBinding.inflate(LayoutInflater.from(context), this, true) private var linkPreviewDraftView: LinkPreviewDraftView? = null private var quoteView: QuoteView? = null var delegate: InputBarDelegate? = null - var additionalContentHeight = 0 var quote: MessageRecord? = null var linkPreview: LinkPreview? = null var showInput: Boolean = true @@ -68,7 +70,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li } var text: String - get() { return binding.inputBarEditText.text?.toString() ?: "" } + get() = binding.inputBarEditText.text?.toString() ?: "" set(value) { binding.inputBarEditText.setText(value) } // Keep track of when the user pressed the record voice message button, the duration that @@ -77,21 +79,11 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li var voiceMessageDurationMS = 0L var voiceRecorderState = VoiceRecorderState.Idle - val attachmentButtonsContainerHeight: Int - get() = binding.attachmentsButtonContainer.height + private val attachmentsButton = InputBarButton(context, R.drawable.ic_plus_24).apply { contentDescription = context.getString(R.string.AccessibilityId_attachments_button)} + val microphoneButton = InputBarButton(context, R.drawable.ic_microphone).apply { contentDescription = context.getString(R.string.AccessibilityId_microphone_button)} + private val sendButton = InputBarButton(context, R.drawable.ic_arrow_up, true).apply { contentDescription = context.getString(R.string.AccessibilityId_send_message_button)} - private val attachmentsButton by lazy { InputBarButton(context, R.drawable.ic_plus_24).apply { contentDescription = context.getString(R.string.AccessibilityId_attachments_button)} } - private val microphoneButton by lazy { InputBarButton(context, R.drawable.ic_microphone).apply { contentDescription = context.getString(R.string.AccessibilityId_microphone_button)} } - private val sendButton by lazy { InputBarButton(context, R.drawable.ic_arrow_up, true).apply { contentDescription = context.getString(R.string.AccessibilityId_send_message_button)} } - - // 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() } - - @SuppressLint("ClickableViewAccessibility") - private fun initialize() { - binding = ViewInputBarBinding.inflate(LayoutInflater.from(context), this, true) + init { // Attachments button binding.attachmentsButtonContainer.addView(attachmentsButton) attachmentsButton.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) @@ -110,6 +102,7 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li // `microphoneButton.onUp` and tap the button then the logged output order is onUp and THEN onPress! microphoneButton.setOnTouchListener(object : OnTouchListener { override fun onTouch(v: View, event: MotionEvent): Boolean { + if (!microphoneButton.snIsEnabled) return true // We only handle single finger touch events so just consume the event and bail if there are more if (event.pointerCount > 1) return true @@ -160,12 +153,11 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li binding.inputBarEditText.setOnEditorActionListener(this) if (TextSecurePreferences.isEnterSendsEnabled(context)) { binding.inputBarEditText.imeOptions = EditorInfo.IME_ACTION_SEND - binding.inputBarEditText.inputType = - InputType.TYPE_TEXT_FLAG_CAP_SENTENCES + binding.inputBarEditText.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES } else { binding.inputBarEditText.imeOptions = EditorInfo.IME_ACTION_NONE binding.inputBarEditText.inputType = - binding.inputBarEditText.inputType or + binding.inputBarEditText.inputType InputType.TYPE_TEXT_FLAG_CAP_SENTENCES } val incognitoFlag = if (TextSecurePreferences.isIncognitoKeyboardEnabled(context)) 16777216 else 0 @@ -182,9 +174,6 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li return false } - // endregion - - // region Updating override fun inputBarEditTextContentChanged(text: CharSequence) { microphoneButton.isVisible = text.trim().isEmpty() sendButton.isVisible = microphoneButton.isGone @@ -286,12 +275,9 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate, QuoteViewDelegate, Li fun setInputBarEditableFactory(factory: Editable.Factory) { binding.inputBarEditText.setEditableFactory(factory) } - - // endregion } interface InputBarDelegate { - fun inputBarEditTextContentChanged(newContent: CharSequence) fun toggleAttachmentOptions() fun showVoiceMessageUI() @@ -301,4 +287,4 @@ interface InputBarDelegate { fun onMicrophoneButtonUp(event: MotionEvent) fun sendMessage() fun commitInputContent(contentUri: Uri) -} \ No newline at end of file +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 76c5dafd22..177becd497 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -57,7 +57,7 @@ object ConversationMenuHelper { if (!isOpenGroup && (thread.hasApprovedMe() || thread.isClosedGroupRecipient || thread.isLocalNumber)) { inflater.inflate(R.menu.menu_conversation_expiration, menu) } - // One-on-one chat menu allows copying the session id + // One-on-one chat menu allows copying the account id if (thread.isContactRecipient) { inflater.inflate(R.menu.menu_conversation_copy_account_id, menu) } @@ -325,7 +325,7 @@ object ConversationMenuHelper { interface ConversationMenuListener { fun block(deleteThread: Boolean = false) fun unblock() - fun copyAccountID(sessionId: String) + fun copyAccountID(accountId: String) fun copyOpenGroupUrl(thread: Recipient) fun showDisappearingMessages(thread: Recipient) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt index 618616d91d..4d3e48bc5b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt @@ -1,15 +1,12 @@ package org.thoughtcrime.securesms.conversation.v2.utilities import android.content.Context -import android.graphics.Color import android.graphics.Typeface import android.text.Spannable import android.text.SpannableString -import android.text.style.BackgroundColorSpan import android.text.style.ForegroundColorSpan import android.text.style.StyleSpan import android.util.Range -import androidx.core.content.res.ResourcesCompat import network.loki.messenger.R import nl.komponents.kovenant.combine.Tuple2 import org.session.libsession.messaging.contacts.Contact @@ -22,7 +19,6 @@ import org.session.libsession.utilities.truncateIdForDisplay import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.util.RoundedBackgroundSpan import org.thoughtcrime.securesms.util.getAccentColor -import org.thoughtcrime.securesms.util.toPx import java.util.regex.Pattern object MentionUtilities { @@ -161,7 +157,7 @@ object MentionUtilities { } private fun isYou(mentionedPublicKey: String, userPublicKey: String, openGroup: OpenGroup?): Boolean { - val isUserBlindedPublicKey = openGroup?.let { SodiumUtilities.sessionId(userPublicKey, mentionedPublicKey, it.publicKey) } ?: false + val isUserBlindedPublicKey = openGroup?.let { SodiumUtilities.accountId(userPublicKey, mentionedPublicKey, it.publicKey) } ?: false return mentionedPublicKey.equals(userPublicKey, ignoreCase = true) || isUserBlindedPublicKey } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/BlindedIdMappingDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/BlindedIdMappingDatabase.kt index 950c1c6bcf..a5919d4394 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/BlindedIdMappingDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/BlindedIdMappingDatabase.kt @@ -31,7 +31,7 @@ class BlindedIdMappingDatabase(context: Context, helper: SQLCipherOpenHelper) : private fun readBlindedIdMapping(cursor: Cursor): BlindedIdMapping { return BlindedIdMapping( blindedId = cursor.getString(cursor.getColumnIndexOrThrow(BLINDED_PK)), - sessionId = cursor.getStringOrNull(cursor.getColumnIndexOrThrow(SESSION_PK)), + accountId = cursor.getStringOrNull(cursor.getColumnIndexOrThrow(SESSION_PK)), serverUrl = cursor.getString(cursor.getColumnIndexOrThrow(SERVER_URL)), serverId = cursor.getString(cursor.getColumnIndexOrThrow(SERVER_PK)), ) @@ -58,7 +58,7 @@ class BlindedIdMappingDatabase(context: Context, helper: SQLCipherOpenHelper) : try { val values = ContentValues().apply { put(BLINDED_PK, blindedIdMapping.blindedId) - put(SERVER_PK, blindedIdMapping.sessionId) + put(SERVER_PK, blindedIdMapping.accountId) put(SERVER_URL, blindedIdMapping.serverUrl) put(SERVER_PK, blindedIdMapping.serverId) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt index 23a1af7ceb..9d3a6c9c18 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt @@ -1242,73 +1242,50 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa } private fun getNotificationMmsMessageRecord(cursor: Cursor): NotificationMmsMessageRecord { - val id = cursor.getLong(cursor.getColumnIndexOrThrow(ID)) - val dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT)) - val dateReceived = cursor.getLong( - cursor.getColumnIndexOrThrow( - NORMALIZED_DATE_RECEIVED - ) - ) - val threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)) - val mailbox = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)) - val address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)) - val addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(ADDRESS_DEVICE_ID)) - val recipient = getRecipientFor(address) - val contentLocation = cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_LOCATION)) - val transactionId = cursor.getString(cursor.getColumnIndexOrThrow(TRANSACTION_ID)) - val messageSize = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_SIZE)) - val expiry = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRY)) - val status = cursor.getInt(cursor.getColumnIndexOrThrow(STATUS)) - val deliveryReceiptCount = cursor.getInt( - cursor.getColumnIndexOrThrow( - DELIVERY_RECEIPT_COUNT - ) - ) - val readReceiptCount = if (isReadReceiptsEnabled(context)) cursor.getInt(cursor.getColumnIndexOrThrow(READ_RECEIPT_COUNT)) else 0 - val hasMention = (cursor.getInt(cursor.getColumnIndexOrThrow(HAS_MENTION)) == 1) - val contentLocationBytes: ByteArray? = contentLocation?.takeUnless { it.isEmpty() }?.let(::toIsoBytes) - val transactionIdBytes: ByteArray? = transactionId?.takeUnless { it.isEmpty() }?.let(::toIsoBytes) - val slideDeck = SlideDeck(context, MmsNotificationAttachment(status, messageSize)) + // Note: Additional details such as ADDRESS_DEVICE_ID, CONTENT_LOCATION, and TRANSACTION_ID are available if required. + val id = cursor.getLong(cursor.getColumnIndexOrThrow(ID)) + val dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT)) + val dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_RECEIVED)) + val threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)) + val mailbox = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)) + val address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)) + val recipient = getRecipientFor(address) + val messageSize = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_SIZE)) + val expiry = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRY)) + val status = cursor.getInt(cursor.getColumnIndexOrThrow(STATUS)) + val deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(DELIVERY_RECEIPT_COUNT)) + val readReceiptCount = if (isReadReceiptsEnabled(context)) cursor.getInt(cursor.getColumnIndexOrThrow(READ_RECEIPT_COUNT)) else 0 + val hasMention = (cursor.getInt(cursor.getColumnIndexOrThrow(HAS_MENTION)) == 1) + val slideDeck = SlideDeck(context, MmsNotificationAttachment(status, messageSize)) + return NotificationMmsMessageRecord( id, recipient, recipient, dateSent, dateReceived, deliveryReceiptCount, threadId, - contentLocationBytes, messageSize, expiry, status, - transactionIdBytes, mailbox, slideDeck, + messageSize, expiry, status, mailbox, slideDeck, readReceiptCount, hasMention ) } private fun getMediaMmsMessageRecord(cursor: Cursor, getQuote: Boolean): MediaMmsMessageRecord { - val id = cursor.getLong(cursor.getColumnIndexOrThrow(ID)) - val dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT)) - val dateReceived = cursor.getLong( - cursor.getColumnIndexOrThrow( - NORMALIZED_DATE_RECEIVED - ) - ) - val box = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)) - val threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)) - val address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)) - val addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(ADDRESS_DEVICE_ID)) - val deliveryReceiptCount = cursor.getInt( - cursor.getColumnIndexOrThrow( - DELIVERY_RECEIPT_COUNT - ) - ) - var readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(READ_RECEIPT_COUNT)) - val body = cursor.getString(cursor.getColumnIndexOrThrow(BODY)) - val partCount = cursor.getInt(cursor.getColumnIndexOrThrow(PART_COUNT)) - val mismatchDocument = cursor.getString( - cursor.getColumnIndexOrThrow( - MISMATCHED_IDENTITIES - ) - ) - val networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(NETWORK_FAILURE)) - val subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID)) - val expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN)) - val expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRE_STARTED)) - val unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED)) == 1 - val hasMention = cursor.getInt(cursor.getColumnIndexOrThrow(HAS_MENTION)) == 1 + val id = cursor.getLong(cursor.getColumnIndexOrThrow(ID)) + val dateSent = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT)) + val dateReceived = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_RECEIVED)) + val box = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX)) + val threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID)) + val address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)) + val addressDeviceId = cursor.getInt(cursor.getColumnIndexOrThrow(ADDRESS_DEVICE_ID)) + val deliveryReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(DELIVERY_RECEIPT_COUNT)) + var readReceiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(READ_RECEIPT_COUNT)) + val body = cursor.getString(cursor.getColumnIndexOrThrow(BODY)) + val partCount = cursor.getInt(cursor.getColumnIndexOrThrow(PART_COUNT)) + val mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MISMATCHED_IDENTITIES)) + val networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(NETWORK_FAILURE)) + val subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID)) + val expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN)) + val expireStarted = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRE_STARTED)) + val unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED)) == 1 + val hasMention = cursor.getInt(cursor.getColumnIndexOrThrow(HAS_MENTION)) == 1 + if (!isReadReceiptsEnabled(context)) { readReceiptCount = 0 } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt index c856295ea4..27b3e73397 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SessionContactDatabase.kt @@ -15,7 +15,7 @@ class SessionContactDatabase(context: Context, helper: SQLCipherOpenHelper) : Da companion object { private const val sessionContactTable = "session_contact_database" - const val accountID = "account_id" + const val accountID = "session_id" const val name = "name" const val nickname = "nickname" const val profilePictureURL = "profile_picture_url" @@ -42,12 +42,12 @@ class SessionContactDatabase(context: Context, helper: SQLCipherOpenHelper) : Da } } - fun getContacts(sessionIDs: Collection): List { + fun getContacts(accountIDs: Collection): List { val database = databaseHelper.readableDatabase return database.getAll( sessionContactTable, "$accountID IN (SELECT value FROM json_each(?))", - arrayOf(JSONArray(sessionIDs).toString()) + arrayOf(JSONArray(accountIDs).toString()) ) { cursor -> contactFromCursor(cursor) } } @@ -56,8 +56,7 @@ class SessionContactDatabase(context: Context, helper: SQLCipherOpenHelper) : Da return database.getAll(sessionContactTable, null, null) { cursor -> contactFromCursor(cursor) }.filter { contact -> - val sessionId = AccountId(contact.accountID) - sessionId.prefix == IdPrefix.STANDARD + contact.accountID.let(::AccountId).prefix == IdPrefix.STANDARD }.toSet() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index b19bd76aed..3115275773 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -6,6 +6,7 @@ import java.security.MessageDigest import network.loki.messenger.libsession_util.ConfigBase import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_HIDDEN import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_PINNED +import network.loki.messenger.libsession_util.ConfigBase.Companion.PRIORITY_VISIBLE import network.loki.messenger.libsession_util.Contacts import network.loki.messenger.libsession_util.ConversationVolatileConfig import network.loki.messenger.libsession_util.UserGroupsConfig @@ -111,12 +112,12 @@ open class Storage( if (address.isGroup) { val groups = configFactory.userGroups ?: return if (address.isClosedGroup) { - val sessionId = GroupUtil.doubleDecodeGroupId(address.serialize()) + val accountId = GroupUtil.doubleDecodeGroupId(address.serialize()) val closedGroup = getGroup(address.toGroupString()) if (closedGroup != null && closedGroup.isActive) { - val legacyGroup = groups.getOrConstructLegacyGroupInfo(sessionId) + val legacyGroup = groups.getOrConstructLegacyGroupInfo(accountId) groups.set(legacyGroup) - val newVolatileParams = volatile.getOrConstructLegacyGroup(sessionId).copy( + val newVolatileParams = volatile.getOrConstructLegacyGroup(accountId).copy( lastRead = SnodeAPI.nowWithOffset, ) volatile.set(newVolatileParams) @@ -132,11 +133,11 @@ open class Storage( if (getUserPublicKey() != address.serialize()) { val contacts = configFactory.contacts ?: return contacts.upsertContact(address.serialize()) { - priority = ConfigBase.PRIORITY_VISIBLE + priority = PRIORITY_VISIBLE } } else { val userProfile = configFactory.user ?: return - userProfile.setNtsPriority(ConfigBase.PRIORITY_VISIBLE) + userProfile.setNtsPriority(PRIORITY_VISIBLE) DatabaseComponent.get(context).threadDatabase().setHasSent(threadId, true) } val newVolatileParams = volatile.getOrConstructOneToOne(address.serialize()) @@ -149,9 +150,9 @@ open class Storage( if (address.isGroup) { val groups = configFactory.userGroups ?: return if (address.isClosedGroup) { - val sessionId = GroupUtil.doubleDecodeGroupId(address.serialize()) - volatile.eraseLegacyClosedGroup(sessionId) - groups.eraseLegacyGroup(sessionId) + val accountId = GroupUtil.doubleDecodeGroupId(address.serialize()) + volatile.eraseLegacyClosedGroup(accountId) + groups.eraseLegacyGroup(accountId) } else if (address.isCommunity) { // these should be removed in the group leave / handling new configs Log.w("Loki", "Thread delete called for open group address, expecting to be handled elsewhere") @@ -265,10 +266,8 @@ open class Storage( } // otherwise recipient is one to one recipient.isContactRecipient -> { - // don't process non-standard session IDs though - val sessionId = AccountId(recipient.address.serialize()) - if (sessionId.prefix != IdPrefix.STANDARD) return - + // don't process non-standard account IDs though + if (AccountId(recipient.address.serialize()).prefix != IdPrefix.STANDARD) return config.getOrConstructOneToOne(recipient.address.serialize()) } else -> throw NullPointerException("Weren't expecting to have a convo with address ${recipient.address.serialize()}") @@ -299,8 +298,8 @@ open class Storage( var messageID: Long? = null val senderAddress = fromSerialized(message.sender!!) val isUserSender = (message.sender!! == getUserPublicKey()) - val isUserBlindedSender = message.threadID?.takeIf { it >= 0 }?.let { getOpenGroup(it)?.publicKey } - ?.let { SodiumUtilities.sessionId(getUserPublicKey()!!, message.sender!!, it) } ?: false + val isUserBlindedSender = message.threadID?.takeIf { it >= 0 }?.let(::getOpenGroup)?.publicKey + ?.let { SodiumUtilities.accountId(getUserPublicKey()!!, message.sender!!, it) } ?: false val group: Optional = when { openGroupID != null -> Optional.of(SignalServiceGroup(openGroupID.toByteArray(), SignalServiceGroup.GroupType.PUBLIC_CHAT)) groupPublicKey != null -> { @@ -540,7 +539,7 @@ open class Storage( val extracted = convos.all() for (conversation in extracted) { val threadId = when (conversation) { - is Conversation.OneToOne -> getThreadIdFor(conversation.sessionId, null, null, createThread = false) + is Conversation.OneToOne -> getThreadIdFor(conversation.accountId, null, null, createThread = false) is Conversation.LegacyGroup -> getThreadIdFor("", conversation.groupId,null, createThread = false) is Conversation.Community -> getThreadIdFor("",null, "${conversation.baseCommunityInfo.baseUrl.removeSuffix("/")}.${conversation.baseCommunityInfo.room}", createThread = false) } @@ -571,7 +570,7 @@ open class Storage( val existingJoinUrls = existingCommunities.values.map { it.joinURL } val existingClosedGroups = getAllGroups(includeInactive = true).filter { it.isClosedGroup } - val lgcIds = lgc.map { it.sessionId } + val lgcIds = lgc.map { it.accountId } val toDeleteClosedGroups = existingClosedGroups.filter { group -> GroupUtil.doubleDecodeGroupId(group.encodedId) !in lgcIds } @@ -605,8 +604,8 @@ open class Storage( } for (group in lgc) { - val groupId = GroupUtil.doubleEncodeGroupID(group.sessionId) - val existingGroup = existingClosedGroups.firstOrNull { GroupUtil.doubleDecodeGroupId(it.encodedId) == group.sessionId } + val groupId = GroupUtil.doubleEncodeGroupID(group.accountId) + val existingGroup = existingClosedGroups.firstOrNull { GroupUtil.doubleDecodeGroupId(it.encodedId) == group.accountId } val existingThread = existingGroup?.let { getThreadId(existingGroup.encodedId) } if (existingGroup != null) { if (group.priority == PRIORITY_HIDDEN && existingThread != null) { @@ -625,19 +624,19 @@ open class Storage( createGroup(groupId, title, admins + members, null, null, admins, formationTimestamp) setProfileSharing(Address.fromSerialized(groupId), true) // Add the group to the user's set of public keys to poll for - addClosedGroupPublicKey(group.sessionId) + addClosedGroupPublicKey(group.accountId) // Store the encryption key pair val keyPair = ECKeyPair(DjbECPublicKey(group.encPubKey), DjbECPrivateKey(group.encSecKey)) - addClosedGroupEncryptionKeyPair(keyPair, group.sessionId, SnodeAPI.nowWithOffset) + addClosedGroupEncryptionKeyPair(keyPair, group.accountId, SnodeAPI.nowWithOffset) // Notify the PN server - PushRegistryV1.subscribeGroup(group.sessionId, publicKey = localUserPublicKey) + PushRegistryV1.subscribeGroup(group.accountId, publicKey = localUserPublicKey) // Notify the user val threadID = getOrCreateThreadIdFor(Address.fromSerialized(groupId)) threadDb.setDate(threadID, formationTimestamp) insertOutgoingInfoMessage(context, groupId, SignalServiceGroup.Type.CREATION, title, members.map { it.serialize() }, admins.map { it.serialize() }, threadID, formationTimestamp) // Don't create config group here, it's from a config update // Start polling - ClosedGroupPollerV2.shared.startPolling(group.sessionId) + ClosedGroupPollerV2.shared.startPolling(group.accountId) } getThreadId(Address.fromSerialized(groupId))?.let { setExpirationConfiguration( @@ -938,10 +937,10 @@ open class Storage( groupVolatileConfig.lastRead = formationTimestamp volatiles.set(groupVolatileConfig) val groupInfo = GroupInfo.LegacyGroupInfo( - sessionId = groupPublicKey, + accountId = groupPublicKey, name = name, members = members, - priority = ConfigBase.PRIORITY_VISIBLE, + priority = PRIORITY_VISIBLE, encPubKey = (encryptionKeyPair.publicKey as DjbECPublicKey).publicKey, // 'serialize()' inserts an extra byte encSecKey = encryptionKeyPair.privateKey.serialize(), disappearingTimer = expirationTimer.toLong(), @@ -975,7 +974,7 @@ open class Storage( members = membersMap, encPubKey = (latestKeyPair.publicKey as DjbECPublicKey).publicKey, // 'serialize()' inserts an extra byte encSecKey = latestKeyPair.privateKey.serialize(), - priority = if (isPinned(threadID)) PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE, + priority = if (isPinned(threadID)) PRIORITY_PINNED else PRIORITY_VISIBLE, disappearingTimer = getExpirationConfiguration(threadID)?.expiryMode?.expirySeconds ?: 0L, joinedAt = (existingGroup.formationTimestamp / 1000L) ) @@ -1209,7 +1208,7 @@ open class Storage( val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase() val moreContacts = contacts.filter { contact -> val id = AccountId(contact.id) - id.prefix?.isBlinded() == false || mappingDb.getBlindedIdMapping(contact.id).none { it.sessionId != null } + id.prefix?.isBlinded() == false || mappingDb.getBlindedIdMapping(contact.id).none { it.accountId != null } } val profileManager = SSKEnvironment.shared.profileManager moreContacts.forEach { contact -> @@ -1262,7 +1261,7 @@ open class Storage( val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase() val moreContacts = contacts.filter { contact -> val id = AccountId(contact.publicKey) - id.prefix != IdPrefix.BLINDED || mappingDb.getBlindedIdMapping(contact.publicKey).none { it.sessionId != null } + id.prefix != IdPrefix.BLINDED || mappingDb.getBlindedIdMapping(contact.publicKey).none { it.accountId != null } } for (contact in moreContacts) { val address = fromSerialized(contact.publicKey) @@ -1329,25 +1328,25 @@ open class Storage( val threadRecipient = getRecipientForThread(threadID) ?: return if (threadRecipient.isLocalNumber) { val user = configFactory.user ?: return - user.setNtsPriority(if (isPinned) PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE) + user.setNtsPriority(if (isPinned) PRIORITY_PINNED else PRIORITY_VISIBLE) } else if (threadRecipient.isContactRecipient) { val contacts = configFactory.contacts ?: return contacts.upsertContact(threadRecipient.address.serialize()) { - priority = if (isPinned) PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE + priority = if (isPinned) PRIORITY_PINNED else PRIORITY_VISIBLE } } else if (threadRecipient.isGroupRecipient) { val groups = configFactory.userGroups ?: return if (threadRecipient.isClosedGroupRecipient) { - val sessionId = GroupUtil.doubleDecodeGroupId(threadRecipient.address.serialize()) - val newGroupInfo = groups.getOrConstructLegacyGroupInfo(sessionId).copy ( - priority = if (isPinned) PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE - ) - groups.set(newGroupInfo) + threadRecipient.address.serialize() + .let(GroupUtil::doubleDecodeGroupId) + .let(groups::getOrConstructLegacyGroupInfo) + .copy (priority = if (isPinned) PRIORITY_PINNED else PRIORITY_VISIBLE) + .let(groups::set) } else if (threadRecipient.isCommunityRecipient) { val openGroup = getOpenGroup(threadID) ?: return val (baseUrl, room, pubKeyHex) = BaseCommunityInfo.parseFullUrl(openGroup.joinURL) ?: return val newGroupInfo = groups.getOrConstructCommunityInfo(baseUrl, room, Hex.toStringCondensed(pubKeyHex)).copy ( - priority = if (isPinned) PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE + priority = if (isPinned) PRIORITY_PINNED else PRIORITY_VISIBLE ) groups.set(newGroupInfo) } @@ -1505,10 +1504,10 @@ open class Storage( } } for (mapping in mappings) { - if (!SodiumUtilities.sessionId(senderPublicKey, mapping.value.blindedId, mapping.value.serverId)) { + if (!SodiumUtilities.accountId(senderPublicKey, mapping.value.blindedId, mapping.value.serverId)) { continue } - mappingDb.addBlindedIdMapping(mapping.value.copy(sessionId = senderPublicKey)) + mappingDb.addBlindedIdMapping(mapping.value.copy(accountId = senderPublicKey)) val blindedThreadId = threadDB.getOrCreateThreadIdFor(Recipient.from(context, fromSerialized(mapping.key), false)) mmsDb.updateThreadId(blindedThreadId, threadId) @@ -1614,20 +1613,20 @@ open class Storage( ): BlindedIdMapping { val db = DatabaseComponent.get(context).blindedIdMappingDatabase() val mapping = db.getBlindedIdMapping(blindedId).firstOrNull() ?: BlindedIdMapping(blindedId, null, server, serverPublicKey) - if (mapping.sessionId != null) { + if (mapping.accountId != null) { return mapping } getAllContacts().forEach { contact -> - val sessionId = AccountId(contact.accountID) - if (sessionId.prefix == IdPrefix.STANDARD && SodiumUtilities.sessionId(sessionId.hexString, blindedId, serverPublicKey)) { - val contactMapping = mapping.copy(sessionId = sessionId.hexString) + val accountId = AccountId(contact.accountID) + if (accountId.prefix == IdPrefix.STANDARD && SodiumUtilities.accountId(accountId.hexString, blindedId, serverPublicKey)) { + val contactMapping = mapping.copy(accountId = accountId.hexString) db.addBlindedIdMapping(contactMapping) return contactMapping } } db.getBlindedIdMappingsExceptFor(server).forEach { - if (SodiumUtilities.sessionId(it.sessionId!!, blindedId, serverPublicKey)) { - val otherMapping = mapping.copy(sessionId = it.sessionId) + if (SodiumUtilities.accountId(it.accountId!!, blindedId, serverPublicKey)) { + val otherMapping = mapping.copy(accountId = it.accountId) db.addBlindedIdMapping(otherMapping) return otherMapping } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java deleted file mode 100644 index 9fb4047879..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2012 Moxie Marlinspike - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.database.model; - -import static java.util.Collections.emptyList; - -import android.content.Context; -import android.text.SpannableString; - -import androidx.annotation.NonNull; - -import org.session.libsession.utilities.recipients.Recipient; -import org.thoughtcrime.securesms.database.MmsDatabase; -import org.thoughtcrime.securesms.database.SmsDatabase.Status; -import org.thoughtcrime.securesms.mms.SlideDeck; - -import network.loki.messenger.R; - -/** - * Represents the message record model for MMS messages that are - * notifications (ie: they're pointers to undownloaded media). - * - * @author Moxie Marlinspike - * - */ - -public class NotificationMmsMessageRecord extends MmsMessageRecord { - private final byte[] contentLocation; - private final long messageSize; - private final long expiry; - private final int status; - private final byte[] transactionId; - - public NotificationMmsMessageRecord(long id, Recipient conversationRecipient, - Recipient individualRecipient, - long dateSent, long dateReceived, int deliveryReceiptCount, - long threadId, byte[] contentLocation, long messageSize, - long expiry, int status, byte[] transactionId, long mailbox, - SlideDeck slideDeck, int readReceiptCount, boolean hasMention) - { - super(id, "", conversationRecipient, individualRecipient, - dateSent, dateReceived, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, - emptyList(), emptyList(), - 0, 0, slideDeck, readReceiptCount, null, emptyList(), emptyList(), false, emptyList(), hasMention); - - this.contentLocation = contentLocation; - this.messageSize = messageSize; - this.expiry = expiry; - this.status = status; - this.transactionId = transactionId; - } - - public byte[] getTransactionId() { - return transactionId; - } - public int getStatus() { - return this.status; - } - public byte[] getContentLocation() { - return contentLocation; - } - public long getMessageSize() { - return (messageSize + 1023) / 1024; - } - public long getExpiration() { - return expiry * 1000; - } - - @Override - public boolean isOutgoing() { - return false; - } - - @Override - public boolean isPending() { - return false; - } - - @Override - public boolean isMmsNotification() { - return true; - } - - @Override - public boolean isMediaPending() { - return true; - } - - @Override - public SpannableString getDisplayBody(@NonNull Context context) { - if (status == MmsDatabase.Status.DOWNLOAD_INITIALIZED) { - return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_multimedia_message)); - } else if (status == MmsDatabase.Status.DOWNLOAD_CONNECTING) { - return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_downloading_mms_message)); - } else { - return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_error_downloading_mms_message)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.kt new file mode 100644 index 0000000000..eb742cd6b1 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/NotificationMmsMessageRecord.kt @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Moxie Marlinspike + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.thoughtcrime.securesms.database.model + +import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.database.SmsDatabase +import org.thoughtcrime.securesms.mms.SlideDeck + +/** + * Represents the message record model for MMS messages that are + * notifications (ie: they're pointers to undownloaded media). + * + * @author Moxie Marlinspike + */ +class NotificationMmsMessageRecord( + id: Long, conversationRecipient: Recipient?, + individualRecipient: Recipient?, + dateSent: Long, + dateReceived: Long, + deliveryReceiptCount: Int, + threadId: Long, + private val messageSize: Long, + private val expiry: Long, + val status: Int, + mailbox: Long, + slideDeck: SlideDeck?, + readReceiptCount: Int, + hasMention: Boolean +) : MmsMessageRecord( + id, "", conversationRecipient, individualRecipient, + dateSent, dateReceived, threadId, SmsDatabase.Status.STATUS_NONE, deliveryReceiptCount, mailbox, + emptyList(), emptyList(), + 0, 0, slideDeck!!, readReceiptCount, null, emptyList(), emptyList(), false, emptyList(), hasMention +) { + fun getMessageSize(): Long { + return (messageSize + 1023) / 1024 + } + + val expiration: Long + get() = expiry * 1000 + + override fun isOutgoing(): Boolean { + return false + } + + override fun isPending(): Boolean { + return false + } + + override fun isMmsNotification(): Boolean { + return true + } + + override fun isMediaPending(): Boolean { + return true + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt index 7db87f17dc..68aea84417 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.res.Resources import android.graphics.Typeface import android.graphics.drawable.ColorDrawable -import android.text.SpannableString import android.text.TextUtils import android.util.AttributeSet import android.util.TypedValue @@ -23,7 +22,6 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.NOTIFY_TYPE_ALL import org.thoughtcrime.securesms.database.RecipientDatabase.NOTIFY_TYPE_NONE import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.dependencies.ConfigFactory -import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.getAccentColor import org.thoughtcrime.securesms.util.getConversationUnread @@ -51,7 +49,7 @@ class ConversationView : LinearLayout { // endregion // region Updating - fun bind(thread: ThreadRecord, isTyping: Boolean, glide: GlideRequests) { + fun bind(thread: ThreadRecord, isTyping: Boolean) { this.thread = thread if (thread.isPinned) { binding.conversationViewDisplayNameTextView.setCompoundDrawablesRelativeWithIntrinsicBounds( @@ -142,11 +140,10 @@ class ConversationView : LinearLayout { 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.getSnippet(): CharSequence = listOfNotNull( + getSnippetPrefix(), + getDisplayBody(context) + ).joinToString(": ") private fun ThreadRecord.getSnippetPrefix(): CharSequence? = when { recipient.isLocalNumber || lastMessage?.isControlMessage == true -> null diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index 322e041582..ee82a708c4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -8,7 +8,6 @@ import android.content.Context import android.content.Intent import android.os.Build import android.os.Bundle -import android.provider.Telephony.Mms.Addr import android.widget.Toast import androidx.activity.viewModels import androidx.core.os.bundleOf @@ -23,6 +22,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import network.loki.messenger.R @@ -59,6 +59,7 @@ import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.groups.OpenGroupManager import org.thoughtcrime.securesms.home.search.GlobalSearchAdapter import org.thoughtcrime.securesms.home.search.GlobalSearchInputLayout +import org.thoughtcrime.securesms.home.search.GlobalSearchResult import org.thoughtcrime.securesms.home.search.GlobalSearchViewModel import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity import org.thoughtcrime.securesms.mms.GlideApp @@ -85,6 +86,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), GlobalSearchInputLayout.GlobalSearchInputLayoutListener { companion object { + const val NEW_ACCOUNT = "HomeActivity_NEW_ACCOUNT" const val FROM_ONBOARDING = "HomeActivity_FROM_ONBOARDING" } @@ -135,6 +137,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), } } + private val isNewAccount: Boolean get() = intent.getBooleanExtra(FROM_ONBOARDING, false) + // region Lifecycle override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) { super.onCreate(savedInstanceState, isReady) @@ -175,7 +179,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), // Set up empty state view binding.emptyStateContainer.setThemedContent { - EmptyView(ApplicationContext.getInstance(this).newAccount) + EmptyView(isNewAccount) } IP2Country.configureIfNeeded(this@HomeActivity) @@ -240,67 +244,25 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), } // Get group results and display them launch { - globalSearchViewModel.result.collect { result -> - if (result.query.isEmpty()) { - class NamedValue(val name: String?, val value: T) - - // Unknown is temporarily to be grouped together with numbers title. - // https://optf.atlassian.net/browse/SES-2287 - val numbersTitle = "#" - val unknownTitle = numbersTitle - - listOf( - GlobalSearchAdapter.Model.Header(R.string.contacts), - GlobalSearchAdapter.Model.SavedMessages(publicKey) - ) + result.contacts - // Remove ourself, we're shown above. - .filter { it.accountID != publicKey } - // Get the name that we will display and sort by, and uppercase it to - // help with sorting and we need the char uppercased later. - .map { (it.nickname?.takeIf(String::isNotEmpty) ?: it.name?.takeIf(String::isNotEmpty)) - .let { name -> NamedValue(name?.uppercase(), it) } } - // Digits are all grouped under a #, the rest are grouped by their first character.uppercased() - // If there is no name, they go under Unknown - .groupBy { it.name?.run { first().takeUnless(Char::isDigit)?.toString() ?: numbersTitle } ?: unknownTitle } - // place the # at the end, after all the names starting with alphabetic chars - .toSortedMap(compareBy { - when (it) { - unknownTitle -> Char.MAX_VALUE - numbersTitle -> Char.MAX_VALUE - 1 - else -> it.first() - } - }) - // Flatten the map of char to lists into an actual List that can be displayed. - .flatMap { (key, contacts) -> - listOf( - GlobalSearchAdapter.Model.SubHeader(key) - ) + contacts.sortedBy { it.name ?: it.value.accountID }.map { it.value }.map { GlobalSearchAdapter.Model.Contact(it, it.accountID == publicKey) } + globalSearchViewModel.result.map { result -> + result.query to when { + result.query.isEmpty() -> buildList { + add(GlobalSearchAdapter.Model.Header(R.string.contacts)) + add(GlobalSearchAdapter.Model.SavedMessages(publicKey)) + addAll(result.groupedContacts) + } + else -> buildList { + result.contactAndGroupList.takeUnless { it.isEmpty() }?.let { + add(GlobalSearchAdapter.Model.Header(R.string.contacts)) + addAll(it) + } + result.messageResults.takeUnless { it.isEmpty() }?.let { + add(GlobalSearchAdapter.Model.Header(R.string.global_search_messages)) + addAll(it) } - } else { - val contactAndGroupList = result.contacts.map { GlobalSearchAdapter.Model.Contact(it, it.accountID == publicKey) } + - result.threads.map(GlobalSearchAdapter.Model::GroupConversation) - - val contactResults = contactAndGroupList.toMutableList() - - if (contactResults.isNotEmpty()) { - contactResults.add(0, GlobalSearchAdapter.Model.Header(R.string.conversations)) } - - val unreadThreadMap = result.messages - .map { it.threadId }.toSet() - .associateWith { mmsSmsDatabase.getUnreadCount(it) } - - val messageResults: MutableList = result.messages - .map { GlobalSearchAdapter.Model.Message(it, unreadThreadMap[it.threadId] ?: 0, it.conversationRecipient.isLocalNumber) } - .toMutableList() - - if (messageResults.isNotEmpty()) { - messageResults.add(0, GlobalSearchAdapter.Model.Header(R.string.global_search_messages)) - } - - contactResults + messageResults - }.let { globalSearchAdapter.setNewData(result.query, it) } - } + } + }.collectLatest(globalSearchAdapter::setNewData) } } EventBus.getDefault().register(this@HomeActivity) @@ -318,6 +280,54 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), } } + private val GlobalSearchResult.groupedContacts: List get() { + class NamedValue(val name: String?, val value: T) + + // Unknown is temporarily to be grouped together with numbers title. + // https://optf.atlassian.net/browse/SES-2287 + val numbersTitle = "#" + val unknownTitle = numbersTitle + + return contacts + // Remove ourself, we're shown above. + .filter { it.accountID != publicKey } + // Get the name that we will display and sort by, and uppercase it to + // help with sorting and we need the char uppercased later. + .map { (it.nickname?.takeIf(String::isNotEmpty) ?: it.name?.takeIf(String::isNotEmpty)) + .let { name -> NamedValue(name?.uppercase(), it) } } + // Digits are all grouped under a #, the rest are grouped by their first character.uppercased() + // If there is no name, they go under Unknown + .groupBy { it.name?.run { first().takeUnless(Char::isDigit)?.toString() ?: numbersTitle } ?: unknownTitle } + // place the # at the end, after all the names starting with alphabetic chars + .toSortedMap(compareBy { + when (it) { + unknownTitle -> Char.MAX_VALUE + numbersTitle -> Char.MAX_VALUE - 1 + else -> it.first() + } + }) + // Flatten the map of char to lists into an actual List that can be displayed. + .flatMap { (key, contacts) -> + listOf( + GlobalSearchAdapter.Model.SubHeader(key) + ) + contacts.sortedBy { it.name ?: it.value.accountID }.map { it.value }.map { GlobalSearchAdapter.Model.Contact(it, it.nickname ?: it.name, it.accountID == publicKey) } + } + } + + private val GlobalSearchResult.contactAndGroupList: List get() = + contacts.map { GlobalSearchAdapter.Model.Contact(it, it.nickname ?: it.name, it.accountID == publicKey) } + + threads.map(GlobalSearchAdapter.Model::GroupConversation) + + private val GlobalSearchResult.messageResults: List get() { + val unreadThreadMap = messages + .map { it.threadId }.toSet() + .associateWith { mmsSmsDatabase.getUnreadCount(it) } + + return messages.map { + GlobalSearchAdapter.Model.Message(it, unreadThreadMap[it.threadId] ?: 0, it.conversationRecipient.isLocalNumber) + } + } + override fun onInputFocusChanged(hasFocus: Boolean) { setSearchShown(hasFocus || binding.globalSearchInputLayout.query.value.isNotEmpty()) } @@ -629,9 +639,10 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), } } -fun Context.startHomeActivity() { +fun Context.startHomeActivity(isNewAccount: Boolean) { Intent(this, HomeActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + putExtra(HomeActivity.NEW_ACCOUNT, true) putExtra(HomeActivity.FROM_ONBOARDING, true) }.also(::startActivity) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt index 571adb7358..5410df9d47 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeAdapter.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.home import android.content.Context import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListUpdateCallback @@ -12,8 +11,6 @@ import network.loki.messenger.R import network.loki.messenger.databinding.ViewMessageRequestBannerBinding import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.mms.GlideRequests -import org.thoughtcrime.securesms.util.DateUtils -import java.util.Locale class HomeAdapter( private val context: Context, @@ -115,7 +112,7 @@ class HomeAdapter( val offset = if (hasHeaderView()) position - 1 else position val thread = data.threads[offset] val isTyping = data.typingThreadIDs.contains(thread.threadId) - holder.view.bind(thread, isTyping, glide) + holder.view.bind(thread, isTyping) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt index c7db4fc8b7..71c2c62506 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchAdapter.kt @@ -28,6 +28,8 @@ class GlobalSearchAdapter(private val modelCallback: (Model)->Unit): RecyclerVie private var data: List = listOf() private var query: String? = null + fun setNewData(data: Pair>) = setNewData(data.first, data.second) + fun setNewData(query: String, newData: List) { val diffResult = DiffUtil.calculateDiff(GlobalSearchDiff(this.query, query, data, newData)) this.query = query @@ -134,7 +136,7 @@ class GlobalSearchAdapter(private val modelCallback: (Model)->Unit): RecyclerVie constructor(title: String): this(GetString(title)) } data class SavedMessages(val currentUserPublicKey: String): Model() - data class Contact(val contact: ContactModel, val isSelf: Boolean): Model() + data class Contact(val contact: ContactModel, val name: String?, val isSelf: Boolean): Model() data class GroupConversation(val groupRecord: GroupRecord): Model() data class Message(val messageResult: MessageResult, val unread: Int, val isSelf: Boolean): Model() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt index b8b57ca1d2..fb4a61a558 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt @@ -6,22 +6,18 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.buffer -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.consumeAsFlow import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.merge -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.plus import org.session.libsignal.utilities.SettableFuture @@ -35,16 +31,32 @@ import javax.inject.Inject class GlobalSearchViewModel @Inject constructor( private val searchRepository: SearchRepository, ) : ViewModel() { - - private val executor = viewModelScope + SupervisorJob() - - private val _result: MutableStateFlow = MutableStateFlow(GlobalSearchResult.EMPTY) - - val result: StateFlow = _result - + private val scope = viewModelScope + SupervisorJob() private val refreshes = MutableSharedFlow() + private val _queryText = MutableStateFlow("") - private val _queryText: MutableStateFlow = MutableStateFlow("") + val result = _queryText + .reEmit(refreshes) + .buffer(onBufferOverflow = BufferOverflow.DROP_OLDEST) + .mapLatest { query -> + if (query.trim().isEmpty()) { + // searching for 05 as contactDb#getAllContacts was not returning contacts + // without a nickname/name who haven't approved us. + GlobalSearchResult(query.toString(), searchRepository.queryContacts("05").first.toList()) + } else { + // User input delay in case we get a new query within a few hundred ms this + // coroutine will be cancelled and the expensive query will not be run. + delay(300) + val settableFuture = SettableFuture() + searchRepository.query(query.toString(), settableFuture::set) + try { + // search repository doesn't play nicely with suspend functions (yet) + settableFuture.get(10_000, TimeUnit.MILLISECONDS).toGlobalSearchResult() + } catch (e: Exception) { + GlobalSearchResult(query.toString()) + } + } + } fun setQuery(charSequence: CharSequence) { _queryText.value = charSequence @@ -55,34 +67,6 @@ class GlobalSearchViewModel @Inject constructor( refreshes.emit(Unit) } } - - init { - _queryText - .reEmit(refreshes) - .buffer(onBufferOverflow = BufferOverflow.DROP_OLDEST) - .mapLatest { query -> - if (query.trim().isEmpty()) { - // searching for 05 as contactDb#getAllContacts was not returning contacts - // without a nickname/name who haven't approved us. - GlobalSearchResult(query.toString(), searchRepository.queryContacts("05").first.toList()) - } else { - // User input delay in case we get a new query within a few hundred ms this - // coroutine will be cancelled and the expensive query will not be run. - delay(300) - val settableFuture = SettableFuture() - searchRepository.query(query.toString(), settableFuture::set) - try { - // search repository doesn't play nicely with suspend functions (yet) - settableFuture.get(10_000, TimeUnit.MILLISECONDS).toGlobalSearchResult() - } catch (e: Exception) { - GlobalSearchResult(query.toString()) - } - } - }.onEach { result -> - // update the latest _result value - _result.value = result - }.launchIn(executor) - } } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestView.kt b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestView.kt index a916d8e4d6..6584f4e519 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestView.kt @@ -34,13 +34,13 @@ class MessageRequestView : LinearLayout { // region Updating fun bind(thread: ThreadRecord, glide: GlideRequests) { this.thread = thread - val senderDisplayName = getUserDisplayName(thread.recipient) - ?: thread.recipient.address.toString() + + val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString() + binding.displayNameTextView.text = senderDisplayName binding.timestampTextView.text = DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), thread.date) - val rawSnippet = thread.getDisplayBody(context) val snippet = highlightMentions( - text = rawSnippet, + text = thread.getDisplayBody(context), formatOnly = true, // no styling here, only text formatting threadID = thread.threadId, context = context diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java b/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java index f322d17091..2c92121cf2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/Slide.java @@ -16,24 +16,23 @@ */ package org.thoughtcrime.securesms.mms; +import static org.session.libsession.utilities.StringSubstitutionConstants.EMOJI_KEY; + import android.content.Context; import android.content.res.Resources.Theme; import android.net.Uri; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; -import org.thoughtcrime.securesms.util.MediaUtil; -import org.session.libsignal.utilities.guava.Optional; - +import com.squareup.phrase.Phrase; +import java.security.SecureRandom; +import network.loki.messenger.R; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; +import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment; import org.session.libsession.utilities.Util; - -import java.security.SecureRandom; - -import network.loki.messenger.R; +import org.session.libsignal.utilities.guava.Optional; +import org.thoughtcrime.securesms.util.MediaUtil; public abstract class Slide { @@ -72,20 +71,23 @@ public abstract class Slide { return Optional.fromNullable("🎤 " + attachmentString); } } - return Optional.fromNullable(emojiForMimeType() + attachmentString); + String txt = Phrase.from(context, R.string.attachmentsNotification) + .put(EMOJI_KEY, emojiForMimeType()) + .format().toString(); + return Optional.fromNullable(txt); } private String emojiForMimeType() { if (MediaUtil.isImage(attachment)) { - return "📷 "; + return "📷"; } else if (MediaUtil.isVideo(attachment)) { - return "🎥 "; + return "🎥"; } else if (MediaUtil.isAudio(attachment)) { - return "🎧 "; + return "🎧"; } else if (MediaUtil.isFile(attachment)) { - return "📎 "; + return "📎"; } else { - return "🎡 "; + return "🎡"; // `isGif` } } @@ -155,20 +157,20 @@ public abstract class Slide { return false; } - protected static Attachment constructAttachmentFromUri(@NonNull Context context, - @NonNull Uri uri, - @NonNull String defaultMime, - long size, - int width, - int height, - boolean hasThumbnail, - @Nullable String fileName, - @Nullable String caption, - boolean voiceNote, - boolean quote) + protected static Attachment constructAttachmentFromUri(@NonNull Context context, + @NonNull Uri uri, + @NonNull String defaultMime, + long size, + int width, + int height, + boolean hasThumbnail, + @Nullable String fileName, + @Nullable String caption, + boolean voiceNote, + boolean quote) { - String resolvedType = Optional.fromNullable(MediaUtil.getMimeType(context, uri)).or(defaultMime); - String fastPreflightId = String.valueOf(new SecureRandom().nextLong()); + String resolvedType = Optional.fromNullable(MediaUtil.getMimeType(context, uri)).or(defaultMime); + String fastPreflightId = String.valueOf(new SecureRandom().nextLong()); return new UriAttachment(uri, hasThumbnail ? uri : null, resolvedType, diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/SlideDeck.java b/app/src/main/java/org/thoughtcrime/securesms/mms/SlideDeck.java index 6db38e6bc5..ffe91704df 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/SlideDeck.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/SlideDeck.java @@ -24,6 +24,7 @@ import androidx.annotation.Nullable; import com.annimon.stream.Stream; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; +import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.guava.Optional; import org.thoughtcrime.securesms.util.MediaUtil; @@ -47,8 +48,7 @@ public class SlideDeck { if (slide != null) slides.add(slide); } - public SlideDeck() { - } + public SlideDeck() { } public void clear() { slides.clear(); @@ -65,7 +65,6 @@ public class SlideDeck { body = slideBody.get(); } } - return body; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 5abaee4033..e80c47a9f6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -29,6 +29,7 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.service.notification.StatusBarNotification; +import android.text.SpannableString; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -145,9 +146,8 @@ public class DefaultMessageNotifier implements MessageNotifier { } public void notifyMessagesPending(Context context) { - if (!TextSecurePreferences.isNotificationsEnabled(context)) { - return; - } + + if (!TextSecurePreferences.isNotificationsEnabled(context)) { return; } PendingMessageNotificationBuilder builder = new PendingMessageNotificationBuilder(context, TextSecurePreferences.getNotificationPrivacy(context)); ServiceUtil.getNotificationManager(context).notify(PENDING_MESSAGES_ID, builder.build()); @@ -185,9 +185,9 @@ public class DefaultMessageNotifier implements MessageNotifier { for (StatusBarNotification notification : activeNotifications) { boolean validNotification = false; - if (notification.getId() != SUMMARY_NOTIFICATION_ID && - notification.getId() != KeyCachingService.SERVICE_RUNNING_ID && - notification.getId() != FOREGROUND_ID && + if (notification.getId() != SUMMARY_NOTIFICATION_ID && + notification.getId() != KeyCachingService.SERVICE_RUNNING_ID && + notification.getId() != FOREGROUND_ID && notification.getId() != PENDING_MESSAGES_ID) { for (NotificationItem item : notificationState.getNotifications()) { @@ -197,9 +197,7 @@ public class DefaultMessageNotifier implements MessageNotifier { } } - if (!validNotification) { - notifications.cancel(notification.getId()); - } + if (!validNotification) { notifications.cancel(notification.getId()); } } } } catch (Throwable e) { @@ -231,7 +229,7 @@ public class DefaultMessageNotifier implements MessageNotifier { @Override public void updateNotification(@NonNull Context context, long threadId, boolean signal) { - boolean isVisible = visibleThread == threadId; + boolean isVisible = visibleThread == threadId; ThreadDatabase threads = DatabaseComponent.get(context).threadDatabase(); Recipient recipient = threads.getRecipientForThreadId(threadId); @@ -348,14 +346,19 @@ public class DefaultMessageNotifier implements MessageNotifier { builder.setThread(notifications.get(0).getRecipient()); builder.setMessageCount(notificationState.getMessageCount()); - // TODO: Removing highlighting mentions in the notification because this context is the libsession one which - // TODO: doesn't have access to the `R.attr.message_sent_text_color` and `R.attr.message_received_text_color` - // TODO: attributes to perform the colour lookup. Also, it makes little sense to highlight the mentions using - // TODO: the app theme as it may result in insufficient contrast with the notification background which will - // TODO: be using the SYSTEM theme. - builder.setPrimaryMessageBody(recipient, notifications.get(0).getIndividualRecipient(), - //MentionUtilities.highlightMentions(text == null ? "" : text, notifications.get(0).getThreadId(), context), // Removing hightlighting mentions -ACL - text == null ? "" : text, + CharSequence builderCS = text == null ? "" : text; + SpannableString ss = MentionUtilities.highlightMentions( + builderCS, + false, + false, + true, + bundled ? notifications.get(0).getThreadId() : 0, + context + ); + + builder.setPrimaryMessageBody(recipient, + notifications.get(0).getIndividualRecipient(), + ss, notifications.get(0).getSlideDeck()); builder.setContentIntent(notifications.get(0).getPendingIntent(context)); @@ -505,24 +508,39 @@ public class DefaultMessageNotifier implements MessageNotifier { continue; } } + + // If this is a message request from an unknown user.. if (messageRequest) { body = SpanUtil.italic(context.getString(R.string.message_requests_notification)); + + // If we received some manner of notification but Session is locked.. } else if (KeyCachingService.isLocked(context)) { body = SpanUtil.italic(context.getString(R.string.MessageNotifier_locked_message)); + + // ----- All further cases assume we know the contact and that Session isn't locked ----- + + // If this is a notification about a multimedia message from a contact we know about.. } else if (record.isMms() && !((MmsMessageRecord) record).getSharedContacts().isEmpty()) { Contact contact = ((MmsMessageRecord) record).getSharedContacts().get(0); body = ContactUtil.getStringSummary(context, contact); + + // If this is a notification about a multimedia message which contains no text but DOES contain a slide deck with at least one slide.. } else if (record.isMms() && TextUtils.isEmpty(body) && !((MmsMessageRecord) record).getSlideDeck().getSlides().isEmpty()) { slideDeck = ((MediaMmsMessageRecord)record).getSlideDeck(); body = SpanUtil.italic(slideDeck.getBody()); + + // If this is a notification about a multimedia message, but it's not ITSELF a multimedia notification AND it contains a slide deck with at least one slide.. } else if (record.isMms() && !record.isMmsNotification() && !((MmsMessageRecord) record).getSlideDeck().getSlides().isEmpty()) { slideDeck = ((MediaMmsMessageRecord)record).getSlideDeck(); String message = slideDeck.getBody() + ": " + record.getBody(); int italicLength = message.length() - body.length(); body = SpanUtil.italic(message, italicLength); + + // If this is a notification about an invitation to a community.. } else if (record.isOpenGroupInvitation()) { body = SpanUtil.italic(context.getString(R.string.ThreadRecord_open_group_invitation)); } + String userPublicKey = TextSecurePreferences.getLocalNumber(context); String blindedPublicKey = cache.get(threadId); if (blindedPublicKey == null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java index 4d32a8cda5..8db5f810b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java @@ -1,11 +1,9 @@ package org.thoughtcrime.securesms.notifications; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; - import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.dependencies.DatabaseComponent; diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt index db61cefd05..9c8a1869d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/LoadingActivity.kt @@ -8,7 +8,6 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import org.session.libsession.utilities.TextSecurePreferences -import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.BaseActionBarActivity import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.home.startHomeActivity @@ -33,7 +32,7 @@ class LoadingActivity: BaseActionBarActivity() { when { loadFailed -> startPickDisplayNameActivity(loadFailed = true) - else -> startHomeActivity() + else -> startHomeActivity(isNewAccount = false) } finish() @@ -44,8 +43,6 @@ class LoadingActivity: BaseActionBarActivity() { setUpActionBarSessionLogo() - ApplicationContext.getInstance(this).newAccount = false - setComposeContent { val progress by viewModel.progress.collectAsState() LoadingScreen(progress) diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotificationsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotificationsActivity.kt index fa23da8fb2..42cf49bce8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotificationsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotificationsActivity.kt @@ -49,7 +49,7 @@ class MessageNotificationsActivity : BaseActionBarActivity() { viewModel.events.collect { when (it) { Event.Loading -> start() - Event.OnboardingComplete -> startHomeActivity() + Event.OnboardingComplete -> startHomeActivity(isNewAccount = true) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameActivity.kt index 62f209454e..97aacf82e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameActivity.kt @@ -45,7 +45,7 @@ class PickDisplayNameActivity : BaseActionBarActivity() { viewModel.events.collect { when (it) { is Event.CreateAccount -> startMessageNotificationsActivity(it.profileName) - Event.LoadAccountComplete -> startHomeActivity() + Event.LoadAccountComplete -> startHomeActivity(isNewAccount = false) } } } @@ -72,8 +72,6 @@ class PickDisplayNameActivity : BaseActionBarActivity() { } fun Context.startPickDisplayNameActivity(loadFailed: Boolean = false, flags: Int = 0) { - ApplicationContext.getInstance(this).newAccount = !loadFailed - Intent(this, PickDisplayNameActivity::class.java) .apply { putExtra(EXTRA_LOAD_FAILED, loadFailed) } .also { it.flags = flags } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt index b1fb2ab56f..9778a1c8b8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt @@ -72,7 +72,7 @@ class QRCodeActivity : PassphraseRequiredActionBarActivity() { @OptIn(ExperimentalFoundationApi::class) @Composable -private fun Tabs(sessionId: String, errors: Flow, onScan: (String) -> Unit) { +private fun Tabs(accountId: String, errors: Flow, onScan: (String) -> Unit) { val pagerState = rememberPagerState { TITLES.size } Column { @@ -82,7 +82,7 @@ private fun Tabs(sessionId: String, errors: Flow, onScan: (String) -> Un modifier = Modifier.weight(1f) ) { page -> when (TITLES[page]) { - R.string.view -> QrPage(sessionId) + R.string.view -> QrPage(accountId) R.string.scan -> MaybeScanQrCode(errors, onScan = onScan) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt index 52f163ba0b..cfcb131882 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt @@ -35,9 +35,6 @@ import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.localbroadcastmanager.content.LocalBroadcastManager import dagger.hilt.android.AndroidEntryPoint -import java.io.File -import java.security.SecureRandom -import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow @@ -49,7 +46,6 @@ import network.loki.messenger.BuildConfig import network.loki.messenger.R import network.loki.messenger.databinding.ActivitySettingsBinding import network.loki.messenger.libsession_util.util.UserPic -import nl.komponents.kovenant.Promise import nl.komponents.kovenant.ui.alwaysUi import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi @@ -90,8 +86,12 @@ import org.thoughtcrime.securesms.ui.setThemedContent import org.thoughtcrime.securesms.util.BitmapDecodingException import org.thoughtcrime.securesms.util.BitmapUtil import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities +import org.thoughtcrime.securesms.util.NetworkUtils import org.thoughtcrime.securesms.util.push import org.thoughtcrime.securesms.util.show +import java.io.File +import java.security.SecureRandom +import javax.inject.Inject @AndroidEntryPoint class SettingsActivity : PassphraseRequiredActionBarActivity() { @@ -197,7 +197,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { try { val profilePictureToBeUploaded = BitmapUtil.createScaledBytes(this@SettingsActivity, AvatarSelection.getResultUri(data), ProfileMediaConstraints()).bitmap launch(Dispatchers.Main) { - updateProfile(true, profilePictureToBeUploaded) + updateProfilePicture(profilePictureToBeUploaded) } } catch (e: BitmapDecodingException) { Log.e(TAG, e) @@ -246,57 +246,60 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { } } - private fun updateProfile( - isUpdatingProfilePicture: Boolean, - profilePicture: ByteArray? = null, - displayName: String? = null - ) { + private fun updateDisplayName(displayName: String): Boolean { binding.loader.isVisible = true - if (displayName != null) { - TextSecurePreferences.setProfileName(this, displayName) - configFactory.user?.setName(displayName) - } + // We'll assume we fail & flip the flag on success + var updateWasSuccessful = false - // Bail if we're not updating the profile picture in any way - if (!isUpdatingProfilePicture) return - - val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this) - - val uploadProfilePicturePromise: Promise<*, Exception> - var removingProfilePic = false - - // Adding a new profile picture? - if (profilePicture != null) { - uploadProfilePicturePromise = ProfilePictureUtilities.upload(profilePicture, encodedProfileKey, this) + val haveNetworkConnection = NetworkUtils.haveValidNetworkConnection(this@SettingsActivity); + if (!haveNetworkConnection) { + Log.w(TAG, "Cannot update display name - no network connection.") } else { - // If not then we must be removing the existing one. - // Note: To get a promise that will resolve / sync correctly we overwrite the existing profile picture with - // a 0 byte image. - removingProfilePic = true - val emptyByteArray = ByteArray(0) - uploadProfilePicturePromise = ProfilePictureUtilities.upload(emptyByteArray, encodedProfileKey, this) + // if we have a network connection then attempt to update the display name + TextSecurePreferences.setProfileName(this, displayName) + val user = configFactory.user + if (user == null) { + Log.w(TAG, "Cannot update display name - missing user details from configFactory.") + } else { + user.setName(displayName) + binding.btnGroupNameDisplay.text = displayName + updateWasSuccessful = true + } } - // If the upload picture promise succeeded then we hit this successUi block - uploadProfilePicturePromise.successUi { + // Inform the user if we failed to update the display name + if (!updateWasSuccessful) { + Toast.makeText(this@SettingsActivity, R.string.profileErrorUpdate, Toast.LENGTH_LONG).show() + } - // If we successfully removed the profile picture on the network then we can clear the - // local data - otherwise it's weird to fail the online section but it _looks_ like it - // worked because we cleared the local image (also it denies them the chance to retry - // removal if we do it locally, and may result in them having a visible profile picture - // everywhere EXCEPT on their own device!). - if (removingProfilePic) { + binding.loader.isVisible = false + return updateWasSuccessful + } + + // Helper method used by updateProfilePicture and removeProfilePicture to sync it online + private fun syncProfilePicture(profilePicture: ByteArray, onFail: () -> Unit) { + binding.loader.isVisible = true + + // Grab the profile key and kick of the promise to update the profile picture + val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this) + val updateProfilePicturePromise = ProfilePictureUtilities.upload(profilePicture, encodedProfileKey, this) + + // If the online portion of the update succeeded then update the local state + updateProfilePicturePromise.successUi { + + // When removing the profile picture the supplied ByteArray is empty so we'll clear the local data + if (profilePicture.isEmpty()) { MessagingModuleConfiguration.shared.storage.clearUserPic() } val userConfig = configFactory.user AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture) - prefs.setProfileAvatarId(profilePicture?.let { SecureRandom().nextInt() } ?: 0 ) - + prefs.setProfileAvatarId(SecureRandom().nextInt() ) ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey) - // new config - val url = TextSecurePreferences.getProfilePictureURL(this) + + // Attempt to grab the details we require to update the profile picture + val url = prefs.getProfilePictureURL() val profileKey = ProfileKeyUtil.getProfileKey(this) // If we have a URL and a profile key then set the user's profile picture @@ -309,30 +312,52 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { } ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@SettingsActivity) + + // Update our visuals + binding.profilePictureView.recycle() + binding.profilePictureView.update() } - // Or if the promise failed to upload the new profile picture then we hit this failUi block - uploadProfilePicturePromise.failUi { - if (removingProfilePic) { - Log.e(TAG, "Failed to remove profile picture") - Toast.makeText(this@SettingsActivity, R.string.profileDisplayPictureRemoveError, Toast.LENGTH_LONG).show() - } else { - Log.e(TAG, "Failed to upload profile picture") - Toast.makeText(this@SettingsActivity, R.string.profileErrorUpdate, Toast.LENGTH_LONG).show() - } + // If the sync failed then inform the user + updateProfilePicturePromise.failUi { onFail() } + + // Finally, remove the loader animation after we've waited for the attempt to succeed or fail + updateProfilePicturePromise.alwaysUi { binding.loader.isVisible = false } + } + + private fun updateProfilePicture(profilePicture: ByteArray) { + + val haveNetworkConnection = NetworkUtils.haveValidNetworkConnection(this@SettingsActivity); + if (!haveNetworkConnection) { + Log.w(TAG, "Cannot update profile picture - no network connection.") + Toast.makeText(this@SettingsActivity, R.string.profileErrorUpdate, Toast.LENGTH_LONG).show() + return } - // Finally, regardless of whether the promise succeeded or failed, we always hit this `alwaysUi` block - uploadProfilePicturePromise.alwaysUi { - if (displayName != null) { - binding.btnGroupNameDisplay.text = displayName - } - if (isUpdatingProfilePicture) { - binding.profilePictureView.recycle() // Clear the cached image before updating - binding.profilePictureView.update() - } - binding.loader.isVisible = false + val onFail: () -> Unit = { + Log.e(TAG, "Sync failed when uploading profile picture.") + Toast.makeText(this@SettingsActivity, R.string.profileErrorUpdate, Toast.LENGTH_LONG).show() } + + syncProfilePicture(profilePicture, onFail) + } + + private fun removeProfilePicture() { + + val haveNetworkConnection = NetworkUtils.haveValidNetworkConnection(this@SettingsActivity); + if (!haveNetworkConnection) { + Log.w(TAG, "Cannot remove profile picture - no network connection.") + Toast.makeText(this@SettingsActivity, R.string.profileDisplayPictureRemoveError, Toast.LENGTH_LONG).show() + return + } + + val onFail: () -> Unit = { + Log.e(TAG, "Sync failed when removing profile picture.") + Toast.makeText(this@SettingsActivity, R.string.profileDisplayPictureRemoveError, Toast.LENGTH_LONG).show() + } + + val emptyProfilePicture = ByteArray(0) + syncProfilePicture(emptyProfilePicture, onFail) } // endregion @@ -351,8 +376,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { Toast.makeText(this, R.string.activity_settings_display_name_too_long_error, Toast.LENGTH_SHORT).show() return false } - updateProfile(false, displayName = displayName) - return true + return updateDisplayName(displayName) } private fun showEditProfilePictureUI() { @@ -361,7 +385,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { view(R.layout.dialog_change_avatar) button(R.string.activity_settings_upload) { startAvatarSelection() } if (prefs.getProfileAvatarId() != 0) { - button(R.string.activity_settings_remove) { removeAvatar() } + button(R.string.activity_settings_remove) { removeProfilePicture() } } cancelButton() }.apply { @@ -379,10 +403,6 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { } } - private fun removeAvatar() { - updateProfile(true) - } - private fun startAvatarSelection() { // Ask for an optional camera permission. Permissions.with(this) diff --git a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt index 5389180995..2a00440dda 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/repository/ConversationRepository.kt @@ -293,7 +293,7 @@ class DefaultConversationRepository @Inject constructor( override suspend fun banAndDeleteAll(threadId: Long, recipient: Recipient): ResultOf = suspendCoroutine { continuation -> - // Note: This sessionId could be the blinded Id + // Note: This accountId could be the blinded Id val accountID = recipient.address.toString() val openGroup = lokiThreadDb.getOpenGroupChat(threadId)!! diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index 18127b0040..d6383ab7fc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -92,8 +92,8 @@ class ProfileManager(private val context: Context, private val configFactory: Co override fun contactUpdatedInternal(contact: Contact): String? { val contactConfig = configFactory.contacts ?: return null if (contact.accountID == TextSecurePreferences.getLocalNumber(context)) return null - val sessionId = AccountId(contact.accountID) - if (sessionId.prefix != IdPrefix.STANDARD) return null // only internally store standard session IDs + val accountId = AccountId(contact.accountID) + if (accountId.prefix != IdPrefix.STANDARD) return null // only internally store standard account IDs contactConfig.upsertContact(contact.accountID) { this.name = contact.name.orEmpty() this.nickname = contact.nickname.orEmpty() diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt index f9fa54f916..e59d3aae17 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConfigurationMessageUtilities.kt @@ -205,7 +205,7 @@ object ConfigurationMessageUtilities { val admins = group.admins.map { it.serialize() to true }.toMap() val members = group.members.filterNot { it.serialize() !in admins.keys }.map { it.serialize() to false }.toMap() GroupInfo.LegacyGroupInfo( - sessionId = groupPublicKey, + accountId = groupPublicKey, name = group.title, members = admins + members, priority = if (isPinned) ConfigBase.PRIORITY_PINNED else ConfigBase.PRIORITY_VISIBLE, diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml index 3f8df83471..c4b3afcdac 100644 --- a/app/src/main/res/values-ar-rSA/strings.xml +++ b/app/src/main/res/values-ar-rSA/strings.xml @@ -186,9 +186,6 @@ أختر الكل جارٍ جمع المرفقات... - رسالة وسائط متعددة - تنزيل رسالة الوسائط المتعددة - خطأ في تنزيل رسالة الوسائط المتعددة، انقر لاعادة المحاولة إرسال إلى %s diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 3f8df83471..c4b3afcdac 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -186,9 +186,6 @@ أختر الكل جارٍ جمع المرفقات... - رسالة وسائط متعددة - تنزيل رسالة الوسائط المتعددة - خطأ في تنزيل رسالة الوسائط المتعددة، انقر لاعادة المحاولة إرسال إلى %s diff --git a/app/src/main/res/values-az-rAZ/strings.xml b/app/src/main/res/values-az-rAZ/strings.xml index 12c4edcb42..b516b4d482 100644 --- a/app/src/main/res/values-az-rAZ/strings.xml +++ b/app/src/main/res/values-az-rAZ/strings.xml @@ -150,9 +150,6 @@ Hamısını seç Qoşmalar yığılır... - Multimedia mesajı - MMS mesaj endirilir - MMS mesajı endirmə xətası, yenidən sınamaq üçün toxunun %s - göndər diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 426cf4131d..e88cabda44 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -150,9 +150,6 @@ Hamısını seç Qoşmalar yığılır... - Multimedia mesajı - MMS mesaj endirilir - MMS mesajı endirmə xətası, yenidən sınamaq üçün toxunun %s - göndər diff --git a/app/src/main/res/values-bal-rBA/strings.xml b/app/src/main/res/values-bal-rBA/strings.xml index 6178303af8..f47408b9a6 100644 --- a/app/src/main/res/values-bal-rBA/strings.xml +++ b/app/src/main/res/values-bal-rBA/strings.xml @@ -96,9 +96,6 @@ Pilih semua Mengumpulkan lampiran... - Pesan multimedia - Mengunduh pesan MMS. - Gagal saat mengunduh pesan MMS, ketuk untuk mencoba lagi Kirim ke %s diff --git a/app/src/main/res/values-bal/strings.xml b/app/src/main/res/values-bal/strings.xml index 6178303af8..f47408b9a6 100644 --- a/app/src/main/res/values-bal/strings.xml +++ b/app/src/main/res/values-bal/strings.xml @@ -96,9 +96,6 @@ Pilih semua Mengumpulkan lampiran... - Pesan multimedia - Mengunduh pesan MMS. - Gagal saat mengunduh pesan MMS, ketuk untuk mencoba lagi Kirim ke %s diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 04ae82886f..4d1fa98314 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -142,9 +142,6 @@ Избери всичко Събиране на прикачени файлове... - Мултимедийно съобщение - Изтегляне на MMS съобщение - Грешка при изтегляне на MMS съобщение, натиснете за да опитате повторно Изпрати на %s diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 04ae82886f..4d1fa98314 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -142,9 +142,6 @@ Избери всичко Събиране на прикачени файлове... - Мултимедийно съобщение - Изтегляне на MMS съобщение - Грешка при изтегляне на MMS съобщение, натиснете за да опитате повторно Изпрати на %s diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index f9ba1e4b5a..46d156a746 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -147,9 +147,6 @@ Selecciona-ho tot S\'estan adjuntant els fitxers... - Missatge multimèdia - S\'està baixant el missatge MMS - S\'ha produït un error en baixar el missatge MMS. Toqueu per tornar a intentar-ho Envia-ho a %s diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index f9ba1e4b5a..46d156a746 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -147,9 +147,6 @@ Selecciona-ho tot S\'estan adjuntant els fitxers... - Missatge multimèdia - S\'està baixant el missatge MMS - S\'ha produït un error en baixar el missatge MMS. Toqueu per tornar a intentar-ho Envia-ho a %s diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 6cdcfa3344..1f3d993aa3 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -168,9 +168,6 @@ Označit vše Shromažďuji přílohy... - Multimediální zpráva - Stahuji MMS zprávu - Chyba při stahování MMS zprávy, ťukněte pro opakování Poslat %s diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 6cdcfa3344..1f3d993aa3 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -168,9 +168,6 @@ Označit vše Shromažďuji přílohy... - Multimediální zpráva - Stahuji MMS zprávu - Chyba při stahování MMS zprávy, ťukněte pro opakování Poslat %s diff --git a/app/src/main/res/values-cy-rGB/strings.xml b/app/src/main/res/values-cy-rGB/strings.xml index b481439583..6c3b42cfdb 100644 --- a/app/src/main/res/values-cy-rGB/strings.xml +++ b/app/src/main/res/values-cy-rGB/strings.xml @@ -172,9 +172,6 @@ Dewis popeth Casglu atodiadau... - Neges amlgyfrwng - Llwytho i lawr neges MMS - Gwall wrth lawrlwytho neges MMS, tapio i geisio eto Anfon i %s diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index b481439583..6c3b42cfdb 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -172,9 +172,6 @@ Dewis popeth Casglu atodiadau... - Neges amlgyfrwng - Llwytho i lawr neges MMS - Gwall wrth lawrlwytho neges MMS, tapio i geisio eto Anfon i %s diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml index 7d1bc12ef4..7cfd927873 100644 --- a/app/src/main/res/values-da-rDK/strings.xml +++ b/app/src/main/res/values-da-rDK/strings.xml @@ -150,9 +150,6 @@ Vælg alle Samler vedhæftninger... - Multimedie besked - Downloader MMS... - MMS besked kunne ikke downloades, tap for at prøve igen Send til %s diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 7d1bc12ef4..7cfd927873 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -150,9 +150,6 @@ Vælg alle Samler vedhæftninger... - Multimedie besked - Downloader MMS... - MMS besked kunne ikke downloades, tap for at prøve igen Send til %s diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 9f624b99a6..32920f29e4 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -150,9 +150,6 @@ Alle auswählen Anhänge werden gesammelt … - MMS - MMS wird heruntergeladen … - Fehler beim Herunterladen der MMS. Für erneuten Versuch antippen. An %s senden @@ -569,7 +566,7 @@ Scannen Sie den QR-Code eines Benutzers, um eine Session zu starten. QR-Codes finden Sie, indem Sie in den Einstellungen auf das QR-Code-Symbol tippen. Sitzungs-ID oder ONS-Name eingeben Benutzer können ihre Account ID freigeben, indem sie in ihren Einstellungen auf \"Account ID freigeben\" tippen oder ihren QR-Code freigeben. - Bitte überprüfe die Session-ID oder den ONS-Namen und versuche es erneut. + Bitte überprüfe die Account-ID oder den ONS-Namen und versuche es erneut. Session benötigt Kamerazugriff, um die QR-Codes scannen zu können. Kamerazugriff gewähren Neue geschlossene Gruppe @@ -641,7 +638,7 @@ Tag Nacht Systemstandard - Session-ID kopieren + Account-ID kopieren Anhang Sprachnachricht Details diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9f624b99a6..32920f29e4 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -150,9 +150,6 @@ Alle auswählen Anhänge werden gesammelt … - MMS - MMS wird heruntergeladen … - Fehler beim Herunterladen der MMS. Für erneuten Versuch antippen. An %s senden @@ -569,7 +566,7 @@ Scannen Sie den QR-Code eines Benutzers, um eine Session zu starten. QR-Codes finden Sie, indem Sie in den Einstellungen auf das QR-Code-Symbol tippen. Sitzungs-ID oder ONS-Name eingeben Benutzer können ihre Account ID freigeben, indem sie in ihren Einstellungen auf \"Account ID freigeben\" tippen oder ihren QR-Code freigeben. - Bitte überprüfe die Session-ID oder den ONS-Namen und versuche es erneut. + Bitte überprüfe die Account-ID oder den ONS-Namen und versuche es erneut. Session benötigt Kamerazugriff, um die QR-Codes scannen zu können. Kamerazugriff gewähren Neue geschlossene Gruppe @@ -641,7 +638,7 @@ Tag Nacht Systemstandard - Session-ID kopieren + Account-ID kopieren Anhang Sprachnachricht Details diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index 0159f2f3bf..5daadded79 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -150,9 +150,6 @@ Επιλογή όλων Τα συνημμένα συλλέγονται... - Μήνυμα πολυμέσων - Το μήνυμα MMS λαμβάνεται - Πρόβλημα κατά τη λήψη μηνύματος MMS, πατήστε για να ξαναδοκιμάσουμε Αποστολή σε %s diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 0159f2f3bf..5daadded79 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -150,9 +150,6 @@ Επιλογή όλων Τα συνημμένα συλλέγονται... - Μήνυμα πολυμέσων - Το μήνυμα MMS λαμβάνεται - Πρόβλημα κατά τη λήψη μηνύματος MMS, πατήστε για να ξαναδοκιμάσουμε Αποστολή σε %s diff --git a/app/src/main/res/values-eo-rUY/strings.xml b/app/src/main/res/values-eo-rUY/strings.xml index 5e0300dc88..66e6b6198c 100644 --- a/app/src/main/res/values-eo-rUY/strings.xml +++ b/app/src/main/res/values-eo-rUY/strings.xml @@ -150,9 +150,6 @@ Elekti ĉiujn Kolekto de kunsendaĵoj... - Aŭdvida mesaĝo - Elŝutante MMS-mesaĝon - Eraro dum elŝuto de MMS-mesaĝo, tuŝetu por reprovi Sendi al %s diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 5e0300dc88..66e6b6198c 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -150,9 +150,6 @@ Elekti ĉiujn Kolekto de kunsendaĵoj... - Aŭdvida mesaĝo - Elŝutante MMS-mesaĝon - Eraro dum elŝuto de MMS-mesaĝo, tuŝetu por reprovi Sendi al %s diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 7f7de554bc..3a0304d9f6 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -150,9 +150,6 @@ Seleccionar todo Recopilando adjuntos ... - Mensaje multimedia - Descargando mensaje MMS - Fallo al descargar mensaje MMS, toca para reintentar Enviar a %s diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 7f7de554bc..3a0304d9f6 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -150,9 +150,6 @@ Seleccionar todo Recopilando adjuntos ... - Mensaje multimedia - Descargando mensaje MMS - Fallo al descargar mensaje MMS, toca para reintentar Enviar a %s diff --git a/app/src/main/res/values-et-rEE/strings.xml b/app/src/main/res/values-et-rEE/strings.xml index eedb1e79d6..0fda309718 100644 --- a/app/src/main/res/values-et-rEE/strings.xml +++ b/app/src/main/res/values-et-rEE/strings.xml @@ -134,9 +134,6 @@ Vali kõik Kogun manuseid... - Multimeediasõnum - Laadin alla MMS-sõnumit - MMS-sõnumi allalaadimisel tekkis viga, koputa uuesti proovimiseks Saada kohta %s diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index eedb1e79d6..0fda309718 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -134,9 +134,6 @@ Vali kõik Kogun manuseid... - Multimeediasõnum - Laadin alla MMS-sõnumit - MMS-sõnumi allalaadimisel tekkis viga, koputa uuesti proovimiseks Saada kohta %s diff --git a/app/src/main/res/values-fa-rIR/strings.xml b/app/src/main/res/values-fa-rIR/strings.xml index 788062f67d..d46e3eb821 100644 --- a/app/src/main/res/values-fa-rIR/strings.xml +++ b/app/src/main/res/values-fa-rIR/strings.xml @@ -156,9 +156,6 @@ انتخاب همه در حال جمع‌آوری پیوست‌ها... - پیام های چند رسانه ای - در حال بارگیری پیام چندرسانه‌ای... - بروز مشکل در دانلود پیام MMS، جهت تلاش دوباره تپ کنید ارسال به %s diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 6207ab0fb5..82183872e8 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -150,9 +150,6 @@ انتخاب همه در حال جمع‌آوری پیوست‌ها... - پیام های چند رسانه ای - در حال بارگیری پیام چندرسانه‌ای... - بروز مشکل در دانلود پیام MMS، جهت تلاش دوباره تپ کنید ارسال به %s diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index d8a6123a91..45818d27f2 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -150,9 +150,6 @@ Valitse kaikki Kerätään liitetiedostoja... - Multimediaviesti - Ladataan MMS-viestiä - Virhe ladattaessa MMS-viestiä. Yritä uudelleen napauttamalla. Lähetä yhteystiedolle %s diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index d8a6123a91..45818d27f2 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -150,9 +150,6 @@ Valitse kaikki Kerätään liitetiedostoja... - Multimediaviesti - Ladataan MMS-viestiä - Virhe ladattaessa MMS-viestiä. Yritä uudelleen napauttamalla. Lähetä yhteystiedolle %s diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 7288b145a4..5513aa6619 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -157,9 +157,6 @@ Tout sélectionner Récupération des pièces jointes… - Message multimédia - Téléchargement du message multimédia - Erreur de téléchargement du message multimédia. Touchez pour ressayer Envoyer à %s diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 7288b145a4..5513aa6619 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -157,9 +157,6 @@ Tout sélectionner Récupération des pièces jointes… - Message multimédia - Téléchargement du message multimédia - Erreur de téléchargement du message multimédia. Touchez pour ressayer Envoyer à %s diff --git a/app/src/main/res/values-gl-rES/strings.xml b/app/src/main/res/values-gl-rES/strings.xml index 880020f8d1..7073bf4316 100644 --- a/app/src/main/res/values-gl-rES/strings.xml +++ b/app/src/main/res/values-gl-rES/strings.xml @@ -149,9 +149,6 @@ Seleccionar todo Recompilando anexos... - Mensaxe multimedia - Descargando mensaxe MMS - Erro ao descargar a mensaxe MMS, toca para volver tentar Enviar a %s diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 880020f8d1..7073bf4316 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -149,9 +149,6 @@ Seleccionar todo Recompilando anexos... - Mensaxe multimedia - Descargando mensaxe MMS - Erro ao descargar a mensaxe MMS, toca para volver tentar Enviar a %s diff --git a/app/src/main/res/values-ha-rHG/strings.xml b/app/src/main/res/values-ha-rHG/strings.xml index 9bdf7796bc..574699ae38 100644 --- a/app/src/main/res/values-ha-rHG/strings.xml +++ b/app/src/main/res/values-ha-rHG/strings.xml @@ -134,9 +134,6 @@ Gişan bibijêre ...Servehî tên berhevkirin - Peyama multîmedyayê - Peyama MMS tê daxistin - Peyama MMSê nehate daxistin, ji bo dîsa hewldanê bitepîne Ji %s re bişîne diff --git a/app/src/main/res/values-ha/strings.xml b/app/src/main/res/values-ha/strings.xml index 9bdf7796bc..574699ae38 100644 --- a/app/src/main/res/values-ha/strings.xml +++ b/app/src/main/res/values-ha/strings.xml @@ -134,9 +134,6 @@ Gişan bibijêre ...Servehî tên berhevkirin - Peyama multîmedyayê - Peyama MMS tê daxistin - Peyama MMSê nehate daxistin, ji bo dîsa hewldanê bitepîne Ji %s re bişîne diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index 1e58bc0b79..308874646c 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -150,9 +150,6 @@ सभी को चुन लो स` अटैचमेंट्स इकट्ठे कर रहे हैं... - मल्टीमीडिया संदेश - एमएमएस संदेश डाउनलोड किया जा रहा है - एमएमएस संदेश डाउनलोड करने में त्रुटि, पुनः प्रयास करने के लिए टैप करें %s को भेजें diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 1e58bc0b79..308874646c 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -150,9 +150,6 @@ सभी को चुन लो स` अटैचमेंट्स इकट्ठे कर रहे हैं... - मल्टीमीडिया संदेश - एमएमएस संदेश डाउनलोड किया जा रहा है - एमएमएस संदेश डाउनलोड करने में त्रुटि, पुनः प्रयास करने के लिए टैप करें %s को भेजें diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index d3729c783c..8e5c653181 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -151,9 +151,6 @@ Összes kiválasztása Mellékletek összegyűjtése... - Multimédia üzenet - MMS üzenet letöltése - Hiba történt az MMS üzenet letöltése során, koppints az újrapróbálkozáshoz Küldés neki: %s diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index d3729c783c..8e5c653181 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -151,9 +151,6 @@ Összes kiválasztása Mellékletek összegyűjtése... - Multimédia üzenet - MMS üzenet letöltése - Hiba történt az MMS üzenet letöltése során, koppints az újrapróbálkozáshoz Küldés neki: %s diff --git a/app/src/main/res/values-hy-rAM/strings.xml b/app/src/main/res/values-hy-rAM/strings.xml index c368215fae..14731ac6df 100644 --- a/app/src/main/res/values-hy-rAM/strings.xml +++ b/app/src/main/res/values-hy-rAM/strings.xml @@ -155,9 +155,6 @@ Ընտրել բոլորը Կցորդների հավաքում... - Մուլտիմեդիա հաղորդագրություններ - Ներբեռնում է MMS հաղորդագրությունը - Խնդիր առաջացավ MMS հաղորդագրությունը ներբեռնելիս, սեղմեք կրկին փորձելու համար Ուղարկել %s֊ին diff --git a/app/src/main/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml index c368215fae..14731ac6df 100644 --- a/app/src/main/res/values-hy/strings.xml +++ b/app/src/main/res/values-hy/strings.xml @@ -155,9 +155,6 @@ Ընտրել բոլորը Կցորդների հավաքում... - Մուլտիմեդիա հաղորդագրություններ - Ներբեռնում է MMS հաղորդագրությունը - Խնդիր առաջացավ MMS հաղորդագրությունը ներբեռնելիս, սեղմեք կրկին փորձելու համար Ուղարկել %s֊ին diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml index b17a48d257..d0b0ee6954 100644 --- a/app/src/main/res/values-in-rID/strings.xml +++ b/app/src/main/res/values-in-rID/strings.xml @@ -126,9 +126,6 @@ Pilih semua Mengumpulkan semua lampiran... - Pesan Multimedia - Mengunduh pesan MMS - Gagal mengunduh pesan MMS, sentuh untuk coba kembali Kirim ke %s diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 14dbe46ecb..354449c9e1 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -126,9 +126,6 @@ Pilih semua Mengumpulkan semua lampiran... - Pesan Multimedia - Mengunduh pesan MMS - Gagal mengunduh pesan MMS, sentuh untuk coba kembali Kirim ke %s diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 63e09d830a..754f633b38 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -151,9 +151,6 @@ Seleziona tutto Recupero allegati... - Messaggio multimediale - Scarico MMS - Errore nello scaricare MMS, premi per riprovare Invia a %s diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 63e09d830a..754f633b38 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -151,9 +151,6 @@ Seleziona tutto Recupero allegati... - Messaggio multimediale - Scarico MMS - Errore nello scaricare MMS, premi per riprovare Invia a %s diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index 3b5bd5dc3a..8227c8684d 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -166,9 +166,6 @@ בחר הכל אוסף צרופות... - הודעת מולטימדיה - מוריד הודעת MMS - שגיאה בהורדת הודעת MMS, הקש כדי לנסות שוב שלח אל %s diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 3b5bd5dc3a..8227c8684d 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -166,9 +166,6 @@ בחר הכל אוסף צרופות... - הודעת מולטימדיה - מוריד הודעת MMS - שגיאה בהורדת הודעת MMS, הקש כדי לנסות שוב שלח אל %s diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 2cfd354ef9..f5c5928b40 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -140,9 +140,6 @@ すべて選択 添付ファイルを集めています... - マルチメディアメッセージ - MMSメッセージをダウンロード中 - MMSメッセージのダウンロード中にエラーが発生しました。タップして再試行してください。 %sに送信 diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 2cfd354ef9..f5c5928b40 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -140,9 +140,6 @@ すべて選択 添付ファイルを集めています... - マルチメディアメッセージ - MMSメッセージをダウンロード中 - MMSメッセージのダウンロード中にエラーが発生しました。タップして再試行してください。 %sに送信 diff --git a/app/src/main/res/values-km-rKH/strings.xml b/app/src/main/res/values-km-rKH/strings.xml index de0e3b6fab..6397c24266 100644 --- a/app/src/main/res/values-km-rKH/strings.xml +++ b/app/src/main/res/values-km-rKH/strings.xml @@ -127,9 +127,6 @@ ជ្រើសរើសទាំងអស់ កំពុងប្រមូលឯកសារភ្ជាប់... - សារចម្រុះ - កំពុងទាញយកសារ MMS - មានបញ្ហាទាញយកសារMMS សូមចុច ដើម្បីព្យាយាមម្តងទៀត ផ្ញើទៅកាន់ %s diff --git a/app/src/main/res/values-km/strings.xml b/app/src/main/res/values-km/strings.xml index de0e3b6fab..6397c24266 100644 --- a/app/src/main/res/values-km/strings.xml +++ b/app/src/main/res/values-km/strings.xml @@ -127,9 +127,6 @@ ជ្រើសរើសទាំងអស់ កំពុងប្រមូលឯកសារភ្ជាប់... - សារចម្រុះ - កំពុងទាញយកសារ MMS - មានបញ្ហាទាញយកសារMMS សូមចុច ដើម្បីព្យាយាមម្តងទៀត ផ្ញើទៅកាន់ %s diff --git a/app/src/main/res/values-kn-rIN/strings.xml b/app/src/main/res/values-kn-rIN/strings.xml index 086fe16e3b..3fddf94bc5 100644 --- a/app/src/main/res/values-kn-rIN/strings.xml +++ b/app/src/main/res/values-kn-rIN/strings.xml @@ -75,7 +75,6 @@ ದಾಖಲೆಗಳು ಎಲ್ಲ ಆಯ್ದುಕೊಳ್ಳಿ - ಮಲ್ಟಿಮೀಡಿಯಾ ಸಂದೇಶ diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml index 086fe16e3b..3fddf94bc5 100644 --- a/app/src/main/res/values-kn/strings.xml +++ b/app/src/main/res/values-kn/strings.xml @@ -75,7 +75,6 @@ ದಾಖಲೆಗಳು ಎಲ್ಲ ಆಯ್ದುಕೊಳ್ಳಿ - ಮಲ್ಟಿಮೀಡಿಯಾ ಸಂದೇಶ diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index dfe0fcec29..8562708de1 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -136,9 +136,6 @@ 모두 선택 첨부파일 저장 준비 중… - 멀티미디어 메시지 - MMS 메시지 내려 받는 중 - MMS 내려 받기 오류, 다시 보내려면 다시 시도를 눌러주세요. %s에게 전송 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index dfe0fcec29..8562708de1 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -136,9 +136,6 @@ 모두 선택 첨부파일 저장 준비 중… - 멀티미디어 메시지 - MMS 메시지 내려 받는 중 - MMS 내려 받기 오류, 다시 보내려면 다시 시도를 눌러주세요. %s에게 전송 diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index 8707529591..353f11156f 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -166,9 +166,6 @@ Žymėti visus Renkami priedai... - Multimedijos žinutė - Atsiunčiama MMS žinutė - Klaida, atsiunčiant MMS žinutę, bakstelėkite, norėdami bandyti dar kartą Siųsti adresatui %s diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 8707529591..353f11156f 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -166,9 +166,6 @@ Žymėti visus Renkami priedai... - Multimedijos žinutė - Atsiunčiama MMS žinutė - Klaida, atsiunčiant MMS žinutę, bakstelėkite, norėdami bandyti dar kartą Siųsti adresatui %s diff --git a/app/src/main/res/values-mk-rMK/strings.xml b/app/src/main/res/values-mk-rMK/strings.xml index ceafb0d0be..49715b2e5a 100644 --- a/app/src/main/res/values-mk-rMK/strings.xml +++ b/app/src/main/res/values-mk-rMK/strings.xml @@ -87,9 +87,6 @@ အားလုံးကို ရွေးပါ ပူးတွဲဖိုင်များကို စုစည်းနေသည် - ရုပ်၊သံပါ အချက်အလက်များ - MMS များအား ဒေါင်းလုပ်ဆွဲမည် - MMS များအားဒေါင်းလုပ်ဆွဲနေစဉ် ရပ်တန့်သွားသည်၊ ပြန်စရန် နှိပ်ပါ diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index ceafb0d0be..49715b2e5a 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -87,9 +87,6 @@ အားလုံးကို ရွေးပါ ပူးတွဲဖိုင်များကို စုစည်းနေသည် - ရုပ်၊သံပါ အချက်အလက်များ - MMS များအား ဒေါင်းလုပ်ဆွဲမည် - MMS များအားဒေါင်းလုပ်ဆွဲနေစဉ် ရပ်တန့်သွားသည်၊ ပြန်စရန် နှိပ်ပါ diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index c7da0756a4..0a46d0176f 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -150,9 +150,6 @@ Velg alle Henter vedlegg … - Multimediemelding - Laster ned MMS-melding - Feil under nedlasting av MMS-melding. Trykk for å prøve igjen Send til %s @@ -554,7 +551,7 @@ nøkkelutvekslingsmelding. Er du sikker på at du vil slette denne samtalen? Samtalen slettet Sikre kontoen din ved å lagre din gjenopprettingsfrase - Trykk og hold inne de overflødige ordene for å hente gjenopprettingsfrasen din, og lagre den trygt å sikre din Session-ID. + Trykk og hold inne de overflødige ordene for å hente gjenopprettingsfrasen din, og lagre den trygt å sikre din Account-ID. Pass på å lagre gjenopprettingsfrasen på et sikkert sted Bane Session skjuler din IP ved å laste ned meldingene dine gjennom flere Service Noder i Sessions desentraliserte nettverk. Disse er landene som koblingen din for øyeblikket blir kontaktet gjennom: @@ -568,9 +565,9 @@ nøkkelutvekslingsmelding. Skriv inn Account ID Skann QR-kode Skann en brukers QR-kode for å starte en økt. QR-koder finnes ved å trykke på QR-koden i kontoinnstillingene. - Angi Session-ID eller ONS-navn - Brukere kan dele sin Session-ID ved å gå inn i sine kontoinnstillinger og trykke på \"Del Session-ID\", eller ved å dele sin QR-kode. - Vennligst sjekk Session-ID\'en eller ONS-navnet og prøv igjen. + Angi Account-ID eller ONS-navn + Brukere kan dele sin Account-ID ved å gå inn i sine kontoinnstillinger og trykke på \"Del Account-ID\", eller ved å dele sin QR-kode. + Vennligst sjekk Account-ID\'en eller ONS-navnet og prøv igjen. Session trenger kameratilgang for å skanne QR-koder Gi kameratilgang Ny lukket gruppe @@ -642,7 +639,7 @@ nøkkelutvekslingsmelding. Dag Natt Systemstandard - Kopier Session-ID + Kopier Account-ID Vedlegg Talemelding Detaljer diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index c7da0756a4..0a46d0176f 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -150,9 +150,6 @@ Velg alle Henter vedlegg … - Multimediemelding - Laster ned MMS-melding - Feil under nedlasting av MMS-melding. Trykk for å prøve igjen Send til %s @@ -554,7 +551,7 @@ nøkkelutvekslingsmelding. Er du sikker på at du vil slette denne samtalen? Samtalen slettet Sikre kontoen din ved å lagre din gjenopprettingsfrase - Trykk og hold inne de overflødige ordene for å hente gjenopprettingsfrasen din, og lagre den trygt å sikre din Session-ID. + Trykk og hold inne de overflødige ordene for å hente gjenopprettingsfrasen din, og lagre den trygt å sikre din Account-ID. Pass på å lagre gjenopprettingsfrasen på et sikkert sted Bane Session skjuler din IP ved å laste ned meldingene dine gjennom flere Service Noder i Sessions desentraliserte nettverk. Disse er landene som koblingen din for øyeblikket blir kontaktet gjennom: @@ -568,9 +565,9 @@ nøkkelutvekslingsmelding. Skriv inn Account ID Skann QR-kode Skann en brukers QR-kode for å starte en økt. QR-koder finnes ved å trykke på QR-koden i kontoinnstillingene. - Angi Session-ID eller ONS-navn - Brukere kan dele sin Session-ID ved å gå inn i sine kontoinnstillinger og trykke på \"Del Session-ID\", eller ved å dele sin QR-kode. - Vennligst sjekk Session-ID\'en eller ONS-navnet og prøv igjen. + Angi Account-ID eller ONS-navn + Brukere kan dele sin Account-ID ved å gå inn i sine kontoinnstillinger og trykke på \"Del Account-ID\", eller ved å dele sin QR-kode. + Vennligst sjekk Account-ID\'en eller ONS-navnet og prøv igjen. Session trenger kameratilgang for å skanne QR-koder Gi kameratilgang Ny lukket gruppe @@ -642,7 +639,7 @@ nøkkelutvekslingsmelding. Dag Natt Systemstandard - Kopier Session-ID + Kopier Account-ID Vedlegg Talemelding Detaljer diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index a6056b0c35..a02485849d 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -150,9 +150,6 @@ Alles selecteren Bijlagen aan het verzamelen… - Multimediabericht - Mms-bericht aan het downloaden - Fout bij downloaden van mms-bericht, tik om opnieuw te proberen Verzenden naar %s @@ -570,7 +567,7 @@ Scan QR-code Scan de QR-code van een gebruiker om een sessie te starten. QR-codes kunnen worden gevonden door op het QR-icoon in de accountinstellingen te tikken. Voer uw Account ID of ONS naam in - Gebruikers kunnen hun Session-ID delen door naar hun accountinstellingen te gaan en op \"Deel Session-ID\" te tikken, of door hun QR-code te delen. + Gebruikers kunnen hun Account-ID delen door naar hun accountinstellingen te gaan en op \"Deel Account-ID\" te tikken, of door hun QR-code te delen. Controleer de sessie-ID of ONS naam en probeer het opnieuw. Sessie heeft cameratoegang nodig om QR-codes te scannen Toegang tot camera verlenen diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index a6056b0c35..a02485849d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -150,9 +150,6 @@ Alles selecteren Bijlagen aan het verzamelen… - Multimediabericht - Mms-bericht aan het downloaden - Fout bij downloaden van mms-bericht, tik om opnieuw te proberen Verzenden naar %s @@ -570,7 +567,7 @@ Scan QR-code Scan de QR-code van een gebruiker om een sessie te starten. QR-codes kunnen worden gevonden door op het QR-icoon in de accountinstellingen te tikken. Voer uw Account ID of ONS naam in - Gebruikers kunnen hun Session-ID delen door naar hun accountinstellingen te gaan en op \"Deel Session-ID\" te tikken, of door hun QR-code te delen. + Gebruikers kunnen hun Account-ID delen door naar hun accountinstellingen te gaan en op \"Deel Account-ID\" te tikken, of door hun QR-code te delen. Controleer de sessie-ID of ONS naam en probeer het opnieuw. Sessie heeft cameratoegang nodig om QR-codes te scannen Toegang tot camera verlenen diff --git a/app/src/main/res/values-nn-rNO/strings.xml b/app/src/main/res/values-nn-rNO/strings.xml index d5f869b152..1c38aae5d0 100644 --- a/app/src/main/res/values-nn-rNO/strings.xml +++ b/app/src/main/res/values-nn-rNO/strings.xml @@ -132,9 +132,6 @@ Vel alle Hentar vedlegg … - Multimediemelding - Lastar ned MMS-melding - Klarte ikkje lasta ned MMS-melding, trykk for å prøva igjen Send til %s diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml index d5f869b152..1c38aae5d0 100644 --- a/app/src/main/res/values-nn/strings.xml +++ b/app/src/main/res/values-nn/strings.xml @@ -132,9 +132,6 @@ Vel alle Hentar vedlegg … - Multimediemelding - Lastar ned MMS-melding - Klarte ikkje lasta ned MMS-melding, trykk for å prøva igjen Send til %s diff --git a/app/src/main/res/values-ny-rMW/strings.xml b/app/src/main/res/values-ny-rMW/strings.xml index 44ad2e5ccf..02e8224159 100644 --- a/app/src/main/res/values-ny-rMW/strings.xml +++ b/app/src/main/res/values-ny-rMW/strings.xml @@ -125,9 +125,6 @@ Pankakuna Tukuyta akllana - Multimedia chaski - MMS chaskita uryakuchikun - MMS chaski mana uryakurkachu, kutinlla rurapay diff --git a/app/src/main/res/values-ny/strings.xml b/app/src/main/res/values-ny/strings.xml index 44ad2e5ccf..02e8224159 100644 --- a/app/src/main/res/values-ny/strings.xml +++ b/app/src/main/res/values-ny/strings.xml @@ -125,9 +125,6 @@ Pankakuna Tukuyta akllana - Multimedia chaski - MMS chaskita uryakuchikun - MMS chaski mana uryakurkachu, kutinlla rurapay diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 034369ff63..546a6a6b36 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -168,9 +168,6 @@ Zaznacz wszystko Zbieranie załączników... - Wiadomość multimedialna - Pobieranie wiadomości MMS - Błąd podczas pobierania wiadomości MMS. Dotknij, aby spróbować ponownie. Wyślij do %s diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 034369ff63..546a6a6b36 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -168,9 +168,6 @@ Zaznacz wszystko Zbieranie załączników... - Wiadomość multimedialna - Pobieranie wiadomości MMS - Błąd podczas pobierania wiadomości MMS. Dotknij, aby spróbować ponownie. Wyślij do %s diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 33e4d91ae1..3ece1fb158 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -150,9 +150,6 @@ Selecionar todos Coletando anexos... - Mensagem multimídia - Fazendo download de mensagem MMS - Erro fazendo download de mensagem MMS, toque para retentar Enviar para %s diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 89d20a93e6..396dd7a465 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -150,9 +150,6 @@ Seleccionar tudo A recolher anexos... - Mensagem multimédia - A descarregar MMS - Erro ao descarregar a mensagem MMS, toque para repetir Enviar para %s diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 33e4d91ae1..3ece1fb158 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -150,9 +150,6 @@ Selecionar todos Coletando anexos... - Mensagem multimídia - Fazendo download de mensagem MMS - Erro fazendo download de mensagem MMS, toque para retentar Enviar para %s diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index ce022b297a..9d29835da6 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -160,9 +160,6 @@ Selectează tot Se colectează atașamentele... - Mesaj multimedia - Se descarcă mesajul MMS - Eroare la descărcarea mesajului MMS, apasă pentru reîncercare Trimiteți la %s diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index ce022b297a..9d29835da6 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -160,9 +160,6 @@ Selectează tot Se colectează atașamentele... - Mesaj multimedia - Se descarcă mesajul MMS - Eroare la descărcarea mesajului MMS, apasă pentru reîncercare Trimiteți la %s diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 35d830fc7e..78a7c3512f 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -168,9 +168,6 @@ Выбрать все Сбор вложений... - MMS-сообщение - Загрузка MMS-сообщения - Ошибка при скачивании MMS-сообщения; нажмите для повтора Отправить пользователю %s diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 35d830fc7e..78a7c3512f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -168,9 +168,6 @@ Выбрать все Сбор вложений... - MMS-сообщение - Загрузка MMS-сообщения - Ошибка при скачивании MMS-сообщения; нажмите для повтора Отправить пользователю %s diff --git a/app/src/main/res/values-si-rLK/strings.xml b/app/src/main/res/values-si-rLK/strings.xml index aab98bd37f..7f17f00a71 100644 --- a/app/src/main/res/values-si-rLK/strings.xml +++ b/app/src/main/res/values-si-rLK/strings.xml @@ -61,8 +61,6 @@ මාධ්‍යය ලේඛන - බහුමාධ්‍ය පණිවිඩය - මාධ්‍ය පණිවිඩය බාගතවෙමින් %s ට යවන්න diff --git a/app/src/main/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml index aab98bd37f..7f17f00a71 100644 --- a/app/src/main/res/values-si/strings.xml +++ b/app/src/main/res/values-si/strings.xml @@ -61,8 +61,6 @@ මාධ්‍යය ලේඛන - බහුමාධ්‍ය පණිවිඩය - මාධ්‍ය පණිවිඩය බාගතවෙමින් %s ට යවන්න diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index 141e173856..ab30427042 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -164,9 +164,6 @@ Označiť všetko Ukladám prílohy... - Multimediálna správa - Preberanie MMS správy - Chyba pri preberaní MMS správy, ťuknite pre opakovanie Poslať používateľovi %s diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 141e173856..ab30427042 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -164,9 +164,6 @@ Označiť všetko Ukladám prílohy... - Multimediálna správa - Preberanie MMS správy - Chyba pri preberaní MMS správy, ťuknite pre opakovanie Poslať používateľovi %s diff --git a/app/src/main/res/values-sq-rAL/strings.xml b/app/src/main/res/values-sq-rAL/strings.xml index 9457a68b8f..0db99225ad 100644 --- a/app/src/main/res/values-sq-rAL/strings.xml +++ b/app/src/main/res/values-sq-rAL/strings.xml @@ -150,9 +150,6 @@ Përzgjidhi krejt Po mblidhen bashkëngjitje… - Mesazh multimedia - Po shkarkohet mesazh MMS - Gabim në shkarkim mesazhi MMS, prekeni që të riprovohet Dërgoje te %s diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 9457a68b8f..0db99225ad 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -150,9 +150,6 @@ Përzgjidhi krejt Po mblidhen bashkëngjitje… - Mesazh multimedia - Po shkarkohet mesazh MMS - Gabim në shkarkim mesazhi MMS, prekeni që të riprovohet Dërgoje te %s diff --git a/app/src/main/res/values-sr-rSP/strings.xml b/app/src/main/res/values-sr-rSP/strings.xml index e3f689652b..a36f5c5f19 100644 --- a/app/src/main/res/values-sr-rSP/strings.xml +++ b/app/src/main/res/values-sr-rSP/strings.xml @@ -157,9 +157,6 @@ Изабери све Сакупљам прилоге... - Мултимедијална порука - Преузимам ММС поруку - Грешка при преузимању ММС поруке, тапните да покушам поново Пошаљи %s diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index e3f689652b..a36f5c5f19 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -157,9 +157,6 @@ Изабери све Сакупљам прилоге... - Мултимедијална порука - Преузимам ММС поруку - Грешка при преузимању ММС поруке, тапните да покушам поново Пошаљи %s diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 12374eb2e1..bd53554428 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -150,9 +150,6 @@ Markera alla Samlar bifogade filer... - Multimediameddelande - Hämtning av MMS-meddelanden - Fel vid hämtning av MMS-meddelanden, tryck för att försöka igen Skicka till %s @@ -554,7 +551,7 @@ för nyckelutbyte! Är du säker på att du vill ta bort denna konversation? Konversationen har raderats Säkra ditt konto genom att spara din återställningsfras - Tryck på och håll ned de dolda orden för att avslöja din återställningsfras och lagra dem på ett säkert sätt för att säkra ditt Session-ID. + Tryck på och håll ned de dolda orden för att avslöja din återställningsfras och lagra dem på ett säkert sätt för att säkra ditt Account-ID. Se till att spara din återställningsfras på en säker plats Sökväg Session döljer din IP-adress genom att dirigera dina meddelanden genom flera Tjänstnoder i Sessions decentraliserade nätverk. Detta är de länder som din anslutning för närvarande går igenom: @@ -642,7 +639,7 @@ för nyckelutbyte! Dag Natt Systemets inställning - Kopiera Session-ID + Kopiera Account-ID Bilaga Röstmeddelande Detaljer diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 12374eb2e1..bd53554428 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -150,9 +150,6 @@ Markera alla Samlar bifogade filer... - Multimediameddelande - Hämtning av MMS-meddelanden - Fel vid hämtning av MMS-meddelanden, tryck för att försöka igen Skicka till %s @@ -554,7 +551,7 @@ för nyckelutbyte! Är du säker på att du vill ta bort denna konversation? Konversationen har raderats Säkra ditt konto genom att spara din återställningsfras - Tryck på och håll ned de dolda orden för att avslöja din återställningsfras och lagra dem på ett säkert sätt för att säkra ditt Session-ID. + Tryck på och håll ned de dolda orden för att avslöja din återställningsfras och lagra dem på ett säkert sätt för att säkra ditt Account-ID. Se till att spara din återställningsfras på en säker plats Sökväg Session döljer din IP-adress genom att dirigera dina meddelanden genom flera Tjänstnoder i Sessions decentraliserade nätverk. Detta är de länder som din anslutning för närvarande går igenom: @@ -642,7 +639,7 @@ för nyckelutbyte! Dag Natt Systemets inställning - Kopiera Session-ID + Kopiera Account-ID Bilaga Röstmeddelande Detaljer diff --git a/app/src/main/res/values-sw-rKE/strings.xml b/app/src/main/res/values-sw-rKE/strings.xml index 08c2e7c52f..31120c468b 100644 --- a/app/src/main/res/values-sw-rKE/strings.xml +++ b/app/src/main/res/values-sw-rKE/strings.xml @@ -100,9 +100,6 @@ Chagua vyote kukusanya viambatisho - Ujumbe wa Multimedia - kupakua ujumbe wa mms - Hitilafu kupakua ujumbe wa MMS, bomba ili ujaribu tena tuma kwa 1%s diff --git a/app/src/main/res/values-sw/strings.xml b/app/src/main/res/values-sw/strings.xml index 08c2e7c52f..31120c468b 100644 --- a/app/src/main/res/values-sw/strings.xml +++ b/app/src/main/res/values-sw/strings.xml @@ -100,9 +100,6 @@ Chagua vyote kukusanya viambatisho - Ujumbe wa Multimedia - kupakua ujumbe wa mms - Hitilafu kupakua ujumbe wa MMS, bomba ili ujaribu tena tuma kwa 1%s diff --git a/app/src/main/res/values-te-rIN/strings.xml b/app/src/main/res/values-te-rIN/strings.xml index ed65034517..17c79804e5 100644 --- a/app/src/main/res/values-te-rIN/strings.xml +++ b/app/src/main/res/values-te-rIN/strings.xml @@ -142,9 +142,6 @@ అన్నీ ఎంచుకో జోడింపుల సేకరణ ... - మల్టీమీడియా సందేశం - ఎమ్మెమ్మెస్ సందేశం దిగుమతి - ఎమ్మెమ్మెస్ సందేశం దిగుమతిలో లోపం, తట్టి మళ్ళీ ప్రయత్నించండి కెమెరా అందుబాటులో లేదు. diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index ed65034517..17c79804e5 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -142,9 +142,6 @@ అన్నీ ఎంచుకో జోడింపుల సేకరణ ... - మల్టీమీడియా సందేశం - ఎమ్మెమ్మెస్ సందేశం దిగుమతి - ఎమ్మెమ్మెస్ సందేశం దిగుమతిలో లోపం, తట్టి మళ్ళీ ప్రయత్నించండి కెమెరా అందుబాటులో లేదు. diff --git a/app/src/main/res/values-th-rTH/strings.xml b/app/src/main/res/values-th-rTH/strings.xml index 014bc598ed..7bc5a08352 100644 --- a/app/src/main/res/values-th-rTH/strings.xml +++ b/app/src/main/res/values-th-rTH/strings.xml @@ -119,9 +119,6 @@ เลือกทั้งหมด รวบรวมสิ่งแนบ... - ข้อความมัลติมีเดีย - กำลังดาวน์โหลดข้อความ MMS - เกิดข้อผิดพลาดระหว่างดาวน์โหลด MMS แตะเพื่อลองใหม่ diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 014bc598ed..7bc5a08352 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -119,9 +119,6 @@ เลือกทั้งหมด รวบรวมสิ่งแนบ... - ข้อความมัลติมีเดีย - กำลังดาวน์โหลดข้อความ MMS - เกิดข้อผิดพลาดระหว่างดาวน์โหลด MMS แตะเพื่อลองใหม่ diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 29ceccc2a6..f7fbd85e53 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -150,9 +150,6 @@ Hepsini seç Eklentiler toplanıyor... - Çoğulortam iletisi - MMS iletisi indiriliyor - MMS iletisi indirilirken hata, yeniden denemek için dokunun %s alıcısına gönder diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 29ceccc2a6..f7fbd85e53 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -150,9 +150,6 @@ Hepsini seç Eklentiler toplanıyor... - Çoğulortam iletisi - MMS iletisi indiriliyor - MMS iletisi indirilirken hata, yeniden denemek için dokunun %s alıcısına gönder diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml index 6940a0efe9..4d68467003 100644 --- a/app/src/main/res/values-uk-rUA/strings.xml +++ b/app/src/main/res/values-uk-rUA/strings.xml @@ -168,9 +168,6 @@ Обрати все Збираю вкладення... - Мультимедійне повідомлення - Завантаження MMS... - Виникла помилка при завантаженні MMS, натисніть щоб повторити Відправити %s diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index c443c9ed25..2cd6940060 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -168,9 +168,6 @@ Обрати все Збираю вкладення... - Мультимедійне повідомлення - Завантаження MMS... - Виникла помилка при завантаженні MMS, натисніть щоб повторити Відправити %s diff --git a/app/src/main/res/values-ur-rIN/strings.xml b/app/src/main/res/values-ur-rIN/strings.xml index cb03080ca7..91f024c58e 100644 --- a/app/src/main/res/values-ur-rIN/strings.xml +++ b/app/src/main/res/values-ur-rIN/strings.xml @@ -87,8 +87,6 @@ تمام منتخب کریں منسلکات کو جمع کرنے کا عمل جاری ہے... - ملٹی میڈیا پیغام - MMS پیغام ڈاؤن لوڈ ہو رہا ہے diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index cb03080ca7..91f024c58e 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -87,8 +87,6 @@ تمام منتخب کریں منسلکات کو جمع کرنے کا عمل جاری ہے... - ملٹی میڈیا پیغام - MMS پیغام ڈاؤن لوڈ ہو رہا ہے diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml index 886a85eb3c..d6a68a3e06 100644 --- a/app/src/main/res/values-vi-rVN/strings.xml +++ b/app/src/main/res/values-vi-rVN/strings.xml @@ -103,8 +103,6 @@ Chọn tất cả Đang thu thập đính kèm... - Tin nhắn đa phương tiện - Đang tải xuống tin nhắn MMS diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 886a85eb3c..d6a68a3e06 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -103,8 +103,6 @@ Chọn tất cả Đang thu thập đính kèm... - Tin nhắn đa phương tiện - Đang tải xuống tin nhắn MMS diff --git a/app/src/main/res/values-xh-rZA/strings.xml b/app/src/main/res/values-xh-rZA/strings.xml index 9ad53ec043..99aecc28e5 100644 --- a/app/src/main/res/values-xh-rZA/strings.xml +++ b/app/src/main/res/values-xh-rZA/strings.xml @@ -82,7 +82,6 @@ Londa byonna. ebigatibwako bikunganyizibwa - obubaka obwa vidiyo oba amaloboozi diff --git a/app/src/main/res/values-xh/strings.xml b/app/src/main/res/values-xh/strings.xml index 9ad53ec043..99aecc28e5 100644 --- a/app/src/main/res/values-xh/strings.xml +++ b/app/src/main/res/values-xh/strings.xml @@ -82,7 +82,6 @@ Londa byonna. ebigatibwako bikunganyizibwa - obubaka obwa vidiyo oba amaloboozi diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 76a8bdded3..5785fbf8b6 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -141,9 +141,6 @@ 选择全部 正在收集附件… - 多媒体信息 - 正在下载彩信 - 下载彩信时错误,点击重试 发送给%s diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 264e80f51a..722f23a252 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -145,9 +145,6 @@ 全選 正在收集附件... - 多媒體訊息 - 正在下載MMS訊息 - 下載MMS訊息時發生錯誤,點擊重試 傳送給 %s diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index e536eb392b..0d222ad5b7 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -141,9 +141,6 @@ 选择全部 正在收集附件… - 多媒体信息 - 正在下载彩信 - 下载彩信时错误,点击重试 发送给%s diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 123137ee03..f00717c57c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -310,9 +310,6 @@ Select all Collecting attachments... - Multimedia message - Downloading MMS message - Error downloading MMS message, tap to retry Send to %s diff --git a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt index 33addc3aab..ea27128205 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/MentionViewModelTest.kt @@ -91,14 +91,14 @@ class MentionViewModelTest { contactDatabase = mock { on { getContacts(any()) } doAnswer { val ids = it.arguments[0] as Collection - memberContacts.filter { contact -> contact.accountID in ids } + memberContacts.filter { it.accountID in ids } } }, memberDatabase = mock { on { getGroupMembersRoles(eq(openGroup.id), any()) } doAnswer { val memberIDs = it.arguments[1] as Collection memberIDs.associateWith { id -> - threadMembers.first { m -> m.pubKey == id }.roles + threadMembers.first { it.pubKey == id }.roles } } }, diff --git a/gradle.properties b/gradle.properties index a3db023cef..6154652583 100644 --- a/gradle.properties +++ b/gradle.properties @@ -36,6 +36,7 @@ materialVersion=1.8.0 mockitoKotlinVersion=4.1.0 okhttpVersion=4.12.0 pagingVersion=3.0.0 +phraseVersion=1.2.0 preferenceVersion=1.2.0 protobufVersion=2.5.0 testCoreVersion=1.5.0 diff --git a/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt b/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt index 952c357851..2c75de50ce 100644 --- a/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt +++ b/libsession-util/src/androidTest/java/network/loki/messenger/libsession_util/InstrumentedTests.kt @@ -368,7 +368,7 @@ class InstrumentedTests { assertEquals(2, convos.sizeOneToOnes()) val numErased = convos.eraseAll { convo -> - convo is Conversation.OneToOne && convo.sessionId == definitelyRealId + convo is Conversation.OneToOne && convo.accountId == definitelyRealId } assertEquals(1, numErased) assertEquals(1, convos.sizeOneToOnes()) @@ -453,7 +453,7 @@ class InstrumentedTests { val c = convos.getOrConstructOneToOne(definitelyRealId) - assertEquals(definitelyRealId, c.sessionId) + assertEquals(definitelyRealId, c.accountId) assertEquals(0, c.lastRead) assertFalse(convos.needsPush()) @@ -504,7 +504,7 @@ class InstrumentedTests { val x1 = convos2.getOneToOne(definitelyRealId)!! assertEquals(nowMs, x1.lastRead) - assertEquals(definitelyRealId, x1.sessionId) + assertEquals(definitelyRealId, x1.accountId) assertEquals(false, x1.unread) val x2 = convos2.getCommunity("http://EXAMPLE.org:5678", "sudokuRoom")!! @@ -548,7 +548,7 @@ class InstrumentedTests { val allConvos = conv.all() for (convo in allConvos) { when (convo) { - is Conversation.OneToOne -> seen.add("1-to-1: ${convo.sessionId}") + is Conversation.OneToOne -> seen.add("1-to-1: ${convo.accountId}") is Conversation.Community -> seen.add("og: ${convo.baseCommunityInfo.baseUrl}/r/${convo.baseCommunityInfo.room}") is Conversation.LegacyGroup -> seen.add("cl: ${convo.groupId}") } @@ -569,7 +569,7 @@ class InstrumentedTests { assertEquals(1, convos.allOneToOnes().size) assertEquals("051111111111111111111111111111111111111111111111111111111111111111", - convos.allOneToOnes().map(Conversation.OneToOne::sessionId).first() + convos.allOneToOnes().map(Conversation.OneToOne::accountId).first() ) assertEquals(1, convos.allCommunities().size) assertEquals("http://example.org:5678", diff --git a/libsession-util/src/main/cpp/contacts.cpp b/libsession-util/src/main/cpp/contacts.cpp index 324d0f0ea8..d064ccd683 100644 --- a/libsession-util/src/main/cpp/contacts.cpp +++ b/libsession-util/src/main/cpp/contacts.cpp @@ -5,15 +5,15 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_Contacts_get(JNIEnv *env, jobject thiz, - jstring session_id) { + jstring account_id) { // If an exception is thrown, return nullptr return jni_utils::run_catching_cxx_exception_or( [=]() -> jobject { std::lock_guard lock{util::util_mutex_}; auto contacts = ptrToContacts(env, thiz); - auto session_id_chars = env->GetStringUTFChars(session_id, nullptr); - auto contact = contacts->get(session_id_chars); - env->ReleaseStringUTFChars(session_id, session_id_chars); + auto account_id_chars = env->GetStringUTFChars(account_id, nullptr); + auto contact = contacts->get(account_id_chars); + env->ReleaseStringUTFChars(account_id, account_id_chars); if (!contact) return nullptr; jobject j_contact = serialize_contact(env, contact.value()); return j_contact; @@ -25,13 +25,13 @@ Java_network_loki_messenger_libsession_1util_Contacts_get(JNIEnv *env, jobject t extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_Contacts_getOrConstruct(JNIEnv *env, jobject thiz, - jstring session_id) { + jstring account_id) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { std::lock_guard lock{util::util_mutex_}; auto contacts = ptrToContacts(env, thiz); - auto session_id_chars = env->GetStringUTFChars(session_id, nullptr); - auto contact = contacts->get_or_construct(session_id_chars); - env->ReleaseStringUTFChars(session_id, session_id_chars); + auto account_id_chars = env->GetStringUTFChars(account_id, nullptr); + auto contact = contacts->get_or_construct(account_id_chars); + env->ReleaseStringUTFChars(account_id, account_id_chars); return serialize_contact(env, contact); }); } @@ -51,14 +51,14 @@ Java_network_loki_messenger_libsession_1util_Contacts_set(JNIEnv *env, jobject t extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_Contacts_erase(JNIEnv *env, jobject thiz, - jstring session_id) { + jstring account_id) { return jni_utils::run_catching_cxx_exception_or_throws(env, [=] { std::lock_guard lock{util::util_mutex_}; auto contacts = ptrToContacts(env, thiz); - auto session_id_chars = env->GetStringUTFChars(session_id, nullptr); + auto account_id_chars = env->GetStringUTFChars(account_id, nullptr); - bool result = contacts->erase(session_id_chars); - env->ReleaseStringUTFChars(session_id, session_id_chars); + bool result = contacts->erase(account_id_chars); + env->ReleaseStringUTFChars(account_id, account_id_chars); return result; }); } diff --git a/libsession-util/src/main/cpp/contacts.h b/libsession-util/src/main/cpp/contacts.h index ecb2cb3749..5db6837190 100644 --- a/libsession-util/src/main/cpp/contacts.h +++ b/libsession-util/src/main/cpp/contacts.h @@ -43,8 +43,8 @@ inline session::config::contact_info deserialize_contact(JNIEnv *env, jobject in "Lnetwork/loki/messenger/libsession_util/util/UserPic;"); getPriority = env->GetFieldID(contactClass, "priority", "I"); getExpiry = env->GetFieldID(contactClass, "expiryMode", "Lnetwork/loki/messenger/libsession_util/util/ExpiryMode;"); - jstring name, nickname, session_id; - session_id = static_cast(env->GetObjectField(info, getId)); + jstring name, nickname, account_id; + account_id = static_cast(env->GetObjectField(info, getId)); name = static_cast(env->GetObjectField(info, getName)); nickname = static_cast(env->GetObjectField(info, getNick)); bool approved, approvedMe, blocked, hidden; @@ -69,11 +69,11 @@ inline session::config::contact_info deserialize_contact(JNIEnv *env, jobject in key = util::ustring_from_bytes(env, deserialized_pic.second); } - auto session_id_bytes = env->GetStringUTFChars(session_id, nullptr); + auto account_id_bytes = env->GetStringUTFChars(account_id, nullptr); auto name_bytes = name ? env->GetStringUTFChars(name, nullptr) : nullptr; auto nickname_bytes = nickname ? env->GetStringUTFChars(nickname, nullptr) : nullptr; - auto contact_info = conf->get_or_construct(session_id_bytes); + auto contact_info = conf->get_or_construct(account_id_bytes); if (name_bytes) { contact_info.name = name_bytes; } @@ -89,7 +89,7 @@ inline session::config::contact_info deserialize_contact(JNIEnv *env, jobject in contact_info.profile_picture = session::config::profile_pic(); } - env->ReleaseStringUTFChars(session_id, session_id_bytes); + env->ReleaseStringUTFChars(account_id, account_id_bytes); if (name_bytes) { env->ReleaseStringUTFChars(name, name_bytes); } diff --git a/libsession-util/src/main/cpp/conversation.h b/libsession-util/src/main/cpp/conversation.h index 45e453a595..eaf96dc840 100644 --- a/libsession-util/src/main/cpp/conversation.h +++ b/libsession-util/src/main/cpp/conversation.h @@ -14,10 +14,10 @@ inline session::config::ConvoInfoVolatile *ptrToConvoInfo(JNIEnv *env, jobject o inline jobject serialize_one_to_one(JNIEnv *env, session::config::convo::one_to_one one_to_one) { jclass clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne"); jmethodID constructor = env->GetMethodID(clazz, "", "(Ljava/lang/String;JZ)V"); - auto session_id = env->NewStringUTF(one_to_one.session_id.data()); + auto account_id = env->NewStringUTF(one_to_one.session_id.data()); auto last_read = one_to_one.last_read; auto unread = one_to_one.unread; - jobject serialized = env->NewObject(clazz, constructor, session_id, last_read, unread); + jobject serialized = env->NewObject(clazz, constructor, account_id, last_read, unread); return serialized; } @@ -55,7 +55,7 @@ inline jobject serialize_any(JNIEnv *env, session::config::convo::any any) { inline session::config::convo::one_to_one deserialize_one_to_one(JNIEnv *env, jobject info, session::config::ConvoInfoVolatile *conf) { auto clazz = env->FindClass("network/loki/messenger/libsession_util/util/Conversation$OneToOne"); - auto id_getter = env->GetFieldID(clazz, "sessionId", "Ljava/lang/String;"); + auto id_getter = env->GetFieldID(clazz, "accountId", "Ljava/lang/String;"); auto last_read_getter = env->GetFieldID(clazz, "lastRead", "J"); auto unread_getter = env->GetFieldID(clazz, "unread", "Z"); jstring id = static_cast(env->GetObjectField(info, id_getter)); diff --git a/libsession-util/src/main/cpp/user_groups.cpp b/libsession-util/src/main/cpp/user_groups.cpp index 9754b40891..81a3e664b5 100644 --- a/libsession-util/src/main/cpp/user_groups.cpp +++ b/libsession-util/src/main/cpp/user_groups.cpp @@ -74,16 +74,16 @@ extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getLegacyGroupInfo(JNIEnv *env, jobject thiz, - jstring session_id) { + jstring account_id) { std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto id_bytes = env->GetStringUTFChars(session_id, nullptr); + auto id_bytes = env->GetStringUTFChars(account_id, nullptr); auto legacy_group = conf->get_legacy_group(id_bytes); jobject return_group = nullptr; if (legacy_group) { return_group = serialize_legacy_group_info(env, *legacy_group); } - env->ReleaseStringUTFChars(session_id, id_bytes); + env->ReleaseStringUTFChars(account_id, id_bytes); return return_group; } @@ -108,12 +108,12 @@ Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getOrConstructComm extern "C" JNIEXPORT jobject JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_getOrConstructLegacyGroupInfo( - JNIEnv *env, jobject thiz, jstring session_id) { + JNIEnv *env, jobject thiz, jstring account_id) { std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto id_bytes = env->GetStringUTFChars(session_id, nullptr); + auto id_bytes = env->GetStringUTFChars(account_id, nullptr); auto group = conf->get_or_construct_legacy_group(id_bytes); - env->ReleaseStringUTFChars(session_id, id_bytes); + env->ReleaseStringUTFChars(account_id, id_bytes); return serialize_legacy_group_info(env, group); } @@ -264,11 +264,11 @@ extern "C" JNIEXPORT jboolean JNICALL Java_network_loki_messenger_libsession_1util_UserGroupsConfig_eraseLegacyGroup(JNIEnv *env, jobject thiz, - jstring session_id) { + jstring account_id) { std::lock_guard lock{util::util_mutex_}; auto conf = ptrToUserGroups(env, thiz); - auto session_id_bytes = env->GetStringUTFChars(session_id, nullptr); - bool return_bool = conf->erase_legacy_group(session_id_bytes); - env->ReleaseStringUTFChars(session_id, session_id_bytes); + auto account_id_bytes = env->GetStringUTFChars(account_id, nullptr); + bool return_bool = conf->erase_legacy_group(account_id_bytes); + env->ReleaseStringUTFChars(account_id, account_id_bytes); return return_bool; } \ No newline at end of file diff --git a/libsession-util/src/main/cpp/user_groups.h b/libsession-util/src/main/cpp/user_groups.h index c4754fe113..6e52bf7fe1 100644 --- a/libsession-util/src/main/cpp/user_groups.h +++ b/libsession-util/src/main/cpp/user_groups.h @@ -44,7 +44,7 @@ inline void deserialize_members_into(JNIEnv *env, jobject members_map, session:: inline session::config::legacy_group_info deserialize_legacy_group_info(JNIEnv *env, jobject info, session::config::UserGroups* conf) { auto clazz = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$LegacyGroupInfo"); - auto id_field = env->GetFieldID(clazz, "sessionId", "Ljava/lang/String;"); + auto id_field = env->GetFieldID(clazz, "accountId", "Ljava/lang/String;"); auto name_field = env->GetFieldID(clazz, "name", "Ljava/lang/String;"); auto members_field = env->GetFieldID(clazz, "members", "Ljava/util/Map;"); auto enc_pub_key_field = env->GetFieldID(clazz, "encPubKey", "[B"); @@ -104,16 +104,16 @@ inline jobject serialize_members(JNIEnv *env, std::map member jobject new_map = env->NewObject(map_class, map_constructor); for (auto it = members_map.begin(); it != members_map.end(); it++) { - auto session_id = env->NewStringUTF(it->first.data()); + auto account_id = env->NewStringUTF(it->first.data()); bool is_admin = it->second; auto jbool = env->NewObject(boxed_bool, new_bool, is_admin); - env->CallObjectMethod(new_map, insert, session_id, jbool); + env->CallObjectMethod(new_map, insert, account_id, jbool); } return new_map; } inline jobject serialize_legacy_group_info(JNIEnv *env, session::config::legacy_group_info info) { - jstring session_id = env->NewStringUTF(info.session_id.data()); + jstring account_id = env->NewStringUTF(info.session_id.data()); jstring name = env->NewStringUTF(info.name.data()); jobject members = serialize_members(env, info.members()); jbyteArray enc_pubkey = util::bytes_from_ustring(env, info.enc_pubkey); @@ -123,7 +123,7 @@ inline jobject serialize_legacy_group_info(JNIEnv *env, session::config::legacy_ jclass legacy_group_class = env->FindClass("network/loki/messenger/libsession_util/util/GroupInfo$LegacyGroupInfo"); jmethodID constructor = env->GetMethodID(legacy_group_class, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;[B[BIJJ)V"); - jobject serialized = env->NewObject(legacy_group_class, constructor, session_id, name, members, enc_pubkey, enc_seckey, priority, (jlong) info.disappearing_timer.count(), joined_at); + jobject serialized = env->NewObject(legacy_group_class, constructor, account_id, name, members, enc_pubkey, enc_seckey, priority, (jlong) info.disappearing_timer.count(), joined_at); return serialized; } diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt index 03af4a3968..ccdda282fe 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt @@ -61,49 +61,41 @@ class Contacts(pointer: Long) : ConfigBase(pointer) { external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): Contacts } - external fun get(sessionId: String): Contact? - external fun getOrConstruct(sessionId: String): Contact + external fun get(accountId: String): Contact? + external fun getOrConstruct(accountId: String): Contact external fun all(): List external fun set(contact: Contact) - external fun erase(sessionId: String): Boolean + external fun erase(accountId: String): Boolean /** * Similar to [updateIfExists], but will create the underlying contact if it doesn't exist before passing to [updateFunction] */ - fun upsertContact(sessionId: String, updateFunction: Contact.()->Unit = {}) { - if (sessionId.startsWith(IdPrefix.BLINDED.value)) { - Log.w("Loki", "Trying to create a contact with a blinded ID prefix") - return - } else if (sessionId.startsWith(IdPrefix.UN_BLINDED.value)) { - Log.w("Loki", "Trying to create a contact with an un-blinded ID prefix") - return - } else if (sessionId.startsWith(IdPrefix.BLINDEDV2.value)) { - Log.w("Loki", "Trying to create a contact with a blindedv2 ID prefix") - return + fun upsertContact(accountId: String, updateFunction: Contact.()->Unit = {}) { + when { + accountId.startsWith(IdPrefix.BLINDED.value) -> Log.w("Loki", "Trying to create a contact with a blinded ID prefix") + accountId.startsWith(IdPrefix.UN_BLINDED.value) -> Log.w("Loki", "Trying to create a contact with an un-blinded ID prefix") + accountId.startsWith(IdPrefix.BLINDEDV2.value) -> Log.w("Loki", "Trying to create a contact with a blindedv2 ID prefix") + else -> getOrConstruct(accountId).let { + updateFunction(it) + set(it) + } } - val contact = getOrConstruct(sessionId) - updateFunction(contact) - set(contact) } /** - * Updates the contact by sessionId with a given [updateFunction], and applies to the underlying config. + * Updates the contact by accountId with a given [updateFunction], and applies to the underlying config. * the [updateFunction] doesn't run if there is no contact */ - fun updateIfExists(sessionId: String, updateFunction: Contact.()->Unit) { - if (sessionId.startsWith(IdPrefix.BLINDED.value)) { - Log.w("Loki", "Trying to create a contact with a blinded ID prefix") - return - } else if (sessionId.startsWith(IdPrefix.UN_BLINDED.value)) { - Log.w("Loki", "Trying to create a contact with an un-blinded ID prefix") - return - } else if (sessionId.startsWith(IdPrefix.BLINDEDV2.value)) { - Log.w("Loki", "Trying to create a contact with a blindedv2 ID prefix") - return + private fun updateIfExists(accountId: String, updateFunction: Contact.()->Unit) { + when { + accountId.startsWith(IdPrefix.BLINDED.value) -> Log.w("Loki", "Trying to create a contact with a blinded ID prefix") + accountId.startsWith(IdPrefix.UN_BLINDED.value) -> Log.w("Loki", "Trying to create a contact with an un-blinded ID prefix") + accountId.startsWith(IdPrefix.BLINDEDV2.value) -> Log.w("Loki", "Trying to create a contact with a blindedv2 ID prefix") + else -> get(accountId)?.let { + updateFunction(it) + set(it) + } } - val contact = get(sessionId) ?: return - updateFunction(contact) - set(contact) } } @@ -184,14 +176,14 @@ class UserGroupsConfig(pointer: Long): ConfigBase(pointer) { } external fun getCommunityInfo(baseUrl: String, room: String): GroupInfo.CommunityGroupInfo? - external fun getLegacyGroupInfo(sessionId: String): GroupInfo.LegacyGroupInfo? + external fun getLegacyGroupInfo(accountId: String): GroupInfo.LegacyGroupInfo? external fun getOrConstructCommunityInfo(baseUrl: String, room: String, pubKeyHex: String): GroupInfo.CommunityGroupInfo - external fun getOrConstructLegacyGroupInfo(sessionId: String): GroupInfo.LegacyGroupInfo + external fun getOrConstructLegacyGroupInfo(accountId: String): GroupInfo.LegacyGroupInfo external fun set(groupInfo: GroupInfo) external fun erase(communityInfo: GroupInfo) external fun eraseCommunity(baseCommunityInfo: BaseCommunityInfo): Boolean external fun eraseCommunity(server: String, room: String): Boolean - external fun eraseLegacyGroup(sessionId: String): Boolean + external fun eraseLegacyGroup(accountId: String): Boolean external fun sizeCommunityInfo(): Int external fun sizeLegacyGroupInfo(): Int external fun size(): Int diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt index 97930e8b40..5f96df6dad 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/Conversation.kt @@ -6,7 +6,7 @@ sealed class Conversation { abstract var unread: Boolean data class OneToOne( - val sessionId: String, + val accountId: String, override var lastRead: Long, override var unread: Boolean ): Conversation() diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt index c8ace0a9a7..752c8be0f3 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupInfo.kt @@ -5,7 +5,7 @@ sealed class GroupInfo { data class CommunityGroupInfo(val community: BaseCommunityInfo, val priority: Int) : GroupInfo() data class LegacyGroupInfo( - val sessionId: String, + val accountId: String, val name: String, val members: Map, val encPubKey: ByteArray, @@ -25,7 +25,7 @@ sealed class GroupInfo { other as LegacyGroupInfo - if (sessionId != other.sessionId) return false + if (accountId != other.accountId) return false if (name != other.name) return false if (members != other.members) return false if (!encPubKey.contentEquals(other.encPubKey)) return false @@ -38,7 +38,7 @@ sealed class GroupInfo { } override fun hashCode(): Int { - var result = sessionId.hashCode() + var result = accountId.hashCode() result = 31 * result + name.hashCode() result = 31 * result + members.hashCode() result = 31 * result + encPubKey.contentHashCode() diff --git a/libsession/src/main/java/org/session/libsession/messaging/BlindedIdMapping.kt b/libsession/src/main/java/org/session/libsession/messaging/BlindedIdMapping.kt index 3b4af098ad..d00abd28c3 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/BlindedIdMapping.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/BlindedIdMapping.kt @@ -2,7 +2,7 @@ package org.session.libsession.messaging data class BlindedIdMapping( val blindedId: String, - val sessionId: String?, + val accountId: String?, val serverUrl: String, val serverId: String ) \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt index 9ca2534f66..54efa1c80b 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt @@ -38,7 +38,7 @@ class RetrieveProfileAvatarJob(private val profileAvatar: String?, val recipient } override suspend fun execute(dispatcherName: String) { - val delegate = delegate ?: return + val delegate = delegate ?: return Log.w(TAG, "RetrieveProfileAvatarJob has no delegate method to work with!") if (profileAvatar in errorUrls) return delegate.handleJobFailed(this, dispatcherName, Exception("Profile URL 404'd this app instance")) val context = MessagingModuleConfiguration.shared.context val storage = MessagingModuleConfiguration.shared.storage diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt index d7472bb797..e50fe293e1 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/Endpoint.kt @@ -30,8 +30,8 @@ sealed class Endpoint(val value: String) { data class RoomMessagesSince(val roomToken: String, val seqNo: Long) : Endpoint("room/$roomToken/messages/since/$seqNo") - data class RoomDeleteMessages(val roomToken: String, val sessionId: String) : - Endpoint("room/$roomToken/all/$sessionId") + data class RoomDeleteMessages(val roomToken: String, val accountId: String) : + Endpoint("room/$roomToken/all/$accountId") data class Reactors(val roomToken: String, val messageId: Long, val emoji: String): Endpoint("room/$roomToken/reactors/$messageId/$emoji") @@ -67,15 +67,15 @@ sealed class Endpoint(val value: String) { object Inbox : Endpoint("inbox") data class InboxSince(val id: Long) : Endpoint("inbox/since/$id") - data class InboxFor(val sessionId: String) : Endpoint("inbox/$sessionId") + data class InboxFor(val accountId: String) : Endpoint("inbox/$accountId") object Outbox : Endpoint("outbox") data class OutboxSince(val id: Long) : Endpoint("outbox/since/$id") // Users - data class UserBan(val sessionId: String) : Endpoint("user/$sessionId/ban") - data class UserUnban(val sessionId: String) : Endpoint("user/$sessionId/unban") - data class UserModerator(val sessionId: String) : Endpoint("user/$sessionId/moderator") + data class UserBan(val accountId: String) : Endpoint("user/$accountId/ban") + data class UserUnban(val accountId: String) : Endpoint("user/$accountId/unban") + data class UserModerator(val accountId: String) : Endpoint("user/$accountId/moderator") } diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt index 4e15a6c98b..1125b998f1 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupApi.kt @@ -6,18 +6,13 @@ import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.PropertyNamingStrategy import com.fasterxml.jackson.databind.annotation.JsonNaming import com.fasterxml.jackson.databind.type.TypeFactory -import com.goterl.lazysodium.LazySodiumAndroid -import com.goterl.lazysodium.SodiumAndroid import com.goterl.lazysodium.interfaces.GenericHash import com.goterl.lazysodium.interfaces.Sign import kotlinx.coroutines.flow.MutableSharedFlow import nl.komponents.kovenant.Promise import nl.komponents.kovenant.functional.map -import okhttp3.Headers import okhttp3.Headers.Companion.toHeaders -import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull -import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody import org.session.libsession.messaging.MessagingModuleConfiguration @@ -203,7 +198,7 @@ object OpenGroupApi { @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class) data class Message( val id : Long = 0, - val sessionId: String = "", + val accountId: String = "", val posted: Double = 0.0, val edited: Long = 0, val seqno: Long = 0, diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessage.kt index 71981867c0..1b5b870bfa 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessage.kt @@ -36,7 +36,7 @@ data class OpenGroupMessage( val base64EncodedData = json["data"] as? String ?: return null val sentTimestamp = json["posted"] as? Double ?: return null val serverID = json["id"] as? Int - val sender = json["account_id"] as? String + val sender = json["session_id"] as? String val base64EncodedSignature = json["signature"] as? String return OpenGroupMessage( serverID = serverID?.toLong(), diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt index 72966f908c..3da1161cb0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/SessionServiceAttachmentStream.kt @@ -72,4 +72,4 @@ class SessionServiceAttachmentStream(val inputStream: InputStream?, contentType: return null } } -} \ No newline at end of file +} diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt index b713681659..0efed74a13 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt @@ -13,9 +13,9 @@ import kotlinx.serialization.Serializable @Serializable data class SubscriptionRequest( - /** the 33-byte account being subscribed to; typically a session ID */ + /** the 33-byte account being subscribed to; typically an account ID */ val pubkey: String, - /** when the pubkey starts with 05 (i.e. a session ID) this is the ed25519 32-byte pubkey associated with the session ID */ + /** when the pubkey starts with 05 (i.e. an account ID) this is the ed25519 32-byte pubkey associated with the account ID */ val session_ed25519: String?, /** 32-byte swarm authentication subkey; omitted (or null) when not using subkey auth (new closed groups) */ val subkey_tag: String? = null, @@ -38,9 +38,9 @@ data class SubscriptionRequest( @Serializable data class UnsubscriptionRequest( - /** the 33-byte account being subscribed to; typically a session ID */ + /** the 33-byte account being subscribed to; typically a account ID */ val pubkey: String, - /** when the pubkey starts with 05 (i.e. a session ID) this is the ed25519 32-byte pubkey associated with the session ID */ + /** when the pubkey starts with 05 (i.e. an account ID) this is the ed25519 32-byte pubkey associated with the account ID */ val session_ed25519: String?, /** 32-byte swarm authentication subkey; omitted (or null) when not using subkey auth (new closed groups) */ val subkey_tag: String? = null, diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt index b9baadcaba..d3ed7fb643 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt @@ -222,7 +222,7 @@ class OpenGroupPoller(private val server: String, private val executorService: S handleNewMessages(server, roomToken, additions.map { OpenGroupMessage( serverID = it.id, - sender = it.sessionId, + sender = it.accountId, sentTimestamp = (it.posted * 1000).toLong(), base64EncodedData = it.data, base64EncodedSignature = it.signature, @@ -272,7 +272,7 @@ class OpenGroupPoller(private val server: String, private val executorService: S serverPublicKey, true ) - val syncTarget = mapping.sessionId ?: it.recipient + val syncTarget = mapping.accountId ?: it.recipient if (message is VisibleMessage) { message.syncTarget = syncTarget } else if (message is ExpirationTimerUpdate) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/SodiumUtilities.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/SodiumUtilities.kt index 532af774ac..f31ab49e57 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/SodiumUtilities.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/SodiumUtilities.kt @@ -159,22 +159,22 @@ object SodiumUtilities { } else null } - /* This method should be used to check if a users standard sessionId matches a blinded one */ - fun sessionId( + /* This method should be used to check if a users standard accountId matches a blinded one */ + fun accountId( standardAccountId: String, blindedAccountId: String, serverPublicKey: String ): Boolean { - // Only support generating blinded keys for standard session ids - val sessionId = AccountId(standardAccountId) - if (sessionId.prefix != IdPrefix.STANDARD) return false + // Only support generating blinded keys for standard account ids + val accountId = AccountId(standardAccountId) + if (accountId.prefix != IdPrefix.STANDARD) return false val blindedId = AccountId(blindedAccountId) if (blindedId.prefix != IdPrefix.BLINDED) return false val k = generateBlindingFactor(serverPublicKey) ?: return false - // From the session id (ignoring 05 prefix) we have two possible ed25519 pubkeys; + // From the account id (ignoring 05 prefix) we have two possible ed25519 pubkeys; // the first is the positive (which is what Signal's XEd25519 conversion always uses) - val xEd25519Key = curve.convertToEd25519PublicKey(Key.fromHexString(sessionId.publicKey).asBytes) + val xEd25519Key = curve.convertToEd25519PublicKey(Key.fromHexString(accountId.publicKey).asBytes) // Blind the positive public key val pk1 = combineKeys(k, xEd25519Key) ?: return false diff --git a/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt b/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt index 4407378da9..a4a762c54b 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/GroupUtil.kt @@ -17,9 +17,9 @@ object GroupUtil { } @JvmStatic - fun getEncodedOpenGroupInboxID(openGroup: OpenGroup, sessionId: AccountId): Address { + fun getEncodedOpenGroupInboxID(openGroup: OpenGroup, accountId: AccountId): Address { val openGroupInboxId = - "${openGroup.server}!${openGroup.publicKey}!${sessionId.hexString}".toByteArray() + "${openGroup.server}!${openGroup.publicKey}!${accountId.hexString}".toByteArray() return getEncodedOpenGroupInboxID(openGroupInboxId) } diff --git a/libsession/src/main/java/org/session/libsession/utilities/StringSubKeys.kt b/libsession/src/main/java/org/session/libsession/utilities/StringSubKeys.kt new file mode 100644 index 0000000000..88dd9569eb --- /dev/null +++ b/libsession/src/main/java/org/session/libsession/utilities/StringSubKeys.kt @@ -0,0 +1,29 @@ +package org.session.libsession.utilities + +// String substitution keys for use with the Phrase library. +// Note: The substitution will be to {app_name} etc. in the strings - but do NOT include the curly braces in these keys! +object StringSubstitutionConstants { + const val APP_NAME_KEY = "app_name" + const val COMMUNITY_NAME_KEY = "community_name" + const val CONVERSATION_COUNT_KEY = "conversation_count" + const val CONVERSATION_NAME_KEY = "conversation_name" + const val COUNT_KEY = "count" + const val DATE_TIME_KEY = "date_time" + const val DISAPPEARING_MESSAGES_TYPE_KEY = "disappearing_messages_type" + const val DOWNLOAD_URL_KEY = "download_url" // Used to invite people to download Session + const val EMOJI_KEY = "emoji" + const val FILE_TYPE_KEY = "file_type" + const val GROUP_NAME_KEY = "group_name" + const val MEMBERS_KEY = "members" + const val MESSAGE_COUNT_KEY = "message_count" + const val NAME_KEY = "name" + const val OTHER_NAME_KEY = "other_name" + const val QUERY_KEY = "query" + const val SECONDS_KEY = "seconds" + const val TOTAL_COUNT_KEY = "total_count" + const val TIME_KEY = "time" + const val TIME_LARGE_KEY = "time_large" + const val TIME_SMALL_KEY = "time_small" + const val URL_KEY = "url" + const val VERSION_KEY = "version" +} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java b/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java index 2b233e1f3d..0aef158387 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java +++ b/libsession/src/main/java/org/session/libsession/utilities/recipients/Recipient.java @@ -331,11 +331,11 @@ public class Recipient implements RecipientModifiedListener { } else if (isOpenGroupInboxRecipient()){ String inboxID = GroupUtil.getDecodedOpenGroupInboxAccountId(accountID); Contact contact = storage.getContactWithAccountID(inboxID); - if (contact == null) { return accountID; } + if (contact == null) return accountID; return contact.displayName(Contact.ContactContext.REGULAR); } else { Contact contact = storage.getContactWithAccountID(accountID); - if (contact == null) { return null; } + if (contact == null) return null; return contact.displayName(Contact.ContactContext.REGULAR); } } @@ -511,11 +511,11 @@ public class Recipient implements RecipientModifiedListener { public synchronized String toShortString() { String name = getName(); if (name != null) return name; - String sessionId = address.serialize(); - if (sessionId.length() < 4) return sessionId; // so substrings don't throw out of bounds exceptions + String accountId = address.serialize(); + if (accountId.length() < 4) return accountId; // so substrings don't throw out of bounds exceptions int takeAmount = 4; - String start = sessionId.substring(0, takeAmount); - String end = sessionId.substring(sessionId.length()-takeAmount); + String start = accountId.substring(0, takeAmount); + String end = accountId.substring(accountId.length()-takeAmount); return start+"..."+end; } diff --git a/libsession/src/main/res/values/strings.xml b/libsession/src/main/res/values/strings.xml index 53cc1bacca..499b6f9956 100644 --- a/libsession/src/main/res/values/strings.xml +++ b/libsession/src/main/res/values/strings.xml @@ -83,4 +83,7 @@ Failed to remove display picture. Failed to update profile. + + + {emoji} Attachment diff --git a/libsignal/src/main/java/org/session/libsignal/utilities/Validation.kt b/libsignal/src/main/java/org/session/libsignal/utilities/Validation.kt index d0453fc140..fdf9bd386f 100644 --- a/libsignal/src/main/java/org/session/libsignal/utilities/Validation.kt +++ b/libsignal/src/main/java/org/session/libsignal/utilities/Validation.kt @@ -1,11 +1,11 @@ package org.session.libsignal.utilities object PublicKeyValidation { - private val HEX_CHARACTERS = "0123456789ABCDEF".toSet() + private val HEX_CHARACTERS = "0123456789ABCDEFabcdef".toSet() private val INVALID_PREFIXES = setOf(IdPrefix.GROUP, IdPrefix.BLINDED, IdPrefix.BLINDEDV2) fun isValid(candidate: String, isPrefixRequired: Boolean = true): Boolean = hasValidLength(candidate) && isValidHexEncoding(candidate) && (!isPrefixRequired || IdPrefix.fromValue(candidate) != null) fun hasValidPrefix(candidate: String) = IdPrefix.fromValue(candidate) !in INVALID_PREFIXES private fun hasValidLength(candidate: String) = candidate.length == 66 - private fun isValidHexEncoding(candidate: String) = HEX_CHARACTERS.containsAll(candidate.uppercase().toSet()) + private fun isValidHexEncoding(candidate: String) = HEX_CHARACTERS.containsAll(candidate.toSet()) }