From 7fdd7e89bd2e98f15ce1b748117dec7335ade31f Mon Sep 17 00:00:00 2001 From: Jim Gustafson Date: Thu, 26 Oct 2023 07:28:52 -0700 Subject: [PATCH 01/31] Update to RingRTC v2.34.1 --- dependencies.gradle | 2 +- gradle/verification-metadata.xml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 80647b8ff9..ba66e204d2 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -116,7 +116,7 @@ dependencyResolutionManagement { library('libsignal-client', 'org.signal', 'libsignal-client').versionRef('libsignal-client') library('libsignal-android', 'org.signal', 'libsignal-android').versionRef('libsignal-client') library('signal-aesgcmprovider', 'org.signal:aesgcmprovider:0.0.3') - library('signal-ringrtc', 'org.signal:ringrtc-android:2.34.0') + library('signal-ringrtc', 'org.signal:ringrtc-android:2.34.1') library('signal-android-database-sqlcipher', 'org.signal:sqlcipher-android:4.5.4-S2') // Third Party diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 53cf3c3527..129c42b946 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -5349,12 +5349,12 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - + + + - - + + From c4f511014893bb935a9808498a84e0219f9b34e8 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 27 Oct 2023 12:02:35 -0700 Subject: [PATCH 02/31] Stop falling back to CDN0 for attachments. --- .../securesms/jobs/AttachmentUploadJob.kt | 268 ++++++++++++++++++ .../securesms/jobs/JobManagerFactories.java | 5 +- ...ob.java => LegacyAttachmentUploadJob.java} | 33 +-- .../securesms/jobs/PushSendJob.java | 13 +- .../jobs/ResumableUploadSpecJob.java | 12 +- .../securesms/sms/MessageSender.java | 9 +- .../securesms/sms/UploadDependencyGraph.kt | 3 - app/src/main/protowire/JobData.proto | 9 + .../sms/UploadDependencyGraphTest.kt | 15 +- .../org/signal/core/util/ByteExtensions.kt | 12 + .../signal/core/util/DurationExtensions.kt | 14 + .../api/SignalServiceMessageSender.java | 1 + .../push/http/ResumableUploadSpec.java | 60 ++-- 13 files changed, 364 insertions(+), 90 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt rename app/src/main/java/org/thoughtcrime/securesms/jobs/{AttachmentUploadJob.java => LegacyAttachmentUploadJob.java} (88%) create mode 100644 core-util-jvm/src/main/java/org/signal/core/util/DurationExtensions.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt new file mode 100644 index 0000000000..6b83845dfd --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt @@ -0,0 +1,268 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ +package org.thoughtcrime.securesms.jobs + +import android.graphics.Bitmap +import android.os.Build +import android.text.TextUtils +import org.greenrobot.eventbus.EventBus +import org.signal.core.util.inRoundedDays +import org.signal.core.util.logging.Log +import org.signal.core.util.mebiBytes +import org.signal.protos.resumableuploads.ResumableUpload +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.attachments.Attachment +import org.thoughtcrime.securesms.attachments.AttachmentId +import org.thoughtcrime.securesms.attachments.PointerAttachment +import org.thoughtcrime.securesms.blurhash.BlurHashEncoder +import org.thoughtcrime.securesms.database.SignalDatabase +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import org.thoughtcrime.securesms.events.PartProgressEvent +import org.thoughtcrime.securesms.jobmanager.Job +import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint +import org.thoughtcrime.securesms.jobs.ForegroundServiceUtil.startGenericTaskWhenCapable +import org.thoughtcrime.securesms.jobs.protos.AttachmentUploadJobData +import org.thoughtcrime.securesms.mms.PartAuthority +import org.thoughtcrime.securesms.net.NotPushRegisteredException +import org.thoughtcrime.securesms.recipients.Recipient +import org.thoughtcrime.securesms.service.NotificationController +import org.thoughtcrime.securesms.util.FeatureFlags +import org.thoughtcrime.securesms.util.MediaUtil +import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil +import org.whispersystems.signalservice.api.messages.SignalServiceAttachment +import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream +import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException +import org.whispersystems.signalservice.internal.crypto.PaddingInputStream +import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec +import java.io.IOException +import java.util.Objects +import java.util.Optional +import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.milliseconds + +/** + * Uploads an attachment without alteration. + * + * Queue [AttachmentCompressionJob] before to compress. + */ +class AttachmentUploadJob private constructor( + parameters: Parameters, + private val attachmentId: AttachmentId, + private var uploadSpec: ResumableUpload? +) : BaseJob(parameters) { + + companion object { + const val KEY = "AttachmentUploadJobV3" + + private val TAG = Log.tag(AttachmentUploadJob::class.java) + + private val UPLOAD_REUSE_THRESHOLD = TimeUnit.DAYS.toMillis(3) + + /** + * Foreground notification shows while uploading attachments above this. + */ + private val FOREGROUND_LIMIT = 10.mebiBytes.inWholeBytes + + @JvmStatic + val maxPlaintextSize: Long + get() { + val maxCipherTextSize = FeatureFlags.maxAttachmentSizeBytes() + val maxPaddedSize = AttachmentCipherStreamUtil.getPlaintextLength(maxCipherTextSize) + return PaddingInputStream.getMaxUnpaddedSize(maxPaddedSize) + } + } + + constructor(attachmentId: AttachmentId) : this( + Parameters.Builder() + .addConstraint(NetworkConstraint.KEY) + .setLifespan(TimeUnit.DAYS.toMillis(1)) + .setMaxAttempts(Parameters.UNLIMITED) + .build(), + attachmentId, + null + ) + + override fun serialize(): ByteArray { + return AttachmentUploadJobData( + attachmentRowId = attachmentId.rowId, + attachmentUniqueId = attachmentId.uniqueId, + uploadSpec = uploadSpec + ).encode() + } + + override fun getFactoryKey(): String = KEY + + override fun shouldTrace(): Boolean = true + + @Throws(Exception::class) + public override fun onRun() { + if (!Recipient.self().isRegistered) { + throw NotPushRegisteredException() + } + + val messageSender = ApplicationDependencies.getSignalServiceMessageSender() + val databaseAttachment = SignalDatabase.attachments.getAttachment(attachmentId) ?: throw InvalidAttachmentException("Cannot find the specified attachment.") + + val timeSinceUpload = System.currentTimeMillis() - databaseAttachment.uploadTimestamp + if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.location)) { + Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded $timeSinceUpload ms (${timeSinceUpload.milliseconds.inRoundedDays()} days) ago. Skipping.") + return + } else if (databaseAttachment.uploadTimestamp > 0) { + Log.i(TAG, "This file was previously-uploaded, but too long ago to be re-used. Age: $timeSinceUpload ms (${timeSinceUpload.milliseconds.inRoundedDays()} days)") + } + + if (uploadSpec != null && System.currentTimeMillis() > uploadSpec!!.timeout) { + Log.w(TAG, "Upload spec expired! Clearing.") + uploadSpec = null + } + + if (uploadSpec == null) { + Log.d(TAG, "Need an upload spec. Fetching...") + uploadSpec = ApplicationDependencies.getSignalServiceMessageSender().getResumableUploadSpec().toProto() + } else { + Log.d(TAG, "Re-using existing upload spec.") + } + + Log.i(TAG, "Uploading attachment for message " + databaseAttachment.mmsId + " with ID " + databaseAttachment.attachmentId) + try { + getAttachmentNotificationIfNeeded(databaseAttachment).use { notification -> + buildAttachmentStream(databaseAttachment, notification, uploadSpec!!).use { localAttachment -> + val remoteAttachment = messageSender.uploadAttachment(localAttachment) + val attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.fastPreflightId).get() + SignalDatabase.attachments.updateAttachmentAfterUpload(databaseAttachment.attachmentId, attachment, remoteAttachment.uploadTimestamp) + } + } + } catch (e: NonSuccessfulResumableUploadResponseCodeException) { + if (e.code == 400) { + Log.w(TAG, "Failed to upload due to a 400 when getting resumable upload information. Clearing upload spec.", e) + uploadSpec = null + } + + throw e + } + } + + private fun getAttachmentNotificationIfNeeded(attachment: Attachment): NotificationController? { + return if (attachment.size >= FOREGROUND_LIMIT) { + try { + startGenericTaskWhenCapable(context, context.getString(R.string.AttachmentUploadJob_uploading_media)) + } catch (e: UnableToStartException) { + Log.w(TAG, "Unable to start foreground service", e) + null + } + } else { + null + } + } + + override fun onFailure() { + if (isCanceled) { + SignalDatabase.attachments.deleteAttachment(attachmentId) + } + } + + override fun onShouldRetry(exception: Exception): Boolean { + return exception is IOException && exception !is NotPushRegisteredException + } + + @Throws(InvalidAttachmentException::class) + private fun buildAttachmentStream(attachment: Attachment, notification: NotificationController?, resumableUploadSpec: ResumableUpload): SignalServiceAttachmentStream { + if (attachment.uri == null || attachment.size == 0L) { + throw InvalidAttachmentException(IOException("Outgoing attachment has no data!")) + } + + return try { + val inputStream = PartAuthority.getAttachmentStream(context, attachment.uri!!) + val builder = SignalServiceAttachment.newStreamBuilder() + .withStream(inputStream) + .withContentType(attachment.contentType) + .withLength(attachment.size) + .withFileName(attachment.fileName) + .withVoiceNote(attachment.isVoiceNote) + .withBorderless(attachment.isBorderless) + .withGif(attachment.isVideoGif) + .withWidth(attachment.width) + .withHeight(attachment.height) + .withUploadTimestamp(System.currentTimeMillis()) + .withCaption(attachment.caption) + .withResumableUploadSpec(ResumableUploadSpec.from(resumableUploadSpec)) + .withCancelationSignal { this.isCanceled } + .withListener(object : SignalServiceAttachment.ProgressListener { + override fun onAttachmentProgress(total: Long, progress: Long) { + EventBus.getDefault().postSticky(PartProgressEvent(attachment, PartProgressEvent.Type.NETWORK, total, progress)) + notification?.setProgress(total, progress) + } + + override fun shouldCancel(): Boolean { + return isCanceled + } + }) + + if (MediaUtil.isImageType(attachment.contentType)) { + builder.withBlurHash(getImageBlurHash(attachment)).build() + } else if (MediaUtil.isVideoType(attachment.contentType)) { + builder.withBlurHash(getVideoBlurHash(attachment)).build() + } else { + builder.build() + } + } catch (e: IOException) { + throw InvalidAttachmentException(e) + } + } + + @Throws(IOException::class) + private fun getImageBlurHash(attachment: Attachment): String? { + if (attachment.blurHash != null) { + return attachment.blurHash!!.hash + } + + if (attachment.uri == null) { + return null + } + + return PartAuthority.getAttachmentStream(context, attachment.uri!!).use { inputStream -> + BlurHashEncoder.encode(inputStream) + } + } + + @Throws(IOException::class) + private fun getVideoBlurHash(attachment: Attachment): String? { + if (attachment.blurHash != null) { + return attachment.blurHash!!.hash + } + + if (Build.VERSION.SDK_INT < 23) { + Log.w(TAG, "Video thumbnails not supported...") + return null + } + + return MediaUtil.getVideoThumbnail(context, Objects.requireNonNull(attachment.uri), 1000)?.let { bitmap -> + val thumb = Bitmap.createScaledBitmap(bitmap, 100, 100, false) + bitmap.recycle() + + Log.i(TAG, "Generated video thumbnail...") + val hash = BlurHashEncoder.encode(thumb) + thumb.recycle() + + hash + } + } + + private inner class InvalidAttachmentException : Exception { + constructor(message: String?) : super(message) + constructor(e: Exception?) : super(e) + } + + class Factory : Job.Factory { + override fun create(parameters: Parameters, serializedData: ByteArray?): AttachmentUploadJob { + val data = AttachmentUploadJobData.ADAPTER.decode(serializedData!!) + return AttachmentUploadJob( + parameters = parameters, + attachmentId = AttachmentId(data.attachmentRowId, data.attachmentUniqueId), + data.uploadSpec + ) + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index c51e795896..dcf7c2e383 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -95,11 +95,11 @@ public final class JobManagerFactories { public static Map getJobFactories(@NonNull Application application) { return new HashMap() {{ put(AccountConsistencyWorkerJob.KEY, new AccountConsistencyWorkerJob.Factory()); + put(AttachmentCompressionJob.KEY, new AttachmentCompressionJob.Factory()); put(AttachmentCopyJob.KEY, new AttachmentCopyJob.Factory()); put(AttachmentDownloadJob.KEY, new AttachmentDownloadJob.Factory()); - put(AttachmentUploadJob.KEY, new AttachmentUploadJob.Factory()); put(AttachmentMarkUploadedJob.KEY, new AttachmentMarkUploadedJob.Factory()); - put(AttachmentCompressionJob.KEY, new AttachmentCompressionJob.Factory()); + put(AttachmentUploadJob.KEY, new AttachmentUploadJob.Factory()); put(AutomaticSessionResetJob.KEY, new AutomaticSessionResetJob.Factory()); put(AvatarGroupsV1DownloadJob.KEY, new AvatarGroupsV1DownloadJob.Factory()); put(AvatarGroupsV2DownloadJob.KEY, new AvatarGroupsV2DownloadJob.Factory()); @@ -132,6 +132,7 @@ public static Map getJobFactories(@NonNull Application appl put(IndividualSendJob.KEY, new IndividualSendJob.Factory()); put(LeaveGroupV2Job.KEY, new LeaveGroupV2Job.Factory()); put(LeaveGroupV2WorkerJob.KEY, new LeaveGroupV2WorkerJob.Factory()); + put(LegacyAttachmentUploadJob.KEY, new LegacyAttachmentUploadJob.Factory()); put(LocalBackupJob.KEY, new LocalBackupJob.Factory()); put(LocalBackupJobApi29.KEY, new LocalBackupJobApi29.Factory()); put(MarkerJob.KEY, new MarkerJob.Factory()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java similarity index 88% rename from app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java rename to app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java index f6a302c866..2c1271c06f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LegacyAttachmentUploadJob.java @@ -26,21 +26,17 @@ import org.thoughtcrime.securesms.events.PartProgressEvent; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.JsonJobData; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.mms.PartAuthority; import org.thoughtcrime.securesms.net.NotPushRegisteredException; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.NotificationController; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.MediaUtil; import org.whispersystems.signalservice.api.SignalServiceMessageSender; -import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException; import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException; -import org.whispersystems.signalservice.internal.crypto.PaddingInputStream; import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec; import java.io.IOException; @@ -54,12 +50,13 @@ *

* Queue {@link AttachmentCompressionJob} before to compress. */ -public final class AttachmentUploadJob extends BaseJob { +@Deprecated +public final class LegacyAttachmentUploadJob extends BaseJob { public static final String KEY = "AttachmentUploadJobV2"; @SuppressWarnings("unused") - private static final String TAG = Log.tag(AttachmentUploadJob.class); + private static final String TAG = Log.tag(LegacyAttachmentUploadJob.class); private static final long UPLOAD_REUSE_THRESHOLD = TimeUnit.DAYS.toMillis(3); @@ -72,27 +69,11 @@ public final class AttachmentUploadJob extends BaseJob { */ private static final int FOREGROUND_LIMIT = 10 * 1024 * 1024; - public static long getMaxPlaintextSize() { - long maxCipherTextSize = FeatureFlags.maxAttachmentSizeBytes(); - long maxPaddedSize = AttachmentCipherStreamUtil.getPlaintextLength(maxCipherTextSize); - return PaddingInputStream.getMaxUnpaddedSize(maxPaddedSize); - } - private final AttachmentId attachmentId; private boolean forceV2; - public AttachmentUploadJob(AttachmentId attachmentId) { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build(), - attachmentId, - false); - } - - private AttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId, boolean forceV2) { + private LegacyAttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId, boolean forceV2) { super(parameters); this.attachmentId = attachmentId; this.forceV2 = forceV2; @@ -289,12 +270,12 @@ private class InvalidAttachmentException extends Exception { } } - public static final class Factory implements Job.Factory { + public static final class Factory implements Job.Factory { @Override - public @NonNull AttachmentUploadJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) { + public @NonNull LegacyAttachmentUploadJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) { JsonJobData data = JsonJobData.deserialize(serializedData); - return new AttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)), data.getBooleanOrDefault(KEY_FORCE_V2, false)); + return new LegacyAttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)), data.getBooleanOrDefault(KEY_FORCE_V2, false)); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java index 43c23b6025..90d16c0721 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -242,16 +242,9 @@ protected static Set enqueueCompressingAndUploadAttachmentsChains(@NonNu return new HashSet<>(Stream.of(attachments).map(a -> { AttachmentUploadJob attachmentUploadJob = new AttachmentUploadJob(((DatabaseAttachment) a).getAttachmentId()); - if (message.isGroup()) { - jobManager.startChain(AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, false, -1)) - .then(attachmentUploadJob) - .enqueue(); - } else { - jobManager.startChain(AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, false, -1)) - .then(new ResumableUploadSpecJob()) - .then(attachmentUploadJob) - .enqueue(); - } + jobManager.startChain(AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, false, -1)) + .then(attachmentUploadJob) + .enqueue(); return attachmentUploadJob.getId(); }) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ResumableUploadSpecJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/ResumableUploadSpecJob.java index b73b2b8a0c..47147ff4a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ResumableUploadSpecJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ResumableUploadSpecJob.java @@ -13,6 +13,10 @@ import java.io.IOException; import java.util.concurrent.TimeUnit; +/** + * No longer used. Functionality has been merged into {@link AttachmentUploadJob}. + */ +@Deprecated public class ResumableUploadSpecJob extends BaseJob { private static final String TAG = Log.tag(ResumableUploadSpecJob.class); @@ -21,14 +25,6 @@ public class ResumableUploadSpecJob extends BaseJob { public static final String KEY = "ResumableUploadSpecJob"; - public ResumableUploadSpecJob() { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build()); - } - private ResumableUploadSpecJob(@NonNull Parameters parameters) { super(parameters); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java index 4e51e50247..55b52d5d6f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sms/MessageSender.java @@ -59,7 +59,6 @@ import org.thoughtcrime.securesms.jobs.IndividualSendJob; import org.thoughtcrime.securesms.jobs.ReactionSendJob; import org.thoughtcrime.securesms.jobs.RemoteDeleteSendJob; -import org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob; import org.thoughtcrime.securesms.jobs.SmsSendJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.linkpreview.LinkPreview; @@ -418,17 +417,15 @@ public static void sendMediaBroadcast(@NonNull Context context, AttachmentTable attachmentDatabase = SignalDatabase.attachments(); DatabaseAttachment databaseAttachment = attachmentDatabase.insertAttachmentForPreUpload(attachment); - Job compressionJob = AttachmentCompressionJob.fromAttachment(databaseAttachment, false, -1); - Job resumableUploadSpecJob = new ResumableUploadSpecJob(); - Job uploadJob = new AttachmentUploadJob(databaseAttachment.getAttachmentId()); + Job compressionJob = AttachmentCompressionJob.fromAttachment(databaseAttachment, false, -1); + Job uploadJob = new AttachmentUploadJob(databaseAttachment.getAttachmentId()); ApplicationDependencies.getJobManager() .startChain(compressionJob) - .then(resumableUploadSpecJob) .then(uploadJob) .enqueue(); - return new PreUploadResult(media, databaseAttachment.getAttachmentId(), Arrays.asList(compressionJob.getId(), resumableUploadSpecJob.getId(), uploadJob.getId())); + return new PreUploadResult(media, databaseAttachment.getAttachmentId(), Arrays.asList(compressionJob.getId(), uploadJob.getId())); } catch (MmsException e) { Log.w(TAG, "preUploadPushAttachment() - Failed to upload!", e); return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/sms/UploadDependencyGraph.kt b/app/src/main/java/org/thoughtcrime/securesms/sms/UploadDependencyGraph.kt index 04f6ab202b..b2d475e0e7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sms/UploadDependencyGraph.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sms/UploadDependencyGraph.kt @@ -11,7 +11,6 @@ import org.thoughtcrime.securesms.jobmanager.JobManager import org.thoughtcrime.securesms.jobs.AttachmentCompressionJob import org.thoughtcrime.securesms.jobs.AttachmentCopyJob import org.thoughtcrime.securesms.jobs.AttachmentUploadJob -import org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob import org.thoughtcrime.securesms.mms.OutgoingMessage /** @@ -196,12 +195,10 @@ class UploadDependencyGraph private constructor( */ private fun createAttachmentUploadChain(jobManager: JobManager, databaseAttachment: DatabaseAttachment): Pair { val compressionJob: Job = AttachmentCompressionJob.fromAttachment(databaseAttachment, false, -1) - val resumableUploadSpecJob: Job = ResumableUploadSpecJob() val uploadJob: Job = AttachmentUploadJob(databaseAttachment.attachmentId) return uploadJob.id to jobManager .startChain(compressionJob) - .then(resumableUploadSpecJob) .then(uploadJob) } } diff --git a/app/src/main/protowire/JobData.proto b/app/src/main/protowire/JobData.proto index aa7020bed5..6503ce3c12 100644 --- a/app/src/main/protowire/JobData.proto +++ b/app/src/main/protowire/JobData.proto @@ -2,9 +2,12 @@ syntax = "proto3"; package signal; +import "ResumableUploads.proto"; + option java_package = "org.thoughtcrime.securesms.jobs.protos"; option java_multiple_files = true; + message CallSyncEventJobRecord { uint64 recipientId = 1; reserved 2; @@ -28,3 +31,9 @@ message CallLogEventSendJobData { message CallLinkUpdateSendJobData { string callLinkRoomId = 1; } + +message AttachmentUploadJobData { + uint64 attachmentRowId = 1; + uint64 attachmentUniqueId = 2; + optional ResumableUpload uploadSpec = 3; +} \ No newline at end of file diff --git a/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt b/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt index bcf5946565..9b499e7187 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt @@ -21,7 +21,7 @@ import org.thoughtcrime.securesms.jobmanager.JsonJobData import org.thoughtcrime.securesms.jobs.AttachmentCompressionJob import org.thoughtcrime.securesms.jobs.AttachmentCopyJob import org.thoughtcrime.securesms.jobs.AttachmentUploadJob -import org.thoughtcrime.securesms.jobs.ResumableUploadSpecJob +import org.thoughtcrime.securesms.jobs.protos.AttachmentUploadJobData import org.thoughtcrime.securesms.mms.OutgoingMessage import org.thoughtcrime.securesms.mms.SentMediaQuality import org.thoughtcrime.securesms.recipients.Recipient @@ -206,16 +206,15 @@ class UploadDependencyGraphTest { assertTrue(steps.all { it.size == 1 }) assertTrue(steps[0][0] is AttachmentCompressionJob) - assertTrue(steps[1][0] is ResumableUploadSpecJob) - assertTrue(steps[2][0] is AttachmentUploadJob) + assertTrue(steps[1][0] is AttachmentUploadJob) if (expectedCopyDestinationCount > 0) { - assertTrue(steps[3][0] is AttachmentCopyJob) + assertTrue(steps[2][0] is AttachmentCopyJob) - val uploadData = JsonJobData.deserialize(steps[2][0].serialize()) - val copyData = JsonJobData.deserialize(steps[3][0].serialize()) + val uploadData = AttachmentUploadJobData.ADAPTER.decode(steps[1][0].serialize()!!) + val copyData = JsonJobData.deserialize(steps[2][0].serialize()) - val uploadAttachmentId = AttachmentId(uploadData.getLong("row_id"), uploadData.getLong("unique_id")) + val uploadAttachmentId = AttachmentId(uploadData.attachmentRowId, uploadData.attachmentUniqueId) val copySourceAttachmentId = JsonUtils.fromJson(copyData.getString("source_id"), AttachmentId::class.java) assertEquals(uploadAttachmentId, copySourceAttachmentId) @@ -223,7 +222,7 @@ class UploadDependencyGraphTest { val copyDestinations = copyData.getStringArray("destination_ids") assertEquals(expectedCopyDestinationCount, copyDestinations.size) } else { - assertEquals(3, steps.size) + assertEquals(2, steps.size) } } diff --git a/core-util-jvm/src/main/java/org/signal/core/util/ByteExtensions.kt b/core-util-jvm/src/main/java/org/signal/core/util/ByteExtensions.kt index 52067d0d1b..5b8f5b9a8b 100644 --- a/core-util-jvm/src/main/java/org/signal/core/util/ByteExtensions.kt +++ b/core-util-jvm/src/main/java/org/signal/core/util/ByteExtensions.kt @@ -8,15 +8,27 @@ package org.signal.core.util inline val Long.bytes: ByteSize get() = ByteSize(this) +inline val Int.bytes: ByteSize + get() = ByteSize(this.toLong()) + inline val Long.kibiBytes: ByteSize get() = (this * 1024).bytes +inline val Int.kibiBytes: ByteSize + get() = (this * 1024).bytes + inline val Long.mebiBytes: ByteSize get() = (this * 1024).kibiBytes +inline val Int.mebiBytes: ByteSize + get() = (this * 1024).kibiBytes + inline val Long.gibiBytes: ByteSize get() = (this * 1024).mebiBytes +inline val Int.gibiBytes: ByteSize + get() = (this * 1024).mebiBytes + class ByteSize(val bytes: Long) { val inWholeBytes: Long get() = bytes diff --git a/core-util-jvm/src/main/java/org/signal/core/util/DurationExtensions.kt b/core-util-jvm/src/main/java/org/signal/core/util/DurationExtensions.kt new file mode 100644 index 0000000000..d3fb7e867e --- /dev/null +++ b/core-util-jvm/src/main/java/org/signal/core/util/DurationExtensions.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.signal.core.util + +import kotlin.time.Duration +import kotlin.time.DurationUnit + +fun Duration.inRoundedMilliseconds(places: Int = 2) = this.toDouble(DurationUnit.MILLISECONDS).roundedString(places) +fun Duration.inRoundedMinutes(places: Int = 2) = this.toDouble(DurationUnit.MINUTES).roundedString(places) +fun Duration.inRoundedHours(places: Int = 2) = this.toDouble(DurationUnit.HOURS).roundedString(places) +fun Duration.inRoundedDays(places: Int = 2) = this.toDouble(DurationUnit.DAYS).roundedString(places) diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java index 7cd3a3a7c9..39b854cf9a 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java @@ -798,6 +798,7 @@ public SignalServiceAttachmentPointer uploadAttachment(SignalServiceAttachmentSt if (attachment.getResumableUploadSpec().isPresent()) { return uploadAttachmentV4(attachment, attachmentKey, attachmentData); } else { + Log.w(TAG, "Using legacy attachment upload endpoint."); return uploadAttachmentV2(attachment, attachmentKey, attachmentData); } } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/ResumableUploadSpec.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/ResumableUploadSpec.java index c1f28c4edf..d3fe2d2419 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/ResumableUploadSpec.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/ResumableUploadSpec.java @@ -6,7 +6,6 @@ import java.io.IOException; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -68,15 +67,15 @@ public Map getHeaders() { return headers; } - public String serialize() { + public ResumableUpload toProto() { ResumableUpload.Builder builder = new ResumableUpload.Builder() - .secretKey(ByteString.of(getSecretKey())) - .iv(ByteString.of(getIV())) - .timeout(getExpirationTimestamp()) - .cdnNumber(getCdnNumber()) - .cdnKey(getCdnKey()) - .location(getResumeLocation()) - .timeout(getExpirationTimestamp()); + .secretKey(ByteString.of(getSecretKey())) + .iv(ByteString.of(getIV())) + .timeout(getExpirationTimestamp()) + .cdnNumber(getCdnNumber()) + .cdnKey(getCdnKey()) + .location(getResumeLocation()) + .timeout(getExpirationTimestamp()); builder.headers( headers.entrySet() @@ -85,31 +84,38 @@ public String serialize() { .collect(Collectors.toList()) ); - return Base64.encodeWithPadding(builder.build().encode()); + return builder.build(); } - public static ResumableUploadSpec deserialize(String serializedSpec) throws ResumeLocationInvalidException { - if (serializedSpec == null) return null; + public String serialize() { + return Base64.encodeWithPadding(toProto().encode()); + } + public static ResumableUploadSpec deserialize(String serializedSpec) throws ResumeLocationInvalidException { try { ResumableUpload resumableUpload = ResumableUpload.ADAPTER.decode(Base64.decode(serializedSpec)); - - Map headers = new HashMap<>(); - for (ResumableUpload.Header header : resumableUpload.headers) { - headers.put(header.key, header.value_); - } - - return new ResumableUploadSpec( - resumableUpload.secretKey.toByteArray(), - resumableUpload.iv.toByteArray(), - resumableUpload.cdnKey, - resumableUpload.cdnNumber, - resumableUpload.location, - resumableUpload.timeout, - headers - ); + return from(resumableUpload); } catch (IOException e) { throw new ResumeLocationInvalidException(); } } + + public static ResumableUploadSpec from(ResumableUpload resumableUpload) throws ResumeLocationInvalidException { + if (resumableUpload == null) return null; + + Map headers = new HashMap<>(); + for (ResumableUpload.Header header : resumableUpload.headers) { + headers.put(header.key, header.value_); + } + + return new ResumableUploadSpec( + resumableUpload.secretKey.toByteArray(), + resumableUpload.iv.toByteArray(), + resumableUpload.cdnKey, + resumableUpload.cdnNumber, + resumableUpload.location, + resumableUpload.timeout, + headers + ); + } } From b8d229e58eb7ddacfd956d3dcc538bfb48116944 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 27 Oct 2023 14:27:17 -0700 Subject: [PATCH 03/31] Enable auto-updates for nightly builds. --- app/build.gradle | 32 ++++++++++++++++--- .../securesms/apkupdate/ApkUpdateInstaller.kt | 17 ++-------- .../apkupdate/ApkUpdateNotifications.kt | 23 +++++++++++++ .../ApkUpdatePackageInstallerReceiver.kt | 5 ++- .../securesms/jobs/ApkUpdateJob.kt | 2 +- .../notifications/NotificationIds.java | 1 + .../securesms/util/Environment.kt | 1 + app/src/main/res/values/strings.xml | 2 ++ app/src/nightly/AndroidManifest.xml | 28 ++++++++++++++++ 9 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 app/src/nightly/AndroidManifest.xml diff --git a/app/build.gradle b/app/build.gradle index 7b58b1428c..0b89d83b13 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -320,22 +320,26 @@ android { dimension 'distribution' isDefault true buildConfigField "boolean", "MANAGES_APP_UPDATES", "false" - buildConfigField "String", "APK_UPDATE_URL", "null" + buildConfigField "String", "APK_UPDATE_MANIFEST_URL", "null" buildConfigField "String", "BUILD_DISTRIBUTION_TYPE", "\"play\"" } website { dimension 'distribution' buildConfigField "boolean", "MANAGES_APP_UPDATES", "true" - buildConfigField "String", "APK_UPDATE_URL", "\"https://updates.signal.org/android\"" + buildConfigField "String", "APK_UPDATE_MANIFEST_URL", "\"https://updates.signal.org/android/latest.json\"" buildConfigField "String", "BUILD_DISTRIBUTION_TYPE", "\"website\"" } nightly { + def apkUpdateManifestUrl = "" + if (project.hasProperty('nightlyApkUpdateManifestUrl')) { + apkUpdateManifestUrl = project.getProperty('nightlyApkUpdateManifestUrl') + } dimension 'distribution' versionNameSuffix "-nightly-untagged-${getDateSuffix()}" - buildConfigField "boolean", "MANAGES_APP_UPDATES", "false" - buildConfigField "String", "APK_UPDATE_URL", "null" + buildConfigField "boolean", "MANAGES_APP_UPDATES", "true" + buildConfigField "String", "APK_UPDATE_MANIFEST_URL", "\"${apkUpdateManifestUrl}\"" buildConfigField "String", "BUILD_DISTRIBUTION_TYPE", "\"nightly\"" } @@ -400,6 +404,9 @@ android { tag = tag.substring(1) } output.versionNameOverride = tag + output.outputFileName = output.outputFileName.replace(".apk", "-${versionNameOverride}.apk") + } else { + output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk") } } else { output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk") @@ -659,6 +666,23 @@ tasks.withType(Test) { } } +project.tasks.configureEach { task -> + if (task.name.toLowerCase().contains("nightly") && task.name != 'checkNightlyParams') { + task.dependsOn checkNightlyParams + } +} + +tasks.register('checkNightlyParams') { + doFirst { + if (project.gradle.startParameter.taskNames.any { it.toLowerCase().contains("nightly") }) { + if (!project.hasProperty('nightlyApkUpdateManifestUrl')) { + throw new GradleException("Required command-line parameter 'nightlyApkUpdateManifestUrl' not found for nightly build!") + } + } + } +} + + def loadKeystoreProperties(filename) { def keystorePropertiesFile = file("${project.rootDir}/${filename}") if (keystorePropertiesFile.exists()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateInstaller.kt b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateInstaller.kt index a29a40278c..1945561ebc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateInstaller.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateInstaller.kt @@ -16,6 +16,7 @@ import org.signal.core.util.getDownloadManager import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.util.Environment import org.thoughtcrime.securesms.util.FileUtils import java.io.FileInputStream import java.io.IOException @@ -86,17 +87,6 @@ object ApkUpdateInstaller { Log.d(TAG, "Beginning APK install...") val packageInstaller: PackageInstaller = context.packageManager.packageInstaller - Log.d(TAG, "Clearing inactive sessions...") - packageInstaller.mySessions - .filter { session -> !session.isActive } - .forEach { session -> - try { - packageInstaller.abandonSession(session.sessionId) - } catch (e: SecurityException) { - Log.w(TAG, "Failed to abandon inactive session!", e) - } - } - val sessionParams = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL).apply { // At this point, we always want to set this if possible, since we've already prompted the user with our own notification when necessary. // This lets us skip the system-generated notification. @@ -151,8 +141,7 @@ object ApkUpdateInstaller { } private fun shouldAutoUpdate(): Boolean { - // TODO Auto-updates temporarily disabled. Once we have designs for allowing users to opt-out of auto-updates, we can re-enable this - return false -// return Build.VERSION.SDK_INT >= 31 && SignalStore.apkUpdate().autoUpdate && !ApplicationDependencies.getAppForegroundObserver().isForegrounded + // TODO Auto-updates temporarily restricted to nightlies. Once we have designs for allowing users to opt-out of auto-updates, we can re-enable this + return Environment.IS_NIGHTLY && Build.VERSION.SDK_INT >= 31 && SignalStore.apkUpdate().autoUpdate && !ApplicationDependencies.getAppForegroundObserver().isForegrounded } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateNotifications.kt b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateNotifications.kt index 76dc1a26b5..0e715fd3a2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateNotifications.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateNotifications.kt @@ -66,11 +66,34 @@ object ApkUpdateNotifications { .setSmallIcon(R.drawable.ic_notification) .setColor(ContextCompat.getColor(context, R.color.core_ultramarine)) .setContentIntent(pendingIntent) + .setAutoCancel(true) .build() ServiceUtil.getNotificationManager(context).notify(NotificationIds.APK_UPDATE_FAILED_INSTALL, notification) } + fun showAutoUpdateSuccess(context: Context) { + val pendingIntent = PendingIntent.getActivity( + context, + 0, + Intent(context, MainActivity::class.java), + PendingIntentFlags.immutable() + ) + + val appVersionName = context.packageManager.getPackageInfo(context.packageName, 0).versionName + + val notification = NotificationCompat.Builder(context, NotificationChannels.getInstance().APP_UPDATES) + .setContentTitle(context.getString(R.string.ApkUpdateNotifications_auto_update_success_title)) + .setContentText(context.getString(R.string.ApkUpdateNotifications_auto_update_success_body, appVersionName)) + .setSmallIcon(R.drawable.ic_notification) + .setColor(ContextCompat.getColor(context, R.color.core_ultramarine)) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .build() + + ServiceUtil.getNotificationManager(context).notify(NotificationIds.APK_UPDATE_SUCCESSFUL_INSTALL, notification) + } + enum class FailureReason { UNKNOWN, ABORTED, diff --git a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdatePackageInstallerReceiver.kt b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdatePackageInstallerReceiver.kt index 9deb2c4b98..c988d2c5ba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdatePackageInstallerReceiver.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdatePackageInstallerReceiver.kt @@ -34,8 +34,11 @@ class ApkUpdatePackageInstallerReceiver : BroadcastReceiver() { Log.w(TAG, "[onReceive] Status: $statusCode, Message: $statusMessage") when (statusCode) { + PackageInstaller.STATUS_SUCCESS -> { + Log.i(TAG, "Update installed successfully!") + ApkUpdateNotifications.showAutoUpdateSuccess(context) + } PackageInstaller.STATUS_PENDING_USER_ACTION -> handlePendingUserAction(context, userInitiated, intent!!) - PackageInstaller.STATUS_SUCCESS -> Log.w(TAG, "Update installed successfully!") PackageInstaller.STATUS_FAILURE_ABORTED -> ApkUpdateNotifications.showInstallFailed(context, FailureReason.ABORTED) PackageInstaller.STATUS_FAILURE_BLOCKED -> ApkUpdateNotifications.showInstallFailed(context, FailureReason.BLOCKED) PackageInstaller.STATUS_FAILURE_INCOMPATIBLE -> ApkUpdateNotifications.showInstallFailed(context, FailureReason.INCOMPATIBLE) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt index 846969b0c2..2e7094b87b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt @@ -63,7 +63,7 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet Log.i(TAG, "Checking for APK update...") val client = OkHttpClient() - val request = Request.Builder().url("${BuildConfig.APK_UPDATE_URL}/latest.json").build() + val request = Request.Builder().url(BuildConfig.APK_UPDATE_MANIFEST_URL).build() val rawUpdateDescriptor: String = client.newCall(request).execute().use { response -> if (!response.isSuccessful || response.body() == null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java index 02b74fe1d4..7173aeb46a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java @@ -9,6 +9,7 @@ public final class NotificationIds { public static final int FCM_FAILURE = 12; public static final int APK_UPDATE_PROMPT_INSTALL = 666; public static final int APK_UPDATE_FAILED_INSTALL = 667; + public static final int APK_UPDATE_SUCCESSFUL_INSTALL = 668; public static final int PENDING_MESSAGES = 1111; public static final int MESSAGE_SUMMARY = 1338; public static final int APPLICATION_MIGRATION = 4242; diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt b/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt index 8e68650274..2733b10119 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt @@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.BuildConfig object Environment { const val IS_STAGING: Boolean = BuildConfig.BUILD_ENVIRONMENT_TYPE == "Staging" const val IS_PNP: Boolean = BuildConfig.BUILD_ENVIRONMENT_TYPE == "Pnp" + const val IS_NIGHTLY: Boolean = BuildConfig.BUILD_DISTRIBUTION_TYPE == "nightly" object Donations { @JvmStatic diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c7c6ed3c1e..22c36b5a98 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2105,6 +2105,8 @@ A new version of Signal is available. Tap to update. Signal failed to update We will try again later. + Signal successfully updated + You were automatically updated to version %1$s. Send message? diff --git a/app/src/nightly/AndroidManifest.xml b/app/src/nightly/AndroidManifest.xml new file mode 100644 index 0000000000..613e309f7f --- /dev/null +++ b/app/src/nightly/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ea0c3dbe5a9e31bf134c259f9d03df51df726d53 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 30 Oct 2023 09:36:20 -0400 Subject: [PATCH 04/31] Add logging around database transactions and group recipient creation. --- .../java/org/thoughtcrime/securesms/database/RecipientTable.kt | 2 ++ .../thoughtcrime/securesms/messages/IncomingMessageObserver.kt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt index 1f8cafa905..c74ba9febc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt @@ -607,6 +607,8 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da Log.w(TAG, "Failed to update newly-created record for $recipientId") } + Log.i(TAG, "Group $groupId was newly-inserted as $recipientId") + return recipientId } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt index 93a407d37f..95dfaad7fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt @@ -393,6 +393,7 @@ class IncomingMessageObserver(private val context: Application) { GroupsV2ProcessingLock.acquireGroupProcessingLock().use { ReentrantSessionLock.INSTANCE.acquire().use { batch.forEach { + Log.d(TAG, "Beginning database transaction...") SignalDatabase.runInTransaction { val followUpOperations: List? = processEnvelope(bufferedStore, it.envelope, it.serverDeliveredTimestamp) bufferedStore.flushToDisk() @@ -401,6 +402,7 @@ class IncomingMessageObserver(private val context: Application) { ApplicationDependencies.getJobManager().addAll(jobs) } } + Log.d(TAG, "Ended database transaction.") signalWebSocket.sendAck(it) } } From 297308ad763f8cee8027d7d429716368a4d49acf Mon Sep 17 00:00:00 2001 From: Nicholas Tinsley Date: Mon, 30 Oct 2023 10:29:55 -0400 Subject: [PATCH 05/31] Only suggest scheduled message times in the future. Addresses #13139 --- .../conversation/ScheduleMessageTimePickerBottomSheet.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ScheduleMessageTimePickerBottomSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/ScheduleMessageTimePickerBottomSheet.kt index f3127cede1..45abb6abd3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ScheduleMessageTimePickerBottomSheet.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ScheduleMessageTimePickerBottomSheet.kt @@ -61,6 +61,10 @@ class ScheduleMessageTimePickerBottomSheet : FixedRoundedCornerBottomSheetDialog scheduledLocalDateTime = scheduledLocalDateTime.plusMinutes(5L - (scheduledLocalDateTime.minute % 5)) } + if (scheduledLocalDateTime.isBefore(LocalDateTime.now())) { + scheduledLocalDateTime.plusDays(1) + } + scheduledHour = scheduledLocalDateTime.hour scheduledMinute = scheduledLocalDateTime.minute From a8e02b9cedc412d4e41893707e7a44476652250c Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 30 Oct 2023 08:51:37 -0700 Subject: [PATCH 06/31] Move envelope follow-up operations outside of the transaction. --- .../securesms/database/SignalDatabase.kt | 11 ++++------ .../securesms/jobs/RetrieveProfileJob.java | 3 ++- .../messages/IncomingMessageObserver.kt | 20 +++++++++++-------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt index fbc238f1f8..57ddff5ec9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt @@ -6,6 +6,7 @@ import androidx.annotation.VisibleForTesting import net.zetetic.database.sqlcipher.SQLiteOpenHelper import org.signal.core.util.SqlUtil import org.signal.core.util.logging.Log +import org.signal.core.util.withinTransaction import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.DatabaseSecret import org.thoughtcrime.securesms.crypto.MasterSecret @@ -345,13 +346,9 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data } @JvmStatic - fun runInTransaction(operation: Runnable) { - instance!!.signalWritableDatabase.beginTransaction() - try { - operation.run() - instance!!.signalWritableDatabase.setTransactionSuccessful() - } finally { - instance!!.signalWritableDatabase.endTransaction() + fun runInTransaction(block: (SQLiteDatabase) -> T): T { + return instance!!.signalWritableDatabase.withinTransaction { + block(it) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java index 7dd60b3a15..37a946af20 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java @@ -292,10 +292,11 @@ public void onRun() throws IOException, RetryLaterException { //noinspection SimplifyStreamApiCallChains ListUtil.chunk(operationState.profiles, 150).stream().forEach(list -> { - SignalDatabase.runInTransaction(() -> { + SignalDatabase.runInTransaction((db) -> { for (Pair profile : list) { process(profile.first(), profile.second()); } + return null; }); }); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt index 95dfaad7fd..57975b0c1d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.kt @@ -392,18 +392,22 @@ class IncomingMessageObserver(private val context: Application) { val startTime = System.currentTimeMillis() GroupsV2ProcessingLock.acquireGroupProcessingLock().use { ReentrantSessionLock.INSTANCE.acquire().use { - batch.forEach { + batch.forEach { response -> Log.d(TAG, "Beginning database transaction...") - SignalDatabase.runInTransaction { - val followUpOperations: List? = processEnvelope(bufferedStore, it.envelope, it.serverDeliveredTimestamp) + val followUpOperations = SignalDatabase.runInTransaction { db -> + val followUps: List? = processEnvelope(bufferedStore, response.envelope, response.serverDeliveredTimestamp) bufferedStore.flushToDisk() - if (followUpOperations != null) { - val jobs = followUpOperations.mapNotNull { it.run() } - ApplicationDependencies.getJobManager().addAll(jobs) - } + followUps } Log.d(TAG, "Ended database transaction.") - signalWebSocket.sendAck(it) + + if (followUpOperations != null) { + Log.d(TAG, "Running ${followUpOperations.size} follow-up operations...") + val jobs = followUpOperations.mapNotNull { it.run() } + ApplicationDependencies.getJobManager().addAll(jobs) + } + + signalWebSocket.sendAck(response) } } } From de2cf6026e84d2e0f42d2a714e356d2085729497 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 30 Oct 2023 12:45:52 -0400 Subject: [PATCH 07/31] Fix nightly build. --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 0b89d83b13..46af528b71 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -404,7 +404,7 @@ android { tag = tag.substring(1) } output.versionNameOverride = tag - output.outputFileName = output.outputFileName.replace(".apk", "-${versionNameOverride}.apk") + output.outputFileName = output.outputFileName.replace(".apk", "-${output.versionNameOverride}.apk") } else { output.outputFileName = output.outputFileName.replace(".apk", "-${variant.versionName}.apk") } From 622aa844e49ccd68d00f594ca53001fe8cf2855f Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 30 Oct 2023 15:26:32 -0400 Subject: [PATCH 08/31] Clear glide memory cache on attachment delete. --- .../org/thoughtcrime/securesms/database/AttachmentTable.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java index 42775e72af..3af59350b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.java @@ -44,6 +44,7 @@ import org.signal.core.util.SetUtil; import org.signal.core.util.SqlUtil; import org.signal.core.util.StreamUtil; +import org.signal.core.util.ThreadUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.AttachmentId; @@ -586,6 +587,7 @@ private void deleteAttachmentOnDisk(@Nullable String data, if (MediaUtil.isImageType(contentType) || MediaUtil.isVideoType(contentType)) { Glide.get(context).clearDiskCache(); + ThreadUtil.runOnMain(() -> Glide.get(context).clearMemory()); } } From c53c316303c5fac77966c1bd28ddfe377e9e136c Mon Sep 17 00:00:00 2001 From: Jim Gustafson Date: Tue, 31 Oct 2023 06:44:04 -0700 Subject: [PATCH 09/31] Update to RingRTC v2.34.2 --- dependencies.gradle | 2 +- gradle/verification-metadata.xml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index ba66e204d2..ff607fe132 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -116,7 +116,7 @@ dependencyResolutionManagement { library('libsignal-client', 'org.signal', 'libsignal-client').versionRef('libsignal-client') library('libsignal-android', 'org.signal', 'libsignal-android').versionRef('libsignal-client') library('signal-aesgcmprovider', 'org.signal:aesgcmprovider:0.0.3') - library('signal-ringrtc', 'org.signal:ringrtc-android:2.34.1') + library('signal-ringrtc', 'org.signal:ringrtc-android:2.34.2') library('signal-android-database-sqlcipher', 'org.signal:sqlcipher-android:4.5.4-S2') // Third Party diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 129c42b946..8a35daf6ba 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -5349,12 +5349,12 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - + + + - - + + From 776a4c5dce24c48d0d81fb73ff0ab3089fb130f8 Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Tue, 31 Oct 2023 10:19:34 -0400 Subject: [PATCH 10/31] Fix string issues. --- .../securesms/preferences/BackupsPreferenceFragment.java | 2 +- .../securesms/safety/SafetyNumberBottomSheetFragment.kt | 2 +- app/src/main/res/values/strings.xml | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java index 42e24eadf5..470c32b879 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/BackupsPreferenceFragment.java @@ -264,7 +264,7 @@ private void pickTime() { .setTimeFormat(timeFormat) .setHour(SignalStore.settings().getBackupHour()) .setMinute(SignalStore.settings().getBackupMinute()) - .setTitleText("Set Backup Time") + .setTitleText(R.string.BackupsPreferenceFragment__set_backup_time) .build(); timePickerFragment.addOnPositiveButtonClickListener(v -> { int hour = timePickerFragment.getHour(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/safety/SafetyNumberBottomSheetFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/safety/SafetyNumberBottomSheetFragment.kt index c50345cfe2..332f0eeb90 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/safety/SafetyNumberBottomSheetFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/safety/SafetyNumberBottomSheetFragment.kt @@ -128,7 +128,7 @@ class SafetyNumberBottomSheetFragment : DSLSettingsBottomSheetFragment(layoutId title = DSLSettingsText.from( when { state.isCheckupComplete() && state.hasLargeNumberOfUntrustedRecipients -> getString(R.string.SafetyNumberBottomSheetFragment__all_connections_have_been_reviewed) - state.hasLargeNumberOfUntrustedRecipients -> getString(R.string.SafetyNumberBottomSheetFragment__you_have_d_connections, args.untrustedRecipients.size) + state.hasLargeNumberOfUntrustedRecipients -> resources.getQuantityString(R.plurals.SafetyNumberBottomSheetFragment__you_have_d_connections_plural, args.untrustedRecipients.size, args.untrustedRecipients.size) else -> getString(R.string.SafetyNumberBottomSheetFragment__the_following_people) }, DSLSettingsText.TextAppearanceModifier(R.style.Signal_Text_BodyLarge), diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 22c36b5a98..ef7e89c296 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -643,6 +643,8 @@ %1$s%% so far… Signal requires external storage permission in order to create backups, but it has been permanently denied. Please continue to app settings, select \"Permissions\" and enable \"Storage\". + + Set backup time @@ -5586,7 +5588,10 @@ All connections have been reviewed, tap send to continue. - You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verify safety number From 5a005fb80975bc41a12b7dd0c2c75f4da355606b Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 31 Oct 2023 13:53:32 -0700 Subject: [PATCH 11/31] Build a simple ANR detector. --- .../securesms/ApplicationContext.java | 16 +++ .../app/internal/InternalSettingsFragment.kt | 33 +++++ .../securesms/database/LogDatabase.kt | 91 +++++++++++- .../securesms/logsubmit/LogSectionAnr.kt | 35 +++++ .../logsubmit/SubmitDebugLogRepository.java | 1 + .../core/util/SQLiteDatabaseExtensions.kt | 2 +- .../core/util/concurrent/AnrDetector.kt | 132 ++++++++++++++++++ 7 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionAnr.kt create mode 100644 core-util/src/main/java/org/signal/core/util/concurrent/AnrDetector.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 76cbe7f75f..2505ed6416 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -30,6 +30,7 @@ import org.greenrobot.eventbus.EventBus; import org.signal.aesgcmprovider.AesGcmProvider; import org.signal.core.util.MemoryTracker; +import org.signal.core.util.concurrent.AnrDetector; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.AndroidLogger; import org.signal.core.util.logging.Log; @@ -109,6 +110,7 @@ import io.reactivex.rxjava3.exceptions.UndeliverableException; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import io.reactivex.rxjava3.schedulers.Schedulers; +import kotlin.Unit; import rxdogtag2.RxDogTag; /** @@ -151,6 +153,7 @@ public void onCreate() { initializeLogging(); Log.i(TAG, "onCreate()"); }) + .addBlocking("anr-detector", this::startAnrDetector) .addBlocking("security-provider", this::initializeSecurityProvider) .addBlocking("crash-handling", this::initializeCrashHandling) .addBlocking("rx-init", this::initializeRx) @@ -227,6 +230,7 @@ public void onForeground() { SubscriptionKeepAliveJob.enqueueAndTrackTimeIfNecessary(); ExternalLaunchDonationJob.enqueueIfNecessary(); FcmFetchManager.onForeground(this); + startAnrDetector(); SignalExecutors.BOUNDED.execute(() -> { FeatureFlags.refreshIfNecessary(); @@ -260,6 +264,7 @@ public void onBackground() { ApplicationDependencies.getShakeToReport().disable(); ApplicationDependencies.getDeadlockDetector().stop(); MemoryTracker.stop(); + AnrDetector.stop(); } public void checkBuildExpiration() { @@ -269,6 +274,17 @@ public void checkBuildExpiration() { } } + /** + * Note: this is purposefully "started" twice -- once during application create, and once during foreground. + * This is so we can capture ANR's that happen on boot before the foreground event. + */ + private void startAnrDetector() { + AnrDetector.start(TimeUnit.SECONDS.toMillis(5), FeatureFlags::internalUser, (dumps) -> { + LogDatabase.getInstance(this).anrs().save(System.currentTimeMillis(), dumps); + return Unit.INSTANCE; + }); + } + private void initializeSecurityProvider() { int aesPosition = Security.insertProviderAt(new AesGcmProvider(), 1); Log.i(TAG, "Installed AesGcmProvider: " + aesPosition); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index d644cd08e9..04fb4638b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -171,6 +171,17 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter } ) + clickPref( + title = DSLSettingsText.from("Clear all logs"), + onClick = { + SimpleTask.run({ + LogDatabase.getInstance(requireActivity().application).logs.clearAll() + }) { + Toast.makeText(requireContext(), "Cleared all logs", Toast.LENGTH_SHORT).show() + } + } + ) + clickPref( title = DSLSettingsText.from("Clear keep longer logs"), onClick = { @@ -178,6 +189,28 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter } ) + clickPref( + title = DSLSettingsText.from("Clear all crashes"), + onClick = { + SimpleTask.run({ + LogDatabase.getInstance(requireActivity().application).crashes.clear() + }) { + Toast.makeText(requireContext(), "Cleared crashes", Toast.LENGTH_SHORT).show() + } + } + ) + + clickPref( + title = DSLSettingsText.from("Clear all ANRs"), + onClick = { + SimpleTask.run({ + LogDatabase.getInstance(requireActivity().application).anrs.clear() + }) { + Toast.makeText(requireContext(), "Cleared ANRs", Toast.LENGTH_SHORT).show() + } + } + ) + clickPref( title = DSLSettingsText.from("Log dump PreKey ServiceId-KeyIds"), onClick = { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt index 033f9ad988..7dbd016e61 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/LogDatabase.kt @@ -16,6 +16,7 @@ import org.signal.core.util.logging.Log import org.signal.core.util.mebiBytes import org.signal.core.util.readToList import org.signal.core.util.readToSingleInt +import org.signal.core.util.requireLong import org.signal.core.util.requireNonNullString import org.signal.core.util.select import org.signal.core.util.update @@ -56,7 +57,7 @@ class LogDatabase private constructor( companion object { private val TAG = Log.tag(LogDatabase::class.java) - private const val DATABASE_VERSION = 3 + private const val DATABASE_VERSION = 4 private const val DATABASE_NAME = "signal-logs.db" @SuppressLint("StaticFieldLeak") // We hold an Application context, not a view context @@ -83,11 +84,15 @@ class LogDatabase private constructor( @get:JvmName("crashes") val crashes: CrashTable by lazy { CrashTable(this) } + @get:JvmName("anrs") + val anrs: AnrTable by lazy { AnrTable(this) } + override fun onCreate(db: SQLiteDatabase) { Log.i(TAG, "onCreate()") db.execSQL(LogTable.CREATE_TABLE) db.execSQL(CrashTable.CREATE_TABLE) + db.execSQL(AnrTable.CREATE_TABLE) LogTable.CREATE_INDEXES.forEach { db.execSQL(it) } CrashTable.CREATE_INDEXES.forEach { db.execSQL(it) } @@ -108,6 +113,10 @@ class LogDatabase private constructor( db.execSQL("CREATE INDEX crash_created_at ON crash (created_at)") db.execSQL("CREATE INDEX crash_name_message ON crash (name, message)") } + + if (oldVersion < 4) { + db.execSQL("CREATE TABLE anr (_id INTEGER PRIMARY KEY, created_at INTEGER NOT NULL, thread_dump TEXT NOT NULL)") + } } override fun onOpen(db: SQLiteDatabase) { @@ -258,6 +267,12 @@ class LogDatabase private constructor( .run() } + fun clearAll() { + writableDatabase + .delete(TABLE_NAME) + .run() + } + private fun getSize(query: String?, args: Array?): Long { readableDatabase.query(TABLE_NAME, arrayOf("SUM($SIZE)"), query, args, null, null, null).use { cursor -> return if (cursor.moveToFirst()) { @@ -387,6 +402,12 @@ class LogDatabase private constructor( .run() } + fun clear() { + writableDatabase + .delete(TABLE_NAME) + .run() + } + private fun CrashConfig.CrashPattern.asLikeQuery(): Pair> { val query = StringBuilder() var args = arrayOf() @@ -415,4 +436,72 @@ class LogDatabase private constructor( return query.toString() to args } } + + class AnrTable(private val openHelper: LogDatabase) { + companion object { + const val TABLE_NAME = "anr" + const val ID = "_id" + const val CREATED_AT = "created_at" + const val THREAD_DUMP = "thread_dump" + + const val CREATE_TABLE = """ + CREATE TABLE $TABLE_NAME ( + $ID INTEGER PRIMARY KEY, + $CREATED_AT INTEGER NOT NULL, + $THREAD_DUMP TEXT NOT NULL + ) + """ + } + + private val readableDatabase: SQLiteDatabase get() = openHelper.readableDatabase + private val writableDatabase: SQLiteDatabase get() = openHelper.writableDatabase + + fun save(currentTime: Long, threadDumps: String) { + writableDatabase + .insertInto(TABLE_NAME) + .values( + CREATED_AT to currentTime, + THREAD_DUMP to threadDumps + ) + .run() + + val count = writableDatabase + .delete(TABLE_NAME) + .where( + """ + $ID NOT IN (SELECT $ID FROM $TABLE_NAME ORDER BY $CREATED_AT DESC LIMIT 10) + """.trimIndent() + ) + .run() + + if (count > 0) { + Log.i(TAG, "Deleted $count old ANRs") + } + } + + fun getAll(): List { + return readableDatabase + .select() + .from(TABLE_NAME) + .run() + .readToList { cursor -> + AnrRecord( + createdAt = cursor.requireLong(CREATED_AT), + threadDump = cursor.requireNonNullString(THREAD_DUMP) + ) + } + .sortedBy { it.createdAt } + } + + fun clear() { + writableDatabase + .delete(TABLE_NAME) + .run() + } + + data class AnrRecord( + val createdAt: Long, + val threadDump: String + ) + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionAnr.kt b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionAnr.kt new file mode 100644 index 0000000000..edb52b9743 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionAnr.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.logsubmit + +import android.content.Context +import org.thoughtcrime.securesms.database.LogDatabase +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +class LogSectionAnr : LogSection { + + companion object { + private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzz", Locale.US) + } + + override fun getTitle(): String = "ANR" + + override fun getContent(context: Context): CharSequence { + val anrs = LogDatabase.getInstance(ApplicationDependencies.getApplication()).anrs.getAll() + + return if (anrs.isEmpty()) { + "None" + } else { + "\n" + anrs.joinToString(separator = "\n\n") { + val date = dateFormat.format(Date(it.createdAt)) + "------------- $date -------------\n${it.threadDump}" + } + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogRepository.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogRepository.java index fba84a11ed..857b0c7a17 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitDebugLogRepository.java @@ -97,6 +97,7 @@ public class SubmitDebugLogRepository { add(new LogSectionSenderKey()); } add(new LogSectionRemappedRecords()); + add(new LogSectionAnr()); add(new LogSectionLogcat()); add(new LogSectionLoggerHeader()); }}; diff --git a/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt b/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt index 89148a24c1..832c9e4b36 100644 --- a/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt +++ b/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt @@ -303,7 +303,7 @@ class DeleteBuilderPart1( } fun run(): Int { - return db.delete(tableName, null, null) + return db.delete(tableName, null, emptyArray()) } } diff --git a/core-util/src/main/java/org/signal/core/util/concurrent/AnrDetector.kt b/core-util/src/main/java/org/signal/core/util/concurrent/AnrDetector.kt new file mode 100644 index 0000000000..fcada855fd --- /dev/null +++ b/core-util/src/main/java/org/signal/core/util/concurrent/AnrDetector.kt @@ -0,0 +1,132 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.signal.core.util.concurrent + +import android.os.Debug +import android.os.Looper +import androidx.annotation.MainThread +import org.signal.core.util.ThreadUtil +import org.signal.core.util.logging.Log +import java.lang.IllegalStateException +import java.lang.RuntimeException +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds + +/** + * Attempts to detect ANR's by posting runnables to the main thread and detecting if they've been run within the [anrThreshold]. + * If an ANR is detected, it is logged, and the [anrSaver] is called with the series of thread dumps that were taken of the main thread. + * + * The detection of an ANR will cause an internal user to crash. + */ +object AnrDetector { + + private val TAG = Log.tag(AnrDetector::class.java) + + private var thread: AnrDetectorThread? = null + + private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzz", Locale.US) + + @JvmStatic + @MainThread + fun start(anrThreshold: Long = 5.seconds.inWholeMilliseconds, isInternal: () -> Boolean, anrSaver: (String) -> Unit) { + thread?.end() + thread = null + + thread = AnrDetectorThread(anrThreshold.milliseconds, isInternal, anrSaver) + thread!!.start() + } + + @JvmStatic + @MainThread + fun stop() { + thread?.end() + thread = null + } + + private class AnrDetectorThread( + private val anrThreshold: Duration, + private val isInternal: () -> Boolean, + private val anrSaver: (String) -> Unit + ) : Thread("signal-anr") { + + @Volatile + private var uiRan = false + private val uiRunnable = Runnable { + uiRan = true + } + + @Volatile + private var stopped = false + + override fun run() { + while (!stopped) { + uiRan = false + ThreadUtil.postToMain(uiRunnable) + + val intervalCount = 5 + val intervalDuration = anrThreshold.inWholeMilliseconds / intervalCount + if (intervalDuration == 0L) { + throw IllegalStateException("ANR threshold is too small!") + } + + val dumps = mutableListOf() + + for (i in 1..intervalCount) { + if (stopped) { + Log.i(TAG, "Thread shutting down during intervals.") + return + } + + ThreadUtil.sleep(intervalDuration) + + if (!uiRan) { + dumps += getMainThreadDump() + } else { + dumps.clear() + } + } + + if (!uiRan && !Debug.isDebuggerConnected() && !Debug.waitingForDebugger()) { + Log.w(TAG, "Failed to post to main in ${anrThreshold.inWholeMilliseconds} ms! Likely ANR!") + + val dumpString = dumps.joinToString(separator = "\n\n") + Log.w(TAG, "Main thread dumps:\n$dumpString") + + ThreadUtil.cancelRunnableOnMain(uiRunnable) + anrSaver(dumpString) + + if (isInternal()) { + Log.e(TAG, "Internal user -- crashing!") + throw SignalAnrException() + } + } + + dumps.clear() + } + + Log.i(TAG, "Thread shutting down.") + } + + fun end() { + stopped = true + } + + private fun getMainThreadDump(): String { + val dump: Map> = Thread.getAllStackTraces() + val mainThread = Looper.getMainLooper().thread + val date = dateFormat.format(Date()) + val dumpString = dump[mainThread]?.joinToString(separator = "\n") ?: "Not available." + + return "--- $date:\n$dumpString" + } + } + + private class SignalAnrException : RuntimeException() +} From 6f30aec4f2d302c79afabb45aaadece81c705ea7 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 07:10:49 -0400 Subject: [PATCH 12/31] Improve LocalMetrics logging. --- .../securesms/database/model/LocalMetricsEvent.kt | 14 +++++++++++++- .../securesms/database/model/LocalMetricsSplit.kt | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsEvent.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsEvent.kt index b5d2f2a1cf..e540cabff1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsEvent.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsEvent.kt @@ -1,6 +1,9 @@ package org.thoughtcrime.securesms.database.model +import org.signal.core.util.roundedString import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.nanoseconds +import kotlin.time.DurationUnit data class LocalMetricsEvent( val createdAt: Long, @@ -10,6 +13,15 @@ data class LocalMetricsEvent( val timeunit: TimeUnit ) { override fun toString(): String { - return "[$eventName] total: ${splits.sumOf { timeunit.convert(it.duration, TimeUnit.NANOSECONDS) }} | ${splits.map { it.toString() }.joinToString(", ")}" + return "[$eventName] total: ${splits.sumOf { it.duration }.fractionalMillis(timeunit)} | ${splits.map { it.toString() }.joinToString(", ")}" + } + + private fun Long.fractionalMillis(timeunit: TimeUnit): String { + val places = when (timeunit) { + TimeUnit.MICROSECONDS -> 3 + TimeUnit.NANOSECONDS -> 6 + else -> 0 + } + return this.nanoseconds.toDouble(DurationUnit.MILLISECONDS).roundedString(places) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsSplit.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsSplit.kt index f31494510c..3214a7a4b8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsSplit.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/LocalMetricsSplit.kt @@ -1,6 +1,9 @@ package org.thoughtcrime.securesms.database.model +import org.signal.core.util.roundedString import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.nanoseconds +import kotlin.time.DurationUnit data class LocalMetricsSplit( val name: String, @@ -8,6 +11,15 @@ data class LocalMetricsSplit( val timeunit: TimeUnit = TimeUnit.MILLISECONDS ) { override fun toString(): String { - return "$name: ${timeunit.convert(duration, TimeUnit.NANOSECONDS)}" + return "$name: ${duration.fractionalMillis(timeunit)}" + } + + private fun Long.fractionalMillis(timeunit: TimeUnit): String { + val places = when (timeunit) { + TimeUnit.MICROSECONDS -> 3 + TimeUnit.NANOSECONDS -> 6 + else -> 0 + } + return this.nanoseconds.toDouble(DurationUnit.MILLISECONDS).roundedString(places) } } From a91192611987542518771cca429692e591c9f0b1 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 07:33:02 -0400 Subject: [PATCH 13/31] Always for a full contact sync via ContactDiscovery.refreshAll(). --- .../securesms/contacts/sync/ContactDiscovery.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt index 117a40179b..a88f17ece4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt @@ -73,7 +73,8 @@ object ContactDiscovery { ContactDiscoveryRefreshV2.refreshAll(context, useCompat = FeatureFlags.cdsCompatMode()) }, removeSystemContactLinksIfMissing = true, - notifyOfNewUsers = notifyOfNewUsers + notifyOfNewUsers = notifyOfNewUsers, + forceFullSystemContactSync = true ) StorageSyncHelper.scheduleSyncForDataChange() @@ -140,7 +141,8 @@ object ContactDiscovery { descriptor: String, refresh: () -> RefreshResult, removeSystemContactLinksIfMissing: Boolean, - notifyOfNewUsers: Boolean + notifyOfNewUsers: Boolean, + forceFullSystemContactSync: Boolean = false ): RefreshResult { val stopwatch = Stopwatch(descriptor) @@ -153,7 +155,7 @@ object ContactDiscovery { if (hasContactsPermissions(context)) { ApplicationDependencies.getJobManager().add(SyncSystemContactLinksJob()) - val useFullSync = removeSystemContactLinksIfMissing && result.registeredIds.size > FULL_SYSTEM_CONTACT_SYNC_THRESHOLD + val useFullSync = forceFullSystemContactSync || (removeSystemContactLinksIfMissing && result.registeredIds.size > FULL_SYSTEM_CONTACT_SYNC_THRESHOLD) syncRecipientsWithSystemContacts( context = context, rewrites = result.rewrites, From c69a4dda00475818b69d22957af45925e1e09b3d Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 09:44:20 -0400 Subject: [PATCH 14/31] Convert GenericForegroundService to kotlin. --- .../service/GenericForegroundService.java | 315 ------------------ .../service/GenericForegroundService.kt | 272 +++++++++++++++ .../service/NotificationController.java | 120 ------- .../service/NotificationController.kt | 123 +++++++ 4 files changed, 395 insertions(+), 435 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.java b/app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.java deleted file mode 100644 index 425e147058..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.java +++ /dev/null @@ -1,315 +0,0 @@ -package org.thoughtcrime.securesms.service; - -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.Binder; -import android.os.Build; -import android.os.IBinder; - -import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; - -import org.signal.core.util.PendingIntentFlags; -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.MainActivity; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.jobs.ForegroundServiceUtil; -import org.thoughtcrime.securesms.jobs.UnableToStartException; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.whispersystems.signalservice.api.util.Preconditions; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; - -public final class GenericForegroundService extends Service { - - private static final String TAG = Log.tag(GenericForegroundService.class); - - private final IBinder binder = new LocalBinder(); - - private static final int NOTIFICATION_ID = 827353982; - private static final String EXTRA_TITLE = "extra_title"; - private static final String EXTRA_CHANNEL_ID = "extra_channel_id"; - private static final String EXTRA_ICON_RES = "extra_icon_res"; - private static final String EXTRA_ID = "extra_id"; - private static final String EXTRA_PROGRESS = "extra_progress"; - private static final String EXTRA_PROGRESS_MAX = "extra_progress_max"; - private static final String EXTRA_PROGRESS_INDETERMINATE = "extra_progress_indeterminate"; - - private static final String ACTION_START = "start"; - private static final String ACTION_STOP = "stop"; - - private static final AtomicInteger NEXT_ID = new AtomicInteger(); - - private final LinkedHashMap allActiveMessages = new LinkedHashMap<>(); - - private static final Entry DEFAULTS = new Entry("", NotificationChannels.getInstance().OTHER, R.drawable.ic_notification, -1, 0, 0, false); - - private @Nullable Entry lastPosted; - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (intent == null) { - throw new IllegalStateException("Intent needs to be non-null."); - } - - synchronized (GenericForegroundService.class) { - String action = intent.getAction(); - - if (action != null) { - if (ACTION_START.equals(action)) handleStart(intent); - else if (ACTION_STOP .equals(action)) handleStop(intent); - else throw new IllegalStateException(String.format("Action needs to be %s or %s.", ACTION_START, ACTION_STOP)); - - updateNotification(); - } - - return START_NOT_STICKY; - } - } - - private synchronized void updateNotification() { - Iterator iterator = allActiveMessages.values().iterator(); - - if (iterator.hasNext()) { - postObligatoryForegroundNotification(iterator.next()); - } else { - Log.i(TAG, "Last request. Ending foreground service."); - postObligatoryForegroundNotification(lastPosted != null ? lastPosted : DEFAULTS); - stopForeground(true); - stopSelf(); - } - } - - private synchronized void handleStart(@NonNull Intent intent) { - Entry entry = Entry.fromIntent(intent); - - Log.i(TAG, String.format(Locale.US, "handleStart() %s", entry)); - - allActiveMessages.put(entry.id, entry); - } - - private synchronized void handleStop(@NonNull Intent intent) { - Log.i(TAG, "handleStop()"); - - int id = intent.getIntExtra(EXTRA_ID, -1); - - Entry removed = allActiveMessages.remove(id); - - if (removed == null) { - Log.w(TAG, "Could not find entry to remove"); - } - } - - private void postObligatoryForegroundNotification(@NonNull Entry active) { - lastPosted = active; - // TODO [greyson] Navigation - startForeground(NOTIFICATION_ID, new NotificationCompat.Builder(this, active.channelId) - .setSmallIcon(active.iconRes) - .setContentTitle(active.title) - .setProgress(active.progressMax, active.progress, active.indeterminate) - .setContentIntent(PendingIntent.getActivity(this, 0, MainActivity.clearTop(this), PendingIntentFlags.mutable())) - .setVibrate(new long[]{0}) - .build()); - } - - @Override - public IBinder onBind(Intent intent) { - return binder; - } - - /** - * Waits for {@param delayMillis} ms before starting the foreground task. - *

- * The delayed notification controller can also shown on demand and promoted to a regular notification controller to update the message etc. - * - * Do not call this method on API > 31 - */ - public static DelayedNotificationController startForegroundTaskDelayed(@NonNull Context context, @NonNull String task, long delayMillis, @DrawableRes int iconRes) { - Preconditions.checkArgument(Build.VERSION.SDK_INT < 31); - - return DelayedNotificationController.create(delayMillis, () -> { - try { - return startForegroundTask(context, task, DEFAULTS.channelId, iconRes); - } catch (UnableToStartException e) { - Log.w(TAG, "This should not happen on API < 31", e); - throw new AssertionError(e.getCause()); - } - }); - } - - public static NotificationController startForegroundTask(@NonNull Context context, @NonNull String task) throws UnableToStartException { - return startForegroundTask(context, task, DEFAULTS.channelId); - } - - public static NotificationController startForegroundTask(@NonNull Context context, @NonNull String task, @NonNull String channelId) - throws UnableToStartException - { - return startForegroundTask(context, task, channelId, DEFAULTS.iconRes); - } - - public static NotificationController startForegroundTask( - @NonNull Context context, - @NonNull String task, - @NonNull String channelId, - @DrawableRes int iconRes) - throws UnableToStartException - { - final int id = NEXT_ID.getAndIncrement(); - - Intent intent = new Intent(context, GenericForegroundService.class); - intent.setAction(ACTION_START); - intent.putExtra(EXTRA_TITLE, task); - intent.putExtra(EXTRA_CHANNEL_ID, channelId); - intent.putExtra(EXTRA_ICON_RES, iconRes); - intent.putExtra(EXTRA_ID, id); - - Log.i(TAG, String.format(Locale.US, "Starting foreground service (%s) id=%d", task, id)); - - ForegroundServiceUtil.start(context, intent); - - return new NotificationController(context, id); - } - - public static void stopForegroundTask(@NonNull Context context, int id) throws UnableToStartException, IllegalStateException { - Intent intent = new Intent(context, GenericForegroundService.class); - intent.setAction(ACTION_STOP); - intent.putExtra(EXTRA_ID, id); - - Log.i(TAG, String.format(Locale.US, "Stopping foreground service id=%d", id)); - ForegroundServiceUtil.startWhenCapable(context, intent); - } - - synchronized void replaceTitle(int id, @NonNull String title) { - Entry oldEntry = allActiveMessages.get(id); - - if (oldEntry == null) { - Log.w(TAG, "Failed to replace notification, it was not found"); - return; - } - - Entry newEntry = new Entry(title, oldEntry.channelId, oldEntry.iconRes, oldEntry.id, oldEntry.progressMax, oldEntry.progress, oldEntry.indeterminate); - - if (oldEntry.equals(newEntry)) { - Log.d(TAG, String.format("handleReplace() skip, no change %s", newEntry)); - return; - } - - Log.i(TAG, String.format("handleReplace() %s", newEntry)); - - allActiveMessages.put(newEntry.id, newEntry); - - updateNotification(); - } - - synchronized void replaceProgress(int id, int progressMax, int progress, boolean indeterminate) { - Entry oldEntry = allActiveMessages.get(id); - - if (oldEntry == null) { - Log.w(TAG, "Failed to replace notification, it was not found"); - return; - } - - Entry newEntry = new Entry(oldEntry.title, oldEntry.channelId, oldEntry.iconRes, oldEntry.id, progressMax, progress, indeterminate); - - if (oldEntry.equals(newEntry)) { - Log.d(TAG, String.format("handleReplace() skip, no change %s", newEntry)); - return; - } - - Log.i(TAG, String.format("handleReplace() %s", newEntry)); - - allActiveMessages.put(newEntry.id, newEntry); - - updateNotification(); - } - - private static class Entry { - final @NonNull String title; - final @NonNull String channelId; - final int id; - final @DrawableRes int iconRes; - final int progress; - final int progressMax; - final boolean indeterminate; - - private Entry(@NonNull String title, @NonNull String channelId, @DrawableRes int iconRes, int id, int progressMax, int progress, boolean indeterminate) { - this.title = title; - this.channelId = channelId; - this.iconRes = iconRes; - this.id = id; - this.progress = progress; - this.progressMax = progressMax; - this.indeterminate = indeterminate; - } - - private static Entry fromIntent(@NonNull Intent intent) { - int id = intent.getIntExtra(EXTRA_ID, DEFAULTS.id); - - String title = intent.getStringExtra(EXTRA_TITLE); - if (title == null) title = DEFAULTS.title; - - String channelId = intent.getStringExtra(EXTRA_CHANNEL_ID); - if (channelId == null) channelId = DEFAULTS.channelId; - - int iconRes = intent.getIntExtra(EXTRA_ICON_RES, DEFAULTS.iconRes); - int progress = intent.getIntExtra(EXTRA_PROGRESS, DEFAULTS.progress); - int progressMax = intent.getIntExtra(EXTRA_PROGRESS_MAX, DEFAULTS.progressMax); - boolean indeterminate = intent.getBooleanExtra(EXTRA_PROGRESS_INDETERMINATE, DEFAULTS.indeterminate); - - return new Entry(title, channelId, iconRes, id, progressMax, progress, indeterminate); - } - - @Override - public @NonNull String toString() { - return String.format(Locale.US, "ChannelId: %s Id: %d Progress: %d/%d %s", channelId, id, progress, progressMax, indeterminate ? "indeterminate" : "determinate"); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Entry entry = (Entry) o; - return id == entry.id && - iconRes == entry.iconRes && - progress == entry.progress && - progressMax == entry.progressMax && - indeterminate == entry.indeterminate && - Objects.equals(title, entry.title) && - Objects.equals(channelId, entry.channelId); - } - - @Override - public int hashCode() { - int hashCode = title.hashCode(); - hashCode *= 31; - hashCode += channelId.hashCode(); - hashCode *= 31; - hashCode += id; - hashCode *= 31; - hashCode += iconRes; - hashCode *= 31; - hashCode += progress; - hashCode *= 31; - hashCode += progressMax; - hashCode *= 31; - hashCode += indeterminate ? 1 : 0; - return hashCode; - } - } - - class LocalBinder extends Binder { - GenericForegroundService getService() { - // Return this instance of LocalService so clients can call public methods - return GenericForegroundService.this; - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.kt b/app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.kt new file mode 100644 index 0000000000..afa2318b6e --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/service/GenericForegroundService.kt @@ -0,0 +1,272 @@ +package org.thoughtcrime.securesms.service + +import android.app.PendingIntent +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.Binder +import android.os.Build +import android.os.IBinder +import androidx.annotation.DrawableRes +import androidx.core.app.NotificationCompat +import androidx.core.app.ServiceCompat +import org.signal.core.util.PendingIntentFlags.mutable +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.MainActivity +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.jobs.ForegroundServiceUtil +import org.thoughtcrime.securesms.jobs.UnableToStartException +import org.thoughtcrime.securesms.notifications.NotificationChannels +import org.whispersystems.signalservice.api.util.Preconditions +import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock + +class GenericForegroundService : Service() { + private val binder: IBinder = LocalBinder() + private val allActiveMessages = LinkedHashMap() + private val lock = ReentrantLock() + + private var lastPosted: Entry? = null + + companion object { + private val TAG = Log.tag(GenericForegroundService::class.java) + + private const val NOTIFICATION_ID = 827353982 + private const val EXTRA_TITLE = "extra_title" + private const val EXTRA_CHANNEL_ID = "extra_channel_id" + private const val EXTRA_ICON_RES = "extra_icon_res" + private const val EXTRA_ID = "extra_id" + private const val EXTRA_PROGRESS = "extra_progress" + private const val EXTRA_PROGRESS_MAX = "extra_progress_max" + private const val EXTRA_PROGRESS_INDETERMINATE = "extra_progress_indeterminate" + private const val ACTION_START = "start" + private const val ACTION_STOP = "stop" + + private val NEXT_ID = AtomicInteger() + private val DEFAULT_ENTRY = Entry("", NotificationChannels.getInstance().OTHER, R.drawable.ic_notification, -1, 0, 0, false) + + /** + * Waits for {@param delayMillis} ms before starting the foreground task. + * + * + * The delayed notification controller can also shown on demand and promoted to a regular notification controller to update the message etc. + * + * Do not call this method on API > 31 + */ + @JvmStatic + fun startForegroundTaskDelayed(context: Context, task: String, delayMillis: Long, @DrawableRes iconRes: Int): DelayedNotificationController { + Preconditions.checkArgument(Build.VERSION.SDK_INT < 31) + Log.d(TAG, "[startForegroundTaskDelayed] Task: $task, Delay: $delayMillis") + + return DelayedNotificationController.create(delayMillis) { + try { + return@create startForegroundTask(context, task, DEFAULT_ENTRY.channelId, iconRes) + } catch (e: UnableToStartException) { + Log.w(TAG, "This should not happen on API < 31", e) + throw AssertionError(e.cause) + } + } + } + + @JvmStatic + @JvmOverloads + @Throws(UnableToStartException::class) + fun startForegroundTask( + context: Context, + task: String, + channelId: String = DEFAULT_ENTRY.channelId, + @DrawableRes iconRes: Int = DEFAULT_ENTRY.iconRes + ): NotificationController { + val id = NEXT_ID.getAndIncrement() + Log.i(TAG, "[startForegroundTask] Task: $task, ID: $id") + + val intent = Intent(context, GenericForegroundService::class.java).apply { + action = ACTION_START + putExtra(EXTRA_TITLE, task) + putExtra(EXTRA_CHANNEL_ID, channelId) + putExtra(EXTRA_ICON_RES, iconRes) + putExtra(EXTRA_ID, id) + } + + ForegroundServiceUtil.start(context, intent) + + return NotificationController(context, id) + } + + @JvmStatic + @Throws(UnableToStartException::class, IllegalStateException::class) + fun stopForegroundTask(context: Context, id: Int) { + Log.d(TAG, "[stopForegroundTask] ID: $id") + + val intent = Intent(context, GenericForegroundService::class.java).apply { + action = ACTION_STOP + putExtra(EXTRA_ID, id) + } + + Log.i(TAG, "Stopping foreground service id=$id") + ForegroundServiceUtil.startWhenCapable(context, intent) + } + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + checkNotNull(intent) { "Intent needs to be non-null." } + Log.d(TAG, "[onStartCommand] Action: ${intent.action}") + + lock.withLock { + when (val action = intent.action) { + ACTION_START -> { + val entry = Entry.fromIntent(intent) + Log.i(TAG, "[onStartCommand] Adding entry: $entry") + allActiveMessages[entry.id] = entry + } + + ACTION_STOP -> { + val id = intent.getIntExtra(EXTRA_ID, -1) + val removed = allActiveMessages.remove(id) + if (removed != null) { + Log.i(TAG, "[onStartCommand] ID: $id, Removed: $removed") + } else { + Log.w(TAG, "[onStartCommand] Could not find entry to remove") + } + } + + else -> throw IllegalStateException("Unexpected action: $action") + } + + updateNotification() + + return START_NOT_STICKY + } + } + + override fun onCreate() { + Log.d(TAG, "[onCreate]") + super.onCreate() + } + + override fun onBind(intent: Intent): IBinder { + Log.d(TAG, "[onBind]") + return binder + } + + override fun onUnbind(intent: Intent?): Boolean { + Log.d(TAG, "[onUnbind]") + return super.onUnbind(intent) + } + + override fun onRebind(intent: Intent?) { + Log.d(TAG, "[onRebind]") + super.onRebind(intent) + } + + override fun onDestroy() { + Log.d(TAG, "[onDestroy]") + super.onDestroy() + } + + override fun onLowMemory() { + Log.d(TAG, "[onLowMemory]") + super.onLowMemory() + } + + override fun onTrimMemory(level: Int) { + Log.d(TAG, "[onTrimMemory] level: $level") + super.onTrimMemory(level) + } + + fun replaceTitle(id: Int, title: String) { + lock.withLock { + updateEntry(id) { oldEntry -> + oldEntry.copy(title = title) + } + } + } + + fun replaceProgress(id: Int, progressMax: Int, progress: Int, indeterminate: Boolean) { + lock.withLock { + updateEntry(id) { oldEntry -> + oldEntry.copy(progressMax = progressMax, progress = progress, indeterminate = indeterminate) + } + } + } + + private fun updateNotification() { + if (allActiveMessages.isNotEmpty()) { + postObligatoryForegroundNotification(allActiveMessages.values.first()) + } else { + Log.i(TAG, "Last request. Ending foreground service.") + postObligatoryForegroundNotification(lastPosted ?: DEFAULT_ENTRY) + + ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE) + stopSelf() + } + } + + private fun postObligatoryForegroundNotification(active: Entry) { + lastPosted = active + + startForeground( + NOTIFICATION_ID, + NotificationCompat.Builder(this, active.channelId) + .setSmallIcon(active.iconRes) + .setContentTitle(active.title) + .setProgress(active.progressMax, active.progress, active.indeterminate) + .setContentIntent(PendingIntent.getActivity(this, 0, MainActivity.clearTop(this), mutable())) + .setVibrate(longArrayOf(0)) + .build() + ) + } + + private fun updateEntry(id: Int, transform: (Entry) -> Entry) { + val oldEntry = allActiveMessages[id] + if (oldEntry == null) { + Log.w(TAG, "Failed to replace notification, it was not found") + return + } + + val newEntry = transform(oldEntry) + + if (oldEntry == newEntry) { + Log.d(TAG, "handleReplace() skip, no change $newEntry") + return + } + + Log.i(TAG, "handleReplace() $newEntry") + allActiveMessages[newEntry.id] = newEntry + updateNotification() + } + + private data class Entry( + val title: String, + val channelId: String, + @field:DrawableRes @param:DrawableRes val iconRes: Int, + val id: Int, + val progressMax: Int, + val progress: Int, + val indeterminate: Boolean + ) { + override fun toString(): String { + return "ChannelId: $channelId, ID: $id, Progress: $progress/$progressMax ${if (indeterminate) "indeterminate" else "determinate"}" + } + + companion object { + fun fromIntent(intent: Intent): Entry { + return Entry( + title = intent.getStringExtra(EXTRA_TITLE) ?: DEFAULT_ENTRY.title, + channelId = intent.getStringExtra(EXTRA_CHANNEL_ID) ?: DEFAULT_ENTRY.channelId, + iconRes = intent.getIntExtra(EXTRA_ICON_RES, DEFAULT_ENTRY.iconRes), + id = intent.getIntExtra(EXTRA_ID, DEFAULT_ENTRY.id), + progressMax = intent.getIntExtra(EXTRA_PROGRESS_MAX, DEFAULT_ENTRY.progressMax), + progress = intent.getIntExtra(EXTRA_PROGRESS, DEFAULT_ENTRY.progress), + indeterminate = intent.getBooleanExtra(EXTRA_PROGRESS_INDETERMINATE, DEFAULT_ENTRY.indeterminate) + ) + } + } + } + + inner class LocalBinder : Binder() { + val service: GenericForegroundService + get() = this@GenericForegroundService + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.java b/app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.java deleted file mode 100644 index 7416afd9b0..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.thoughtcrime.securesms.service; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; - -import androidx.annotation.NonNull; - -import org.signal.core.util.logging.Log; -import org.thoughtcrime.securesms.jobs.UnableToStartException; - -import java.util.concurrent.atomic.AtomicReference; - -public final class NotificationController implements AutoCloseable, - ServiceConnection -{ - private static final String TAG = Log.tag(NotificationController.class); - - private final Context context; - private final int id; - - private int progress; - private int progressMax; - private boolean indeterminate; - private long percent = -1; - private boolean isBound; - - private final AtomicReference service = new AtomicReference<>(); - - NotificationController(@NonNull Context context, int id) { - this.context = context; - this.id = id; - - isBound = bindToService(); - } - - private boolean bindToService() { - return context.bindService(new Intent(context, GenericForegroundService.class), this, Context.BIND_AUTO_CREATE); - } - - public int getId() { - return id; - } - - @Override - public void close() { - try { - if (isBound) { - context.unbindService(this); - isBound = false; - } else { - Log.w(TAG, "Service was not bound at the time of close()..."); - } - - GenericForegroundService.stopForegroundTask(context, id); - } catch (IllegalStateException | UnableToStartException e) { - Log.w(TAG, "Failed to unbind service...", e); - } - } - - public void setIndeterminateProgress() { - setProgress(0, 0, true); - } - - public void setProgress(long newProgressMax, long newProgress) { - setProgress((int) newProgressMax, (int) newProgress, false); - } - - public void replaceTitle(@NonNull String title) { - GenericForegroundService genericForegroundService = service.get(); - - if (genericForegroundService == null) return; - - genericForegroundService.replaceTitle(id, title); - } - - private synchronized void setProgress(int newProgressMax, int newProgress, boolean indeterminant) { - int newPercent = newProgressMax != 0 ? 100 * newProgress / newProgressMax : -1; - - boolean same = newPercent == percent && indeterminate == indeterminant; - - percent = newPercent; - progress = newProgress; - progressMax = newProgressMax; - indeterminate = indeterminant; - - if (same) return; - - updateProgressOnService(); - } - - private synchronized void updateProgressOnService() { - GenericForegroundService genericForegroundService = service.get(); - - if (genericForegroundService == null) return; - - genericForegroundService.replaceProgress(id, progressMax, progress, indeterminate); - } - - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - Log.i(TAG, "Service connected " + name); - - GenericForegroundService.LocalBinder binder = (GenericForegroundService.LocalBinder) service; - GenericForegroundService genericForegroundService = binder.getService(); - - this.service.set(genericForegroundService); - - updateProgressOnService(); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - Log.i(TAG, "Service disconnected " + name); - - service.set(null); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.kt b/app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.kt new file mode 100644 index 0000000000..82b9bb7680 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/service/NotificationController.kt @@ -0,0 +1,123 @@ +package org.thoughtcrime.securesms.service + +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection +import android.os.IBinder +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.jobs.UnableToStartException +import org.thoughtcrime.securesms.service.GenericForegroundService.Companion.stopForegroundTask +import org.thoughtcrime.securesms.service.GenericForegroundService.LocalBinder +import java.util.concurrent.atomic.AtomicReference +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock + +class NotificationController internal constructor(private val context: Context, val id: Int) : AutoCloseable, ServiceConnection { + private val service = AtomicReference() + private val lock = ReentrantLock() + + private var progress = 0 + private var progressMax = 0 + private var indeterminate = false + private var percent: Int = -1 + private var isBound: Boolean + + companion object { + private val TAG = Log.tag(NotificationController::class.java) + } + + init { + isBound = bindToService() + } + + override fun onServiceConnected(name: ComponentName, service: IBinder) { + Log.i(TAG, "[onServiceConnected] Name: $name") + + val binder = service as LocalBinder + val genericForegroundService = binder.service + + this.service.set(genericForegroundService) + + lock.withLock { + updateProgressOnService() + } + } + + override fun onServiceDisconnected(name: ComponentName) { + Log.i(TAG, "[onServiceDisconnected] Name: $name") + service.set(null) + } + + override fun close() { + try { + if (isBound) { + Log.d(TAG, "[close] Unbinding service.") + context.unbindService(this) + isBound = false + } else { + Log.w(TAG, "[close] Service was not bound at the time of close()...") + } + stopForegroundTask(context, id) + } catch (e: IllegalStateException) { + Log.w(TAG, "[close] Failed to unbind service...", e) + } catch (e: UnableToStartException) { + Log.w(TAG, "[close] Failed to unbind service...", e) + } + } + + fun setIndeterminateProgress() { + lock.withLock { + setProgress( + newProgressMax = 0, + newProgress = 0, + indeterminant = true + ) + } + } + + fun setProgress(newProgressMax: Long, newProgress: Long) { + lock.withLock { + setProgress( + newProgressMax = newProgressMax.toInt(), + newProgress = newProgress.toInt(), + indeterminant = false + ) + } + } + + fun replaceTitle(title: String) { + lock.withLock { + service.get()?.replaceTitle(id, title) + ?: Log.w(TAG, "Tried to update the title, but the service was no longer bound!") + } + } + + private fun bindToService(): Boolean { + return context.bindService(Intent(context, GenericForegroundService::class.java), this, Context.BIND_AUTO_CREATE) + } + + private fun setProgress(newProgressMax: Int, newProgress: Int, indeterminant: Boolean) { + val newPercent = if (newProgressMax != 0) { + 100 * newProgress / newProgressMax + } else { + -1 + } + + val same = newPercent == percent && indeterminate == indeterminant + + percent = newPercent + progress = newProgress + progressMax = newProgressMax + indeterminate = indeterminant + + if (!same) { + updateProgressOnService() + } + } + + private fun updateProgressOnService() { + service.get()?.replaceProgress(id, progressMax, progress, indeterminate) + ?: Log.w(TAG, "Tried to update the progress, but the service was no longer bound!") + } +} From dcd7ec7383085e2dda84a66b512aeb7af42e11cc Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Wed, 1 Nov 2023 13:58:33 -0400 Subject: [PATCH 15/31] Treat pnp builds also as staging builds. --- .../main/java/org/thoughtcrime/securesms/util/Environment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt b/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt index 2733b10119..6243f35b8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Environment.kt @@ -6,7 +6,7 @@ import org.signal.donations.StripeApi import org.thoughtcrime.securesms.BuildConfig object Environment { - const val IS_STAGING: Boolean = BuildConfig.BUILD_ENVIRONMENT_TYPE == "Staging" + const val IS_STAGING: Boolean = BuildConfig.BUILD_ENVIRONMENT_TYPE == "Staging" || BuildConfig.BUILD_ENVIRONMENT_TYPE == "Pnp" const val IS_PNP: Boolean = BuildConfig.BUILD_ENVIRONMENT_TYPE == "Pnp" const val IS_NIGHTLY: Boolean = BuildConfig.BUILD_DISTRIBUTION_TYPE == "nightly" From a9be6aff4461e8d3a4ed5eac0cd45e0760683e2b Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 14:25:18 -0400 Subject: [PATCH 16/31] Fix delete crash. --- .../main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt b/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt index 832c9e4b36..d65cb3eba2 100644 --- a/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt +++ b/core-util/src/main/java/org/signal/core/util/SQLiteDatabaseExtensions.kt @@ -303,7 +303,7 @@ class DeleteBuilderPart1( } fun run(): Int { - return db.delete(tableName, null, emptyArray()) + return db.delete(tableName, null, emptyArray()) } } From 772bafbe43ca06669de9bcf5dc5849ccc2c52694 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 15:47:48 -0400 Subject: [PATCH 17/31] Inline feature flag to show ACI SN by default. --- .../thoughtcrime/securesms/util/FeatureFlags.java | 11 ----------- .../securesms/verify/VerifyIdentityActivity.java | 13 +++---------- .../verify/VerifySafetyNumberViewModel.kt | 14 +++----------- 3 files changed, 6 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java index f21725b86b..f7cad3fd8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -109,7 +109,6 @@ public final class FeatureFlags { private static final String SVR2_KILLSWITCH = "android.svr2.killSwitch"; private static final String CDS_DISABLE_COMPAT_MODE = "cds.disableCompatibilityMode"; private static final String FCM_MAY_HAVE_MESSAGES_KILL_SWITCH = "android.fcmNotificationFallbackKillSwitch"; - private static final String SAFETY_NUMBER_ACI = "global.safetyNumberAci"; public static final String PROMPT_FOR_NOTIFICATION_LOGS = "android.logs.promptNotifications"; private static final String PROMPT_FOR_NOTIFICATION_CONFIG = "android.logs.promptNotificationsConfig"; public static final String PROMPT_BATTERY_SAVER = "android.promptBatterySaver"; @@ -180,7 +179,6 @@ public final class FeatureFlags { AD_HOC_CALLING, SVR2_KILLSWITCH, CDS_DISABLE_COMPAT_MODE, - SAFETY_NUMBER_ACI, FCM_MAY_HAVE_MESSAGES_KILL_SWITCH, PROMPT_FOR_NOTIFICATION_LOGS, PROMPT_FOR_NOTIFICATION_CONFIG, @@ -259,7 +257,6 @@ public final class FeatureFlags { MAX_ATTACHMENT_SIZE_BYTES, SVR2_KILLSWITCH, CDS_DISABLE_COMPAT_MODE, - SAFETY_NUMBER_ACI, FCM_MAY_HAVE_MESSAGES_KILL_SWITCH, PROMPT_FOR_NOTIFICATION_LOGS, PROMPT_FOR_NOTIFICATION_CONFIG, @@ -373,14 +370,6 @@ public static boolean verifyV2() { return getBoolean(VERIFY_V2, false); } - /** Whether or not we show the ACI safety number as the default initial safety number. */ - public static boolean showAciSafetyNumberAsDefault() { - long estimatedServerTimeSeconds = (System.currentTimeMillis() - SignalStore.misc().getLastKnownServerTimeOffset()) / 1000; - long flagEnableTimeSeconds = getLong(SAFETY_NUMBER_ACI, Long.MAX_VALUE); - - return estimatedServerTimeSeconds > flagEnableTimeSeconds; - } - /** The raw client expiration JSON string. */ public static String clientExpiration() { return getString(CLIENT_EXPIRATION, null); diff --git a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyIdentityActivity.java b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyIdentityActivity.java index c7af36de96..82b1caef84 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyIdentityActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyIdentityActivity.java @@ -56,16 +56,9 @@ public static void startOrShowExchangeMessagesDialog(@NonNull Context context, boolean verified) { Recipient recipient = Recipient.live(recipientId).resolve(); - if (FeatureFlags.showAciSafetyNumberAsDefault()) { - if (!recipient.hasServiceId()) { - showExchangeMessagesDialog(context); - return; - } - } else { - if (!recipient.hasServiceId() || !recipient.hasE164()) { - showExchangeMessagesDialog(context); - return; - } + if (!recipient.hasServiceId()) { + showExchangeMessagesDialog(context); + return; } context.startActivity(newIntent(context, recipientId, identityKey, verified)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt index 21787cb9c1..089de4840a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt @@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.recipients.LiveRecipient import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.storage.StorageSyncHelper -import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.IdentityUtil class VerifySafetyNumberViewModel( @@ -70,17 +69,10 @@ class VerifySafetyNumberViewModel( aciFingerprint = SafetyNumberFingerprint(version, localIdentifier, localIdentity, remoteIdentifier, remoteIdentity, generator.createFor(version, localIdentifier, localIdentity, remoteIdentifier, remoteIdentity)) } - if (FeatureFlags.showAciSafetyNumberAsDefault()) { - if (aciFingerprint != null) { - fingerprintList.add(aciFingerprint) - if (e164Fingerprint != null) { - fingerprintList.add(e164Fingerprint) - } - } - } else { - if (aciFingerprint != null && e164Fingerprint != null) { + if (aciFingerprint != null) { + fingerprintList.add(aciFingerprint) + if (e164Fingerprint != null) { fingerprintList.add(e164Fingerprint) - fingerprintList.add(aciFingerprint) } } From dcb870c43273fd0def4befbcc0304b05757749d9 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 16:11:27 -0400 Subject: [PATCH 18/31] Only show ACI SN's. --- .../PnpSafetyNumberEducationDialogFragment.kt | 79 --------------- .../securesms/verify/VerifyDisplayFragment.kt | 13 --- .../verify/VerifySafetyNumberViewModel.kt | 12 --- ...fety_number_pnp_education_bottom_sheet.xml | 99 ------------------- .../res/layout/verify_display_fragment.xml | 44 +-------- app/src/main/res/values/strings.xml | 13 +-- 6 files changed, 5 insertions(+), 255 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/verify/PnpSafetyNumberEducationDialogFragment.kt delete mode 100644 app/src/main/res/layout/safety_number_pnp_education_bottom_sheet.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/verify/PnpSafetyNumberEducationDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/verify/PnpSafetyNumberEducationDialogFragment.kt deleted file mode 100644 index b25609f0d6..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/verify/PnpSafetyNumberEducationDialogFragment.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2023 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.thoughtcrime.securesms.verify - -import android.animation.Animator -import android.app.Dialog -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.FragmentManager -import com.airbnb.lottie.LottieDrawable -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog -import org.thoughtcrime.securesms.R -import org.thoughtcrime.securesms.animation.AnimationCompleteListener -import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment -import org.thoughtcrime.securesms.components.ViewBinderDelegate -import org.thoughtcrime.securesms.databinding.SafetyNumberPnpEducationBottomSheetBinding -import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.util.BottomSheetUtil -import org.thoughtcrime.securesms.util.CommunicationActions -import org.thoughtcrime.securesms.util.visible - -class PnpSafetyNumberEducationDialogFragment : FixedRoundedCornerBottomSheetDialogFragment() { - private val binding by ViewBinderDelegate(SafetyNumberPnpEducationBottomSheetBinding::bind) - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - return inflater.inflate(R.layout.safety_number_pnp_education_bottom_sheet, container, false) - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog - dialog.behavior.skipCollapsed = true - dialog.setOnShowListener { - dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED - } - return dialog - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding.lottie.visible = true - binding.lottie.playAnimation() - binding.lottie.addAnimatorListener(object : AnimationCompleteListener() { - override fun onAnimationEnd(animation: Animator) { - binding.lottie.removeAnimatorListener(this) - binding.lottie.setMinAndMaxFrame(60, 360) - binding.lottie.repeatMode = LottieDrawable.RESTART - binding.lottie.repeatCount = LottieDrawable.INFINITE - binding.lottie.frame = 60 - binding.lottie.playAnimation() - } - }) - - binding.okay.setOnClickListener { - SignalStore.uiHints().markHasSeenSafetyNumberUpdateNux() - dismiss() - } - - binding.help.setOnClickListener { - CommunicationActions.openBrowserLink(requireContext(), "https://support.signal.org/hc/en-us/articles/360007060632") - } - } - - companion object { - @JvmStatic - fun show(fragmentManager: FragmentManager) { - val fragment = PnpSafetyNumberEducationDialogFragment() - if (fragmentManager.findFragmentByTag(BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG) == null) { - fragment.show(fragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG) - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyDisplayFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyDisplayFragment.kt index 83459a955e..d2e732d8dc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyDisplayFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifyDisplayFragment.kt @@ -82,10 +82,6 @@ class VerifyDisplayFragment : Fragment(), OnScrollChangedListener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { initializeViewModel() - binding.safetyNumberUpdatingBannerText.text = getString(R.string.verify_display_fragment__safety_numbers_are_updating_banner_no_learn_more) - binding.safetyNumberUpdatingBannerText.setLink("https://signal.org/redirect/safety-numbers") - binding.safetyNumberUpdatingBannerText.setLinkColor(ContextCompat.getColor(requireContext(), R.color.signal_colorPrimary)) - updateVerifyButton(requireArguments().getBoolean(VERIFIED_STATE, false), false) binding.verifyButton.setOnClickListener { updateVerifyButton(!currentVerifiedState, true) } @@ -116,7 +112,6 @@ class VerifyDisplayFragment : Fragment(), OnScrollChangedListener { return@observe } val multipleCards = fingerprints.size > 1 - binding.safetyNumberChangeBanner.visible = multipleCards binding.dotIndicators.visible = multipleCards if (fingerprints.isEmpty()) { @@ -145,14 +140,6 @@ class VerifyDisplayFragment : Fragment(), OnScrollChangedListener { viewModel = ViewModelProvider(this, VerifySafetyNumberViewModel.Factory(recipientId, localIdentity, remoteIdentity)).get(VerifySafetyNumberViewModel::class.java) } - override fun onStart() { - super.onStart() - if (!viewModel.showedSafetyNumberEducationDialog) { - PnpSafetyNumberEducationDialogFragment.show(childFragmentManager) - viewModel.showedSafetyNumberEducationDialog = true - } - } - override fun onResume() { super.onResume() setRecipientText(viewModel.recipient.get()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt index 089de4840a..78613e5b01 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberViewModel.kt @@ -37,7 +37,6 @@ class VerifySafetyNumberViewModel( } val recipient: LiveRecipient = Recipient.live(recipientId) - var showedSafetyNumberEducationDialog = SignalStore.uiHints().hasSeenSafetyNumberUpdateNux() private val fingerprintListLiveData = MutableLiveData>() @@ -53,14 +52,6 @@ class VerifySafetyNumberViewModel( val generator = NumericFingerprintGenerator(5200) var aciFingerprint: SafetyNumberFingerprint? = null - var e164Fingerprint: SafetyNumberFingerprint? = null - - if (resolved.e164.isPresent) { - val localIdentifier = Recipient.self().requireE164().toByteArray() - val remoteIdentifier = resolved.requireE164().toByteArray() - val version = 1 - e164Fingerprint = SafetyNumberFingerprint(version, localIdentifier, localIdentity, remoteIdentifier, remoteIdentity, generator.createFor(version, localIdentifier, localIdentity, remoteIdentifier, remoteIdentity)) - } if (resolved.aci.isPresent) { val localIdentifier = SignalStore.account().requireAci().toByteArray() @@ -71,9 +62,6 @@ class VerifySafetyNumberViewModel( if (aciFingerprint != null) { fingerprintList.add(aciFingerprint) - if (e164Fingerprint != null) { - fingerprintList.add(e164Fingerprint) - } } fingerprintListLiveData.postValue(fingerprintList) diff --git a/app/src/main/res/layout/safety_number_pnp_education_bottom_sheet.xml b/app/src/main/res/layout/safety_number_pnp_education_bottom_sheet.xml deleted file mode 100644 index 319f54ee6f..0000000000 --- a/app/src/main/res/layout/safety_number_pnp_education_bottom_sheet.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/verify_display_fragment.xml b/app/src/main/res/layout/verify_display_fragment.xml index 28e8da5182..b7d864df2b 100644 --- a/app/src/main/res/layout/verify_display_fragment.xml +++ b/app/src/main/res/layout/verify_display_fragment.xml @@ -21,50 +21,13 @@ app:titleTextAppearance="@style/Signal.Text.TitleLarge" tools:title="@string/AndroidManifest__verify_safety_number" /> - - - - - - - + app:constraint_referenced_ids="toolbar"/> @@ -91,6 +54,7 @@ android:id="@+id/dot_indicators" android:layout_width="match_parent" android:layout_height="wrap_content" + android:visibility="gone" app:tabBackground="@drawable/safety_dot_indicator" app:tabGravity="center" app:tabPaddingEnd="10dp" @@ -104,7 +68,7 @@ android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginEnd="32dp" - android:layout_marginTop="8dp" + android:layout_marginTop="24dp" android:layout_marginBottom="20dp" android:gravity="center" android:lineSpacingExtra="3sp" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ef7e89c296..3172c85613 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2716,24 +2716,13 @@ - To verify end-to-end encryption with %s, match the color card above with their device and compare the numbers. If these don’t match, swipe and try the other pair of safety numbers. Only one pair needs to match. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Tap to scan Successful match Failed to verify safety number Loading… Mark as verified Clear verification - - Safety numbers are being updated. - - - Changes to safety numbers - - Safety numbers are being updated over a transition period to enable upcoming privacy features in Signal.\n\nTo verify safety numbers, match the color card with your contact’s device. If these don’t match, swipe and try the other pair of safety numbers. Only one pair needs to match. - - Need help? - - Got it Scan the QR Code on your contact\'s device. From 0659edb762a9bf72de4821bb05dc00a96b788da4 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 13:26:56 -0700 Subject: [PATCH 19/31] Add a new foreground service for attachment progress. --- app/src/main/AndroidManifest.xml | 4 + .../jobs/AttachmentCompressionJob.java | 11 +- .../securesms/jobs/AttachmentUploadJob.kt | 11 +- .../notifications/NotificationIds.java | 1 + .../service/AttachmentProgressService.kt | 163 ++++++++++++++++++ .../service/SafeForegroundService.kt | 111 ++++++++++++ 6 files changed, 289 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/AttachmentProgressService.kt create mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee2cb903ee..4ab2e46c24 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1189,6 +1189,10 @@ android:name=".service.GenericForegroundService" android:exported="false"/> + + diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java index a8587e9503..f5cf9858de 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java @@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.mms.MediaStream; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.SentMediaQuality; -import org.thoughtcrime.securesms.service.NotificationController; +import org.thoughtcrime.securesms.service.AttachmentProgressService; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.util.BitmapDecodingException; import org.thoughtcrime.securesms.util.FeatureFlags; @@ -205,9 +205,8 @@ private void compress(@NonNull AttachmentTable attachmentDatabase, return attachment; } - try (NotificationController notification = ForegroundServiceUtil.startGenericTaskWhenCapable(context, context.getString(R.string.AttachmentUploadJob_compressing_video_start))) { - - notification.setIndeterminateProgress(); + try (AttachmentProgressService.Controller notification = AttachmentProgressService.start(context, context.getString(R.string.AttachmentUploadJob_compressing_video_start))) { + notification.setIndeterminate(true); try (MediaDataSource dataSource = attachmentDatabase.mediaDataSourceFor(attachment.getAttachmentId(), false)) { if (dataSource == null) { @@ -233,7 +232,7 @@ private void compress(@NonNull AttachmentTable attachmentDatabase, try { try (OutputStream outputStream = ModernEncryptingPartOutputStream.createFor(attachmentSecret, file, true).second) { transcoder.transcode(percent -> { - notification.setProgress(100, percent); + notification.setProgress(percent / 100f); eventBus.postSticky(new PartProgressEvent(attachment, PartProgressEvent.Type.COMPRESSION, 100, @@ -262,7 +261,7 @@ private void compress(@NonNull AttachmentTable attachmentDatabase, Log.i(TAG, "Compressing with android in-memory muxer"); try (MediaStream mediaStream = transcoder.transcode(percent -> { - notification.setProgress(100, percent); + notification.setProgress(percent/100f); eventBus.postSticky(new PartProgressEvent(attachment, PartProgressEvent.Type.COMPRESSION, 100, diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt index 6b83845dfd..ddb4291203 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt @@ -22,12 +22,11 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.events.PartProgressEvent import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint -import org.thoughtcrime.securesms.jobs.ForegroundServiceUtil.startGenericTaskWhenCapable import org.thoughtcrime.securesms.jobs.protos.AttachmentUploadJobData import org.thoughtcrime.securesms.mms.PartAuthority import org.thoughtcrime.securesms.net.NotPushRegisteredException import org.thoughtcrime.securesms.recipients.Recipient -import org.thoughtcrime.securesms.service.NotificationController +import org.thoughtcrime.securesms.service.AttachmentProgressService import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.MediaUtil import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil @@ -144,10 +143,10 @@ class AttachmentUploadJob private constructor( } } - private fun getAttachmentNotificationIfNeeded(attachment: Attachment): NotificationController? { + private fun getAttachmentNotificationIfNeeded(attachment: Attachment): AttachmentProgressService.Controller? { return if (attachment.size >= FOREGROUND_LIMIT) { try { - startGenericTaskWhenCapable(context, context.getString(R.string.AttachmentUploadJob_uploading_media)) + AttachmentProgressService.start(context, context.getString(R.string.AttachmentUploadJob_uploading_media)) } catch (e: UnableToStartException) { Log.w(TAG, "Unable to start foreground service", e) null @@ -168,7 +167,7 @@ class AttachmentUploadJob private constructor( } @Throws(InvalidAttachmentException::class) - private fun buildAttachmentStream(attachment: Attachment, notification: NotificationController?, resumableUploadSpec: ResumableUpload): SignalServiceAttachmentStream { + private fun buildAttachmentStream(attachment: Attachment, notification: AttachmentProgressService.Controller?, resumableUploadSpec: ResumableUpload): SignalServiceAttachmentStream { if (attachment.uri == null || attachment.size == 0L) { throw InvalidAttachmentException(IOException("Outgoing attachment has no data!")) } @@ -192,7 +191,7 @@ class AttachmentUploadJob private constructor( .withListener(object : SignalServiceAttachment.ProgressListener { override fun onAttachmentProgress(total: Long, progress: Long) { EventBus.getDefault().postSticky(PartProgressEvent(attachment, PartProgressEvent.Type.NETWORK, total, progress)) - notification?.setProgress(total, progress) + notification?.progress = (progress.toFloat() / total) } override fun shouldCancel(): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java index 7173aeb46a..723747e3c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationIds.java @@ -7,6 +7,7 @@ public final class NotificationIds { public static final int FCM_FAILURE = 12; + public static final int ATTACHMENT_PROGRESS = 50; public static final int APK_UPDATE_PROMPT_INSTALL = 666; public static final int APK_UPDATE_FAILED_INSTALL = 667; public static final int APK_UPDATE_SUCCESSFUL_INSTALL = 668; diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/AttachmentProgressService.kt b/app/src/main/java/org/thoughtcrime/securesms/service/AttachmentProgressService.kt new file mode 100644 index 0000000000..af8ca46040 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/service/AttachmentProgressService.kt @@ -0,0 +1,163 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.service + +import android.app.Notification +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import androidx.core.app.NotificationCompat +import org.signal.core.util.PendingIntentFlags +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.MainActivity +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.jobs.UnableToStartException +import org.thoughtcrime.securesms.notifications.NotificationChannels +import org.thoughtcrime.securesms.notifications.NotificationIds +import java.util.concurrent.CopyOnWriteArraySet +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock +import kotlin.jvm.Throws + +/** + * A service to show attachment progress. In order to ensure we only show one status notification, + * this handles both compression progress and upload progress. + * + * This class has a bunch of stuff to allow multiple people to "start" this service, but write to a + * single notification. That way if something is compressing while something else is uploading, + * or if there's two things uploading, we just have the one notification. + * + * To do this, it maintains a set of controllers. The service is told when those controllers change, + * and it will only render the oldest controller in the set. + * + * We also use the number of controllers to determine if we actually need to start/stop the actual service. + */ +class AttachmentProgressService : SafeForegroundService() { + companion object { + private val TAG = Log.tag(AttachmentProgressService::class.java) + + private var title: String = "" + private var progress: Float = 0f + set(value) { + field = value.coerceIn(0f, 1f) + } + private var indeterminate: Boolean = false + + private val listeners: MutableSet<() -> Unit> = CopyOnWriteArraySet() + private val controllers: LinkedHashSet = linkedSetOf() + private val controllerLock = ReentrantLock() + + /** + * Start the service with the provided [title]. You will receive a controllers that you can + * use to update the notification. + * + * Important: This could fail to start! We do our best to start the service regardless of context, + * but it will fail on some devices, throwing an [UnableToStartException] if it does so. + */ + @JvmStatic + @Throws(UnableToStartException::class) + fun start(context: Context, title: String): Controller { + controllerLock.withLock { + if (controllers.isEmpty()) { + Log.i(TAG, "[start] First controller. Starting.") + SafeForegroundService.start(context, AttachmentProgressService::class.java) + } else { + Log.i(TAG, "[start] No need to start the service again. Already have an active controller.") + } + + val controller = Controller(context, title) + controllers += controller + onControllersChanged(context) + return controller + } + } + + private fun stop(context: Context) { + SafeForegroundService.stop(context, AttachmentProgressService::class.java) + } + + private fun onControllersChanged(context: Context) { + controllerLock.withLock { + if (controllers.isNotEmpty()) { + val originalTitle = title + val originalProgress = progress + val originalIndeterminate = indeterminate + + title = controllers.first().title + progress = controllers.first().progress + indeterminate = controllers.first().indeterminate + + if (originalTitle != title || originalProgress != progress || originalIndeterminate != indeterminate) { + listeners.forEach { it() } + } + } else { + Log.i(TAG, "[onControllersChanged] No controllers remaining. Stopping.") + stop(context) + } + } + } + } + + val listener = { + startForeground(notificationId, getForegroundNotification(Intent())) + } + + override val tag: String = TAG + + override val notificationId: Int = NotificationIds.ATTACHMENT_PROGRESS + + override fun getForegroundNotification(intent: Intent): Notification { + return NotificationCompat.Builder(this, NotificationChannels.getInstance().OTHER) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle(title) + .setProgress(100, (progress * 100).toInt(), indeterminate) + .setContentIntent(PendingIntent.getActivity(this, 0, MainActivity.clearTop(this), PendingIntentFlags.mutable())) + .setVibrate(longArrayOf(0)) + .build() + } + + override fun onCreate() { + super.onCreate() + listeners += listener + } + + override fun onDestroy() { + super.onDestroy() + listeners -= listener + } + + class Controller(private val context: Context, title: String) : AutoCloseable { + var title: String = title + set(value) { + field = value + onControllersChanged(context) + } + + var progress: Float = 0f + set(value) { + field = value + indeterminate = false + onControllersChanged(context) + } + + var indeterminate: Boolean = false + private set + + /** Has to have separate setter to avoid infinite loops when [progress] and [indeterminate] interact. */ + fun setIndeterminate(value: Boolean) { + indeterminate = value + progress = 0f + onControllersChanged(context) + } + + override fun close() { + controllerLock.withLock { + controllers.remove(this) + onControllersChanged(context) + } + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt b/app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt new file mode 100644 index 0000000000..eb7d2b2391 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt @@ -0,0 +1,111 @@ +/* + * Copyright 2023 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.service + +import android.app.Notification +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.IBinder +import androidx.core.app.ServiceCompat +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.jobs.ForegroundServiceUtil +import org.thoughtcrime.securesms.jobs.UnableToStartException +import kotlin.jvm.Throws + +/** + * A simple parent class meant to encourage the safe usage of foreground services. + * Specifically, it ensures that both starting and "stopping" are done through + * service starts and that we _always_ post a foreground notification. + */ +abstract class SafeForegroundService : Service() { + + companion object { + private val TAG = Log.tag(SafeForegroundService::class.java) + + private const val ACTION_START = "start" + private const val ACTION_STOP = "stop" + + /** + * Safety starts the target foreground service. + * Important: This operation can fail. If it does, [UnableToStartException] is thrown. + */ + @Throws(UnableToStartException::class) + fun start(context: Context, serviceClass: Class) { + val intent = Intent(context, serviceClass).apply { + action = ACTION_START + } + + ForegroundServiceUtil.startWhenCapable(context, intent) + } + + /** + * Safely stops the service by starting it with an action to stop itself. + * This is done to prevent scenarios where you stop the service while + * a start is pending, preventing the posting of a foreground notification. + */ + fun stop(context: Context, serviceClass: Class) { + val intent = Intent(context, serviceClass).apply { + action = ACTION_STOP + } + + try { + ForegroundServiceUtil.startWhenCapable(context, intent) + } catch (e: UnableToStartException) { + Log.w(TAG, "Failed to start service class $serviceClass", e) + } + } + } + + override fun onCreate() { + Log.d(tag, "[onCreate]") + super.onCreate() + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + checkNotNull(intent) { "Must have an intent!" } + + Log.d(tag, "[onStartCommand] action: ${intent.action}") + + startForeground(notificationId, getForegroundNotification(intent)) + + when (val action = intent.action) { + ACTION_START -> { + onServiceStarted(intent) + } + ACTION_STOP -> { + onServiceStopped(intent) + ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE) + stopSelf() + } + else -> Log.w(tag, "Unknown action: $action") + } + + return START_NOT_STICKY + } + + override fun onDestroy() { + Log.d(tag, "[onDestroy]") + super.onDestroy() + } + + override fun onBind(intent: Intent?): IBinder? = null + + /** Log tag for improved logging */ + abstract val tag: String + + /** Notification ID to use when posting the foreground notification */ + abstract val notificationId: Int + + /** Notification to post as our foreground notification. */ + abstract fun getForegroundNotification(intent: Intent): Notification + + /** Event listener for when the service is started via an intent. */ + open fun onServiceStarted(intent: Intent) = Unit + + /** Event listener for when the service is stopped via an intent. */ + open fun onServiceStopped(intent: Intent) = Unit +} From 6e856a7648e098ef3ab83778c06bff3ceb5f50a4 Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Wed, 1 Nov 2023 16:38:06 -0400 Subject: [PATCH 20/31] Update bank mandate CTA UX. --- .../mandate/BankTransferMandateFragment.kt | 209 +++++++++++------- .../compose/StatusBarColorAnimator.kt | 62 ++++++ app/src/main/res/values/strings.xml | 2 + 3 files changed, 192 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/compose/StatusBarColorAnimator.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/mandate/BankTransferMandateFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/mandate/BankTransferMandateFragment.kt index ec1de0ac3d..41445a7370 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/mandate/BankTransferMandateFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/transfer/mandate/BankTransferMandateFragment.kt @@ -5,6 +5,7 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.transfer.mandate +import android.annotation.SuppressLint import android.os.Bundle import android.view.View import androidx.compose.animation.AnimatedVisibility @@ -12,22 +13,33 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.animateScrollBy +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.defaultMinSize -import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.rememberVectorPainter -import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource @@ -37,16 +49,16 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs +import kotlinx.coroutines.launch import org.signal.core.ui.Buttons import org.signal.core.ui.Dividers -import org.signal.core.ui.Scaffolds import org.signal.core.ui.Texts import org.signal.core.ui.theme.SignalTheme import org.signal.donations.PaymentSourceType import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.settings.app.subscription.donate.gateway.GatewayResponse import org.thoughtcrime.securesms.compose.ComposeFragment -import org.thoughtcrime.securesms.compose.StatusBarColorNestedScrollConnection +import org.thoughtcrime.securesms.compose.StatusBarColorAnimator import org.thoughtcrime.securesms.util.SpanUtil import org.thoughtcrime.securesms.util.navigation.safeNavigate import org.thoughtcrime.securesms.util.viewModel @@ -61,15 +73,15 @@ class BankTransferMandateFragment : ComposeFragment() { BankTransferMandateViewModel(PaymentSourceType.Stripe.SEPADebit) } - private lateinit var statusBarColorNestedScrollConnection: StatusBarColorNestedScrollConnection + private lateinit var statusBarColorAnimator: StatusBarColorAnimator override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - statusBarColorNestedScrollConnection = StatusBarColorNestedScrollConnection(requireActivity()) + statusBarColorAnimator = StatusBarColorAnimator(requireActivity()) } override fun onResume() { super.onResume() - statusBarColorNestedScrollConnection.setColorImmediate() + statusBarColorAnimator.setColorImmediate() } @Composable @@ -83,7 +95,7 @@ class BankTransferMandateFragment : ComposeFragment() { onNavigationClick = this::onNavigationClick, onContinueClick = this::onContinueClick, onLearnMoreClick = this::onLearnMoreClick, - modifier = Modifier.nestedScroll(statusBarColorNestedScrollConnection) + onCanScrollUp = statusBarColorAnimator::setCanScrollUp ) } @@ -119,11 +131,14 @@ fun BankTransferScreenPreview() { failedToLoadMandate = false, onNavigationClick = {}, onContinueClick = {}, - onLearnMoreClick = {} + onLearnMoreClick = {}, + onCanScrollUp = {} ) } } +@OptIn(ExperimentalMaterial3Api::class) +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @Composable fun BankTransferScreen( bankMandate: String, @@ -131,91 +146,123 @@ fun BankTransferScreen( onNavigationClick: () -> Unit, onContinueClick: () -> Unit, onLearnMoreClick: () -> Unit, - modifier: Modifier = Modifier + onCanScrollUp: (Boolean) -> Unit ) { - Scaffolds.Settings( - title = stringResource(id = R.string.BankTransferMandateFragment__bank_transfer), - onNavigationClick = onNavigationClick, - navigationIconPainter = rememberVectorPainter(ImageVector.vectorResource(id = R.drawable.symbol_arrow_left_24)), - titleContent = { contentOffset, title -> - AnimatedVisibility( - visible = contentOffset < 0f, - enter = fadeIn(), - exit = fadeOut() - ) { - Text(text = title, style = MaterialTheme.typography.titleLarge) - } - }, - modifier = modifier - ) { - LazyColumn( - horizontalAlignment = CenterHorizontally, - modifier = Modifier - .fillMaxWidth() - .fillMaxHeight() - .padding(top = 64.dp) - ) { - item { - Image( - painter = painterResource(id = R.drawable.bank_transfer), - contentScale = ContentScale.Inside, - contentDescription = null, - modifier = Modifier - .size(72.dp) - .background( - SignalTheme.colors.colorSurface2, - CircleShape + val listState = rememberLazyListState() + val scope = rememberCoroutineScope() + + Scaffold( + topBar = { + TopAppBar( + title = { + AnimatedVisibility( + visible = listState.canScrollBackward, + enter = fadeIn(), + exit = fadeOut() + ) { + Text(text = stringResource(id = R.string.BankTransferMandateFragment__bank_transfer), style = MaterialTheme.typography.titleLarge) + } + }, + navigationIcon = { + IconButton( + onClick = onNavigationClick, + Modifier.padding(end = 16.dp) + ) { + Icon( + painter = rememberVectorPainter(ImageVector.vectorResource(id = R.drawable.symbol_arrow_left_24)), + contentDescription = null ) - ) - } + } + }, + colors = if (listState.canScrollBackward) TopAppBarDefaults.topAppBarColors(containerColor = SignalTheme.colors.colorSurface2) else TopAppBarDefaults.topAppBarColors() + ) + } + ) { + onCanScrollUp(listState.canScrollBackward) - item { - Text( - text = stringResource(id = R.string.BankTransferMandateFragment__bank_transfer), - style = MaterialTheme.typography.headlineMedium, - modifier = Modifier.padding(top = 12.dp, bottom = 15.dp) - ) - } + Column(horizontalAlignment = CenterHorizontally, modifier = Modifier.fillMaxSize()) { + LazyColumn( + state = listState, + horizontalAlignment = CenterHorizontally, + modifier = Modifier + .fillMaxWidth() + .weight(1f, true) + .padding(top = 64.dp) + ) { + item { + Image( + painter = painterResource(id = R.drawable.bank_transfer), + contentScale = ContentScale.Inside, + contentDescription = null, + modifier = Modifier + .size(72.dp) + .background( + SignalTheme.colors.colorSurface2, + CircleShape + ) + ) + } - item { - val learnMore = stringResource(id = R.string.BankTransferMandateFragment__learn_more) - val fullString = stringResource(id = R.string.BankTransferMandateFragment__stripe_processes_donations, learnMore) - - Texts.LinkifiedText( - textWithUrlSpans = SpanUtil.urlSubsequence(fullString, learnMore, stringResource(id = R.string.donate_url)), // TODO [alex] -- final URL - onUrlClick = { - onLearnMoreClick() - }, - style = MaterialTheme.typography.bodyLarge.copy( - color = MaterialTheme.colorScheme.onSurfaceVariant - ), - modifier = Modifier - .padding(bottom = 12.dp) - .padding(horizontal = dimensionResource(id = R.dimen.bank_transfer_mandate_gutter)) - ) - } + item { + Text( + text = stringResource(id = R.string.BankTransferMandateFragment__bank_transfer), + style = MaterialTheme.typography.headlineMedium, + modifier = Modifier.padding(top = 12.dp, bottom = 15.dp) + ) + } - item { - Dividers.Default() - } + item { + val learnMore = stringResource(id = R.string.BankTransferMandateFragment__learn_more) + val fullString = stringResource(id = R.string.BankTransferMandateFragment__stripe_processes_donations, learnMore) - item { - Text( - text = if (failedToLoadMandate) stringResource(id = R.string.BankTransferMandateFragment__failed_to_load_mandate) else bankMandate, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.bank_transfer_mandate_gutter), vertical = 16.dp) - ) + Texts.LinkifiedText( + textWithUrlSpans = SpanUtil.urlSubsequence(fullString, learnMore, stringResource(id = R.string.donate_url)), // TODO [alex] -- final URL + onUrlClick = { + onLearnMoreClick() + }, + style = MaterialTheme.typography.bodyLarge.copy( + color = MaterialTheme.colorScheme.onSurfaceVariant + ), + modifier = Modifier + .padding(bottom = 12.dp) + .padding(horizontal = dimensionResource(id = R.dimen.bank_transfer_mandate_gutter)) + ) + } + + item { + Dividers.Default() + } + + item { + Text( + text = if (failedToLoadMandate) stringResource(id = R.string.BankTransferMandateFragment__failed_to_load_mandate) else bankMandate, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.bank_transfer_mandate_gutter), vertical = 16.dp) + ) + } } if (!failedToLoadMandate) { - item { + Surface( + shadowElevation = if (listState.canScrollForward) 8.dp else 0.dp, + modifier = Modifier.fillMaxWidth() + ) { Buttons.LargeTonal( - onClick = onContinueClick, + onClick = { + if (!listState.canScrollForward) { + onContinueClick() + } else { + scope.launch { + listState.animateScrollBy(value = 1000f) + } + } + }, modifier = Modifier - .padding(top = 16.dp, bottom = 46.dp) + .wrapContentWidth() + .padding(top = 16.dp, bottom = 16.dp) .defaultMinSize(minWidth = 220.dp) ) { - Text(text = stringResource(id = R.string.BankTransferMandateFragment__continue)) + Text(text = if (listState.canScrollForward) stringResource(id = R.string.BankTransferMandateFragment__read_more) else stringResource(id = R.string.BankTransferMandateFragment__continue)) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/compose/StatusBarColorAnimator.kt b/app/src/main/java/org/thoughtcrime/securesms/compose/StatusBarColorAnimator.kt new file mode 100644 index 0000000000..ff1ef7567d --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/compose/StatusBarColorAnimator.kt @@ -0,0 +1,62 @@ +package org.thoughtcrime.securesms.compose + +import android.animation.ValueAnimator +import android.app.Activity +import androidx.core.content.ContextCompat +import com.google.android.material.animation.ArgbEvaluatorCompat +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.util.WindowUtil + +/** + * Controls status-bar color based off ability to scroll up + */ +class StatusBarColorAnimator( + private val activity: Activity +) { + private var animator: ValueAnimator? = null + private var previousCanScrollUp: Boolean = false + + private val normalColor = ContextCompat.getColor(activity, R.color.signal_colorBackground) + private val scrollColor = ContextCompat.getColor(activity, R.color.signal_colorSurface2) + + fun setCanScrollUp(canScrollUp: Boolean) { + if (previousCanScrollUp == canScrollUp) { + return + } + + previousCanScrollUp = canScrollUp + applyState(canScrollUp) + } + + fun setColorImmediate() { + val end = when { + previousCanScrollUp -> scrollColor + else -> normalColor + } + + animator?.cancel() + WindowUtil.setStatusBarColor( + activity.window, + end + ) + } + + private fun applyState(canScrollUp: Boolean) { + val (start, end) = when { + canScrollUp -> normalColor to scrollColor + else -> scrollColor to normalColor + } + + animator?.cancel() + animator = ValueAnimator.ofFloat(0f, 1f).apply { + duration = 200 + addUpdateListener { + WindowUtil.setStatusBarColor( + activity.window, + ArgbEvaluatorCompat.getInstance().evaluate(it.animatedFraction, start, end) + ) + } + start() + } + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3172c85613..469594f508 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5890,6 +5890,8 @@ Learn more Continue + + Read more Failed to load mandate From b96b99c1c4e3aab8012dfc77ed911d0e1d3168ab Mon Sep 17 00:00:00 2001 From: Nicholas Tinsley Date: Wed, 1 Nov 2023 16:40:56 -0400 Subject: [PATCH 21/31] Swallow touch events in forwarding sheet overlay. Addresses #13239. --- .../mutiselect/forward/MultiselectForwardFragment.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt index 065974a41f..a43f969c3b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/mutiselect/forward/MultiselectForwardFragment.kt @@ -175,6 +175,7 @@ class MultiselectForwardFragment : ViewCompat.setBackgroundTintList(sendButton, ColorStateList.valueOf(sendButtonColors.background.resolve(requireContext()))) FullscreenHelper.configureBottomBarLayout(requireActivity(), bottomBarSpacer, bottomBar) + bottomBar.setOnTouchListener { _, _ -> true } backgroundHelper.setBackgroundColor(callback.getDialogBackgroundColor()) bottomBarSpacer.setBackgroundColor(callback.getDialogBackgroundColor()) From 117bbdbcdff97e9cebad07ef4824516eb96f0cc2 Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Wed, 1 Nov 2023 16:52:57 -0400 Subject: [PATCH 22/31] Show dialog when attempting to donate again while still processing previous donation. --- .../app/internal/InternalSettingsFragment.kt | 13 +++ .../DonationSerializationHelper.kt | 16 ---- .../donate/DonateToSignalFragment.kt | 91 ++++++++++++------- .../donate/DonateToSignalState.kt | 18 +++- .../donate/DonateToSignalViewModel.kt | 2 +- .../subscription/donate/DonationPillToggle.kt | 3 +- .../securesms/database/JobDatabase.kt | 6 ++ .../database/model/DatabaseProtosUtil.kt | 24 +++++ .../securesms/keyvalue/DonationsValues.kt | 2 +- app/src/main/res/values/strings.xml | 11 +++ 10 files changed, 131 insertions(+), 55 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index 04fb4638b5..be7d7a10d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.components.settings.DSLConfiguration import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.configure +import org.thoughtcrime.securesms.database.JobDatabase import org.thoughtcrime.securesms.database.LocalMetricsDatabase import org.thoughtcrime.securesms.database.LogDatabase import org.thoughtcrime.securesms.database.MegaphoneDatabase @@ -218,6 +219,18 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter } ) + clickPref( + title = DSLSettingsText.from("Retry all jobs now"), + summary = DSLSettingsText.from("Clear backoff intervals, app will restart"), + onClick = { + SimpleTask.run({ + JobDatabase.getInstance(ApplicationDependencies.getApplication()).debugResetBackoffInterval() + }) { + AppUtil.restart(requireContext()) + } + } + ) + dividerPref() sectionHeaderPref(DSLSettingsText.from("Payments")) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationSerializationHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationSerializationHelper.kt index d203438557..516b228fd1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationSerializationHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/DonationSerializationHelper.kt @@ -17,24 +17,8 @@ import java.math.BigDecimal import java.math.BigInteger import java.math.MathContext import java.util.Currency -import kotlin.time.Duration.Companion.days object DonationSerializationHelper { - - private val PENDING_ONE_TIME_BANK_TRANSFER_TIMEOUT = 14.days - private val PENDING_ONE_TIME_NORMAL_TIMEOUT = 1.days - - val PendingOneTimeDonation.isExpired: Boolean - get() { - val timeout = if (paymentMethodType == PendingOneTimeDonation.PaymentMethodType.SEPA_DEBIT) { - PENDING_ONE_TIME_BANK_TRANSFER_TIMEOUT - } else { - PENDING_ONE_TIME_NORMAL_TIMEOUT - } - - return (timestamp + timeout.inWholeMilliseconds) < System.currentTimeMillis() - } - fun createPendingOneTimeDonationProto( badge: Badge, paymentSourceType: PaymentSourceType, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt index afdca6323b..8b1e9b3d64 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalFragment.kt @@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.util.Projection import org.thoughtcrime.securesms.util.SpanUtil import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.navigation.safeNavigate +import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription import java.util.Currency /** @@ -233,7 +234,6 @@ class DonateToSignalFragment : customPref( DonationPillToggle.Model( - isEnabled = state.areFieldsEnabled, selected = state.donateToSignalType, onClick = { viewModel.toggleDonationType() @@ -256,23 +256,27 @@ class DonateToSignalFragment : text = DSLSettingsText.from(R.string.SubscribeFragment__update_subscription), isEnabled = state.canUpdate, onClick = { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.SubscribeFragment__update_subscription_question) - .setMessage( - getString( - R.string.SubscribeFragment__you_will_be_charged_the_full_amount_s_of, - FiatMoneyUtil.format( - requireContext().resources, - viewModel.getSelectedSubscriptionCost(), - FiatMoneyUtil.formatOptions().trimZerosAfterDecimal() + if (state.monthlyDonationState.transactionState.isTransactionJobPending) { + showDonationPendingDialog(state) + } else { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.SubscribeFragment__update_subscription_question) + .setMessage( + getString( + R.string.SubscribeFragment__you_will_be_charged_the_full_amount_s_of, + FiatMoneyUtil.format( + requireContext().resources, + viewModel.getSelectedSubscriptionCost(), + FiatMoneyUtil.formatOptions().trimZerosAfterDecimal() + ) ) ) - ) - .setPositiveButton(R.string.SubscribeFragment__update) { _, _ -> - viewModel.updateSubscription() - } - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .show() + .setPositiveButton(R.string.SubscribeFragment__update) { _, _ -> + viewModel.updateSubscription() + } + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .show() + } } ) @@ -282,28 +286,58 @@ class DonateToSignalFragment : text = DSLSettingsText.from(R.string.SubscribeFragment__cancel_subscription), isEnabled = state.areFieldsEnabled, onClick = { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.SubscribeFragment__confirm_cancellation) - .setMessage(R.string.SubscribeFragment__you_wont_be_charged_again) - .setPositiveButton(R.string.SubscribeFragment__confirm) { _, _ -> - viewModel.cancelSubscription() - } - .setNegativeButton(R.string.SubscribeFragment__not_now) { _, _ -> } - .show() + if (state.monthlyDonationState.transactionState.isTransactionJobPending) { + showDonationPendingDialog(state) + } else { + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.SubscribeFragment__confirm_cancellation) + .setMessage(R.string.SubscribeFragment__you_wont_be_charged_again) + .setPositiveButton(R.string.SubscribeFragment__confirm) { _, _ -> + viewModel.cancelSubscription() + } + .setNegativeButton(R.string.SubscribeFragment__not_now) { _, _ -> } + .show() + } } ) } else { primaryButton( text = DSLSettingsText.from(R.string.DonateToSignalFragment__continue), - isEnabled = state.canContinue, + isEnabled = state.continueEnabled, onClick = { - viewModel.requestSelectGateway() + if (state.canContinue) { + viewModel.requestSelectGateway() + } else { + showDonationPendingDialog(state) + } } ) } } } + private fun showDonationPendingDialog(state: DonateToSignalState) { + val message = if (state.donateToSignalType == DonateToSignalType.ONE_TIME) { + if (state.oneTimeDonationState.isOneTimeDonationLongRunning) { + R.string.DonateToSignalFragment__bank_transfers_usually_take_1_business_day_to_process_onetime + } else { + R.string.DonateToSignalFragment__your_payment_is_still_being_processed_onetime + } + } else { + if (state.monthlyDonationState.activeSubscription?.paymentMethod == ActiveSubscription.PAYMENT_METHOD_SEPA_DEBIT) { + R.string.DonateToSignalFragment__bank_transfers_usually_take_1_business_day_to_process_monthly + } else { + R.string.DonateToSignalFragment__your_payment_is_still_being_processed_monthly + } + } + + MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.DonateToSignalFragment__you_have_a_donation_pending) + .setMessage(message) + .setPositiveButton(android.R.string.ok, null) + .show() + } + private fun DSLConfiguration.displayOneTimeSelection(areFieldsEnabled: Boolean, state: DonateToSignalState.OneTimeDonationState) { when (state.donationStage) { DonateToSignalState.DonationStage.INIT -> customPref(Boost.LoadingModel()) @@ -337,11 +371,6 @@ class DonateToSignalFragment : } private fun DSLConfiguration.displayMonthlySelection(areFieldsEnabled: Boolean, state: DonateToSignalState.MonthlyDonationState) { - if (state.transactionState.isTransactionJobPending) { - customPref(Subscription.LoaderModel()) - return - } - when (state.donationStage) { DonateToSignalState.DonationStage.INIT -> customPref(Subscription.LoaderModel()) DonateToSignalState.DonationStage.FAILURE -> customPref(NetworkFailure.Model { viewModel.retryMonthlyDonationState() }) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalState.kt index dda20f93f2..ecfb39b4f2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalState.kt @@ -4,6 +4,8 @@ import org.signal.core.util.money.FiatMoney import org.thoughtcrime.securesms.badges.models.Badge import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations import org.thoughtcrime.securesms.components.settings.app.subscription.boost.Boost +import org.thoughtcrime.securesms.database.model.isLongRunning +import org.thoughtcrime.securesms.database.model.isPending import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.subscription.Subscription import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription @@ -19,8 +21,8 @@ data class DonateToSignalState( val areFieldsEnabled: Boolean get() = when (donateToSignalType) { - DonateToSignalType.ONE_TIME -> oneTimeDonationState.donationStage == DonationStage.READY && !oneTimeDonationState.isOneTimeDonationPending - DonateToSignalType.MONTHLY -> monthlyDonationState.donationStage == DonationStage.READY && !monthlyDonationState.transactionState.isInProgress + DonateToSignalType.ONE_TIME -> oneTimeDonationState.donationStage == DonationStage.READY + DonateToSignalType.MONTHLY -> monthlyDonationState.donationStage == DonationStage.READY DonateToSignalType.GIFT -> error("This flow does not support gifts") } @@ -59,13 +61,20 @@ data class DonateToSignalState( DonateToSignalType.GIFT -> error("This flow does not support gifts") } - val canContinue: Boolean + val continueEnabled: Boolean get() = when (donateToSignalType) { DonateToSignalType.ONE_TIME -> areFieldsEnabled && oneTimeDonationState.isSelectionValid && InAppDonations.hasAtLeastOnePaymentMethodAvailable() DonateToSignalType.MONTHLY -> areFieldsEnabled && monthlyDonationState.isSelectionValid && InAppDonations.hasAtLeastOnePaymentMethodAvailable() DonateToSignalType.GIFT -> error("This flow does not support gifts") } + val canContinue: Boolean + get() = when (donateToSignalType) { + DonateToSignalType.ONE_TIME -> continueEnabled && !oneTimeDonationState.isOneTimeDonationPending + DonateToSignalType.MONTHLY -> continueEnabled && !monthlyDonationState.isSubscriptionActive + DonateToSignalType.GIFT -> error("This flow does not support gifts") + } + val canUpdate: Boolean get() = when (donateToSignalType) { DonateToSignalType.ONE_TIME -> false @@ -85,7 +94,8 @@ data class DonateToSignalState( val isCustomAmountFocused: Boolean = false, val donationStage: DonationStage = DonationStage.INIT, val selectableCurrencyCodes: List = emptyList(), - val isOneTimeDonationPending: Boolean = SignalStore.donationsValues().getPendingOneTimeDonation() != null, + val isOneTimeDonationPending: Boolean = SignalStore.donationsValues().getPendingOneTimeDonation().isPending(), + val isOneTimeDonationLongRunning: Boolean = SignalStore.donationsValues().getPendingOneTimeDonation().isLongRunning(), private val minimumDonationAmounts: Map = emptyMap() ) { val minimumDonationAmountOfSelectedCurrency: FiatMoney = minimumDonationAmounts[selectedCurrency] ?: FiatMoney(BigDecimal.ZERO, selectedCurrency) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalViewModel.kt index dd564f19f1..f6bcd692e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonateToSignalViewModel.kt @@ -13,12 +13,12 @@ import org.signal.core.util.StringUtil import org.signal.core.util.logging.Log import org.signal.core.util.money.FiatMoney import org.signal.core.util.money.PlatformCurrencyUtil -import org.thoughtcrime.securesms.components.settings.app.subscription.DonationSerializationHelper.isExpired import org.thoughtcrime.securesms.components.settings.app.subscription.MonthlyDonationRepository import org.thoughtcrime.securesms.components.settings.app.subscription.OneTimeDonationRepository import org.thoughtcrime.securesms.components.settings.app.subscription.boost.Boost import org.thoughtcrime.securesms.components.settings.app.subscription.donate.gateway.GatewayRequest import org.thoughtcrime.securesms.components.settings.app.subscription.manage.DonationRedemptionJobWatcher +import org.thoughtcrime.securesms.database.model.isExpired import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobmanager.JobTracker import org.thoughtcrime.securesms.keyvalue.SignalStore diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationPillToggle.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationPillToggle.kt index b150b3746a..62051ce05c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationPillToggle.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/DonationPillToggle.kt @@ -15,14 +15,13 @@ object DonationPillToggle { } class Model( - val isEnabled: Boolean, val selected: DonateToSignalType, val onClick: () -> Unit ) : MappingModel { override fun areItemsTheSame(newItem: Model): Boolean = true override fun areContentsTheSame(newItem: Model): Boolean { - return isEnabled == newItem.isEnabled && selected == newItem.selected + return selected == newItem.selected } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.kt index b3978ccf75..158422d728 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.app.Application import android.content.ContentValues import android.database.Cursor +import androidx.core.content.contentValuesOf import net.zetetic.database.sqlcipher.SQLiteDatabase import net.zetetic.database.sqlcipher.SQLiteOpenHelper import org.signal.core.util.CursorUtil @@ -408,6 +409,11 @@ class JobDatabase( } } + /** Should only be used for debugging! */ + fun debugResetBackoffInterval() { + writableDatabase.update(Jobs.TABLE_NAME, contentValuesOf(Jobs.NEXT_BACKOFF_INTERVAL to 0), null, null) + } + companion object { private val TAG = Log.tag(JobDatabase::class.java) private const val DATABASE_VERSION = 2 diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/DatabaseProtosUtil.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/DatabaseProtosUtil.kt index 82a033dcb9..890874f4eb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/DatabaseProtosUtil.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/DatabaseProtosUtil.kt @@ -3,7 +3,9 @@ package org.thoughtcrime.securesms.database.model import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList +import org.thoughtcrime.securesms.database.model.databaseprotos.PendingOneTimeDonation import org.whispersystems.signalservice.internal.push.BodyRange +import kotlin.time.Duration.Companion.days /** * Collection of extensions to make working with database protos cleaner. @@ -52,3 +54,25 @@ fun List?.toBodyRangeList(): BodyRangeList? { return builder.build() } + +fun PendingOneTimeDonation?.isPending(): Boolean { + return this != null && this.error == null && !this.isExpired +} + +fun PendingOneTimeDonation?.isLongRunning(): Boolean { + return isPending() && this!!.paymentMethodType == PendingOneTimeDonation.PaymentMethodType.SEPA_DEBIT +} + +val PendingOneTimeDonation.isExpired: Boolean + get() { + val pendingOneTimeBankTransferTimeout = 14.days + val pendingOneTimeNormalTimeout = 1.days + + val timeout = if (paymentMethodType == PendingOneTimeDonation.PaymentMethodType.SEPA_DEBIT) { + pendingOneTimeBankTransferTimeout + } else { + pendingOneTimeNormalTimeout + } + + return (timestamp + timeout.inWholeMilliseconds) < System.currentTimeMillis() + } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/DonationsValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/DonationsValues.kt index 20d04aeb25..038d3f4a66 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/DonationsValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/DonationsValues.kt @@ -14,12 +14,12 @@ import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialRequestContext import org.signal.libsignal.zkgroup.receipts.ReceiptSerial import org.thoughtcrime.securesms.badges.Badges import org.thoughtcrime.securesms.badges.models.Badge -import org.thoughtcrime.securesms.components.settings.app.subscription.DonationSerializationHelper.isExpired import org.thoughtcrime.securesms.components.settings.app.subscription.donate.stripe.Stripe3DSData import org.thoughtcrime.securesms.database.model.databaseprotos.BadgeList import org.thoughtcrime.securesms.database.model.databaseprotos.DonationErrorValue import org.thoughtcrime.securesms.database.model.databaseprotos.PendingOneTimeDonation import org.thoughtcrime.securesms.database.model.databaseprotos.TerminalDonationQueue +import org.thoughtcrime.securesms.database.model.isExpired import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob import org.thoughtcrime.securesms.payments.currency.CurrencyUtil diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 469594f508..25c6a67c7a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5823,6 +5823,17 @@ Continue Private messaging, funded by you. No ads, no tracking, no compromise. Donate now to support Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Monthly From 54953abc673e42d85bf033378351d05dedde8e3f Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 17:02:09 -0400 Subject: [PATCH 23/31] Reduce nightly update check interval to 2 hours. --- .../securesms/apkupdate/ApkUpdateRefreshListener.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java index 8ff760dffb..ff2016dcc3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/apkupdate/ApkUpdateRefreshListener.java @@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.jobs.ApkUpdateJob; import org.thoughtcrime.securesms.service.PersistentAlarmManagerListener; +import org.thoughtcrime.securesms.util.Environment; import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.concurrent.TimeUnit; @@ -21,7 +22,7 @@ public class ApkUpdateRefreshListener extends PersistentAlarmManagerListener { private static final String TAG = Log.tag(ApkUpdateRefreshListener.class); - private static final long INTERVAL = TimeUnit.HOURS.toMillis(6); + private static final long INTERVAL = Environment.IS_NIGHTLY ? TimeUnit.HOURS.toMillis(2) : TimeUnit.HOURS.toMillis(6); @Override protected long getNextScheduledExecutionTime(Context context) { From 74488feec220c0131ee224ae988f4e8b30a8fcf6 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 20:38:39 -0400 Subject: [PATCH 24/31] Update translations and other static files. --- app/src/main/res/values-af/strings.xml | 35 +++++++---- app/src/main/res/values-ar/strings.xml | 39 ++++++++---- app/src/main/res/values-az/strings.xml | 35 +++++++---- app/src/main/res/values-bg/strings.xml | 35 +++++++---- app/src/main/res/values-bn/strings.xml | 35 +++++++---- app/src/main/res/values-bs/strings.xml | 37 +++++++---- app/src/main/res/values-ca/strings.xml | 35 +++++++---- app/src/main/res/values-cs/strings.xml | 37 +++++++---- app/src/main/res/values-da/strings.xml | 35 +++++++---- app/src/main/res/values-de/strings.xml | 35 +++++++---- app/src/main/res/values-el/strings.xml | 35 +++++++---- app/src/main/res/values-es/strings.xml | 35 +++++++---- app/src/main/res/values-et/strings.xml | 69 ++++++++++++--------- app/src/main/res/values-eu/strings.xml | 35 +++++++---- app/src/main/res/values-fa/strings.xml | 35 +++++++---- app/src/main/res/values-fi/strings.xml | 35 +++++++---- app/src/main/res/values-fr/strings.xml | 35 +++++++---- app/src/main/res/values-ga/strings.xml | 72 +++++++++++++--------- app/src/main/res/values-gl/strings.xml | 35 +++++++---- app/src/main/res/values-gu/strings.xml | 35 +++++++---- app/src/main/res/values-hi/strings.xml | 35 +++++++---- app/src/main/res/values-hr/strings.xml | 37 +++++++---- app/src/main/res/values-hu/strings.xml | 35 +++++++---- app/src/main/res/values-in/strings.xml | 34 ++++++---- app/src/main/res/values-it/strings.xml | 35 +++++++---- app/src/main/res/values-iw/strings.xml | 37 +++++++---- app/src/main/res/values-ja/strings.xml | 34 ++++++---- app/src/main/res/values-ka/strings.xml | 35 +++++++---- app/src/main/res/values-kk/strings.xml | 69 ++++++++++++--------- app/src/main/res/values-km/strings.xml | 34 ++++++---- app/src/main/res/values-kn/strings.xml | 69 ++++++++++++--------- app/src/main/res/values-ko/strings.xml | 34 ++++++---- app/src/main/res/values-ky/strings.xml | 34 ++++++---- app/src/main/res/values-lt/strings.xml | 71 ++++++++++++--------- app/src/main/res/values-lv/strings.xml | 36 +++++++---- app/src/main/res/values-mk/strings.xml | 35 +++++++---- app/src/main/res/values-ml/strings.xml | 35 +++++++---- app/src/main/res/values-mr/strings.xml | 35 +++++++---- app/src/main/res/values-ms/strings.xml | 34 ++++++---- app/src/main/res/values-my/strings.xml | 34 ++++++---- app/src/main/res/values-nb/strings.xml | 35 +++++++---- app/src/main/res/values-nl/strings.xml | 35 +++++++---- app/src/main/res/values-pa/strings.xml | 35 +++++++---- app/src/main/res/values-pl/strings.xml | 71 ++++++++++++--------- app/src/main/res/values-pt-rBR/strings.xml | 35 +++++++---- app/src/main/res/values-pt/strings.xml | 69 ++++++++++++--------- app/src/main/res/values-ro/strings.xml | 36 +++++++---- app/src/main/res/values-ru/strings.xml | 37 +++++++---- app/src/main/res/values-sk/strings.xml | 37 +++++++---- app/src/main/res/values-sl/strings.xml | 37 +++++++---- app/src/main/res/values-sq/strings.xml | 35 +++++++---- app/src/main/res/values-sr/strings.xml | 35 +++++++---- app/src/main/res/values-sv/strings.xml | 35 +++++++---- app/src/main/res/values-sw/strings.xml | 35 +++++++---- app/src/main/res/values-ta/strings.xml | 35 +++++++---- app/src/main/res/values-te/strings.xml | 35 +++++++---- app/src/main/res/values-th/strings.xml | 34 ++++++---- app/src/main/res/values-tl/strings.xml | 69 ++++++++++++--------- app/src/main/res/values-tr/strings.xml | 69 ++++++++++++--------- app/src/main/res/values-ug/strings.xml | 68 +++++++++++--------- app/src/main/res/values-uk/strings.xml | 37 +++++++---- app/src/main/res/values-ur/strings.xml | 35 +++++++---- app/src/main/res/values-vi/strings.xml | 34 ++++++---- app/src/main/res/values-yue/strings.xml | 34 ++++++---- app/src/main/res/values-zh-rCN/strings.xml | 34 ++++++---- app/src/main/res/values-zh-rHK/strings.xml | 34 ++++++---- app/src/main/res/values-zh-rTW/strings.xml | 34 ++++++---- app/static-ips.gradle | 2 +- 68 files changed, 1660 insertions(+), 1042 deletions(-) diff --git a/app/src/main/res/values-af/strings.xml b/app/src/main/res/values-af/strings.xml index 66b0149dcc..2b9edc1f4a 100644 --- a/app/src/main/res/values-af/strings.xml +++ b/app/src/main/res/values-af/strings.xml @@ -643,6 +643,8 @@ %1$s%% tot dusver… Signal benodig toestemming om ekstern te stoor ten einde rugsteunkopieë te maak, maar dit is permanent geweier. Gaan asseblief na die toepassinginstellings, kies \"Toestemmings\" en aktiveer \"Storing\". + + Set backup time @@ -2102,6 +2104,8 @@ ’n Nuwe weergawe van Signal is beskikbaar. Tik om opdatering te doen. Signal kon nie opdateer nie Ons sal later weer probeer. + Signal successfully updated + You were automatically updated to version %1$s. Stuur boodskap? @@ -2709,24 +2713,13 @@ - Om jou end-tot-end-enkriptering met %1$s te verifieer, vergelyk die kleurkaart hierbo met hul toestel en vergelyk die nommers. As dié nie ooreenstem nie, vee en probeer die ander paar veiligheidsnommers. Slegs een paar hoef ooreen te stem. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Tik om te skandeer Suksesvolle passing Kon nie veiligheidsnommer verifieer nie Laai tans… Merk as geverifieer Maak verifiëring skoon - - Veiligheidsnommers word tans op datum gebring. - - - Veranderinge aan veiligheidsnommers - - Veiligheidsnommers word gedurende \'n oorgangstydperk op datum gebring om komende privaatheidskenmerke in Signal te aktiveer.\n\nOm veiligheidsnommers te verifieer, vergelyk die kleurkaart met jou kontak se toestel. As dié nie ooreenstem nie, vee en probeer die ander paar veiligheidsnommers. Slegs een paar hoef ooreen te stem. - - Hulp nodig? - - Ek verstaan Skandeer die QR-kode op jou kontak se toestel. @@ -5581,7 +5574,10 @@ Alle verbindings is nagegaan, tik stuur om voort te gaan. - Jy het %1$d konneksies wat moontlik Signal herinstalleer of van toestelle verander het. Voordat jy jou storie met hulle deel, gaan hulle veiligheidsnommers na of oorweeg dit om hulle uit jou storie te verwyder. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verifieer veiligheidsnommer @@ -5824,6 +5820,17 @@ Gaan voort Private boodskappe, befonds deur jou. Geen advertensies, geen nasporing, geen kompromis nie. Maak nou \'n skenking om Signal te ondersteun. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Maandeliks @@ -5891,6 +5898,8 @@ Vind meer uit Gaan voort + + Read more Kon nie versoek laai nie diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index e7e89513d6..8252520277 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -707,6 +707,8 @@ ‫%1$s%% إلى الآن… يحتاج سيجنال إلى إذن الوصول إلى سعة التخزين الخارجية لإنشاء نسخ احتياطية، ولكن رُفض الإذن على نحو دائم. الرجاء الاطلاع على إعدادات التطبيق ثم اختيار \"الصلاحيات\"، ثم تفعيل \"سعة التخزين\". + + Set backup time @@ -2394,6 +2396,8 @@ إصدار جديد من سيجنال متوفر. انقر للتحديث. تعذّر على سيجنال التحديث سنحاول من جديد لاحقًا. + Signal successfully updated + You were automatically updated to version %1$s. هل تود إرسال الرسالة ؟ @@ -3057,24 +3061,13 @@ - للتحقّق من أمان تعميتك من الطرف للطرف مع %1$s، يُرجى مطابقة لون البطاقة أعلاه مع جهازه ومقارنة الأرقام. إذا فشل تطابقهما، يُرجى السحب لتجربة زوج آخر من أرقام الأمان. ستحتاج إلى تطابق زوج واحد فقط. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. المس للمسح تم التوافُق بنجاح لقد فشل التحقق من رقم الأمان قيد التحميل… علِّم كمُتحقَّق منه محو التحقق - - جارٍ تحديث أرقام الأمان. - - - التغييرات التي ستطرأ على أرقام الأمان - - يتم تحديث أرقام الأمان على مدى فترة انتقالية لتفعيل ميزات الخصوصية القادمة في سيجنال-Signal.\n\nللتحقّق من أرقام الأمان، يُرجى مطابقة لون البطاقة مع جهاز جهة اتصالك. إذا فشل تطابقهما، يُرجى السحب لتجربة زوج آخر من أرقام الأمان. ستحتاج إلى تطابق زوج واحد فقط. - - بحاجة إلى مساعدة ؟ - - عُلم امسح رمز الاستجابة السريعة المعروض على جهاز جهة اتصالك. @@ -6085,7 +6078,14 @@ تمت مراجعة كل جهات الاتصال، انقر إرسال للمواصلة. - %1$d من جهات اتصالك قد يكونوا أعادو تثبيت سيجنال أو غيّروا أجهزتهم. قبل مشاركة قِصتك معهم، يُرجى مراجعة أرقام الأمان الخاصة بهم أو فكّر في حذفهم من قصتك. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + تحقق من رقم اﻷمان @@ -6340,6 +6340,17 @@ واصل تراسل خاص، مُموّل من طرفك. بدون إعلانات، بدون مُتعقبات، بدون رقابة. تبرّع الآن لدعم سيجنال. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + شهريًا @@ -6411,6 +6422,8 @@ معرفة المزيد مواصلة + + Read more تعذر تحميل الطلب diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 4b75b63fdc..8c36835569 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -643,6 +643,8 @@ İndiyə qədər %1$s%%… Signal, nüsxələri yaratmaq üçün xarici anbar icazəsi tələb edir, ancaq bu icazə birdəfəlik rədd edilib. Zəhmət olmasa tətbiq tənzimləmələrində \"İcazələr\"i seçib \"Anbar\"ı fəallaşdırın. + + Set backup time @@ -2102,6 +2104,8 @@ Signal-ın yeni versiyası mövcuddur. Yeniləmək üçün toxunun. Signal-ı yeniləmək mümkün olmadı Daha sonra yenidən cəhd edəcəyik. + Signal successfully updated + You were automatically updated to version %1$s. Mesaj göndərilsin? @@ -2709,24 +2713,13 @@ - %1$s ilə olan ucdan-uca şifrələməni yoxlamaq üçün yuxarıdakı rəngli kartda görünən nömrəni istifadəçinin cihazı ilə müqayisə edin. Bu rəqəmlər uyğun gəlmirsə ekranı yana sürüşdürüb digər təhlükəsizlik nömrəsini yoxlayın. Yalnız bir cüt rəqəmi müqayisə etmək tələb olunur. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Skan etmək üçün toxunun Uğurlu Güvənlik nömrəsi təsdiqlənmədi Yüklənir… Təsdiqləndi olaraq işarələ Təsdiqləməni təmizlə - - Təhlükəsizlik nömrələri yeniləndi. - - - Təhlükəsizlik nömrələrində dəyişikliklər - - Signal-dakı növbəti məxfilik xüsusiyyətlərini aktivləşdirmək üçün ötürmə müddətində təhlükəsizlik nömrələri yenilənir.\n\nTəhlükəsizlik nömrələrini yoxlamaq üçün rəngli kartda görünən rəqəmləri kontaktınızın cihazı ilə müqayisə edin. Əgər rəqəmlər uyğun gəlmirsə, ekranı yana sürüşdürüb, digər bir təhlükəsizlik nömrəsini yoxlayın. Yalnız bir cüt nömrə uyğun gəlməlidir. - - Kömək lazımdır? - - Anladım Əlaqənizin cihazındakı QR kodunu skan edin. @@ -5581,7 +5574,10 @@ Bütün əlaqələr nəzərdən keçirilib, davam etmək üçün \"Göndər\" düyməsinə toxunun. - %1$d əlaqəniz Signal-ı yenidən quraşdırmış və ya cihazlarını dəyişmiş ola bilər. Hekayənizi onlarla paylaşmazdan əvvəl onların təhlükəsizlik nömrələrini nəzərdən keçirin və ya onları hekayə izləyiciləri siyahınızdan çıxarın. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Güvənlik nömrəsini təsdiqlə @@ -5824,6 +5820,17 @@ Davam et Dəstəklərinizlə yaradılmış şəxsi mesajlaşma. Reklamsız, təqibsiz və güzəştsiz. Signal-ı dəstəkləmək üçün indi ianə verin. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Aylıq @@ -5891,6 +5898,8 @@ Daha ətraflı Davam et + + Read more Pul köçürmə əmrinizi yükləmək mümkün olmadı diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 69ad969fec..c40a832338 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -643,6 +643,8 @@ %1$s%% дотук… Signal изисква разрешение за достъп до външните хранилища, за да може да създаде архиви, но този достъп е парманентно отказан. Моля, продължете до настройки на приложенията и изберете \"Разрешения\" и активирайте \"Хранилище\". + + Set backup time @@ -2102,6 +2104,8 @@ Има нова версия на Signal. Докоснете за актуализиране. Signal не успя да се актуализира Ще опитаме отново по-късно. + Signal successfully updated + You were automatically updated to version %1$s. Изпращане на съобщение? @@ -2709,24 +2713,13 @@ - За да проверите сигурността на криптирането от край до край между вас и %1$s, напаснете цветната карта по-горе с устройството на другия потребител и сравнете цифрите. Ако не съвпадат, плъзнете и пробвайте другата двойка номера за сигурност. Достатъчно е една двойка да съвпадне. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Натиснете за сканиране Успешно съвпадение Неуспешна проверка на номера за безопасност Зареждане… Маркирайте, както е потвърдено Изчистване на проверка - - Номерата за сигурност се актуализират. - - - Промени в номерата за сигурност - - Номерата за сигурност се актуализират през преходен период, за да се активират предстоящите функции за поверителност в Signal.\n\nЗа да потвърдите номерата за сигурност, цветната карта трябва да съвпадне с устройството на вашия контакт. Ако не съвпадат, плъзнете и пробвайте другата двойка номера за сигурност. Достатъчно е една двойка да съвпадне. - - Нужда от помощ? - - Ясно Сканирайте QR кода на устройството за контакт. @@ -5581,7 +5574,10 @@ Всички връзки бяха прегледани, докоснете \"изпращане\", за да продължите. - Имате %1$d връзки, които е възможно да са преинсталирали Signal или да са сменили устройството си. Преди да споделите историята си с тях, прегледайте номера им за безопасност или обмислете да ги премахнете от историята ви. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Проверка на числата за сигурност @@ -5824,6 +5820,17 @@ Продължи Частни съобщения, финансирани от вас. Без реклами, без следене, без компромис. Дарете сега, за да подкрепите Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Ежемесечно @@ -5891,6 +5898,8 @@ Научете повече Продължете + + Read more Неуспешно зареждане на заявката diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 90efadf289..1948d13fe3 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -643,6 +643,8 @@ এখন পর্যন্ত %1$s %%… ব্যাকআপগুলি তৈরি করতে Signal এর জন্য বাহ্যিক স্টোরেজ অনুমতি প্রয়োজন, তবে এটি স্থায়ীভাবে অস্বীকার করা হয়েছে। দয়া করে অ্যাপ্লিকেশন সেটিংস যান, \"অনুমতিগুলি\" নির্বাচন করুন এবং \"স্টোরেজ\" সক্ষম করুন। + + Set backup time @@ -2102,6 +2104,8 @@ Signal-এর একটি নতুন সংস্করণ পাওয়া যাচ্ছে। আপডেট করতে ট্যাপ করুন। Signal আপডেট করতে ব্যর্থ হয়েছে আমরা পরে আবার চেষ্টা করবো। + Signal successfully updated + You were automatically updated to version %1$s. বার্তা পাঠান? @@ -2709,24 +2713,13 @@ - %1$s-এর সাথে এন্ড-টু-এন্ড এনক্রিপশন যাচাই করতে, তার ডিভাইসের উপরে থাকা রঙিন কার্ডটি মিলিয়ে দেখুন এবং নম্বরগুলো তুলনা করুন। এগুলো যদি না মিলে তবে সোয়াইপ করুন এবং অন্য এক জোড়া নিরাপত্তা নম্বর ব্যবহার করে দেখুন। শুধুমাত্র একটি জোড়া মিলতে হবে। + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. স্ক্যান করতে আলতো চাপুন সফল ম্যাচ নিরাপত্তা নম্বর যাচাই করতে ব্যর্থ হয়েছে লোড হচ্ছে… যাচাইকৃত হিসাবে চিহ্নিত করুন যাচাইকরণ সম্পূর্ণ করুন - - নিরাপত্তা নম্বরগুলো আপডেট করা হচ্ছে। - - - নিরাপত্তা নম্বর পরিবর্তন করুন - - Signal-এ আসন্ন গোপনীয়তা ফিচারগুলোকে সচল করার জন্য পরিবর্তনের সময় নিরাপত্তা নম্বরগুলো আপডেট করা হচ্ছে।\n\nনিরাপত্তা নম্বর যাচাই করতে, আপনার কন্টাক্টের ডিভাইসের সাথে থাকা রঙিন কার্ডটি মিলিয়ে দেখুন। এগুলো যদি না মিলে তবে সোয়াইপ করুন এবং অন্য এক জোড়া নিরাপত্তা নম্বর ব্যবহার করে দেখুন। শুধুমাত্র একটি জোড়া মিলতে হবে। - - সাহায্য প্রয়োজন? - - বুঝতে পেরেছি আপনার পরিচিতি এর ডিভাইস থেকে প্রদর্শিত কিউআর কোডটি স্ক্যান করুন। @@ -5581,7 +5574,10 @@ সকল কানেকশন রিভিউ করা হয়েছে, চালিয়ে যেতে সেন্ডে ট্যাপ করুন। - আপনার %1$dটি কানেকশন আছে, যারা সম্ভবত Signal পুনরায় ইনস্টল করেছেন বা ডিভাইস পরিবর্তন করেছেন৷ তাদের সাথে আপনার স্টোরি শেয়ার করার আগে তাদের নিরাপত্তা নম্বরগুলো রিভিউ করুন বা আপনার স্টোরি দেখা থেকে তাদের বাদ দিন। + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + নিরাপত্তা নাম্বার যাচাই করুন @@ -5824,6 +5820,17 @@ চালিয়ে যান ব্যক্তিগত ম্যাসেজিং, আপনাদের অর্থেই চালিত। নেই কোনো বিজ্ঞাপন, নেই কোনো ট্র্যাকিং, নেই কোনো আপোস। Signal-কে সমর্থন করতে এখনই ডোনেট করুন। + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + মাসিক @@ -5891,6 +5898,8 @@ আরো জানুন চালিয়ে যান + + Read more অনুরোধ লোড করা যায়নি diff --git a/app/src/main/res/values-bs/strings.xml b/app/src/main/res/values-bs/strings.xml index 55010a6ef0..92338f0185 100644 --- a/app/src/main/res/values-bs/strings.xml +++ b/app/src/main/res/values-bs/strings.xml @@ -675,6 +675,8 @@ %1$s%% do sada… Signalu je potrebno dopuštenje da pristupi memoriji uređaja kako bi mogao kreirati rezervne kopije, ali je ono trajno uskraćeno. Molimo nastavite do postavki aplikacije, odaberite \"Dozvole\" i aktivirajte stavku \"Prostor za pohranu\". + + Set backup time @@ -2248,6 +2250,8 @@ Dostupna je nova verzija Signala. Dodirnite za ažuriranje. Ažuriranje signala nije uspjelo Pokušat ćemo ponovo kasnije. + Signal successfully updated + You were automatically updated to version %1$s. Poslati poruku? @@ -2883,24 +2887,13 @@ - Da potvrdite sveobuhvatno šifriranje sa %1$s, uparite gornju karticu u boji s uređajem te osobe i uporedite brojeve. Ako se ne podudaraju, prevucite prstom i pokušajte s drugim parom sigurnosnih brojeva. Samo jedan par se treba podudarati. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Pritisnite da skenirate Podudara se Provjera sigurnosnog broja nije uspjela Učitavanje… Označi kao provjereno Ukloni iz provjerenih - - Sigurnosni brojevi se ažuriraju. - - - Promjene sigurnosnih brojeva - - Sigurnosni brojevi se ažuriraju tokom prelaznog perioda kako bi se omogućile nadolazeće funkcije privatnosti u Signalu.\n\nDa potvrdite sigurnosne brojeve, uskladite karticu u boji s uređajem vašeg kontakta. Ako se ne podudaraju, prevucite prstom i pokušajte s drugim parom sigurnosnih brojeva. Samo jedan par se treba podudarati. - - Trebate li pomoć? - - Razumijem Skenirajte QR kôd na uređaju vašeg kontakta. @@ -5833,7 +5826,12 @@ Sve veze su pregledane, dodirnite \"Pošalji\" da nastavite. - Imate kontakte (njih %1$d) koji su možda ponovo instalirali Signal ili su promijenili uređaje. Prije nego podijelite priču s tim osobama, pregledajte njihove sigurnosne brojeve ili razmotrite opciju da ih uklonite iz svoje priče. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Provjerite sigurnosni broj @@ -6082,6 +6080,17 @@ Nastavi Privatno razmjenjivanje poruka koje finansirate vi. Bez oglasa, bez praćenja, bez kompromisa. Donirajte sada da podržite Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mjesečno @@ -6151,6 +6160,8 @@ Saznaj više Nastavi + + Read more Učitavanje naloga nije uspjelo diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 31d933c66c..f340812764 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -643,6 +643,8 @@ %1$s%% fins ara… El Signal necessita el permís de l\'emmagatzematge extern per tal de crear còpies de seguretat. Si us plau, continueu cap al menú de configuració de l\'aplicació, seleccioneu Permisos i activeu-hi l\'emmagatzematge. + + Set backup time @@ -2102,6 +2104,8 @@ Hi ha disponible una nova versió de Signal. Toca per actualitzar-lo. No s\'ha pogut actualitzar Signal Ho tornarem a provar més tard. + Signal successfully updated + You were automatically updated to version %1$s. Voleu enviar el missatge? @@ -2709,24 +2713,13 @@ - Per verificar el xifrat amb %1$s, tria més a dalt la carta de color que coincideixi amb la del dispositiu d\'aquella persona i compara les xifres. Si aquests no coincideixen, desplaça\'t i prova un altre parell de números de seguretat. Només cal que coincideixin un parell. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Feu un toc per escanejar Coincidència correcta Ha fallat verificar el número de seguretat. Es carrega… Marca com a verificat Neteja la verificació - - Els números de seguretat s\'estan actualitzant. - - - Canvis als números de seguretat - - S\'estan actualitzant els números de seguretat durant un període de transició per habilitar les pròximes funcions de privacitat de Signal.\n\nPer a verificar els números de seguretat, fes que la teva carta de color coincideixi amb la del dispositiu del teu contacte. Si aquests no coincideixen, desplaça\'t i prova un altre parell de números de seguretat. Només cal que coincideixin un parell. - - Us cal ajuda? - - Entesos Escanegeu el codi QR del dispositiu del contacte. @@ -5581,7 +5574,10 @@ S\'han revisat tots els contactes, toca enviar per a continuar. - Tens %1$d contactes que pot ser que hagin reinstal·lat Signal o canviat de dispositiu. Abans de compartir la teva història amb ells, revisa els seus números de seguretat o pensa si vols eliminar-los de la teva història. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verifica el número de seguretat @@ -5824,6 +5820,17 @@ Continuar Missatgeria privada, finançada per tu. Sense anuncis, ni rastrejadors, ni compromís. Fes ja una donació per ajudar a Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mensual @@ -5891,6 +5898,8 @@ Més informació Continuar + + Read more No s\'ha pogut carregar el mandat diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index d0b7de14a3..2be82903be 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -675,6 +675,8 @@ Zatím %1$s%%… Signal potřebuje oprávnění pro přístup k úložišti, aby mohl vytvářet zálohy, ale toto oprávnění je nyní trvale zakázáno. Prosím pokračujte do menu nastavení aplikací, vyberte \"Oprávnění\" a povolte \"Úložiště\". + + Set backup time @@ -2248,6 +2250,8 @@ K dispozici je nová verze aplikace Signal. Klepnutím ji aktualizujete. Signal se nepodařilo aktualizovat Zkusíme to znovu později. + Signal successfully updated + You were automatically updated to version %1$s. Odeslat zprávu? @@ -2883,24 +2887,13 @@ - Chcete-li ověřit bezpečnost koncového šifrování s %1$s, porovnejte čísla a výše uvedenou barevnou kartu se zařízením tohoto kontaktu. Pokud se neshodují, přejeďte prstem dál a vyzkoušejte druhou dvojici bezpečnostních čísel. Musí se shodovat pouze jedna dvojice. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Klepnutím skenovat Shoduje se Nepodařilo se ověřit bezpečnostní číslo Načítání… Označit jako ověřené Vymazat ověření - - Bezpečnostní čísla se aktualizují. - - - Změny u bezpečnostních čísel - - Bezpečnostní čísla se po přechodném období aktualizují, aby bylo možné v aplikaci Signal využívat připravované funkce ochrany osobních údajů.\n\nPro ověření bezpečnostních čísel porovnejte barevnou kartu s daným kontaktem ve vašem zařízení. Pokud se neshodují, přejeďte prstem dál a vyzkoušejte druhou dvojici bezpečnostních čísel. Musí se shodovat pouze jedna dvojice. - - Potřebujete pomoc? - - Rozumím Naskenujte QR kód na zařízení vašeho kontaktu. @@ -5833,7 +5826,12 @@ Všechna spojení byla zkontrolována, pokračujte klepnutím na tlačítko odeslat. - Máte %1$d spojení, která si pravděpodobně přeinstalovala aplikaci Signal nebo změnila zařízení. Než s nimi budete sdílet svůj příběh, zkontrolujte jejich bezpečnostní čísla nebo zvažte jejich odebrání z příběhu. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Ověření bezpečnostního čísla @@ -6082,6 +6080,17 @@ Pokračovat Soukromé zasílání zpráv financované vámi. Žádné reklamy, žádné sledování, žádné kompromisy. Přispějte nyní a podpořte službu Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Měsíčně @@ -6151,6 +6160,8 @@ Více informací Pokračovat + + Read more Požadavek se nepodařilo načíst diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index a66924ec64..c74b6ddff4 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -643,6 +643,8 @@ %1$s%% indtil videre… Signal beder om tilladelse til at tilgå ekstern lagerplads for at oprette sikkerhedskopier, hvilket er blevet nægtet. Gå venligst til appindstillinger, vælg \"Tilladelser\" og tilvælg \"Lagerplads\". + + Set backup time @@ -2102,6 +2104,8 @@ En ny version af Signal er tilgængelig. Tryk for at opdatere. Signal kunne ikke opdateres Vi prøver igen senere. + Signal successfully updated + You were automatically updated to version %1$s. Send besked? @@ -2709,24 +2713,13 @@ - Hvis du vil verificere din E2E-kryptering med %1$s, skal du matche farvekortet ovenfor med deres enhed og sammenligne tallene. Hvis de ikke matcher, skal du swipe for at prøve et andet sæt sikkerhedsnumre. Det er kun ét sæt, der skal matche. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Tryk for at scanne Vellykket match Kunne ikke verificere sikkerhedsnummer Indlæser… Markér som verificeret Fjern verifikation - - Sikkerhedsnumrene opdateres. - - - Ændring af sikkerhedsnumre - - Sikkerhedsnumre opdateres i en overgangsperiode for at muliggøre kommende privatlivsfunktioner i Signal.\n\nFor at verificere sikkerhedsnumrene, skal du matche farvekortet med din kontakts enhed. Hvis de ikke matcher, skal du swipe og prøve et andet sæt sikkerhedsnumre. Det er kun ét sæt, der skal matche. - - Brug for hjælp? - - Forstået Scan QR-koden på din kontakts enhed. @@ -5581,7 +5574,10 @@ Alle forbindelser er gennemgået. Tryk send for at fortsætte. - Du har %1$d kontakter, der muligvis har geninstalleret Signal eller skiftet enhed. Gennemgå deres sikkerhedsnummer, eller overvej at fjerne dem fra din historie, inden du deler din historie med dem. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verificer sikkerhedsnummer @@ -5824,6 +5820,17 @@ Fortsæt Private beskeder, der er finansieret af dig. Ingen annoncer, ingen sporing, ingen kompromiser. Donér nu for at støtte Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Månedlig @@ -5891,6 +5898,8 @@ Få mere at vide Fortsæt + + Read more Kunne ikke indlæse anmodningen diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d71edaa474..7f5bb95ea8 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -643,6 +643,8 @@ %1$s%% bisher … Signal benötigt zum Erstellen von Datensicherungen die Berechtigung »Speicher«, diese wurde jedoch dauerhaft abgelehnt. Bitte öffne die App-Einstellungen, wähle »Berechtigungen« und aktiviere »Speicher«. + + Set backup time @@ -2102,6 +2104,8 @@ Eine neue Signal-Version ist verfügbar. Zum Aktualisieren antippen. Signal konnte nicht aktualisiert werden Wir versuchen es später erneut. + Signal successfully updated + You were automatically updated to version %1$s. Nachricht senden? @@ -2709,24 +2713,13 @@ - Um die Ende-zu-Ende-Verschlüsselung mit %1$s zu gewährleisten, vergleiche die obige Farbkarte und die Nummern mit denen auf dem Gerät der anderen Person. Wenn diese nicht übereinstimmen, wische weiter und versuche es mit dem anderen Paar Sicherheitsnummern. Es reicht, wenn ein Paar zusammenpasst. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Zum Scannen antippen Vergleich erfolgreich Sicherheitsnummer konnte nicht verifiziert werden Wird geladen … Als verifiziert markieren Verifikation entfernen - - Die Sicherheitsnummern werden aktualisiert. - - - Änderungen an den Sicherheitsnummern - - Die Sicherheitsnummern werden während eines Ladevorgangs aktualisiert, um neue Datenschutzfunktionen in Signal zu aktivieren.\n\nUm die Sicherheitsnummern zu überprüfen, stimme die Farbkarte mit der auf dem Gerät deines Kontaktes ab. Wenn diese nicht übereinstimmen, wische weiter und probiere es mit dem anderen Paar Sicherheitsnummern. Es reicht, wenn ein Paar zusammenpasst. - - Hilfe benötigt? - - Verstanden Scanne den QR-Code deines Kontakts ein. @@ -5581,7 +5574,10 @@ Alle Verbindungen wurden geprüft, tippe auf „Senden“, um fortzufahren. - Du hast %1$d Verbindungen, die möglicherweise Signal erneut installiert oder das Gerät gewechselt haben. Prüfe ihre Sicherheitsnummer oder erwäge, sie aus deiner Story zu entfernen, bevor du deine Story mit ihnen teilst. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Sicherheitsnummer verifizieren @@ -5824,6 +5820,17 @@ Fortfahren Privates Messaging. Von dir finanziert. Keine Werbung, kein Tracking, keine Kompromisse. Jetzt Signal unterstützen und spenden. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Monatlich @@ -5891,6 +5898,8 @@ Mehr erfahren Fortfahren + + Read more Lastschriftanfrage konnte nicht geladen werden diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index b0cda6d0ee..677ae64856 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -643,6 +643,8 @@ %1$s%% μέχρι τώρα… Το Signal χρειάζεται τα δικαιώματα πρόσβασης εξωτερικής μνήμης για τη δημιουργία αντιγράφων ασφαλείας, αλλά αυτά δεν έχουν δοθεί μόνιμα. Παρακαλώ πήγαινε στις ρυθμίσεις εφαρμογών, επέλεξε τα \"Δικαιώματα\", και ενεργοποίησε το \"Αποθηκευτικός Χώρος\". + + Set backup time @@ -2102,6 +2104,8 @@ Μια νέα έκδοση του Signal είναι διαθέσιμη. Πάτα για ενημέρωση. Αποτυχία ενημέρωσης Signal Θα προσπαθήσουμε ξανά αργότερα. + Signal successfully updated + You were automatically updated to version %1$s. Αποστολή μηνύματος; @@ -2709,24 +2713,13 @@ - Για να επαληθεύσεις την κρυπτογράφηση από άκρο σε άκρο με τον/την %1$s, αντιστοίχισε την έγχρωμη κάρτα παραπάνω με τη συσκευή του/της και συγκρίνετε τους αριθμούς. Εάν δεν ταιριάζουν, σύρε και δοκίμασε το άλλο ζεύγος αριθμών ασφαλείας. Μόνο ένα ζευγάρι χρειάζεται να ταιριάζει. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Πάτα για σκανάρισμα Επιτυχής σύγκριση Αποτυχία επιβεβαίωσης αριθμού ασφαλείας Φόρτωση… Σημείωση ως επιβεβαιωμένο Αφαίρεση επιβεβαίωσης - - Οι αριθμοί ασφαλείας ενημερώνονται. - - - Αλλαγές στους Αριθμούς Ασφαλείας - - Οι αριθμοί ασφαλείας ενημερώνονται κατά τη διάρκεια μιας μεταβατικής περιόδου για να ενεργοποιηθούν οι επερχόμενες λειτουργίες απορρήτου στο Signal.\n\nΓια να επαληθεύσεις τους αριθμούς ασφαλείας, αντιστοίχισε την έγχρωμη κάρτα με τη συσκευή της επαφής σου. Εάν δεν ταιριάζουν, σύρε και δοκίμασε το άλλο ζεύγος αριθμών ασφαλείας. Μόνο ένα ζευγάρι χρειάζεται να ταιριάζει. - - Χρειάζεσαι βοήθεια; - - Εντάξει Σκάναρε τον κωδικό QR στη συσκευή του άλλου χρήστη. @@ -5581,7 +5574,10 @@ Όλες οι επαφές έχουν ελεγχτεί. Πάτα Αποστολή για να συνεχίσεις. - Έχεις %1$d επαφές που μπορεί να έχουν εγκαταστήσει εκ νέου το Signal ή να έχουν αλλάξει συσκευές. Προτού μοιραστείς την ιστορία σου μαζί τους, έλεγξε τους αριθμούς ασφαλείας τους. Διαφορετικά, μπορείς να τους αφαιρέσεις από την ιστορία σου. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Επαλήθευση αριθμού ασφαλείας @@ -5824,6 +5820,17 @@ Συνέχεια Ιδιωτικά μηνύματα, χρηματοδότηση από εσένα. Χωρίς διαφημίσεις, παρακολούθηση, συμβιβασμούς. Κάνε τώρα μια δωρεά για να στηρίξεις το Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Μηνιαία @@ -5891,6 +5898,8 @@ Μάθε περισσότερα Συνέχεια + + Read more Αποτυχία φόρτωσης εντολής diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 05ba08d631..fba912f309 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -643,6 +643,8 @@ %1$s de %% de momento … Signal necesita acceso al almacenamiento para crear copias de seguridad. Por favor, ve a la aplicación «Ajustes», selecciona Signal en el menú «Aplicaciones y notificaciones» y en «Permisos» activa «Almacenamiento». + + Set backup time @@ -2102,6 +2104,8 @@ Una nueva versión de Signal está disponible. Toca para actualizar. Signal no se ha podido actualizar Lo intentaremos de nuevo más tarde. + Signal successfully updated + You were automatically updated to version %1$s. ¿Enviar mensaje? @@ -2709,24 +2713,13 @@ - Para verificar el cifrado con %1$s, elige la carta de color que coincida con la del dispositivo de esa persona y compara las cifras. Si no coinciden, desliza y prueba otro par de números de seguridad. Solo necesitas que coincida un par. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Toca para escanear Las cifras coinciden Fallo al verificar las cifras de seguridad Cargando … Marcar persona como verificada Retirar marca de verificación - - Actualizaciones en los números de seguridad. - - - Cambios en los números de seguridad - - Se están actualizando los números de seguridad durante un período de transición para habilitar las próximas funciones de privacidad en Signal.\n\nPara verificar los números de seguridad, haz que tu tarjeta de color coincida con la del dispositivo de tu contacto. Si no coinciden, desliza y prueba otro par de números de seguridad. Solo necesitas que coincida un par. - - ¿Necesitas ayuda? - - Entendido Escanea el código QR mostrado en el dispositivo de tu contacto. @@ -5581,7 +5574,10 @@ Se han revisado todos los contactos. Toca enviar para continuar. - %1$d de tus contactos pueden haber reinstalado Signal o cambiado de dispositivo. Antes de compartir tu historia con ellos, revisa sus números de seguridad o considera retirarles de tu historia. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verificar cifras de seguridad @@ -5824,6 +5820,17 @@ Continuar Mensajería privada, financiada por ti. Sin anuncios, ni rastreos, ni compromiso. Haz una donación ya para ayudar a Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mensual @@ -5891,6 +5898,8 @@ Saber más Continuar + + Read more No se pudo cargar el mandato diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index b70453806a..0adf2117d1 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -643,6 +643,8 @@ %1$s/ %% … Signal vajab varukoopiate loomiseks välismälu õigust, ent see on püsivalt keelatud. Palun jätka rakenduse seadetes, vali \"Load\" ning luba \"Mäluruum\". + + Set backup time @@ -2099,9 +2101,11 @@ Signali uuendus - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Signali uus versioon on saadaval. Toksa uuendamiseks. + Signali uuendamine ebaõnnestus + Proovime hiljem uuesti. + Signal successfully updated + You were automatically updated to version %1$s. Saadad sõnumi? @@ -2709,24 +2713,13 @@ - Selleks, et kontrollida otspunktkrüpteerimist kasutajaga %1$s, võrdle ülalolevat värvikaarti ja numbreid tema seadmes olevatega. Kui need on erinevad, nipsa ekraani ja proovi teist turvanumbrite paari. Vaid üks paar peab omavahel klappima. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Koputa skäneerimiseks Edukas sobivus. Turvanumbri kinnitamine ei õnnestunud Laadimine… Märgi kinnitatuks Tühista kontrollimine - - Turvanumbreid uuendatakse. - - - Muudatused turvanumbrites - - Turvanumbreid uuendatakse üleminekuperioodi jooksul, et võimaldada Signali uusi privaatsusfunktsioone.\n\nTurvanumbrite kontrollimiseks võrdle värvikaarti oma kontakti seadmes olevaga. Kui need on erinevad, nipsa ekraani ja proovi teist turvanumbrite paari. Vaid üks paar peab omavahel klappima. - - Kas vajad abi? - - Sain aru Skanni QR-kood sinu kontakti seadmelt. @@ -5581,7 +5574,10 @@ Kõik kontaktid on kontrollitud, jätkamiseks toksa \"Saada\". - Sul on %1$d kontakti, kes võivad olla Signali uuesti paigaldanud või oma seadme välja vahetanud. Enne kui jagad nendega oma lugu, soovitame kontrollida nende turvakoodi või nad oma loo nägijate hulgast eemaldada. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Kinnita turvanumbrit @@ -5824,6 +5820,17 @@ Jätka Privaatne sõnumiside, mida toetad sina ise. Ei mingeid reklaame, jälgijaid ega järeleandmisi. Anneta nüüd, et Signalit toetada. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Igakuine @@ -5851,8 +5858,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Kas lahkuda Signalist, et makse kinnitada? + Kui see makse on kinnitatud, mine tagasi Signalisse, et oma annetuse töötlemine lõpule viia. @@ -5891,8 +5898,10 @@ Rohkem teavet Jätka + + Read more - Failed to load mandate + Käsu laadimine ebaõnnestus @@ -5912,13 +5921,13 @@ Anneta %1$s - IBAN is too short + IBAN on liiga lühike - IBAN is too long + IBAN on liiga pikk IBANi riigikoodi ei toetata - Invalid IBAN + Kehtetu IBAN @@ -5941,7 +5950,7 @@ Leia oma kontoandmed - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Leia oma kontoväljavõtte ülaservast IBAN. IBAN koosneb kuni 34 märgist. Sisestatav nimi peaks ühtima sinu pangakontol oleva täisnimega. Võta täiendava teabe saamiseks ühendust oma pangaga. Annetus on ootel @@ -5957,9 +5966,9 @@ Tehtud - Donation couldn\'t be processed + Annetust ei saanud töödelda - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Meil on raskusi sinu pangaülekande töötlemisega. Sinu kontolt ei võetud raha. Proovi teist maksemeetodit või võta lisainfo saamiseks ühendust oma pangaga. Proovi uuesti @@ -6386,17 +6395,17 @@ Nõustu - Turn on full screen notifications? + Kas lülitada sisse täisekraani formaadis teavitused? - Never miss a call from your contacts and groups. + Ükski kontaktidelt või gruppidelt tulev kõne ei jää märkamata. Lülita sisse - Turn on full screen notifications + Lülita sisse täisekraani formaadis teavitused - To receive call notifications from your contacts and groups: + Selleks, et oma kontaktidelt ja gruppidelt kõneteavitusi saada: - 2. %1$s Allow full screen notifications + 2. %1$s Lülita sisse täisekraani formaadis teavitused diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 9ecf5c828a..c2403ca2b5 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -643,6 +643,8 @@ %% %1$s oraingoz… Signal-ek kanpoko memorian gordetzeko baimena behar du babeskopiak egin ahal izateko baina baimena ukatuta izan du beti. Joan aplikazioaren ezarpenetara, aukeratu \"Baimenak\" eta gaitu \"Biltegiratzea\". + + Set backup time @@ -2102,6 +2104,8 @@ Signal-en bertsio berri bat dago. Eguneratzeko, sakatu hau. Ezin izan da eguneratu Signal Berriro saiatuko gara geroago. + Signal successfully updated + You were automatically updated to version %1$s. Mezua bidali? @@ -2709,24 +2713,13 @@ - %1$s erabiltzailearekin muturretik muturrerako enkriptatzea egiaztatzeko, lotu goiko kolore-txartela haren gailuarekin eta alderatu zenbakiak. Bat ez badatoz, pasatu hatza eta saiatu beste segurtasun-zenbaki parearekin. Bikote bakarrak bat egin behar du. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Sakatu eskaneatzeko Konbinazio arrakastatsua Ezin izan da egiaztatu segurtasun-zenbakia Kargatzen… Markatu egiaztatu gisa Garbitu egiaztapena - - Segurtasun zenbakiak eguneratzen. - - - Segurtasun-zenbakien aldaketak - - Segurtasun-zenbakiak trantsizio-aldi batean eguneratzen ari dira Signal-en datozen pribatutasun-ezaugarriak gaitzeko.\n\nSegurtasun-zenbakiak egiaztatzeko, lotu kolore-txartela zure kontaktuaren gailuarekin. Bat ez badatoz, pasatu hatza eta saiatu beste segurtasun-zenbaki parearekin. Bikote bakarrak bat egin behar du. - - Laguntza behar duzu? - - Ulertu dut Eskaneatu QR kodea zure kontaktuaren gailuan. @@ -5581,7 +5574,10 @@ Konexio guztiak berrikusi dira. Aurrera egiteko, sakatu Bidali. - Agian Signal berriro instalatu duten edo gailuz aldatu diren %1$d konexio dituzu. Istorioa haiekin partekatu aurretik, berrikusi haien segurtasun-zenbakiak edo ken itzazu istoriorik. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Segurtasun zenbakia baieztatu @@ -5824,6 +5820,17 @@ Jarraitu Mezularitza pribatua, zuk finantzatua. Iragarkirik gabe, jarraipen-tresnarik gabe, konpromisorik gabe. Egin dohaintza bat orain Signal-i laguntzeko. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Hilero @@ -5891,6 +5898,8 @@ Informazio gehiago Jarraitu + + Read more Ezin izan da kargatu eskera diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 6d7bcea918..fd6213db70 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -643,6 +643,8 @@ %1$s%% تا کنون… سیگنال برای پشتیبان‌گیری نیاز به مجوز حافظه دارد، اما اجازه آن داده نشده است. لطفاً به تنظیمات برنامه رفته، «مجوزها» را انتخاب کنید و «ذخیره‌سازی» را فعال کنید. + + Set backup time @@ -2102,6 +2104,8 @@ نسخۀ جدیدی از سیگنال دردسترس است. برای به‌روزرسانی، ضربه بزنید. سیگنال به‌روزرسانی نشد بعداً دوباره امتحان خواهیم کرد. + Signal successfully updated + You were automatically updated to version %1$s. ارسال پیام؟ @@ -2709,24 +2713,13 @@ - برای تأیید امنیت رمزگذاری سرتاسری خود با %1$s، کارت رنگی بالا را با دستگاه او تطبیق دهید و اعداد را مقایسه کنید. اگر رنگ و عددها مطابقت نداشتند، روی صفحه بکشید و جفت دیگری از شماره‌های ایمنی را امتحان کنید. فقط کافی است یک جفت شماره مطابقت داشته باشند. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. برای اسکن کردن ضربه بزنید انطباق موفق وارسی شمارهٔ ایمنی ناموفق بود در حال بارگیری… علامت‌گذاری به عنوان وارسی شده پاک کردن وارسی - - شماره‌های ایمنی در حال به‌روزرسانی هستند. - - - تغییرات شماره‌های ایمنی - - برای فعال کردن قابلیت‌های حریم شخصی آتی در سیگنال، شماره‌های ایمنی در حال به‌روزرسانی در طول یک دوران گذار هستند.\n\nبرای تأیید شماره‌های ایمنی، کارت رنگی را با دستگاه مخاطب خود تطبیق دهید. اگر مطابقت نداشتند، روی صفحه بکشید و جفت دیگری از شماره‌های ایمنی را امتحان کنید. فقط کافی است یک جفت شماره مطابقت داشته باشند. - - به راهنمایی نیاز دارید؟ - - فهمیدم کد QR را از دستگاه مخاطب خود اسکن کنید. @@ -5581,7 +5574,10 @@ تمام آشنایان بررسی شده‌اند، برای ادامه روی ارسال ضربه بزنید. - شما %1$d آشنا دارید که ممکن است سیگنال را دوباره نصب کرده باشند یا دستگاه خود را تغییر داده باشند. قبل از همرسانی استوری خود با آنها، شماره ایمنی آنها را بررسی کنید یا آنها را از استوری خود حذف کنید. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + وارسی شمارهٔ ایمنی @@ -5824,6 +5820,17 @@ ادامه پیام‌رسانی خصوصی، با تأمین مالی شما. بدون تبلیغات، بدون ردیابی، بدون کاستن از کیفیت. اکنون برای حمایت از سیگنال کمک مالی اهدا کنید. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + ماهانه @@ -5891,6 +5898,8 @@ اطلاعات بیشتر ادامه + + Read more فرمان بارگیری نشد diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 3b319895f0..a6ab81e20e 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -643,6 +643,8 @@ %1$s%% tähän mennessä… Signal tarvitsee luvan käyttää laitteesi tallennustilaa varmuuskopioiden luomista varten, mutta tämä käyttöoikeus on pysyvästi evätty Signalilta. Voit muuttaa tätä menemällä sovellusten asetuksiin, valitsemalla \"Sovelluksen käyttöoikeudet\" ja laittamalla päälle \"Tallennustila\". + + Set backup time @@ -2102,6 +2104,8 @@ Uusi versio Signalista on saatavilla. Päivitä napauttamalla. Signalin päivitys epäonnistui Yritämme myöhemmin uudelleen. + Signal successfully updated + You were automatically updated to version %1$s. Lähetetäänkö viesti? @@ -2709,24 +2713,13 @@ - Varmentaaksesi päästä päähän -salauksen henkilön %1$s kanssa, varmista, että yllä oleva värikortti vastaa hänen laitettaan ja vertaa numeroita. Jos ne eivät vastaa, sipaise ja kokeile toista turvanumeroparia. Vain yhden parin on vastattava. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Skannaa napauttamalla Vastaavuus varmistettu Turvanumeron varmentaminen epäonnistui Ladataan… Merkitse varmennetuksi Poista varmennus - - Turvanumeroita päivitetään. - - - Muutoksia turvanumeroihin - - Turvanumeroita päivitetään siirtymäkauden aikana, jotta Signalin tulevat yksityisyysominaisuudet voidaan ottaa käyttöön.\n\nTarkista turvanumerot varmistamalla, että värikortti vastaa yhteystietosi laitetta. Jos ne eivät vastaa, sipaise ja kokeile toista turvanumeroparia. Vain yhden parin on vastattava. - - Tarvitsetko apua? - - Selvä Skannaa yhteystietosi laitteessa näkyvä QR-koodi. @@ -5581,7 +5574,10 @@ Kaikki kontaktit on tarkistettu. Jatka napauttamalla. - Sinulla on %1$d kontaktia, jotka ovat ehkä asentaneet Signalin uudelleen tai vaihtaneet käyttämäänsä laitetta. Tarkista heidän turvanumeronsa tai poista heidät tarinastasi ennen sen jakamista. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Varmenna turvanumero @@ -5824,6 +5820,17 @@ Jatka Yksityistä viestintää – sinun rahoittamanasi. Ei mainoksia, seurantaa tai kompromisseja. Tue Signalia lahjoittamalla nyt. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Kuukausittain @@ -5891,6 +5898,8 @@ Lue lisää Jatka + + Read more Pankkivaltuutuksen lataaminen epäonnistui diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 392c5ecd50..6699d7c2cc 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -643,6 +643,8 @@ %1$s%% jusqu’à présent… Signal exige l’autorisation d’accès à l\'espace de stockage externe afin de créer des sauvegardes, mais elle a été refusée définitivement. Veuillez accéder au menu des paramètres des applis, sélectionner « Autorisations » et activer « Stockage ». + + Set backup time @@ -2102,6 +2104,8 @@ Une nouvelle version de Signal est disponible. Appuyez pour lancer la mise à jour. Signal n’a pas pu être mis à jour Nous réessaierons plus tard. + Signal successfully updated + You were automatically updated to version %1$s. Envoyer le message ? @@ -2709,24 +2713,13 @@ - Pour vérifier le cryptage de bout en bout avec %1$s, faites correspondre la carte de couleur ci-dessus avec leur appareil et comparez les chiffres. Si ces numéros ne correspondent pas, passez à l\'autre paire de numéros de sécurité. Une seule paire doit être associée. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Touchez pour lire Correspondance effective Échec de la confirmation du numéro de sécurité. Chargement… Marquer comme confirmé Annuler la confirmation - - Les numéros de sécurité sont mis à jour. - - - Modifications des numéros de sécurité - - Les numéros de sécurité sont mis à jour au cours d\'une période de transition afin d\'activer les prochaines fonctions de confidentialité de Signal.\n\nPour vérifier les numéros de sécurité, faites correspondre la carte de couleur avec l\'appareil de votre contact. Si ces numéros ne correspondent pas, passez à l\'autre paire de numéros de sécurité. Une seule paire doit être associée. - - Besoin d’aide ? - - Compris Lisez le code QR sur l’appareil de votre contact. @@ -5581,7 +5574,10 @@ Toutes les connexions ont été revues, appuyez sur envoyer pour continuer. - %1$d de vos contacts ont sûrement réinstallé Signal ou changé d\'appareil. Avant de partager votre Story avec ces personnes, vérifiez leurs numéros de sécurité ou excluez-les de votre partage. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Confirmer le numéro de sécurité @@ -5824,6 +5820,17 @@ Poursuivre Une messagerie privée, financée par vous. Aucune publicité, aucun traqueur, aucun compromis. Faites un don pour soutenir Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mensuel @@ -5891,6 +5898,8 @@ En savoir plus Poursuivre + + Read more Échec du chargement diff --git a/app/src/main/res/values-ga/strings.xml b/app/src/main/res/values-ga/strings.xml index cb833df9d2..a08a64c041 100644 --- a/app/src/main/res/values-ga/strings.xml +++ b/app/src/main/res/values-ga/strings.xml @@ -691,6 +691,8 @@ %1$s%% go dtí seo… Éilíonn Signal cead stórais sheachtraigh chun cúltacaí a chruthú ach diúltaíodh go buan dó. Lean ar aghaidh chuig socruithe na haipe, roghnaigh \"Ceadanna\" agus cumasaigh \"Stóras\". + + Set backup time @@ -2318,9 +2320,11 @@ Nuashonrú Signal - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Tá leagan nua de Signal ar fáil. Tapáil lena nuashonrú. + Theip ar nuashonrú Signal + Triailfimid arís níos déanaí. + Signal successfully updated + You were automatically updated to version %1$s. Seol an teachtaireacht? @@ -2970,24 +2974,13 @@ - Chun criptiú ó cheann ceann le %1$s a fhíorú, meaitseáil an cárta datha thuas leis an ngléas aige/aici agus cuir na huimhreacha i gcomparáid lena chéile. Mura dtéann siad le chéile, svaidhpeáil agus bain triail as an bpéire uimhreacha sábháilteachta eile. Ní gá ach péire amháin a mheaitseáil. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Cnag le scanadh D\'éirigh leis an meaitseáil Theip ar fhíorú na huimhreach sábháilteachta Ag luchtú… Marcáil Deimhnithe Glan an Deimhniú - - Tá uimhreacha sábháilteachta á nuashonrú. - - - Athruithe ar Uimhreacha Sábháilteachta - - Tá uimhreacha sábháilteachta á nuashonrú thar thréimhse aistrithe le gnéithe príobháideachais atá ar na bacáin a chumasú in Signal.\n\nChun uimhreacha sábháilteachta a fhíorú, meaitseáil an cárta datha le gléas do theagmhálaí. Mura dtéann siad le chéile, svaidhpeáil agus bain triail as an bpéire uimhreacha sábháilteachta eile. Ní gá ach péire amháin a mheaitseáil. - - An bhfuil cúnamh uait? - - Tuigim Scan an Cód QR ar ghléas do theagmhálaí. @@ -5959,7 +5952,13 @@ Rinneadh athbhreithniú ar na teagmhálaithe go léir, tapáil Seol chun leanúint ar aghaidh. - Tá %1$d teagmhálaí agat a bhfuil seans ann gur athshuiteáil siad Signal nó gur athraigh siad a ngléas. Déan athbhreithniú ar a n-uimhir sábháilteachta nó smaoinigh ar a mbaint ó do scéal sula ndéanann tú é a chomhroinnt leo. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Fíordheimhnigh an uimhir shábháilteachta @@ -6211,6 +6210,17 @@ Ar Aghaidh Teachtaireachtaí príobháideacha, maoinithe agatsa. Gan aon fhógraí, gan aon rianairí, gan aon chomhghéilleadh. Bronn airgead ar Signal anois chun tacú leis. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Míosúil @@ -6241,8 +6251,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Imigh as Signal leis an íocaíocht a dheimhniú? + Nuair a dheimhnítear an íocaíocht seo, fill ar Signal chun próiseáil do thabhartais a chur i gcrích. @@ -6281,8 +6291,10 @@ Tuilleadh faisnéise Ar aghaidh + + Read more - Failed to load mandate + Theip ar lódáil an tsainordaithe @@ -6302,13 +6314,13 @@ Tabhair %1$s - IBAN is too short + Tá an IBAN róghearr - IBAN is too long + Tá an IBAN rófhada Cód tíortha IBAN gan tacú - Invalid IBAN + IBAN neamhbhailí @@ -6331,7 +6343,7 @@ Faisnéis faoi do chuntas a aimsiú - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Cuardaigh do IBAN ar bharr do ráitis bainc. Bíonn suas le 34 carachtar in uimhreacha IBAN. Ba cheart go mbeadh an t-ainm a chuireann tú isteach ag teacht le d\'ainm iomlán ar do chuntas bainc. Gheobhaidh tú tuilleadh faisnéise ach teagmháil a dhéanamh le do bhanc. Tabhartas ar feitheamh @@ -6347,9 +6359,9 @@ Déanta - Donation couldn\'t be processed + Níorbh fhéidir an tabhartas a phróiseáil - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Tá deacracht againn le d\'aistriú bainc a phróiseáil. Níor gearradh aon airgead ort. Triail modh íocaíochta eile nó déan teagmháil le do bhanc le tuilleadh faisnéise a fháil. Féach arís é @@ -6794,17 +6806,17 @@ Ceadaigh í - Turn on full screen notifications? + Cas air fógraí lánscáileáin? - Never miss a call from your contacts and groups. + Ná caill glao ó do theagmhálaithe ná do ghrúpaí riamh. Cas orthu - Turn on full screen notifications + Cas air fógraí lánscáileáin - To receive call notifications from your contacts and groups: + D\'fhonn fógraí maidir le glaonna a fháil ó do theagmhálaithe agus ó do ghrúpaí: - 2. %1$s Allow full screen notifications + 2. %1$s Ceadaigh fógraí lánscáileáin diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 8cef2726b7..2293862eef 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -643,6 +643,8 @@ %1$s%% por agora… Signal require permiso de almacenamento para poder crear copias de seguranza, pero este denegouseo de forma permanente. Vai a configuración da aplicación, selecciona «Permisos» e activa «Almacenamento». + + Set backup time @@ -2102,6 +2104,8 @@ Hai dispoñible unha nova versión de Signal. Preme para actualizar. Signal non se puido actualizar Volveremos intentalo de novo máis tarde. + Signal successfully updated + You were automatically updated to version %1$s. Enviar mensaxe? @@ -2709,24 +2713,13 @@ - Para verificar a encriptación de extremo a extremo con %1$s, emparella a cor da tarxeta que se amosa co seu dispositivo e compara os números. Se os números non son iguais, proba outra vez con outros números de seguranza. Só é necesario que unha parella de números coincida. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Toca para escanear Emparellamento realizado con éxito Erro na verificación do número de seguranza Cargando… Marcar como verificado Borrar verificación - - Imos actualizar os número de seguranza. - - - Cambios nos números de seguranza - - Durante unha fase de transición, actualizaremos os números de seguranza para permitir a configuración da futura función de seguridade en Signal.\n\nPara verificar os números de seguranza, tes que emparellar a cor da tarxeta co dispositivo do teu contacto. Se os números non son iguais, proba outra vez con outros números de seguranza. Só é necesario que unha parella de números coincida. - - Necesitas axuda? - - Entendo Escanear o código QR no dispositivo do teu contacto. @@ -5581,7 +5574,10 @@ Revisáronse todas as conexións, preme «Enviar» para continuar. - Tes %1$d conexións que pode que volvesen instalar Signal ou que cambiasen de dispositivos. Antes de compartir nada con estas persoas, revisa o número de seguranza e considera eliminalos da túa historia. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Comprobar número de seguranza @@ -5824,6 +5820,17 @@ Continuar Mensaxería privada que existe grazas a ti. Sen anuncios, sen rastrexadores, sen compromiso. Doa agora para apoiar a Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mensualmente @@ -5891,6 +5898,8 @@ Máis información Continuar + + Read more Erro ao cargar a petición diff --git a/app/src/main/res/values-gu/strings.xml b/app/src/main/res/values-gu/strings.xml index ba37f9d7b6..48b5bb149c 100644 --- a/app/src/main/res/values-gu/strings.xml +++ b/app/src/main/res/values-gu/strings.xml @@ -643,6 +643,8 @@ %1$s%% અત્યાર સુધી… બૅકઅપ બનાવવા માટે Signal ને બાહ્ય સ્ટોરેજ પરવાનગીની જરૂર હોય છે, પરંતુ તે કાયમી ધોરણે નામંજૂર કરવામાં આવી છે. કૃપા કરીને એપ્લિકેશન સેટિંગ્સ ચાલુ રાખો, \"પરવાનગી\" પસંદ કરો અને \"સ્ટોરેજ\" સક્ષમ કરો. + + Set backup time @@ -2102,6 +2104,8 @@ Signalનું નવું વર્ઝન ઉપલબ્ધ છે. અપડેટ કરવા માટે ટૅપ કરો. Signal અપડેટ થવામાં નિષ્ફળ રહ્યું અમે પછીથી ફરી પ્રયાસ કરીશું. + Signal successfully updated + You were automatically updated to version %1$s. મેસેજ મોકલો? @@ -2709,24 +2713,13 @@ - %1$s સાથે તમારા એન્ડ-ટૂ-એન્ડ એન્ક્રિપ્શનની સુરક્ષાની ખાતરી કરવા માટે, ઉપર દર્શાવેલ કલર કાર્ડને તેમના ડિવાઇસ સાથે મેચ કરો અને નંબરની સાથે સરખાવો. જો આ મેચ ન થતાં હોય, તો સ્વાઇપ કરો અને સેફ્ટી નંબરોની બીજી જોડી અજમાવી જુઓ. ફક્ત એક જ જોડી મેચ કરવાની જરૂર છે. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. સ્કેન કરવા માટે ટેપ કરો સફળતાપૂર્વક મેચ થયું સલામતી નંબર ચકાસવામાં નિષ્ફળ લોડ કરી રહ્યું છે ચકાસાયેલ તરીકે માર્ક કરો ચકાસણી દૂર કરો - - સેફ્ટી નંબર અપડેટ કરવામાં આવી રહ્યાં છે. - - - સેફ્ટી નંબરોમાં ફેરફારો - - Signal પર આવનારા ગોપનીયતા ફીચરને સક્ષમ કરવા માટે ફેરફારના સમયગાળા દરમિયાન સેફ્ટી નંબરો અપડેટ કરવામાં આવી રહ્યાં છે.\n\nસેફ્ટી નંબરોની ચકાસણી કરવા માટે, તમારા સંપર્કના ડિવાઇસ સાથે કલર કાર્ડને મેચ કરો. જો આ મેચ ન થતાં હોય, તો સ્વાઇપ કરો અને સેફ્ટી નંબરોની બીજી જોડી અજમાવી જુઓ. ફક્ત એક જ જોડી મેચ કરવાની જરૂર છે. - - મદદ જોઈએ છે? - - સમજાઈ ગયું તમારા સંપર્કના ડિવાઇસ પર QR કોડ સ્કેન કરો. @@ -5581,7 +5574,10 @@ બધા જ કનેક્શનની સમીક્ષા થઈ ચૂકી છે, ચાલુ રાખવા માટે મોકલો પર ટૅપ કરો. - તમારા %1$d કનેક્શન એવા છે જેમણે Signal ફરીથી ઇન્સ્ટોલ કરેલ છે અથવા તેમના ડિવાઇસ બદલેલા હોઈ શકે છે. તેમની સાથે તમારી સ્ટોરી શેર કરતાં પહેલાં તેમના સલામતી નંબરની સમીક્ષા કરો અથવા તેમને તમારી સ્ટોરીમાંથી દૂર કરવાનું વિચારો. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + સલામતી નંબર ચકાસો @@ -5824,6 +5820,17 @@ ચાલુ રાખો ખાનગી મેસેજિંગ, તમારા ભંડોળની મદદથી. કોઈ જાહેરાતો નહીં, કોઈ પગેરું નહીં, કોઈ બાંધછોડ નહીં. Signalને સહાય કરવા દાન આપો. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + માસિક @@ -5891,6 +5898,8 @@ વધુ જાણો ચાલુ રાખો + + Read more મેન્ડેટ લોડ થવામાં નિષ્ફળ થયું diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 9b10749c34..3f58d211c9 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -643,6 +643,8 @@ अब तक %1$s%%… बैकअप बनाने के लिए Signal को बाहरी संग्रहण अनुमति की आवश्यकता होती है, लेकिन इसे स्थायी रूप से अस्वीकार कर दिया गया है। कृपया ऐप सेटिंग्स को जारी रखें, \"अनुमतियां\" चुनें और \"संग्रहण\" सक्षम करें। + + Set backup time @@ -2102,6 +2104,8 @@ Signal का नया संस्करण उपलब्ध है। अपडेट करने के लिए टैप करें। Signal अपडेट करने में विफल रहे हम बाद में पुनः प्रयास करेंगे। + Signal successfully updated + You were automatically updated to version %1$s. मेसेज भेजें? @@ -2709,24 +2713,13 @@ - %1$s के साथ एंड-टू-एंड एन्क्रिप्शन सत्यापित करने के लिए, ऊपर दिए गए कलर कार्ड का उनकी डिवाइस से मिलान करें और नंबरोंकी तुलना करें। यदि ये मेल नहीं खाते, तो स्वाइप करें और सुरक्षा संख्या की दूसरी जोड़ी आज़माएं। केवल एक जोड़ी का मिलान ज़रूरी है। + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. स्कैन करने के लिए टैप करें सफ़ल मैच सुरक्षा नंबर जांचने में असफ़ल लोड हो रहा है साटिपिट होने का मार्क कीजीये जांच क्लियर करें - - सुरक्षा संख्या को अपडेट किया जा रहा है। - - - सुरक्षा नंबरों में बदलाव - - Signal में आगामी गोपनीयता फीचर्स को सक्षम करने के लिए ट्रांजीशन अवधि में सुरक्षा संख्या अपडेट किए जा रहे हैं।\n\nसुरक्षा संख्या सत्यापित करने के लिए, कलर कार्ड का अपने संपर्क की डिवाइस से मिलान करें। यदि ये मेल नहीं खाते, तो स्वाइप करें और सुरक्षा नंबरों की दूसरी जोड़ी आज़माएं। केवल एक जोड़ी का मिलान ज़रूरी है। - - मदद चाहिए? - - समझ गया अपने संपर्क के डिवाइस के QR कोड को स्कैन करें। @@ -5581,7 +5574,10 @@ सभी कनेक्शन की समीक्षा कर ली गई है, जारी रखने के लिए भेजें पर टैप करें। - आपके %1$d कनेक्शन हैं जिन्होंने शायद Signal फिर से इंस्टॉल किया हो या डिवाइस बदले हों। उनके साथ अपनी स्टोरी शेयर करने से पहले उनकी सुरक्षा संख्याओं की समीक्षा कर लें या फिर उन्हें अपनी स्टोरी से हटाने पर विचार करें। + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + सुरक्षा संख्या सत्यापित करें @@ -5824,6 +5820,17 @@ जारी रखें आपके द्वारा आर्थिक सहायता प्राप्त निजी संदेश सेवा। न कोई विज्ञापन, न ट्रैकिंग, न ही समझौता। Signal को सहयोग देने के लिए अभी दान दें। + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + मासिक @@ -5891,6 +5898,8 @@ अधिक जानें जारी रखें + + Read more मैंडेट लोड करने में विफल diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 9065661cef..2cadd1f1e4 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -675,6 +675,8 @@ %1$s%% do sada… Signal zahtijeva dopuštenje za vanjski prostor za pohranu kako bi stvorio sigurnosne kopije, ali je trajno odbijen. Otvorite postavke aplikacije, odaberite \"Dozvole\" i omogućite \"Prostor za pohranu\". + + Set backup time @@ -2248,6 +2250,8 @@ Dostupna je nova verzija Signala. Dodirnite za ažuriranje. Ažuriranje Signala nije uspjelo Pokušat ćemo ponovno kasnije. + Signal successfully updated + You were automatically updated to version %1$s. Pošalji poruku? @@ -2883,24 +2887,13 @@ - Za provjeru sveobuhvatne enkripcije s kontaktom %1$s, povežite gornju karticu u boji s uređajem vašeg sugovornika i usporedite brojeve. Ako se brojevi ne podudaraju, prijeđite prstom i pokušajte s drugim parom sigurnosnih brojeva. Samo jedan par mora odgovarati. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Pritisni za skeniranje Rezultati se podudaraju Provjera sigurnosnog broja nije uspjela Učitavanje… Označi kao provjereno Poništi provjeru - - Ažuriramo sigurnosne brojeve. - - - Promjene u vezi sigurnosnih brojeva - - Sigurnosni brojevi se trenutno ažuriraju tijekom prijelaznog razdoblja kako bi se omogućile predstojeće značajke privatnosti u Signalu.\n\nDa biste provjerili sigurnosne brojeve, uskladite karticu u boji s uređajem vašeg kontakta. Ako se brojevi ne podudaraju, prijeđite prstom i pokušajte s drugim parom sigurnosnih brojeva. Samo jedan par mora odgovarati. - - Trebate pomoć? - - Shvaćam Skenirajte QR kôd na uređaju vašeg kontakta. @@ -5833,7 +5826,12 @@ Svi kontakti su pregledani, dodirnite Pošalji za nastavak. - Među vašim kontaktima, %1$d je možda ponovno instaliralo Signal ili promijenilo uređaje. Prije nego što s njima podijelite svoju priču, pregledajte njihove sigurnosne brojeve ili razmislite o tome da ih uklonite iz svoje priče. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Potvrdi sigurnosni broj @@ -6082,6 +6080,17 @@ Nastavi Privatna razmjena poruka koju financirate vi. Bez oglasa, bez praćenja, bez kompromisa. Donirajte odmah i podržite Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mjesečna donacija @@ -6151,6 +6160,8 @@ Saznajte više Nastavi + + Read more Učitavanje naloga nije uspjelo diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 04f4ae4509..c6d1e8e45e 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -643,6 +643,8 @@ %1$s%% eddig… A Signalnak külső tárhely engedélyre van szüksége ahhoz, hogy biztonsági mentést hozzon létre, de ez jelenleg meg van tagadva. Kérlek menj az alkalmazás-beállításokhoz, válaszd az \"Engedélyek\"-et és engedélyezd a \"Tárhely\"-t. + + Set backup time @@ -2102,6 +2104,8 @@ Megjelent a Signal új verziója. A frissítéshez koppints. A Signal frissítése sikertelen Később újra megpróbáljuk. + Signal successfully updated + You were automatically updated to version %1$s. Üzenet küldése? @@ -2709,24 +2713,13 @@ - A végpontok közötti titkosítás ellenőrzéséhez %1$s segítségével egyeztesd a fenti színkártyát az eszközöddel, és hasonlítsd össze a számokat. Ha ezek nem egyeznek, húzd el az ujjad, és próbáld ki a másik biztonsági számpárt. Csak egy párnak kell egyeznie. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Koppints a szkenneléshez Sikeres egyezés Biztonsági azonosító ellenőrzése sikertelen Betöltés… Megjelölés ellenőrzöttként Ellenőrzött állapot törlése - - A biztonsági számok frissítése folyamatban van. - - - Változások a biztonsági számokban - - A biztonsági számok egy átmeneti időszak alatt frissülnek, hogy lehetővé tegyék a Signal közelgő adatvédelmi funkcióit.\n\nA biztonsági számok ellenőrzéséhez illeszd a színkártyát a névjegyed eszközéhez. Ha ezek nem egyeznek, húzd el az ujjad, és próbáld ki a másik biztonsági számpárt. Csak egy párnak kell egyeznie. - - Segítségre van szükséged? - - Rendben Szkenneld be a QR kódot ismerősöd készülékén. @@ -5581,7 +5574,10 @@ Minden névjegy ellenőrzése megtörtént, a folytatáshoz koppints a Küldés gombra. - %1$d olyan névjegyed van, aki újratelepítette a Signalt vagy eszközt cserélt. Mielőtt megosztanád velük a Történeted, vess egy pillantást a biztonsági számukra, vagy akár ki is zárhatod őket a Történet megtekintéséből. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Bizt. szám ellenőrzése @@ -5824,6 +5820,17 @@ Folytatás Privát üzenetküldés, általad támogatva. Nincsenek hirdetések, nincs nyomon követés, nincsenek kompromisszumok. Adományozz most, és támogasd a Signalt! + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Havi @@ -5891,6 +5898,8 @@ Tudj meg többet Tovább + + Read more Nem sikerült betölteni a megbízást diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index a74a020008..3ccb550fb5 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -627,6 +627,8 @@ %1$s%% sejauh ini… Signal memerlukan izin penyimpanan eksternal untuk membuat cadangan, tetapi saat ini izin ditolak secara permanen. Harap lanjutkan ke menu pengaturan aplikasi, pilih \"Izin\", dan aktifkan \"Penyimpanan\". + + Set backup time @@ -2029,6 +2031,8 @@ Signal versi baru telah tersedia. Ketuk untuk memperbarui. Signal gagal diperbarui Kami akan coba lagi nanti. + Signal successfully updated + You were automatically updated to version %1$s. Kirim pesan? @@ -2622,24 +2626,13 @@ - Untuk memverifikasi enkripsi end-to-end dengan %1$s, cocokkan kartu warna di atas dengan perangkat mereka dan bandingkan angkanya. Jika ini tidak cocok, usap dan coba pasangan nomor keamanan lain. Hanya satu pasang yang harus cocok. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Ketuk untuk memindai Pencocokan berhasil Gagal memverifikasi nomor keamanan Memuat… Tandai terverifikasi Hapus verifikasi - - Nomor keamanan sedang diperbarui. - - - Perubahan pada Nomor Keamanan - - Nomor keamanan sedang diperbarui selama periode transisi agar dapat mengaktifkan fitur privasi yang akan datang di Signal.\n\nUntuk memverifikasi nomor keamanan, cocokkan kartu warna dengan perangkat milik kontak Anda. Jika ini tidak cocok, usap dan coba pasangan nomor keamanan lain. Hanya satu pasang yang harus cocok. - - Butuh bantuan? - - Mengerti Pindai kode QR pada perangkat kontak Anda. @@ -5455,7 +5448,9 @@ Semua koneksi telah ditinjau, ketuk kirim untuk melanjutkan. - Anda punya %1$d koneksi yang mungkin telah menginstal ulang Signal atau berganti perangkat. Sebelum membagikan cerita dengan mereka, tinjau nomor keamanan mereka atau pertimbangkan untuk menghapus mereka dari cerita Anda. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verifikasi nomor keamanan @@ -5695,6 +5690,17 @@ Lanjutkan Perpesanan privat, didanai oleh Anda. Tanpa iklan, tanpa pelacak, tanpa kompromi. Donasi sekarang untuk mendukung Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Bulanan @@ -5761,6 +5767,8 @@ Pelajari selengkapnya Lanjutkan + + Read more Gagal memuat permintaan diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 57848c94ac..73961e2233 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -643,6 +643,8 @@ %1$s%% finora… Signal richiede l\'autorizzazione per creare backup in memoria, ma è stata negata in modo permanente. Si prega di continuare con le impostazioni dell\'app, selezionare \"Autorizzazioni\", quindi abilitare \"Archiviazione\". + + Set backup time @@ -2102,6 +2104,8 @@ È disponibile una nuova versione di Signal. Tocca qui per aggiornare. Signal non è riuscito ad aggiornarsi Proveremo di nuovo più tardi. + Signal successfully updated + You were automatically updated to version %1$s. Inviare messaggio? @@ -2709,24 +2713,13 @@ - Per verificare la sicurezza della tua crittografia end-to-end con %1$s, fai combaciare il colore della scheda qui sopra con la scheda del dispositivo della persona in questione e confronta i codici. Se i codici non combaciano, continua a scorrere e prova un\'altra coppia di codici di sicurezza. Ricorda che deve combaciare una sola coppia. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Tocca per la scansione Verifica riuscita Verifica del numero di sicurezza non riuscita Caricamento… Segna come verificato Rimuovi verifica - - Stiamo aggiornando i codici di sicurezza. - - - Cambiamenti nei codici di sicurezza - - Stiamo aggiornando il sistema dei codici di sicurezza in vista di un periodo di transizione che ci porterà a introdurre nuove funzioni per la privacy su Signal.\n\nPer verificare i codici di sicurezza, fai combaciare il colore della scheda con quello della scheda del dispositivo del tuo contatto. Se i codici non combaciano, continua a scorrere e prova un\'altra coppia di codici di sicurezza. Ricorda che deve combaciare una sola coppia. - - Hai bisogno di aiuto? - - Capito Scansiona il codice QR sul dispositivo del tuo contatto. @@ -5581,7 +5574,10 @@ I codici di sicurezza di tutte le Amicizie di Signal sono stati verificati: tocca Invia per continuare. - Hai %1$d Amicizie di Signal che potrebbero aver reinstallato Signal oppure cambiato dispositivo. Prima di condividere la tua Storia con loro, verifica i loro codici di sicurezza. In alternativa, puoi scegliere di non condividere la Storia con loro. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verifica numero sicuro @@ -5824,6 +5820,17 @@ Continua Messaggi privati e sicuri, sostenuti proprio da te. Niente pubblicità, niente tracciamenti e nessun compromesso. Dona ora a Signal per supportare il nostro lavoro. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mensile @@ -5891,6 +5898,8 @@ Scopri di più Continua + + Read more Impossibile caricare la richiesta diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 3426f5215b..8a88886155 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -675,6 +675,8 @@ %1$s%% עד כה… Signal דורש הרשאת אחסון חיצוני על מנת ליצור גיבויים, אבל היא נדחתה לצמיתות. אנא המשך אל הגדרות היישום, בחר \"הרשאות\" ואפשר את \"אחסון\". + + Set backup time @@ -2248,6 +2250,8 @@ גרסה חדשה של Signal זמינה. יש ללחוץ כדי לעדכן. עדכון Signal נכשל ננסה שוב מאוחר יותר. + Signal successfully updated + You were automatically updated to version %1$s. לשלוח הודעה? @@ -2883,24 +2887,13 @@ - כדי לאמת את האבטחה מקצה לקצה שלך עם %1$s, יש להתאים את כרטיסיית הצבע שלמעלה עם המכשיר שלו או שלה ולהשוות את המספרים. אם הם לא תואמים, אפשר להחליק ולנסות זוג אחר של מספרי בטיחות. רק זוג אחד צריך להתאים. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. הקש כדי לסרוק התאמה מוצלחת אימות מספר בטיחות נכשל טוען… סמן כמוֻדא נקה וידוא - - מספרי בטיחות מתעדכנים. - - - שינויים במספרי בטיחות - - אנחנו מעדכנים את מספרי הבטיחות במהלך תקופת מעבר כדי לאפשר פיצ׳רים עתידיים של פרטיות ב–Signal.\n\nכדי לאמת מספרי בטיחות, יש להתאים את כרטיסיית הצבע שלמעלה עם המכשיר של איש הקשר. אם הם לא תואמים, אפשר להחליק ולנסות זוג אחר של מספרי בטיחות. רק זוג אחד צריך להתאים. - - צריך עזרה? - - הבנתי סרוק את קוד ה־QR במכשיר של איש הקשר שלך. @@ -5833,7 +5826,12 @@ כל חברי ה-Signal נסקרו, יש ללחוץ על שליחה כדי להמשיך. - יש לך %1$d חברי Signal שיתכן והתקינו מחדש את Signal או החליפו מכשירים. לפני שיתוף הסטורי שלך איתם, כדאי לסקור את מספרי הבטיחות שלהם או לשקול להסיר אותם מהסטורי שלך. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + אימות מספר בטיחות @@ -6082,6 +6080,17 @@ המשך שליחת הודעות פרטית, ממומנת על ידך. בלי מודעות, בלי מעקב, בלי פשרות. תורמים עכשיו ותומכים ב–Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + חודשית @@ -6151,6 +6160,8 @@ למידע נוסף המשך + + Read more טעינת בקשה נכשלה diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 80c7cbec3a..1b55aa8f85 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -627,6 +627,8 @@ %1$s%%完了 バックアップを作成するには、Signalに外部ストレージへのアクセス許可が必要ですが、無効になっています。アプリ設定メニューの「アプリの権限」で「ストレージ」を有効にしてください。 + + Set backup time @@ -2029,6 +2031,8 @@ 新バージョンのSignalが利用可能です。タップして更新します。 Signalの更新に失敗しました 後で再度試してみます。 + Signal successfully updated + You were automatically updated to version %1$s. メッセージを送信しますか? @@ -2622,24 +2626,13 @@ - %1$sとのやりとりがエンドツーエンドで暗号化されているかを検証するには、お互いの端末で、上部のカラーカード(色がついた枠内)の数字が一致するかを確認してください。数字が一致しない場合は、スワイプして別の安全番号を表示させてください。一致する数字は一つだけでかまいません。 + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. タップしてスキャンする 一致しました 安全番号を検証できませんでした 読み込んでいます… 検証済みにする 未検証にする - - 安全番号を更新中です。 - - - 安全番号の変更 - - Signal のプライバシー機能を以後も有効にするために、安全番号は移行期間中に更新されます。\n\n安全番号を検証するために、カラーカード(色がついた枠内)の数字が一致するか相手の端末を確認してください。数字が一致しない場合は、スワイプして別の安全番号を表示させてください。一致する数字は一つだけでかまいません。 - - お困りですか? - - わかりました 連絡先の端末のQRコードをスキャンしてください。 @@ -5455,7 +5448,9 @@ すべてのコネクションが確認されました。続行するには送信をタップしてください。 - %1$d人のコネクションがSignalを再インストールしたか、端末を変更した可能性があります。ストーリーを彼らと共有する前に、彼らの安全番号を確認するか、あなたのストーリーから彼らを削除することを検討してください。 + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + 安全番号を確認 @@ -5695,6 +5690,17 @@ 続ける あなたが資金提供するプライベートメッセージ。広告なし、トラッキングなし、不正アクセスなし。Signalをサポートするための寄付を今すぐお願いします。 + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + 毎月 @@ -5761,6 +5767,8 @@ 詳しく見る 続行 + + Read more リクエストを読み込めませんでした diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 0cc292953e..e855406cbd 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -643,6 +643,8 @@ %1$s%% ჯერ… სათადარიგო ასლების შესაქმნელად Signal-ი საჭიროებს გარე მეხსიერებაზე წვდომის ნებართვას, მაგრამ ის სამუდამოდ იქნა უარყოფილი. გთხოვთ, შეხვიდე აპის პარამეტრებში, აირჩიო „ნებართვები“ და ჩართო „შენახვა“. + + Set backup time @@ -2102,6 +2104,8 @@ Signal-ის ახალი ვერსია ხელმისაწვდომია. დააჭირე განახლებისთვის. Signal-ის განახლება ვერ მოხერხდა მოგვიანებით ისევ ვცდით. + Signal successfully updated + You were automatically updated to version %1$s. გავაგზავნოთ შეტყობინება? @@ -2709,24 +2713,13 @@ - %1$s-თან ბოლომდე დაშიფვრის დასადასტურებლად, შეადარე მის მოწყობილობაში ფერად ბარათზე მოცემული ციფრები. თუ ისინი არ ემთხვევა, გადასქროლე და უსაფრთხოების ნომრების სხვა წყვილი სცადე. მხოლოდ ერთი წყვილი უნდა შეესაბამებოდეს. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. დააჭირე დასასკანირებლად წარმატებული დამთხვევა უსაფრთხოების ნომრის ვერიფიცირება ვერ მოხერხდა იტვირთება… Mark as verified ვერიფიკაციის გასუფთავება - - მიმდინარეობს უსაფრთხოების ნომრების განახლება. - - - ცვლილებები უსაფრთხოების ნომრებში - - უსაფრთხოების ნომრები ახლდება გარდამავალი პერიოდის განმავლობაში, რათა ჩართოს კონფიდენციალურობის მომავალი ფუნქციები Signal-ში.\n\nუსაფრთხოების ნომრების დასადასტურებლად, შეუსაბამე ფერადი ბარათი შენი კონტაქტის მოწყობილობას. თუ ისინი არ ემთხვევა, გადასქროლე და უსაფრთხოების ნომრების სხვა წყვილი სცადე. მხოლოდ ერთი წყვილი უნდა შეესაბამებოდეს. - - დახმარება გჭირდება? - - გასაგებია დაასკანირე QR კოდი შენი კონტაქტის მოწყობილობაზე. @@ -5581,7 +5574,10 @@ ყველა კონტაქტი განხილულია, გასაგრძელებლად დააჭირე გაგზავნას. - შენ გყავს %1$d კონტაქტი, რომელთაც შესაძლოა გადააყენეს Signal-ი ან შეცვალეს მოწყობილობები. სანამ მათ შენს Story-ის გაუზიარებდე, გადახედე მათი უსაფრთხოების ნომრებს ან იქნებ შენი Story-იდან გინდა მათი წაშლა. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + უსაფრთხოების ნომრის ვერიფიცირება @@ -5824,6 +5820,17 @@ გაგრძელება კონფიდენციალური მიმოწერა, რომელიც შენით ფინანსდება. არანაირი რეკლამა, არანაირი ტრეკერები, არანაირი კომპრომისი. გააკეთე დონაცია ახლა, რათა მხარი დაუჭირო Signal-ს. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + ყოველთვიური @@ -5891,6 +5898,8 @@ გაიგე მეტი გაგრძელება + + Read more დავალების ჩატვირთვა ვერ მოხერხდა diff --git a/app/src/main/res/values-kk/strings.xml b/app/src/main/res/values-kk/strings.xml index 73818ad603..e06b5e3f68 100644 --- a/app/src/main/res/values-kk/strings.xml +++ b/app/src/main/res/values-kk/strings.xml @@ -643,6 +643,8 @@ Әзірге %1$s%% … Резервтік көшірмелерді жасау үшін Signal қолданбасына сыртқы жадты пайдалануға рұқсат керек, бірақ ол біржола өшірілген. Қолданба параметрлерін ашып, \"Рұқсаттар\" бөлімін таңдаңыз да, \"Жад\" параметрін қосыңыз. + + Set backup time @@ -2099,9 +2101,11 @@ Signal-ды жаңарту - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Signal-дың жаңа нұсқасы шықты. Жаңарту үшін түртіңіз. + Signal жаңартылмады + Кейінірек тағы қайталап көреміз. + Signal successfully updated + You were automatically updated to version %1$s. Хатты жіберу керек пе? @@ -2709,24 +2713,13 @@ - %1$s деген пайдаланушымен өтпелі шифрлау функциясын тексеру үшін, жоғарыдағы түрлі түсті картаны оның құрылғысымен қатар қойып, нөмірлерді салыстырыңыз. Егер нөмірлері сәйкес келмесе, свайп жасап, қауіпсіздік нөмірлерінің басқа жұбын қолданып көріңіз. Тек бір жұп сәйкес келуі керек. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Сканерлеу үшін түртіңіз Сәйкес келді Қауіпсіздік нөмірі тексерілмеді Жүктелуде… Mark as verified Верификацияны тазалау - - Қауіпсіздік нөмірлері жаңартылып жатыр. - - - Қауіпсіздік нөмірлерінің өзгерістері - - Signal қолданбасындағы құпиялылықтың жаңа функцияларын қосу үшін қауіпсіздік нөмірлері ауысым кезеңінде жаңартылады.\n\nҚауіпсіздік нөмірлерін тексеру үшін түрлі түсті картаны контактінің құрылғысымен қатар қойыңыз. Егер нөмірлері сәйкес келмесе, свайп жасап, қауіпсіздік нөмірлерінің басқа жұбын қолданып көріңіз. Тек бір жұп сәйкес келуі керек. - - Көмек керек пе? - - Түсінікті Байланыстық тұлғаңыздың құрылғысындағы QR кодты сканерлеңіз. @@ -5581,7 +5574,10 @@ Барлық байланыс тексерілді, жалғастыру үшін жіберу түймесін басыңыз. - %1$d контактіңіз Signal-ды қайта орнатқан немесе құрылғыларын өзгерткен болуы мүмкін. Олармен стористеріңізді бөліспес бұрын, олардың қауіпсіздік нөмірлерін тексеріңіз немесе оларды сторисіңізден өшіріп тастаңыз. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Қауіпсіздік нөмірін тексеру @@ -5824,6 +5820,17 @@ Жалғастыру Сіз демеушілік жасаған хат алмасу қолданбасы. Жарнамасыз, бақылаусыз, ымырасыз. Signal-ға қазір демеушілік жасаңыз. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Ай сайын @@ -5851,8 +5858,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Төлемді растау үшін Signal-дан шығу керек пе? + Бұл төлем расталған соң, Signal-ға қайтып, демеу жасау процесін аяқтаңыз. @@ -5891,8 +5898,10 @@ Толық ақпарат Жалғастыру + + Read more - Failed to load mandate + Рұқсатты жүктеу мүмкін болмады @@ -5912,13 +5921,13 @@ %1$s демеушілік жасаңыз - IBAN is too short + IBAN нөмірі өте қысқа - IBAN is too long + IBAN нөмірі өте ұзын IBAN ел кодына қолдау көрсетілмейді - Invalid IBAN + IBAN нөмірі жарамсыз @@ -5941,7 +5950,7 @@ Аккаунтыңыз туралы ақпаратты табу - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Банк шотының үзінді көшірмесінің жоғарғы жағында IBAN нөмірі жазылып тұрады. IBAN нөмірлері 34 таңбаға дейін созылуы мүмкін. Енгізілген аты-жөніңіз банк шотыңыздағы толық аты-жөніңізбен бірдей болуы керек. Толық ақпарат алғыңыз келсе, банкіңізге хабарласыңыз. Демеушілік күтілуде @@ -5957,9 +5966,9 @@ Дайын - Donation couldn\'t be processed + Демеуді өңдеу мүмкін болмады - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Банк аударымыңызды өңдеу сәтсіз аяқталды. Сізден ақы алынған жоқ. Басқа төлеу әдісін қолданып көріңіз немесе қосымша ақпарат алу үшін банкке хабарласыңыз. Қайталап көру @@ -6386,17 +6395,17 @@ Мақұлдау - Turn on full screen notifications? + Толық экран хабарландыруларын қосу керек пе? - Never miss a call from your contacts and groups. + Контактілеріңіз бен топтарыңыздан келген қоңырауларды ешқашан жіберіп алмайсыз. Іске қосу - Turn on full screen notifications + Толық экран хабарландыруларын қосыңыз - To receive call notifications from your contacts and groups: + Контактілеріңіз бен топтарыңыздан қоңырау туралы хабарландырулар алу үшін: - 2. %1$s Allow full screen notifications + 2. %1$s Толық экран хабарландыруларына рұқсат ету diff --git a/app/src/main/res/values-km/strings.xml b/app/src/main/res/values-km/strings.xml index 0ad0a428a2..4d8c506171 100644 --- a/app/src/main/res/values-km/strings.xml +++ b/app/src/main/res/values-km/strings.xml @@ -627,6 +627,8 @@ %1$s%% ឥឡូវនេះ​… Signal ត្រូវការសិទ្ធិប្រើប្រាស់អង្គរក្សាទុកខាងក្រៅដើម្បីបង្កើតការស្តារឡើងវិញ ប៉ុន្តែវាត្រូវបានបដិសេធរហូត។ សូមបន្តទៅកាន់ ការកំណត់ ការជ្រើសរើស \"ការអនុញ្ញាត\" និងបើក \"អង្គរក្សាទុក\"។ + + Set backup time @@ -2029,6 +2031,8 @@ Signal មានកំណែថ្មីមួយ។ ចុចដើម្បីដំឡើងកំណែ។ Signal មិនអាចដំឡើងកំណែបានទេ យើងនឹងព្យាយាមម្តងទៀតនៅពេលក្រោយ។ + Signal successfully updated + You were automatically updated to version %1$s. ផ្ញើសារ? @@ -2622,24 +2626,13 @@ - ដើម្បីផ្ទៀងផ្ទាត់ការអ៊ីនគ្រីបទាំងសងខាងជាមួយ %1$s សូមផ្គូផ្គងកាតពណ៌ខាងលើជាមួយឧបករណ៍របស់ពួកគេ ហើយប្រៀបធៀបលេខ។ ប្រសិនបើលេខទាំងនេះមិនត្រូវគ្នាទេ សូមអូស ហើយសាកល្បងលេខសុវត្ថិភាពគូផ្សេងទៀត។ មានតែមួយគូប៉ុណ្ណោះដែលត្រូវផ្គូផ្គង។ + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. ចុច ដើម្បីស្កែន ផ្គូរផ្គងដោយជោគជ័យ បរាជ័យក្នុងការផ្ទៀងផ្ទាត់លេខសុវត្ថិភាព កំពុងផ្ទុក… ដាក់ថាបានផ្ទៀងផ្ទាត់ សំអាតការផ្ទៀងផ្ទាត់ - - លេខសុវត្ថិភាពកំពុងត្រូវបានធ្វើបច្ចុប្បន្នភាព។ - - - ការផ្លាស់ប្តូរចំពោះលេខសុវត្ថិភាព - - លេខសុវត្ថិភាពកំពុងត្រូវបានធ្វើបច្ចុប្បន្នភាពក្នុងរយៈពេលផ្លាស់ប្តូរ ដើម្បីបើកមុខងារឯកជនភាពនាពេលខាងមុខនៅក្នុង Signal។\n\nដើម្បីផ្ទៀងផ្ទាត់លេខសុវត្ថិភាព សូមផ្គូផ្គងកាតពណ៌ជាមួយឧបករណ៍នៃឈ្មោះទំនាក់ទំនងរបស់អ្នក។ ប្រសិនបើលេខទាំងនេះមិនត្រូវគ្នាទេ សូមអូស ហើយសាកល្បងលេខសុវត្ថិភាពគូផ្សេងទៀត។ មានតែមួយគូប៉ុណ្ណោះដែលត្រូវផ្គូផ្គង។ - - ត្រូវការជំនួយ? - - យល់ហើយ ស្កេនកូដ QR លើឧបករណ៍ទំនាក់ទំនងរបស់អ្នក។ @@ -5455,7 +5448,9 @@ អ្នកភ្ជាប់ទំនាក់ទំនងទាំងអស់ត្រូវបានពិនិត្យមើល។ សូមចុចផ្ញើដើម្បីបន្ត។ - អ្នកមានអ្នកភ្ជាប់ទំនាក់ទំនង %1$d នាក់ដែលប្រហែលជាបានដំឡើង Signal ឡើងវិញ ឬផ្លាស់ប្តូរឧបករណ៍។ មុនពេលចែករំលែករឿងរ៉ាវរបស់អ្នកជាមួយពួកគេ សូមពិនិត្យមើលលេខសុវត្ថិភាពរបស់ពួកគេ ឬពិចារណាដកពួកគេចេញពីរឿងរ៉ាវរបស់អ្នក។ + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + ផ្ទៀងផ្ទាត់លេខសុវត្ថិភាព @@ -5695,6 +5690,17 @@ បន្ត ការផ្ញើសារលក្ខណៈឯកជនទទួលបានមូលនិធិពីអ្នក។ គ្មានការផ្សាយពាណិជ្ជកម្ម គ្មានការតាមដាន គ្មានការប៉ះពាល់។ បរិច្ចាគឥឡូវនេះដើម្បីគាំទ្រ Signal។ + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + ប្រចាំខែ @@ -5761,6 +5767,8 @@ ស្វែងយល់បន្ថែម បន្ត + + Read more មិនអាចផ្ទុកសំណើបានទេ diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml index 0248f4b6aa..9fe861362e 100644 --- a/app/src/main/res/values-kn/strings.xml +++ b/app/src/main/res/values-kn/strings.xml @@ -643,6 +643,8 @@ %1$s%% ಈ ತನಕ… ಬ್ಯಾಕಪ್ ಗಳನ್ನು ರಚಿಸಲು Signal ಗೆ ಬಾಹ್ಯ ಸ್ಟೋರೇಜ್ ಅನುಮತಿ ಅಗತ್ಯವಿರುತ್ತದೆ, ಆದರೆ ಅದನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿರಾಕರಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಆ್ಯಪ್ ಸೆಟ್ಟಿಂಗ್ಸ್ ಗೆ ಮುಂದುವರಿಯಿರಿ, \"ಅನುಮತಿಗಳು\" ಆಯ್ಕೆ ಮಾಡಿ ಮತ್ತು \"ಸ್ಟೋರೇಜ್\" ಸಕ್ರಿಯಗೊಳಿಸಿ. + + Set backup time @@ -2099,9 +2101,11 @@ Signal ನವೀಕರಿಸಿ - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Signal ನ ಹೊಸ ಆವೃತ್ತಿ ಲಭ್ಯವಿದೆ. ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. + Signal ಅಪ್‌ಡೇಟ್ ವಿಫಲಗೊಂಡಿದೆ + ನಾವು ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸುತ್ತೇವೆ. + Signal successfully updated + You were automatically updated to version %1$s. ಸಂದೇಶ ಕಳುಹಿಸುವುದೇ? @@ -2709,24 +2713,13 @@ - %1$s ಅವರೊಂದಿಗಿನ ಎಂಡ್-ಟು-ಎಂಡ್ ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಅನ್ನು ದೃಢೀಕರಿಸಲು, ಮೇಲಿನ ಕಲರ್ ಕಾರ್ಡ್ ಅನ್ನು ಅವರ ಸಾಧನೊಂದಿಗೆ ಹೊಂದಿಸಿ ಮತ್ತು ಸಂಖ್ಯೆಗಳನ್ನು ತುಲನೆ ಮಾಡಿ. ಇವುಗಳು ಹೊಂದಿಕೆಯಾಗದಿದ್ದರೆ, ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಸುರಕ್ಷಾ ಸಂಖ್ಯೆಗಳ ಇನ್ನೊಂದು ಜೊತೆಯನ್ನು ಪ್ರಯತ್ನಿಸಿ. ಕೇವಲ ಒಂದು ಜೊತೆ ಹೊಂದಿಕೆಯಾಗಬೇಕು. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. ಸ್ಕ್ಯಾನ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ ಯಶಸ್ವಿ ಹೊಂದಾಣಿಕೆ ಸುರಕ್ಷತಾ ಸಂಖ್ಯೆಯನ್ನು ದೃಢೀಕರಿಸುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ… ಪರಿಶೀಲಿಸಲಾಗಿದೆ ಎಂದು ಗುರುತಿಸಿ ದೃಢೀಕರಣವನ್ನು ತೆರವುಗೊಳಿಸಿ - - ಸುರಕ್ಷಾ ಸಂಖ್ಯೆಗಳನ್ನು ನವೀಕರಿಸಲಾಗುತ್ತಿದೆ. - - - ಸುರಕ್ಷಾ ಸಂಖ್ಯೆಗಳಿಗೆ ಬದಲಾವಣೆಗಳು - - Signal ನಲ್ಲಿ ಮುಂಬರುವ ಗೌಪ್ಯತಾ ಫೀಚರ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ಪರಿವರ್ತನೆಯ ಅವಧಿಯಲ್ಲಿ ಸುರಕ್ಷಾ ಸಂಖ್ಯೆಗಳನ್ನು ನವೀಕರಿಸಲಾಗುತ್ತಿದೆ.\n\nಸುರಕ್ಷಾ ಸಂಖ್ಯೆಗಳನ್ನು ದೃಢೀಕರಿಸಲು, ನಿಮ್ಮ ಸಂಪರ್ಕದ ಸಾಧನದೊಂದಿಗೆ ಕಲರ್ ಕಾರ್ಡ್‌ ಹೊಂದಿಸಿ. ಇವುಗಳು ಹೊಂದಿಕೆಯಾಗದಿದ್ದರೆ, ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಸುರಕ್ಷಾ ಸಂಖ್ಯೆಗಳ ಇನ್ನೊಂದು ಜೊತೆಯನ್ನು ಪ್ರಯತ್ನಿಸಿ. ಕೇವಲ ಒಂದು ಜೊತೆ ಹೊಂದಿಕೆಯಾಗಬೇಕು. - - ಸಹಾಯ ಅಗತ್ಯವಿದೆಯೇ? - - ಅರ್ಥವಾಯಿತು ನಿಮ್ಮ ಸಂಪರ್ಕದ ಸಾಧನದಲ್ಲಿ ಕ್ಯುಆರ್‌ ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ. @@ -5581,7 +5574,10 @@ ಎಲ್ಲಾ ಸಂಪರ್ಕಗಳನ್ನು ಪರಿಶೀಲಿಸಲಾಗಿದೆ, ಮುಂದುವರಿಸಲು send ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ. - ನೀವು %1$d ಸಂಪರ್ಕಗಳನ್ನು ಹೊಂದಿದ್ದು, ಅವರು Signal ಅನ್ನು ಮರುಸ್ಥಾಪಿಸಿರಬಹುದು ಅಥವಾ ಸಾಧನಗಳನ್ನು ಬದಲಿಸಿರಬಹುದು. ನಿಮ್ಮ ಸ್ಟೋರಿಯನ್ನು ಅವರೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳುವ ಮುನ್ನ ಅವರ ಸುರಕ್ಷತಾ ಸಂಖ್ಯೆಗಳನ್ನು ಪರಿಶೀಲಿಸಿ ಅಥವಾ ಅವರನ್ನು ನಿಮ್ಮ ಸ್ಟೋರಿಯಿಂದ ತೆಗೆದುಹಾಕುವುದನ್ನು ಪರಿಗಣಿಸಿ. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + ಸುರಕ್ಷತಾ ಸಂಖ್ಯೆ ದೃಢೀಕರಿಸಿ @@ -5824,6 +5820,17 @@ ಮುಂದುವರಿಸಿ ಖಾಸಗಿ ಮೆಸೇಜ್ ಮಾಡುವಿಕೆ, ನಿಮ್ಮ ಹಣದಿಂದ. ಜಾಹೀರಾತುಗಳಿಲ್ಲ, ಟ್ರ್ಯಾಕರ್‌ಗಳಿಲ್ಲ, ರಾಜಿ ಒಪ್ಪಂದಗಳಿಲ್ಲ. Signal ಅನ್ನು ಬೆಂಬಲಿಸಲು ಈಗಲೇ ದೇಣಿಗೆ ನೀಡಿ. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + ಮಾಸಿಕ @@ -5851,8 +5858,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + ಪಾವತಿಯನ್ನು ಖಚಿತಪಡಿಸಲು Signal ತೊರೆಯಬೇಕೇ? + ಈ ಪಾವತಿಯು ಖಚಿತಗೊಂಡ ಬಳಿಕ, ನಿಮ್ಮ ದೇಣಿಗೆಯ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು Signal ಗೆ ಮರಳಿ. @@ -5891,8 +5898,10 @@ ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ ಮುಂದುವರಿಸಿ + + Read more - Failed to load mandate + ವಿನಂತಿಯನ್ನು ಲೋಡ್ ಮಾಡಲು ವಿಫಲಗೊಂಡಿದೆ @@ -5912,13 +5921,13 @@ %1$s ಅವರಿಗೆ ದೇಣಿಗೆ ನೀಡಿ - IBAN is too short + IBAN ತೀರಾ ಚಿಕ್ಕದಾಗಿದೆ - IBAN is too long + IBAN ತೀರಾ ಉದ್ದವಾಗಿದೆ IBAN ದೇಶದ ಕೋಡ್ ಬೆಂಬಲಿತವಾಗಿಲ್ಲ - Invalid IBAN + ಅಮಾನ್ಯ IBAN @@ -5941,7 +5950,7 @@ ನಿಮ್ಮ ಖಾತೆಯ ಮಾಹಿತಿಯನ್ನು ಹುಡುಕಿ - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + ನಿಮ್ಮ ಬ್ಯಾಂಕ್ ಸ್ಟೇಟ್‌ಮೆಂಟ್‌ನ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ನಿಮ್ಮ IBAN ಅನ್ನು ನೋಡಿ. IBAN ಗಳು 34 ವರೆಗೆ ಕ್ಯಾರೆಕ್ಟರ್‌ಗಳನ್ನು ಹೊಂದಿರುತ್ತವೆ. ನೀವು ನಮೂದಿಸಿದ ಹೆಸರು ನಿಮ್ಮ ಬ್ಯಾಂಕ್ ಖಾತೆಯಲ್ಲಿರುವ ನಿಮ್ಮ ಪೂರ್ಣ ಹೆಸರಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗಬೇಕು. ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ ಬ್ಯಾಂಕ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿ. ದೇಣಿಗೆ ಬಾಕಿಯಿದೆ @@ -5957,9 +5966,9 @@ ಮುಗಿದಿದೆ - Donation couldn\'t be processed + ದೇಣಿಗೆಯನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + ನಿಮ್ಮ ಬ್ಯಾಂಕ್ ವರ್ಗಾವಣೆಯನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವಲ್ಲಿ ನಾವು ಸಮಸ್ಯೆಯನ್ನು ಎದುರಿಸುತ್ತಿದ್ದೇವೆ. ನಿಮಗೆ ಶುಲ್ಕ ವಿಧಿಸಲಾಗಿಲ್ಲ. ಇನ್ನೊಂದು ಪಾವತಿ ವಿಧಾನವನ್ನು ಪ್ರಯತ್ನಿಸಿ ಅಥವಾ ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ನಿಮ್ಮ ಬ್ಯಾಂಕ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ @@ -6386,17 +6395,17 @@ ಅನುಮತಿಸಿ - Turn on full screen notifications? + ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್ ಮಾಡಬೇಕೇ? - Never miss a call from your contacts and groups. + ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಗ್ರೂಪ್‌ಗಳಿಂದ ಕರೆಯನ್ನು ತಪ್ಪಿಸಿಕೊಳ್ಳಬೇಡಿ. ಆನ್‌ ಮಾಡಿ - Turn on full screen notifications + ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್ ಮಾಡಿ - To receive call notifications from your contacts and groups: + ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಗ್ರೂಪ್‌ಗಳಿಂದ ಕರೆ ಅಧಿಸೂಚನೆಗಳನ್ನು ಸ್ವೀಕರಿಸಲು: - 2. %1$s Allow full screen notifications + 2. %1$s ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಅನುಮತಿಸಿ diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 1ed4df89c7..e88418217e 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -627,6 +627,8 @@ %1$s%% 진행중… Signal에서 백업을 저장하려면 저장 공간 권한이 필요하지만 현재 거부되어 있습니다. 앱 설정 메뉴에서 \'권한\'을 선택한 후 \'저장 공간\' 항목을 허용해 주세요. + + Set backup time @@ -2029,6 +2031,8 @@ 새 Signal 버전을 이용할 수 있습니다. 탭하여 업데이트하세요. Signal 업데이트 실패 나중에 다시 시도하겠습니다. + Signal successfully updated + You were automatically updated to version %1$s. 메시지를 보내시겠습니까? @@ -2622,24 +2626,13 @@ - %1$s님과의 종단간 암호화를 검증하려면 위 컬러 카드에 기기를 매칭하여 번호를 비교하세요. 일치하지 않으면 스와이프하여 다른 안전 번호 쌍을 시도해 보세요. 한 쌍만 일치하면 됩니다. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. 탭하여 스캔 일치 확인 안전 번호 확인에 실패함 로드 중… 검증으로 표시 인증 초기화하기 - - 안전 번호가 업데이트됩니다. - - - 안전 번호 변경 - - 전환 기간에 안전 번호가 업데이트 되어 앞으로 Signal에서 예정된 개인정보 보호 기능이 활성화됩니다.\n\n안전 번호를 검증하려면 컬러 카드와 상대의 기기를 매칭하세요. 일치하지 않으면 스와이프하여 다른 안전 번호 쌍을 시도해 보세요. 한 쌍만 일치하면 됩니다. - - 도움이 필요하신가요? - - 확인 연락처의 기기에서 QR 코드를 스캔하세요. @@ -5455,7 +5448,9 @@ 모든 커넥션을 검토했습니다. 보내기를 탭하여 계속하세요. - Signal을 다시 설치하거나 기기를 변경했을 수 있는 커넥션이 %1$d개 있습니다. 스토리를 공유하기 전에 해당 사용자의 안전 번호를 검토하거나 스토리에서 이들을 제거하세요. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + 안전 번호 확인 @@ -5695,6 +5690,17 @@ 계속 사용자의 기부로 운영되는 개인정보를 보호하는 메신저. 광고와 트래커, 타협에서 자유로운 앱. 지금 기부를 통해 Signal을 지지해 주세요. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + 월간 @@ -5761,6 +5767,8 @@ 자세히 알아보기 계속 + + Read more 명령 로드 실패 diff --git a/app/src/main/res/values-ky/strings.xml b/app/src/main/res/values-ky/strings.xml index 923fe15136..5e9301e68b 100644 --- a/app/src/main/res/values-ky/strings.xml +++ b/app/src/main/res/values-ky/strings.xml @@ -627,6 +627,8 @@ %1$s%% болуп калды… Signal колдонмосуна камдык көчүрмөлөрдү түзүү үчүн сактагычты колдонууга уруксат беришиңиз керек, бирок сиз андан баш тарткансыз. Колдонмонун параметрлерине кирүү үчүн \"Улантуу\" дегенди басып, \"Уруксаттар\" дегенди тандап, \"Сактагыч\" дегенди иштетиңиз. + + Set backup time @@ -2029,6 +2031,8 @@ Signal\'дын жаңы версиясы чыкты. Жаңыртуу үчүн басыңыз. Signal жаңырбай калды Бир аздан соң аракет кылып көрөбүз. + Signal successfully updated + You were automatically updated to version %1$s. Билдирүү жөнөтөсүзбү? @@ -2622,24 +2626,13 @@ - %1$s аркылуу баштан аяк шифрлөөнү ырастоо үчүн жогорудагы түс картасын түзмөгүнө дал келтирип, коддорду салыштырыңыз. Эгер алар дал келбесе, экранды сүрүп, коопсуздук коддорунун башка жубун байкап көрүңүз. Бир гана жупту дал келтирүү керек. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Скандоо үчүн басыңыз Дал келди Коопсуздук коду ырасталбай калды Жүктөлүүдө… Ырасталды деп белгилөө Ырастоону өчүрүү - - Коопсуздук коддору жаңырууда. - - - Коопсуздук коддорунун өзгөрүшү - - Signal\'да болочок купуялык функцияларын иштетүү үчүн коопсуздук коддору өткөөл мезгилде жаңырат.\n\nКоопсуздук коддорун ырастоо үчүн түс картасын байланыштын түзмөгүнө дал келтириңиз. Эгер алар дал келбесе, экранды сүрүп, коопсуздук коддорунун башка жубун байкап көрүңүз. Бир гана жупту дал келтирүү керек. - - Жардам керекпи? - - Түшүндүм Байланышыңыздын түзмөгүндөгү QR кодду скандаңыз. @@ -5455,7 +5448,9 @@ Бардык байланыштар текшерилди, улантуу үчүн жөнөтүү дегенди басыңыз. - %1$d байланышыңыз Signal колдонмосун кайра орнотуп же түзмөктөрүн алмаштырышты окшойт. Окуяңызды алар менен бөлүшүүдөн мурун, алар менен болгон коопсуздук коддоруңузду текшериңиз же аларды окуяңыздан чыгарып салыңыз. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Коопсуздук кодун ырастоо @@ -5695,6 +5690,17 @@ Улантуу Өзүңүз каржылаган купуя жазышуу мүмкүнчүлүгү. Жарнамалар жок, эч ким көз салбайт, эч ким ачыктабайт. Signal\'ды колдоо үчүн азыр салым кошуңуз. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Ай сайын @@ -5761,6 +5767,8 @@ Кененирээк маалымат Улантуу + + Read more Сурам жүктөлбөй калды diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 62528d4c4c..34c2f6af9b 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -675,6 +675,8 @@ Jau %1$s%%… Norint daryti atsargines kopijas, Signal reikia išorinės saugyklos leidimo, tačiau jis buvo visam laikui uždraustas. Pereikite į programėlės nustatymus, pasirinkite „Leidimai“ ir įjunkite „Saugyklą“. + + Set backup time @@ -2245,9 +2247,11 @@ Signal atnaujinimas - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Galima nauja „Signal“ versija. Bakstelėk, jei nori atnaujinti. + Nepavyko atnaujinti „Signal“ + Vėliau pabandysime dar kartą. + Signal successfully updated + You were automatically updated to version %1$s. Siųsti žinutę? @@ -2883,24 +2887,13 @@ - Jei nori patikrinti, ar pokalbis su %1$s yra visiškai užšifruotas, palygink skaičius viršuje ir pašnekovo įrenginyje. Jei jie nesutampa, paslink į šoną ir pabandyk kitą saugumo numerių porą. Tereikia vienos sutampančios poros. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Bakstelėkite, norėdami nuskenuoti Sėkminga atitiktis Nepavyko patvirtinti saugumo numerio Įkeliama… Žymėti kaip patvirtintą Išvalyti patvirtinimą - - Saugumo numeriai atnaujinami. - - - Saugumo numerių pakeitimai - - Saugumo numeriai atnaujinami pereinamuoju laikotarpiu, kad įjungtume būsimas „Signal“ privatumo funkcijas.\n\nJei nori patikrinti saugumo numerius, palygink spalvotoje kortelėje rodomus skaičius savo ir pašnekovo įrenginyje. Jei jie nesutampa, paslink į šoną ir pabandyk kitą saugumo numerių porą. Tereikia vienos sutampančios poros. - - Reikia pagalbos? - - Supratau Nuskenuokite QR kodą savo adresato įrenginyje. @@ -5833,7 +5826,12 @@ Visi kontaktai peržiūrėti; bakstelėkite „Siųsti“, jei norite tęsti. - Turi kontaktų (%1$d), kurie galbūt iš naujo įdiegė „Signal“ arba pakeitė įrenginius. Prieš bendrindamas su jais savo istoriją, peržiūrėk jų saugumo numerius arba galbūt pašalink iš savo istorijos. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Patvirtinti saugumo numerį @@ -6082,6 +6080,17 @@ Tęsti Privačios žinutės – jūsų remiama paslauga. Jokių reklamų, jokio sekimo, jokių kompromisų. Skirk paramą dabar ir palaikyk „Signal“. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Kas mėnesį @@ -6111,8 +6120,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Išeiti iš „Signal“ mokėjimo patvirtinimui? + Kai šis mokėjimas bus patvirtintas, grįžk į „Signal“ užbaigti paramos apdorojimo. @@ -6151,8 +6160,10 @@ Sužinoti daugiau Tęsti + + Read more - Failed to load mandate + Nepavyko įkelti nurodymo @@ -6172,13 +6183,13 @@ Skirti %1$s paramą - IBAN is too short + IBAN per trumpas - IBAN is too long + IBAN per ilgas IBAN šalies kodas nepalaikomas - Invalid IBAN + Neteisingas IBAN @@ -6201,7 +6212,7 @@ Rask savo paskyros informaciją - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Ieškok savo IBAN numerio banko ataskaitos viršuje. IBAN numerį sudaro iki 34 simbolių. Įvestas vardas turi sutapti su tavo banko sąskaitoje nurodytu vardu ir pavarde. Kreipkis į savo banką, jei reikia daugiau informacijos. Laukiama paramos @@ -6217,9 +6228,9 @@ Atlikta - Donation couldn\'t be processed + Nepavyko apdoroti paramos - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Iškilo problemų apdorojant tavo banko pavedimą. Pinigai nenuskaičiuoti. Pabandyk naudoti kitą mokėjimo būdą arba kreipkis į savo banką, jei reikia daugiau informacijos. Bandykite dar kartą @@ -6658,17 +6669,17 @@ Patvirtinti - Turn on full screen notifications? + Įjungti viso ekrano pranešimus? - Never miss a call from your contacts and groups. + Niekada nepraleisk savo adresatų ir grupių skambučių. Įjungti - Turn on full screen notifications + Įjunk viso ekrano pranešimus - To receive call notifications from your contacts and groups: + Jei nori gauti savo adresatų ir grupių skambučių pranešimus: - 2. %1$s Allow full screen notifications + 2. %1$s Įjunk viso ekrano pranešimus diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index b7ad84628e..0b541a9cf5 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -659,6 +659,8 @@ %1$s%% līdz šim… Lai izveidotu rezerves kopijas, Signal nepieciešama pieejas atļauja ārējai datu krātuvei, bet tā tiek pastāvīgi liegta. Lūdzu, dodieties uz lietotnes iestatījumiem, izvēlieties \"Atļaujas\" un iespējojiet \"Krātuve\". + + Set backup time @@ -2175,6 +2177,8 @@ Ir pieejama jauna Signal versija. Pieskarieties, lai atjauninātu. Signal atjaunināšana neizdevās Vēlāk mēģināsim vēlreiz. + Signal successfully updated + You were automatically updated to version %1$s. Sūtīt ziņu? @@ -2796,24 +2800,13 @@ - Lai pārbaudītu pilnīgu šifrēšanu sarunai ar %1$s, saskaņojiet augstāk redzamo krāsu karti ar šīs personas ierīcē redzamo un salīdziniet numurus. Ja tie nesakrīt, pavelciet un izmēģiniet otru drošības numuru pāri. Ir jāsakrīt tikai vienam pārim. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Pieskarieties, lai skenētu Veiksmīga sakritība Neizdevās pārbaudīt drošības numuru Lādē… Atzīmēt kā apstiprinātu Dzēst verifikāciju - - Drošības numuri tiek atjaunināti. - - - Drošības numuru izmaiņas - - Drošības numuri tiek atjaunināti pārejas periodā, lai nodrošinātu gaidāmās privātuma funkcijas pakalpojumā Signal.\n\nLai pārbaudītu drošības numurus, saskaņojiet krāsu karti ar kontaktpersonas ierīcē redzamo. Ja tie nesakrīt, pavelciet un izmēģiniet otru drošības numuru pāri. Ir jāsakrīt tikai vienam pārim. - - Nepieciešama palīdzība? - - Skaidrs Skenējiet kvadrātkodu savas kontaktpersonas ierīcē. @@ -5707,7 +5700,11 @@ Visi kontakti ir pārskatīti, pieskarieties \"nosūtīt\", lai turpinātu. - Jums ir %1$d kontakti, kuri, iespējams, ir pārinstalējuši Signal vai nomainījuši ierīces. Pirms kopīgojat stāstu ar viņiem, pārskatiet viņu drošības numurus vai apsveriet iespēju noņemt šos kontaktus no stāsta. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Apstiprināt drošības nummuru @@ -5953,6 +5950,17 @@ Turpināt Privāta ziņapmaiņa, ko finansējat jūs. Bez reklāmām, bez izsekošanas, bez kompromisiem. Ziedojiet tūlīt, lai atbalstītu Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Ikmēneša @@ -6021,6 +6029,8 @@ Lasīt vairāk Turpināt + + Read more Komandu neizdevās ielādēt diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index d3475202f1..a773b6ff2b 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -643,6 +643,8 @@ %1$s%% до сега… Signal има потреба од дозвола до надворешен склад за да може да создава резервни копии. Оваа дозвола е трајно одбиена. Ве молиме продолжете до менито за поставувања, изберете „Дозволи“ и вклучете „Склад“. + + Set backup time @@ -2102,6 +2104,8 @@ Достапна е нова верзија на Signal. Допрете за ажурирање. Signal не успеа да се ажурира Ќе се обидеме повторно подоцна. + Signal successfully updated + You were automatically updated to version %1$s. Да се испрати пораката? @@ -2709,24 +2713,13 @@ - За да ја потврдите целосната шифрираност со %1$s, спојте ја картичката со боја погоре со уредот на %1$s и споредете ги бројките. Ако не се совпаѓаат, повлечете и обидете се со друг пар безбедносни бројки. Само еден пар треба да се совпаѓа. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Допри да скенираш Успешно совпаѓање Неуспешна проверка на безбедносниот број Се вчитува… Обележи како проверено Отстрани проверка - - Се ажурира начинот на кој функционираат безбедносните бројки. - - - Промени на безбедносните броеви - - Се ажурира начинот на кој функционираат безбедносните бројки во текот на преоден период за да се овозможат претстојните функции за приватност на Signal.\n\nЗа да ги потврдите безбедносните броеви, спојте ја картичката со боја со уредот на вашиот контакт. Ако не се совпаѓаат, повлечете и обидете се со друг пар безбедносни бројки. Само еден пар треба да се совпаѓа. - - Потребна Ви е помош? - - Во ред Скенирајте го QR кодот на уредот на Вашиот контакт. @@ -5581,7 +5574,10 @@ Сите врски се прегледани, допрете на испрати за да продолжите. - Имате %1$d врски кои можеби реинсталирале Signal или ги смениле уредите. Пред да ја споделите вашата приказна со нив, прегледајте ги нивните сигурносни броеви и разгледајте ја можноста да ги отстраните од вашите приказни. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Проверка на безбедносен број @@ -5824,6 +5820,17 @@ Продолжи Приватно допишување, финансирано од вас. Без реклами, без тракери, без компромис. Донирајте сега за да го поддржите Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Месечно @@ -5891,6 +5898,8 @@ Дознајте повеќе Продолжи + + Read more Барањето не е вчитано diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 6cdd3c732e..d1d8e745eb 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -643,6 +643,8 @@ %1$s%% ഇതുവരെ… ബാക്കപ്പുകൾ സൃഷ്ടിക്കുന്നതിന് Signal-ന് ബാഹ്യ സ്റ്റോറജ് ​​അനുമതി ആവശ്യമാണ്, പക്ഷേ ഇത് ശാശ്വതമായി നിരസിക്കപ്പെട്ടു. അപ്ലിക്കേഷൻ ക്രമീകരണങ്ങളിലേക്കു പോയി , \"അനുമതികൾ\" തിരഞ്ഞെടുത്ത് \"സ്റ്റോറജ്\" ഉപയോഗാനുമതി നൽകുക . + + Set backup time @@ -2102,6 +2104,8 @@ Signal-ന്റെ ഒരു പുതിയ പതിപ്പ് ലഭ്യമാണ്. അപ്ഡേറ്റ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക. Signal അപ്ഡേറ്റ് ചെയ്യാനായില്ല ഞങ്ങൾ പിന്നീട് വീണ്ടും ശ്രമിക്കും. + Signal successfully updated + You were automatically updated to version %1$s. സന്ദേശം അയക്കണോ? @@ -2709,24 +2713,13 @@ - %1$s എന്നയാളുമായി ആദ്യാവസാനം എൻക്രിപ്റ്റ് ചെയ്യൽ പരിശോധിച്ചുറപ്പിക്കാൻ, അവരുടെ ഉപകരണവുമായി മുകളിലുള്ള കളർ കാർഡ് പൊരുത്തപ്പെടുത്തുകയും അക്കങ്ങൾ താരതമ്യം ചെയ്യുകയും ചെയ്യൂ. ഇത് പൊരുത്തപ്പെടുന്നില്ലെങ്കിൽ, സ്വൈപ്പ് ചെയ്‌ത് സുരക്ഷാ നമ്പറുകളുടെ മറ്റൊരു പെയർ പരീക്ഷിച്ചു നോക്കുക. ഒരു പെയർ പൊരുത്തപ്പെട്ടാൽ മതി. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. സ്കാൻ ചെയ്യാൻ തൊടുക വിജയകരമായ ചേര്‍ച്ച സുരക്ഷാ നമ്പർ പരിശോധിക്കുന്നതിൽ പരാജയപ്പെട്ടു ലഭ്യമാക്കുന്നു പരിശോധിച്ചതായി അടയാളപ്പെടുത്തുക പരിശോധന പൂർത്തിയാക്കുക - - സുരക്ഷാ നമ്പറുകൾ അപ്ഡേറ്റ് ചെയ്യുകയാണ്. - - - സുരക്ഷാ നമ്പറുകളിലെ മാറ്റങ്ങൾ - - Signal-ൽ വരാനിരിക്കുന്ന സ്വകാര്യതാ നയങ്ങൾ പ്രവർത്തനക്ഷമമാക്കാൻ സുരക്ഷാ നമ്പറുകൾ കാലാനുസൃതമായി അപ്ഡേറ്റ് ചെയ്യുന്നു.\n\nസുരക്ഷാ നമ്പറുകൾ പരിശോധിച്ചുറപ്പിക്കാൻ, നിങ്ങളുടെ കോൺടാക്റ്റിന്റെ ഉപകരണവുമായി കളർ കാർഡ് പൊരുത്തപ്പെടുത്തുക. ഇത് പൊരുത്തപ്പെടുന്നില്ലെങ്കിൽ, സ്വൈപ്പ് ചെയ്‌ത് സുരക്ഷാ നമ്പറുകളുടെ മറ്റൊരു പെയർ പരീക്ഷിച്ചു നോക്കുക. ഒരു പെയർ പൊരുത്തപ്പെട്ടാൽ മതി. - - സഹായം ആവശ്യമുണ്ടോ? - - മനസ്സിലായി നിങ്ങളുടെ കോൺടാക്ടിൻ്റെ ഡിവൈസിലുള്ള QR കോഡ് സ്കാൻ ചെയ്യുക. @@ -5581,7 +5574,10 @@ എല്ലാ കണക്ഷനുകളും അവലോകനം ചെയ്‌തു, തുടരുന്നതിന് അയയ്ക്കുക എന്നതിൽ ടാപ്പ് ചെയ്യുക. - Signal വീണ്ടും ഇൻസ്റ്റാൾ ചെയ്യുകയോ ഉപകരണങ്ങൾ മാറുകയോ ചെയ്‌തിട്ടുണ്ടാകാവുന്ന %1$d കണക്ഷനുകൾ നിങ്ങൾക്കുണ്ട്. നിങ്ങളുടെ സ്റ്റോറി അവരുമായി പങ്കിടുന്നതിന് മുമ്പ് അവരുടെ സുരക്ഷാ നമ്പറുകൾ അവലോകനം ചെയ്യുകയോ അവരെ നിങ്ങളുടെ സ്റ്റോറിയിൽ നിന്ന് നീക്കം ചെയ്യുന്നതിനെ കുറിച്ച് ചിന്തിക്കുകയോ ചെയ്യുക. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + സുരക്ഷാ നമ്പർ ഉറപ്പാക്കു @@ -5824,6 +5820,17 @@ തുടരുക സ്വകാര്യ സന്ദേശമയയ്‌ക്കൽ, നിങ്ങളുടെ ധനസഹായത്തിൽ. പരസ്യങ്ങളില്ല, ട്രാക്കിംഗില്ല, വിട്ടുവീഴ്‌ചയില്ല. Signal-നെ പിന്തുണയ്ക്കാൻ ഇപ്പോൾ സംഭാവന നൽകൂ. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + പ്രതിമാസം @@ -5891,6 +5898,8 @@ കൂടുതലറിയുക തുടരുക + + Read more അഭ്യർത്ഥന ലോഡ് ചെയ്യാനായില്ല diff --git a/app/src/main/res/values-mr/strings.xml b/app/src/main/res/values-mr/strings.xml index fbccb7eeb0..254db95e6e 100644 --- a/app/src/main/res/values-mr/strings.xml +++ b/app/src/main/res/values-mr/strings.xml @@ -643,6 +643,8 @@ %1$s%% आत्तापर्यंत… बॅकअप तयार करण्यासाठी Signal ला संचयन परवानगी ची आवश्यकता असते, पण ती कायमची नाकारली गेली आहे. कृपया अॅप सेटिंग मेनू मध्ये सुरू ठेवा, \"परवानग्या\" निवडा, आणि \"संचयन\" सक्षम करा. + + Set backup time @@ -2102,6 +2104,8 @@ Signal ची नवीन आवृत्ती उपलब्ध आहे. अपडेट करण्यास टॅप करा. Signal अपडेट होण्यात अयशस्वी झाला आपण नंतर पुन्हा प्रयत्न करू. + Signal successfully updated + You were automatically updated to version %1$s. संदेश पाठवायचा? @@ -2709,24 +2713,13 @@ - %1$s सह एंड-टू-एंड एन्क्रिप्शनची पडताळणी करण्यासाठी, वरील रंग कार्ड त्यांच्या डिव्हाइससह जुळवा आणि क्रमांकाची तुलना करा. ते जर जुळत नसतील तर, स्वाइप करा आणि सुरक्षितता क्रमांकांची इतर जोडी वापरून पहा. फक्त एक जोडी जुळवण्याची गरज आहे. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. स्कॅन करण्यासाठी टॅप करा यशस्वी जोड सुरक्षितता नंबरची पडताळणी करण्यात अयशस्वी लोड होत आहे… सत्यापित म्हणून चिन्हांकित करा सत्यापन साफ करा - - सुरक्षितता क्रमांक हे अद्यतनित करण्यात आले आहेत. - - - सुरक्षितता क्रमांकामधील बदल - - Signal मधील येऊ घातलेली गोपनीयता वैशिष्ट्ये सक्षम करण्यासाठी सुरक्षितता क्रमांक हे संक्रमण कालावधीदरम्यान अद्यतनित केले जाणार आहेत.\n\nसुरक्षितता क्रमांकांची पडताळणी करण्यासाठी, आपल्या संपर्क डिव्हाइस सह रंग कार्ड जुळवा. ते जर जुळत नसतील तर, स्वाइप करा आणि सुरक्षितता क्रमांकांची इतर जोडी वापरून पहा. फक्त एक जोडी जुळवण्याची गरज आहे. - - मदत हवी? - - कळले आपल्या संपर्काच्या डिव्हाईसवर QR कोड स्कॅन करा @@ -5581,7 +5574,10 @@ सर्व कनेक्शन्सचे पुनरावलोकन करण्यात आले आहे, पुढे सुरू ठेवण्यासाठी टॅप करा. - ज्यांनी कदाचित Signal पुन्हा इन्स्टॉल केले आहे किंवा उपकरणे बदलली आहेत अशी आपणाकडे %1$d कनेक्शन्स आहेत. आपली स्टोरी त्यांच्या सोबत शेअर करण्यापूर्वी त्यांच्या सुरक्षितता क्रमांकांचे पुनरावलोकन करा किंवा त्यांना आपल्या स्टोरीमधून हटवण्याचा विचार करा. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + सुरक्षितता नंबर सत्यापित करा @@ -5824,6 +5820,17 @@ सुरू ठेवा आपल्या निधीवर चालणारे, गोपनीय संदेशन. कोणत्याही जाहिराती नाहीत, कोणतेही ट्रॅकिंग नाही, कोणतीही तडजोड नाही. Signal ला सपोर्ट करण्यासाठी आता देणगी द्या. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + महिन्याला @@ -5891,6 +5898,8 @@ अधिक जाणून घ्या सुरू ठेवा + + Read more विनंती लोड करण्यात अपयशी झालो diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index aac8f37cde..d0542fc0c1 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -627,6 +627,8 @@ %1$s%% setakat ini… Signal memerlukan kebenaran storan luaran untuk mencipta sandaran, tetapi telah ditolak secara kekal. Sila terus ke menu tetapan aplikasi, pilih \"Kebenaran\", dan dayakan \"Storan\". + + Set backup time @@ -2029,6 +2031,8 @@ Versi baharu Signal tersedia. Ketik untuk mengemas kini. Signal gagal dikemas kini Kita akan cuba lagi nanti. + Signal successfully updated + You were automatically updated to version %1$s. Hantar mesej? @@ -2622,24 +2626,13 @@ - Untuk mengesahkan penyulitan hujung ke hujung dengan %1$s, padankan kad warna di atas dengan peranti mereka dan bandingkan nombornya. Jika ini tidak sepadan, leret dan cuba pasangan nombor keselamatan yang lain. Hanya satu pasangan yang perlu dipadankan. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Ketik untuk mengimbas Padanan berjaya Gagal mengesahkan nombor keselamatan Memuatkan… Tanda sebagai disahkan Kosongkan pengesahan - - Nombor keselamatan sedang dikemas kini. - - - Perubahan kepada Nombor Keselamatan - - Nombor keselamatan sedang dikemas kini dalam tempoh peralihan untuk mendayakan ciri privasi yang akan datang dalam Signal.\n\nUntuk mengesahkan nombor keselamatan, padankan kad warna dengan peranti kenalan anda. Jika ini tidak sepadan, leret dan cuba pasangan nombor keselamatan yang lain. Hanya satu pasangan yang perlu dipadankan. - - Perlukan bantuan? - - Faham Imbas Kod QR pada peranti kenalan anda. @@ -5455,7 +5448,9 @@ Semua hubungan telah disemak, ketik hantar untuk meneruskan. - Anda mempunyai %1$d hubungan yang mungkin telah memasang semula Signal atau menukar peranti. Sebelum berkongsi cerita anda dengan mereka, semak nombor keselamatan mereka atau pertimbangkan untuk mengalih keluar mereka daripada cerita anda. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Sahkan nombor keselamatan @@ -5695,6 +5690,17 @@ Teruskan Pemesejan peribadi, dibiayai oleh anda. Tiada iklan, tiada penjejakan, tiada kompromi. Derma sekarang untuk menyokong Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Bulanan @@ -5761,6 +5767,8 @@ Ketahui lebih lanjut Teruskan + + Read more Gagal memuatkan mandat diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml index d242636032..61dce7f915 100644 --- a/app/src/main/res/values-my/strings.xml +++ b/app/src/main/res/values-my/strings.xml @@ -627,6 +627,8 @@ %1$s%% လုပ်ဆောင်ပြီး… သင်၏ အပလီကေးရှင်းပြင်ပ ဖုန်းထဲတွင် သိမ်းထားခွင့်အား Signal ကို ပေးရန်လိုအပ်ပါသည်။သို့သော် လုံးဝခွင့်မပြုပါဟု ရွေးထားပြီး ဖြစ်နေသဖြင့် အပ်ပလီကေးရှင်း အပြင်အဆင်သို့ သွား၍ ခွင့်ပြုချက်များကို ရွေးချယ်ကာ သိုလှောင်မှုခွင့်ပြုချက်ကို အသုံးပြုနိုင်အောင် ပြုလုပ်ပါ။ + + Set backup time @@ -2029,6 +2031,8 @@ Signal ဗားရှင်းအသစ် ရနိုင်ပါပြီ။ အပ်ဒိတ်လုပ်ရန် နှိပ်ပါ။ Signal ကို အပ်ဒိတ်လုပ်ခြင်း မအောင်မြင်ပါ နောက်မှ ထပ်ကြိုးစားပါမည်။ + Signal successfully updated + You were automatically updated to version %1$s. စာပို့မလား? @@ -2622,24 +2626,13 @@ - %1$s နှင့် ဟိုဘက်သည်ဘက် ကုဒ်ပြောင်းဝှက်ထားခြင်းကို စိစစ်အတည်ပြုရန် အထက်ပါ အရောင်ကတ်ပြားကို ၎င်း၏စက်နှင့် ယှဉ်ကြည့်ပြီး နံပါတ်များကို နှိုင်းယှဉ်ပါ။ ထိုနံပါတ်များ မကိုက်ညီပါက ပွတ်ဆွဲပြီးနောက် လုံခြုံရေးနံပါတ် နောက်တစ်တွဲဖြင့် စမ်းကြည့်ပါ။ နံပါတ်အတွဲတစ်တွဲသာလျှင် ကိုက်ညီရန် လိုအပ်ပါသည်။ + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. စကင်ဖတ်ရန်နှိပ်ပါ ကိုက်ညီမှု အောင်မြင်ပါသည် လုံခြုံရေးနံပါတ်ကို အတည်ပြုရန် မအောင်မြင်ခဲ့ပါ လုပ်ဆောင်နေသည်… Mark as verified အတည်ပြုမှု ရှင်းလင်းရန် - - လုံခြုံရေးနံပါတ်များကို အပ်ဒိတ်ပြုလုပ်နေပါသည်။ - - - လုံခြုံရေးနံပါတ်များဆိုင်ရာ အပြောင်းအလဲများ - - Signal တွင် ပါဝင်လာမည့် ကိုယ်ပိုင်အချက်အလက်ဆိုင်ရာ အင်္ဂါရပ်များကို ဖွင့်နိုင်ရန်အတွက် လုံခြုံရေးနံပါတ်များကို အကူးအပြောင်းကာလတစ်ခုအတွင်း အပ်ဒိတ်ပြုလုပ်နေပါသည်။လုံခြုံရေးနံပါတ်များကို စိစစ်အတည်ပြုရန် အရောင်ကတ်ပြားကို သင့်အဆက်အသွယ်၏စက်နှင့် ယှဉ်ကြည့်ပါ။ ထိုနံပါတ်များ ကိုက်ညီခြင်းမရှိပါက ပွတ်ဆွဲပြီးနောက် လုံခြုံရေးနံပါတ် နောက်တစ်တွဲဖြင့် စမ်းကြည့်ပါ။ နံပါတ်အတွဲတစ်တွဲသာလျှင် ကိုက်ညီရန် လိုအပ်ပါသည်။ - - အကူအညီ လိုအပ်ပါသလား? - - ရပြီ တဖက်လူ၏ ဖုန်း/ကွန်ပျူတာပေါ်တွင် QR ကုတ်ကို စကန်ဖတ်ပါ။ @@ -5455,7 +5448,9 @@ ချိတ်ဆက်မှုများ အားလုံးကို ပြန်လည်စိစစ်ထားပါသည်၊ ဆက်လုပ်ရန်အတွက် ပေးပို့မည်ကို နှိပ်ပါ။ - သင့်တွင် Signal ကို ပြန်လည်ထည့်သွင်းထားသည့် သို့မဟုတ် စက်များ ပြောင်းထားသည့် အဆက်အသွယ် %1$d ဦး ရှိပါသည်။ ထိုသူတို့ထံ သင့်စတိုရီကို မဝေမျှမီ ၎င်းတို့၏ လုံခြုံရေးနံပါတ်ကို ပြန်လည်စိစစ်ပါ သို့မဟုတ် ၎င်းတို့အား သင့်စတိုရီမှ ဖယ်ရှားရန် စဉ်းစားပါ။ + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + စိတ်ချရသောနံပါတ်ကို စစ်ဆေးအတည်ပြုခြင်း @@ -5695,6 +5690,17 @@ ဆက်လုပ်ရန် သင် ငွေကြေးထောက်ပံ့ထားသည့် သီးသန့် မက်ဆေ့ချ်လုပ်ဆောင်ချက်။ ကြော်ငြာများ မရှိ၊ ခြေရာခံခြင်း မရှိ၊ အပေးအယူ မရှိ။ Signal ကို ပံ့ပိုးရန် ယခုပင် လှူဒါန်းလိုက်ပါ။ + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + လစဉ် @@ -5761,6 +5767,8 @@ ပိုမိုလေ့လာရန် ဆက်လုပ်ရန် + + Read more ညွှန်ကြားမှုကို ဖွင့်၍မရပါ diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 3bfb79f295..d8f331ce4f 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -643,6 +643,8 @@ %1$s%% på vei … Signal krever tillatelse fra systemet for å kunne lagre sikkerhetskopier, men du har valgt å avslå dette permanent. Gå til «Apper»-menyen på systemet og slå på tillatelsen «Lagring». + + Set backup time @@ -2102,6 +2104,8 @@ En ny versjon av Signal er tilgjengelig. Trykk for å oppdatere appen. Signal kunne ikke oppdateres Vi gir det et nytt forsøk senere. + Signal successfully updated + You were automatically updated to version %1$s. Send melding? @@ -2709,24 +2713,13 @@ - For å sikre ende-til-ende-kryptering med %1$s må dere sjekke om fargekortet og koden ovenfor matcher det som kommer opp på deres enhet. Sveip og prøv med en annen kombinasjon hvis de ikke matcher. Kun ett sett med fargekort og kode trenger å matche. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Trykk for å skanne Samsvar Kunne ikke bekrefte sikkerhetsnummeret Laster… Merk som bekreftet Fjern bekreftelse - - Vi endrer sikkerhetsnumrene. - - - Endringer i sikkerhetsnummer - - I overgangen til nye sikkerhetsfunksjoner i Signal har vi gjort et par endringer i sikkerhetsnumrene.\n\nMatch fargekortet med personen du skal chatte med, for å bekrefte sikkerhetsnumrene. Sveip og prøv med en annen kombinasjon hvis de ikke matcher. Kun ett sett med fargekort og kode trenger å matche. - - Ønsker du hjelp? - - Skjønner Skann QR-koden på kontaktens enhet. @@ -5581,7 +5574,10 @@ Alle kontaktene er gjennomgått, trykk på Send for å fortsette. - Du har %1$d kontakter som kan ha installert Signal på nytt eller byttet enhet. Du bør sjekke sikkerhetsnumrene deres eller fjern dem fra storyen din før du eventuelt deler den med dem. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Bekreft sikkerhetsnummer @@ -5824,6 +5820,17 @@ Fortsett Private meldinger, finansiert av brukere som deg. Ingen annonser, ingen sporing, ingen kompromiss. Støtt Signal med et pengebeløp nå. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Månedlig @@ -5891,6 +5898,8 @@ Les mer Fortsett + + Read more Kunne ikke laste inn forespørselen diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 655bdc7202..e1fea9f14f 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -643,6 +643,8 @@ %1$s%% tot nu toe… Signal heeft toegang nodig tot de opslagruimte om back-upbestanden te kunnen maken, maar deze is pertinent geweigerd. Ga naar de instellingen voor deze app, tik op ‘Machtigingen’ en schakel ‘Opslagruimte’ in. + + Set backup time @@ -2102,6 +2104,8 @@ Een nieuwe versie van Signal is beschikbaar. Tik om bij te werken. Signal kan niet worden bijgewerkt We proberen het later opnieuw. + Signal successfully updated + You were automatically updated to version %1$s. Bericht verzenden? @@ -2709,24 +2713,13 @@ - Om end-to-end-versleuteling met %1$s te verifiëren, moet je bovenstaande kleurenkaart vergelijken met de nummers op de kaart van je contact. Als deze niet overeenkomen, swipe je en probeer je het andere paar veiligheidsnummers. Er hoeft maar één paar te matchen. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Tik om te scannen De nummers komen overeen Verifieren niet gelukt Aan het laden… Als geverifieerd markeren Verificatie ongedaan maken - - Veiligheidsnummers worden bijgewerkt. - - - Veranderingen in veiligheidsnummers - - Veiligheidsnummers worden gedurende een overgangsperiode bijgewerkt als voorbereiding op toekomstige privacyfuncties in Signal.\n\nOm veiligheidsnummers te verifiëren, vergelijk de kleurkaart met die op het apparaat van je contactpersoon. Als deze niet overeenkomen, swipe je en probeer je het andere paar veiligheidsnummers. Er hoeft maar één paar te matchen. - - Hulp nodig? - - Begrepen Scan de QR-code op het apparaat van je gesprekspartner. @@ -5581,7 +5574,10 @@ Alle contacten zijn beoordeeld, tik op versturen om verder te gaan. - Je hebt %1$d contacten die Signal misschien opnieuw geïnstalleerd hebben of van toestel zijn veranderd. Bekijk voordat je je verhaal met hen deelt hun veiligheidsnummers of overweeg om je verhaal niet met hen te delen. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Veiligheidsnummer verifiëren @@ -5824,6 +5820,17 @@ Doorgaan Privéberichten, gefinancierd door jou. Geen advertenties, geen tracking, geen compromissen. Doneer nu om Signal te steunen. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Maandelijks @@ -5891,6 +5898,8 @@ Meer informatie Doorgaan + + Read more Kan verzoek niet laden diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 685b71ce9a..9cf8befc56 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -643,6 +643,8 @@ ਹੁਣ ਤੱਕ %1$s %%… ਬੈਕਅੱਪ ਬਣਾਉਣ ਲਈ Signal ਨੂੰ ਬਾਹਰੀ ਸਟੋਰੇਜ ਦੀ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ, ਪਰ ਇਸਨੂੰ ਸਥਾਈ ਤੌਰ ’ਤੇ ਇਨਕਾਰ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਸੈਟਿੰਗਾਂ ’ਤੇ ਜਾਰੀ ਰੱਖੋ, \"ਇਜਾਜ਼ਤਾਂ\" ਚੁਣੋ ਅਤੇ \"ਸਟੋਰੇਜ\" ਨੂੰ ਸਮਰੱਥ ਕਰੋ। + + Set backup time @@ -2102,6 +2104,8 @@ Signal ਦਾ ਨਵਾਂ ਵਰਜ਼ਨ ਉਪਲਬਧ ਹੈ। ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। Signal ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ ਅਸੀਂ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਾਂਗੇ। + Signal successfully updated + You were automatically updated to version %1$s. ਸੁਨੇਹਾ ਭੇਜਣਾ ਹੈ? @@ -2709,24 +2713,13 @@ - %1$s ਦੇ ਨਾਲ ਸਿਰੇ-ਤੋਂ-ਸਿਰੇ ਤੱਕ ਇਨਕ੍ਰਿਪਸ਼ਨ ਦੀ ਤਸਦੀਕ ਕਰਨ ਲਈ, ਉੱਪਰ ਦਿੱਤੇ ਰੰਗੀਨ ਕਾਰਡ ਨੂੰ ਉਹਨਾਂ ਦੇ ਡਿਵਾਈਸ ਨਾਲ ਮਿਲਾਓ ਅਤੇ ਨੰਬਰਾਂ ਦੀ ਤੁਲਨਾ ਕਰੋ। ਜੇਕਰ ਇਹ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ, ਤਾਂ ਸਵਾਈਪ ਕਰੋ ਅਤੇ ਸੁਰੱਖਿਆ ਨੰਬਰਾਂ ਦੀ ਦੂਜੀ ਜੋੜੀ ਨੂੰ ਮਿਲਾ ਕੇ ਦੇਖੋ। ਸਿਰਫ਼ ਇੱਕ ਜੋੜੀ ਦੇ ਮੇਲ ਖਾਣ ਦੀ ਲੋੜ ਹੈ। + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. ਸਕੈਨ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਸਫਲਤਾਪੂਰਵਕ ਮੇਲ ਖਾਂਦਾ ਹੈ ਸੁਰੱਖਿਆ ਨੰਬਰ ਦੀ ਤਸਦੀਕ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ ਲੋਡ ਕਰ ਰਿਹਾ ਹੈ … ਪ੍ਰਮਾਣਿਤ ਵਜੋਂ ਚਿੰਨ੍ਹ ਲਾਓ ਤਸਦੀਕ ਨੂੰ ਮਿਟਾਓ - - ਸੁਰੱਖਿਆ ਨੰਬਰ ਅੱਪਡੇਟ ਕੀਤੇ ਜਾ ਰਹੇ ਹਨ। - - - ਸੁਰੱਖਿਆ ਨੰਬਰਾਂ ਵਿੱਚ ਬਦਲਾਅ - - Signal ਵਿੱਚ ਆਉਣ ਵਾਲੇ ਪਰਦੇਦਾਰੀ ਫੀਚਰਾਂ ਨੂੰ ਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਸੁਰੱਖਿਆ ਨੰਬਰਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।\n\nਸੁਰੱਖਿਆ ਨੰਬਰਾਂ ਦੀ ਤਸਦੀਕ ਕਰਨ ਲਈ, ਰੰਗੀਨ ਕਾਰਡ ਨੂੰ ਆਪਣੇ ਸੰਪਰਕ ਦੇ ਡਿਵਾਈਸ ਨਾਲ ਮਿਲਾਓ। ਜੇਕਰ ਇਹ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ, ਤਾਂ ਸਵਾਈਪ ਕਰੋ ਅਤੇ ਸੁਰੱਖਿਆ ਨੰਬਰਾਂ ਦੀ ਦੂਜੀ ਜੋੜੀ ਨੂੰ ਮਿਲਾ ਕੇ ਦੇਖੋ। ਸਿਰਫ਼ ਇੱਕ ਜੋੜੀ ਦੇ ਮੇਲ ਖਾਣ ਦੀ ਲੋੜ ਹੈ। - - ਮਦਦ ਚਾਹੀਦੀ ਹੈ? - - ਸਮਝ ਗਏ ਆਪਣੇ ਸੰਪਰਕ ਦੇ ਡਿਵਾਈਸ \'ਤੇ QR ਕੋਡ ਸਕੈਨ ਕਰੋ. @@ -5581,7 +5574,10 @@ ਸਾਰੇ ਕਨੈਕਸ਼ਨਾਂ ਦੀ ਸਮੀਖਿਆ ਹੋ ਗਈ ਹੈ, ਅੱਗੇ ਜਾਰੀ ਰੱਖਣ ਲਈ \"ਭੇਜੋ\" \'ਤੇ ਟੈਪ ਕਰੋ। - ਤੁਹਾਡੇ %1$d ਕਨੈਕਸ਼ਨਾਂ ਨੇ ਸ਼ਾਇਦ Signal ਨੂੰ ਮੁੜ-ਇੰਸਟਾਲ ਕੀਤਾ ਹੈ ਜਾਂ ਆਪਣੇ ਡਿਵਾਈਸਾਂ ਨੂੰ ਬਦਲਿਆ ਹੈ। ਉਹਨਾਂ ਨਾਲ ਆਪਣੀ ਸਟੋਰੀ ਸਾਂਝੀ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਹਨਾਂ ਦੇ ਸੁਰੱਖਿਆ ਨੰਬਰ ਦੀ ਸਮੀਖਿਆ ਕਰੋ ਜਾਂ ਉਹਨਾਂ ਨੂੰ ਆਪਣੀ ਸਟੋਰੀ ਤੋਂ ਹਟਾਉਣ ਬਾਰੇ ਵਿਚਾਰ ਕਰੋ। + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + ਸੁਰੱਖਿਆ ਨੰਬਰ ਦੀ ਤਸਦੀਕ ਕਰੋ @@ -5824,6 +5820,17 @@ ਜਾਰੀ ਰੱਖੋ ਪ੍ਰਾਈਵੇਟ ਮੈਸੇਜਿੰਗ, ਜੋ ਤੁਹਾਡੇ ਸਹਿਯੋਗ ਨਾਲ ਚਲਦੀ ਹੈ। ਕੋਈ ਇਸ਼ਤਿਹਾਰ ਨਹੀਂ, ਕੋਈ ਟ੍ਰੈਕਰ ਨਹੀਂ, ਕੋਈ ਸਮਝੌਤਾ ਨਹੀਂ। ਹੁਣੇ ਦਾਨ ਦੇ ਕੇ Signal ਨੂੰ ਆਪਣਾ ਸਹਿਯੋਗ ਦਿਓ। + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + ਹਰ ਮਹੀਨੇ @@ -5891,6 +5898,8 @@ ਹੋਰ ਜਾਣੋ ਜਾਰੀ ਰੱਖੋ + + Read more ਮੈਨਡੇਟ ਲੋਡ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 19dca3489b..08638d13c6 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -675,6 +675,8 @@ %1$s%% wiadomości… Signal wymaga dostępu do pamięci zewnętrznej urządzenia, aby móc tworzyć kopie zapasowe, ale uprawnienia zostały na stałe odrzucone. Przejdź do ustawień aplikacji, wybierz \"Uprawnienia\" i włącz \"Pamięć\". + + Set backup time @@ -2245,9 +2247,11 @@ Aktualizacja Signal - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Dostępna jest nowa wersja Signal. Wybierz, aby zaktualizować. + Aktualizacja Signal nie powiodła się + Spróbujemy ponownie później. + Signal successfully updated + You were automatically updated to version %1$s. Wysłać wiadomość? @@ -2883,24 +2887,13 @@ - Aby uzyskać szyfrowanie metodą end-to-end z użytkownikiem %1$s, dopasuj kolor karty powyżej i porównaj numery. Jeśli do siebie nie pasują, przesuń i spróbuj z innymi numerami bezpieczeństwa. Wystarczy, że pasuje jedna para. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Dotknij, aby zeskanować Dopasowanie udane Nie udało się zweryfikować numeru bezpieczeństwa! Wczytywanie… Oznacz jako zweryfikowany Wycofaj weryfikację - - Numery bezpieczeństwa otrzymują aktualizację. - - - Zmiany w numerach bezpieczeństwa - - Numery bezpieczeństwa będą aktualizowane przez pewien czas, by umożliwić wprowadzenie nadchodzących funkcji prywatności do Signal.\n\nAby zweryfikować numery bezpieczeństwa, dopasuj kolor karty kolorem na urządzeniu Twojego kontaktu. Jeśli do siebie nie pasują, przesuń i spróbuj z innymi numerami bezpieczeństwa. Wystarczy, że pasuje jedna para. - - Potrzebujesz pomocy? - - Rozumiem Zeskanuj kod QR na urządzeniu Twojego kontaktu. @@ -5833,7 +5826,12 @@ Wszystkie kontakty zostały przejrzane. Stuknij w opcję „wyślij”, aby kontynuować. - Wśród kontaktów masz osoby (%1$d), które mogły ponownie zainstalować aplikację Signal albo zmienić urządzenie. Zanim udostępnisz im swoją relację, zweryfikuj ich numery bezpieczeństwa lub rozważ usunięcie ich z listy odbiorców relacji. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Zweryfikuj numer bezpieczeństwa @@ -6082,6 +6080,17 @@ Kontynuuj Prywatne wysyłanie wiadomości, finansowane przez Ciebie. Bez reklam, bez śledzenia, bez nadzoru. Wpłać darowiznę i wspieraj Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Co miesiąc @@ -6111,8 +6120,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Wyjść z Signal, aby potwierdzić płatność? + Gdy płatność zostanie zatwierdzona, wróć do Signal, by zakończyć proces przekazywania darowizny. @@ -6151,8 +6160,10 @@ Dowiedz się więcej Kontynuuj + + Read more - Failed to load mandate + Nie udało się wczytać zlecenia @@ -6172,13 +6183,13 @@ Wpłać darowiznę w wys. %1$s - IBAN is too short + IBAN jest za krótki - IBAN is too long + IBAN jest za długi Kod kraju IBAN nie jest obsługiwany - Invalid IBAN + Nieprawidłowy IBAN @@ -6201,7 +6212,7 @@ Znajdź informacje o koncie - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Znajdź swój numer IBAN na górze wyciągu bankowego. Numery IBAN zawierają do 34 znaków. Wprowadzone imię i nazwisko powinno zgadzać się z imieniem i nazwiskiem widniejącym na koncie bankowym. Skontaktuj się ze swoim bankiem, by uzyskać więcej informacji. Darowizna oczekuje na realizację @@ -6217,9 +6228,9 @@ Gotowe - Donation couldn\'t be processed + Darowizna nie mogła zostać zrealizowana - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Mamy problem z przetworzeniem Twojego przelewu bankowego. Środki nie zostały pobrane. Wypróbuj inną metodę płatności lub skontaktuj się ze swoim bankiem, aby otrzymać więcej informacji. Spróbuj ponownie @@ -6658,17 +6669,17 @@ Zaakceptuj - Turn on full screen notifications? + Włączyć powiadomienia pełnoekranowe? - Never miss a call from your contacts and groups. + Spraw, by nie ominęło Cię żadne połączenie od kontaktów i grup. Włącz - Turn on full screen notifications + Włącz powiadomienia pełnoekranowe - To receive call notifications from your contacts and groups: + Aby otrzymywać powiadomienia o połączeniach od kontaktów i grup: - 2. %1$s Allow full screen notifications + 2. %1$s Zezwól na powiadomienia pełnoekranowe diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 8ac14dae29..6263c3660a 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -643,6 +643,8 @@ %1$s%% até agora… O Signal precisa da permissão ao armazenamento externo para fazer backup, mas ela foi permanentemente negada. Por favor, vá ao menu de configurações de aplicativos, selecione \"Permissões\", e habilite \"Armazenamento\". + + Set backup time @@ -2102,6 +2104,8 @@ Uma nova versão do Signal está disponível. Toque para atualizar. Falha ao atualizar o Signal Tentaremos novamente mais tarde. + Signal successfully updated + You were automatically updated to version %1$s. Enviar mensagem? @@ -2709,24 +2713,13 @@ - Para verificar a criptografia de ponta a ponta com %1$s, combine o cartão de cor acima com o dispositivo e compare os números. Se não corresponder, deslize e tente usar outro par de números de segurança. Apenas um par precisa dar match. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Toque para escanear Correspondência bem sucedida Falha ao verificar o número de segurança Carregando… Marcar como verificado Apagar verificação - - Os números de segurança estão sendo atualizados. - - - Alterações nos números de segurança - - Vamos atualizar os números de segurança durante um período de transição para habilitar os próximos recursos de privacidade no Signal.\n\nPara verificar números de segurança, combine o cartão da cor com o dispositivo do seu contato. Se não corresponder, deslize e tente usar outro par de números de segurança. Apenas um par precisa dar match. - - Precisa de ajuda? - - Entendi Escanear o Código QR no aparelho da outra pessoa. @@ -5581,7 +5574,10 @@ Todos os contatos foram analisados, toque em enviar para continuar. - Você tem %1$d contatos que talvez tenham reinstalado o Signal ou trocado de aparelho. Antes de compartilhar o story com eles, verifique os números de segurança ou considere removê-los do seu story. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verificar número de segurança @@ -5824,6 +5820,17 @@ Continuar Mensagens privadas, financiadas por você. Sem anúncios, sem rastreamento, sem vigilância. Faça uma doação agora para apoiar o Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mensal @@ -5891,6 +5898,8 @@ Saiba mais Continuar + + Read more Falha ao carregar o mandato diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index ff172f390e..c3ca5a3a0c 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -643,6 +643,8 @@ %1$s%% até agora… O Signal requer permissão de acesso ao armazenamento externo para criar cópias de segurança, mas esta foi negada permanentemente. Por favor, aceda às definições das aplicações do seu telemóvel, selecione a aplicação Signal e nas \"Permissões\" ative \"Armazenamento\". + + Set backup time @@ -2099,9 +2101,11 @@ Atualização do Signal - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Está disponível uma nova versão do Signal. Toque para atualizar. + Falha ao atualizar o Signal + Tentaremos mais tarde. + Signal successfully updated + You were automatically updated to version %1$s. Enviar mensagem? @@ -2709,24 +2713,13 @@ - Para verificar a encriptação ponta-a-ponta com %1$s, corresponda a carta de cor em cima com o seu dispositivo e compare os números. Se não corresponderem, deslize e experimente o outro par de números de segurança. Só um par precisa de corresponder. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Toque para ler Correspondência bem sucedida Falha o verificar o número de segurança A carregar… Marcar como verificado Limpar verificação - - Os números de segurança estão a ser atualizados. - - - Alterações aos Números de Segurança - - Os números de segurança estão a ser atualizados ao longo de um período de transição para possibilitarem as opções de privacidade do Signal a serem lançadas em breve.\n\nPara verificar os números de segurança, corresponda a carta de cor com o dispositivo do seu contacto. Se não corresponderem, deslize e experimente o outro par de números de segurança. Só um par precisa de corresponder. - - Necessita de ajuda? - - Entendido Leia o código QR no dispositivo do seu contacto. @@ -5581,7 +5574,10 @@ Todos os contactos foram analisados, toque em enviar para continuar. - %1$d dos seus contactos talvez tenham reinstalado o Signal ou mudado de dispositivo. Antes de compartilhar a história com eles, verifique os seus números de segurança ou pondere removê-los da sua história. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verificar número de segurança @@ -5824,6 +5820,17 @@ Continuar Mensagens privadas, financiadas por si. Sem anúncios, sem rastreadores, sem compromisso. Faça um donativo agora para apoiar o Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mensal @@ -5851,8 +5858,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Sair do Signal para confirmar pagamento? + Assim que este pagamento estiver confirmado, regresse ao Signal para finalizar o processamento do seu donativo. @@ -5891,8 +5898,10 @@ Saber mais Continuar + + Read more - Failed to load mandate + Falha ao carregar pedido @@ -5912,13 +5921,13 @@ Doar %1$s - IBAN is too short + IBAN demasiado curto - IBAN is too long + IBAN demasiado longo O código de país do IBAN não é suportado - Invalid IBAN + IBAN inválido @@ -5941,7 +5950,7 @@ Encontrar as suas informações de conta - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Procure o seu IBAN no topo do seu extrato bancário. O IBAN contém até 34 caracteres. O nome que introduzir deve corresponder ao seu nome completo na sua conta bancária. Contacte o seu banco para mais informações. Doação pendente @@ -5957,9 +5966,9 @@ Concluído - Donation couldn\'t be processed + O donativo não pôde ser processado - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Estamos a ter problemas a processar a sua transferência bancária. Não foi cobrado. Tente outro método de pagamento ou contacte o seu banco para mais informações. Tentar novamente @@ -6386,17 +6395,17 @@ Aprovar - Turn on full screen notifications? + Ativar as notificações de ecrã inteiro? - Never miss a call from your contacts and groups. + Nunca perca uma chamada dos seus contactos e grupos. Ativar - Turn on full screen notifications + Ative as notificações de ecrã inteiro - To receive call notifications from your contacts and groups: + Para receber notificações de chamada dos seus contactos e grupos: - 2. %1$s Allow full screen notifications + 2. %1$s Permita notificações de ecrã inteiro diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index bc98128b08..0a2e0fa5a6 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -659,6 +659,8 @@ %1$s%% până acum… Signal necesită permisiunea de acces la stocarea externă pentru a putea crea backup-uri, dar i-a fost refuzat permanent. Te rugăm continuă la setări aplicație, selectează \"Permisiuni\" și activează \"Stocare\". + + Set backup time @@ -2175,6 +2177,8 @@ O nouă versiune de Signal este disponibilă. Apasă pentru actualizare. Signal nu a putut fi actualizat Vom încerca din nou mai târziu. + Signal successfully updated + You were automatically updated to version %1$s. Trimit mesajul? @@ -2796,24 +2800,13 @@ - Pentru a verifica criptarea integrală a conversației tale cu %1$s, potrivește cardul de culoare de mai sus cu dispozitivul său și compară numerele. Dacă nu se potrivesc, glisează și încearcă cealaltă pereche de numere de siguranță. Doar o pereche trebuie să se potrivească. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Atinge pentru a scana Potrivire reușită Verificarea numărului de siguranță a eșuat Se încarcă… Marchează ca verificat Șterge verificarea - - Se actualizează numerele de siguranță. - - - Modificări ale numerelor de siguranță - - Numerele de siguranță sunt actualizate într-o perioadă de tranziție pentru a activa viitoarele funcții de confidențialitate în Signal.\n\nPentru a verifica numerele de siguranță, potrivește cardul de culoare cu dispozitivul persoanei de contact. Dacă nu se potrivesc, glisează și încearcă cealaltă pereche de numere de siguranță. Doar o pereche trebuie să se potrivească. - - Ai nevoie de ajutor? - - Am înțeles Scanează codul QR de pe dispozitivul contactului tău. @@ -5707,7 +5700,11 @@ Toate conexiunile au fost evaluate, atinge trimite pentru a continua. - Ai %1$d conexiuni care este posibil să fi reinstalat Signal sau să fi schimbat dispozitivele. Înainte de a-ți împărtăși povestea cu ei, evaluează numerele de siguranță sau ia în considerare să îi elimini de la povestea ta. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verifică numărul de siguranță @@ -5953,6 +5950,17 @@ Continuă Mesaje private, finanțate de tine. Fără anunțuri, fără sisteme de urmărire. Donează acum ca să susții Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Lunar @@ -6021,6 +6029,8 @@ Află mai multe Continuă + + Read more Nu s-a putut încărca solicitarea diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index fc1bc40e3a..c78704f5b5 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -675,6 +675,8 @@ Уже %1$s%%… Signal требуется разрешение на доступ к хранилищу для создания резервных копий, но оно было вами отклонено. Нажмите «Продолжить», чтобы перейти в настройки приложения, откройте «Разрешения» и включите «Хранилище». + + Set backup time @@ -2248,6 +2250,8 @@ Доступна новая версия Signal. Нажмите, чтобы обновить. Не удалось обновить Signal Мы попробуем ещё раз позже. + Signal successfully updated + You were automatically updated to version %1$s. Отправить сообщение? @@ -2883,24 +2887,13 @@ - Чтобы удостовериться в наличии сквозного шифрования с %1$s, сопоставьте цветную карточку выше с устройством вашего собеседника и сравните цифры. Если они не совпадают, свайпните и попробуйте другую пару кодов безопасности. Как минимум одна пара кодов должна совпадать. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Сканировать Успешное совпадение Не удалось подтвердить код безопасности Загружаем… Отметить как подтверждённый Сбросить подтверждение - - Коды безопасности обновляются. - - - Изменения в кодах безопасности - - Коды безопасности обновляются в течение переходного периода для включения новых функций конфиденциальности в Signal.\n\nЧтобы проверить код безопасности, сравните цветную карточку с устройством вашего собеседника. Если они не совпадают, свайпните и попробуйте другую пару кодов безопасности. Как минимум одна пара кодов должна совпадать. - - Нужна помощь? - - Понятно Просканируйте QR-код на устройстве собеседника. @@ -5833,7 +5826,12 @@ Все контакты были проверены, нажмите «отправить», чтобы продолжить. - У вас есть контакты (%1$d), которые, возможно, переустановили Signal или сменили устройства. Прежде чем поделиться с ними своей историей, просмотрите их коды безопасности или подумайте о том, чтобы удалить их из своей истории. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Подтвердить код безопасности @@ -6082,6 +6080,17 @@ Продолжить Безопасный мессенджер, существующий благодаря вашей поддержке. Без рекламы, без трекеров, без компромиссов. Пожертвуйте сейчас, чтобы поддержать Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Ежемесячно @@ -6151,6 +6160,8 @@ Узнать больше Продолжить + + Read more Не удалось загрузить мандат diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 4da67b49f0..86e9e8d0c6 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -675,6 +675,8 @@ Zatiaľ %1$s%% … Signal potrebuje prístup k úložisku aby mohol vytvárať zálohy, ale prístup bol natrvalo zakázaný. Prosím, v nastaveniach aplikácií zvoľte \"Oprávnenia\" a povoľte \"Úložisko\". + + Set backup time @@ -2248,6 +2250,8 @@ K dispozícii je nová verzia Signalu. Ťuknutím aktualizujte. Signal sa nepodarilo aktualizovať Skúsime to znova neskôr. + Signal successfully updated + You were automatically updated to version %1$s. Odoslať správu? @@ -2883,24 +2887,13 @@ - Ak chcete overiť bezpečnosť end-to-end šifrovania s používateľom %1$s, vyberte na obrazovke vyššie farebnú kartu zhodujúcu sa s ich zariadením a porovnajte zobrazené čísla. Ak sa tieto čísla nezhodujú, swajpnite a skúste ďalší pár bezpečnostných čísel. Musí sa zhodovať iba jeden pár. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Ťuknutím naskenujte Zhoda úspešná Bezpečnostné číslo sa nepodarilo overiť Načítava sa… Označiť ako overené Zrušiť overenie - - Bezpečnostné čísla sa aktualizujú. - - - Zmeny v bezpečnostných číslach - - Aktualizácia bezpečnostných čísel bude prebiehať počas prechodnej fázy, čo umožní zavedenie nových funkcií súkromia pre Signal.\n\nAk chcete overiť bezpečnostné čísla, porovnajte farebnú kartu so zariadením vášho kontaktu. Ak sa nezhodujú, swajpnite a skúste ďalší pár bezpečnostných čísel. Musí sa zhodovať iba jeden pár. - - Potrebujete pomôcť? - - Rozumiem Naskenujte QR kód na zariadení vášho kontaktu. @@ -5833,7 +5826,12 @@ Všetky spojenia boli preverené, pokračujte ťuknutím na tlačidlo „Odoslať“. - %1$d z vašich spojení mohlo(i) preinštalovať Signal alebo zmeniť zariadenia. Skôr než s nimi budete zdieľať príbeh skontrolujte ich bezpečnostné čísla, prípadne zvážte ich odstránenie z vášho príbehu. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Overiť bezpečnostné číslo @@ -6082,6 +6080,17 @@ Pokračovať Súkromné posielanie správ, ktoré financujete vy. Žiadne reklamy, žiadne sledovanie, žiadne kompromisy. Prispejte teraz a podporte Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mesačne @@ -6151,6 +6160,8 @@ Zistiť viac Pokračovať + + Read more Nepodarilo sa načítať príkaz diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 354ac5082d..f525b308c3 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -675,6 +675,8 @@ %1$s%% do zdaj … Dovoljenja za dostop do zunanjega pomnilnika, ki ga aplikacija Signal potrebuje za varnostno kopiranje, je bilo trajno odvzeto. Prosimo, pojdite v sistemski meni z nastavitvami za aplikacije, izberite \"Dovoljenja\" in označite polje \"Zunanja shramba\". + + Set backup time @@ -2248,6 +2250,8 @@ Na voljo je nova različica Signala. Tapnite za posodobitev. Posodobitev Signala ni uspela Znova bomo poskusili pozneje. + Signal successfully updated + You were automatically updated to version %1$s. Pošljem sporočilo? @@ -2883,24 +2887,13 @@ - Če želite preveriti šifriranje od-konca-do-konca z uporabnikom_co %1$s, povežite zgornjo barvno kartico z njegovo/njeno napravo in primerjajte številki. Če se ne ujemata, podrsajte in poskusite z drugim parom varnostnih številk. Samo en par se mora ujemati. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Tapnite za skeniranje Ujemanje potrjeno Varnostnega števila ni bilo mogoče preveriti Nalaganje … Označi kot potrjeno. Izbris potrditeve - - Varnostne številke se posodabljajo. - - - Spremembe varnostnih številk - - Varnostne številke se v prehodnem obdobju posodabljajo, da omogočijo prihajajoče funkcije zasebnosti v Signalu.\n\nČe želite preveriti varnostne številke, uskladite barvno kartico z napravo vašega kontakta. Če se ne ujemata, podrsajte in poskusite z drugim parom varnostnih številk. Samo en par se mora ujemati. - - Potrebujete pomoč? - - Razumem Skenirajte kodo QR na napravi vašega stika. @@ -5833,7 +5826,12 @@ Vse povezave so bile pregledane, tapnite pošlji za nadaljevanje. - Imate %1$d povezav_e, ki so morda znova namestile Signal ali zamenjale napravo. Preden z njimi delite svojo zgodbo, preglejte njihove varnostne številke ali razmislite o njihovi odstranitvi iz ogleda zgodbe. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Preglej varnostno število @@ -6082,6 +6080,17 @@ Nadaljuj Zasebna sporočila, ki jih financirate vi. Brez oglasov, brez sledenja, brez kompromisov. Donirajte in podprite Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Mesečno @@ -6151,6 +6160,8 @@ Preberite več Nadaljuj + + Read more Pooblastila ni bilo mogoče naložiti diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index fce0bbaabf..2f09d8a063 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -643,6 +643,8 @@ %1$s%% deri më tani… Që të mund të krijohen kopjeruajtje, Signal-i lyp leje mbi depozitë të jashtme, por kjo i është mohuar. Ju lutemi, kaloni te rregullime aplikacioni, përzgjidhni \"Leje\" dhe aktivizoni \"Depozitim\". + + Set backup time @@ -2102,6 +2104,8 @@ Një version i ri i Signal është i disponueshëm. Kliko për ta përditësuar. Signal nuk u përditësua Do të provojmë përsëri më vonë. + Signal successfully updated + You were automatically updated to version %1$s. Të dërgohet mesazhi? @@ -2709,24 +2713,13 @@ - Për të verifikuar kodimin nga skaji në skaj me %1$s, përputh kartën e mësipërme të ngjyrave me pajisjen e tyre dhe krahaso numrat. Nëse këto nuk përputhen, shfleto dhe provo çiftin tjetër të numrave të sigurisë. Vetëm një palë duhet të përputhet. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Prekeni që të skanohet Përputhje e suksesshme S\\’u arri të verifikohet numër sigurie Po ngarkohet… Vëri shenjë si i verifikuar Spastroje verifikimin - - Numrat e sigurisë po përditësohen. - - - Ndryshimet në numrat e sigurisë - - Numrat e sigurisë po përditësohen gjatë një periudhe tranzicioni për të aktivizuar veçoritë e ardhshme të privatësisë në Signal.\n\nPër të verifikuar numrat e sigurisë, përputh kartën e ngjyrave me pajisjen e kontaktit tënd. Nëse këto nuk përputhen, shfleto dhe provo çiftin tjetër të numrave të sigurisë. Vetëm një palë duhet të përputhet. - - Ju duhet ndihmë? - - E kuptova Skanoni kodin QR te pajisja e kontaktit tuaj. @@ -5581,7 +5574,10 @@ Të gjitha kontaktet janë shqyrtuar; kliko dërgo për të vazhduar. - Ke %1$d kontakte që mund të kenë instaluar sërish Signal ose të kenë ndryshuar pajisje. Para se të shpërndash postimin e përkohshëm me ta, rishiko numrat e tyre të sigurisë ose shih mundësinë e heqjes së tyre nga postimi i përkohshëm. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verifiko numër siguri @@ -5824,6 +5820,17 @@ Vazhdo Mesazhe private, financuar nga ti. Pa reklama, pa gjurmim, pa kompromise. Dhuro tani për të mbështetur Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + I përmuajshëm @@ -5891,6 +5898,8 @@ Mëso më shumë Vazhdo + + Read more Ngarkimi i mandatit dështoi diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index a1d3f82d9d..19cc24f99d 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -643,6 +643,8 @@ %1$s%% за сада… Апликација Signal захтева дозволу спољној меморији да би правила резервне копије, али је трајно одбијено. Наставите до подешавања апликације, одаберите „Дозволе“ и омогућите ставку „Меморија“. + + Set backup time @@ -2102,6 +2104,8 @@ Доступна је нова верзија Signal-а. Додирните да ажурирате. Ажурирање Signal-а није успело Пробаћемо поново касније. + Signal successfully updated + You were automatically updated to version %1$s. Да пошаљем поруку? @@ -2709,24 +2713,13 @@ - Ради верификације end-to-end шифровања са контактом %1$s, повежите картицу у боји с његовим уређајем и упоредите бројеве. Ако се не повежу, превуците и покушајте с другим паром безбедносних бројева. Довољно је да се повеже један пар. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Тапните за скенирање Успешно подударање Сигурносни број није оверен Учитавање… Означи као проверено Уклони оверу - - Безбедносни бројеви се ажурирају. - - - Промена у безбедносне бројеве - - Током прелазног периода ажурирају се безбедносни бројеви, како би се омогућиле будуће опције за приватност на платформи Signal.\n\nРади верификације безбедносних бројева, повежите картицу у боји са уређајем свог контакта. Ако се не повежу, превуците и покушајте с другим паром безбедносних бројева. Довољно је да се повеже један пар. - - Потребна вам је помоћ? - - Разумем Скенирајте QR кôд приказан на уређају вашег контакта. @@ -5581,7 +5574,10 @@ Sve veze su pregledane, dodirnite „Pošalji“ da nastavite. - Њих %1$d је можда поново инсталирало Signal или променило уређај. Пре него што поделите причу са тим везама, прегледајте њихове сигурносне бројеве или размислите о томе да их уклоните из приче. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Овери безбедносни број @@ -5824,6 +5820,17 @@ Nastavi Приватно дописивање које ви финансирате. Без огласа, без праћења, без компромиса. Донирајте сада да подржите Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Месечно @@ -5891,6 +5898,8 @@ Сазнајте више Настави + + Read more Учитавање захтева није успело diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 7f172b2f96..3f58b0ae91 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -643,6 +643,8 @@ %1$s%% hittills… Signal behöver behörigheten Lagring för att skapa säkerhetskopior men den har avfärdats permanent. Fortsätt till inställningar för appar, välj \"Behörigheter\" och aktivera \"Lagring\". + + Set backup time @@ -2102,6 +2104,8 @@ En ny version av Signal är tillgänglig. Tryck för att uppdatera. Det gick inte att uppdatera Signal Vi försöker igen senare. + Signal successfully updated + You were automatically updated to version %1$s. Skicka meddelande? @@ -2709,24 +2713,13 @@ - För att verifiera totalsträckskryptering med %1$s, matcha färgkortet ovan med deras enhet och jämför siffrorna. Om dessa inte matchar, svep och prova det andra paret av säkerhetsnummer. Endast ett par behöver matcha. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Tryck för att skanna Lyckad matchning Det gick inte att verifiera säkerhetsnumret Hämtar in… Markera som verifierat Rensa verifiering - - Säkerhetsnummer uppdateras. - - - Ändringar av säkerhetsnummer - - Säkerhetsnummer uppdateras under en övergångsperiod för att möjliggöra kommande sekretessfunktioner i Signal.\n\nFör att verifiera säkerhetsnummer, matcha färgkortet med din kontakts enhet. Om dessa inte matchar, svep och prova det andra paret av säkerhetsnummer. Endast ett par behöver matcha. - - Behöver du hjälp? - - Uppfattat Skanna QR-koden på din kontakts enhet. @@ -5581,7 +5574,10 @@ Alla förbindelser har granskats. Klicka på skicka för att fortsätta. - Du har %1$d förbindelser som kan ha ominstallerat Signal eller bytt enheter. Granska deras säkerhetsnummer eller ta bort dem från din story innan du delar den. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Verifiera säkerhetsnummer @@ -5824,6 +5820,17 @@ Fortsätt Privata meddelanden, finansierade av dig. Inga annonser, ingen spårning, ingen kompromiss. Donera nu för att stödja Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Månatlig @@ -5891,6 +5898,8 @@ Läs mer Fortsätt + + Read more Det gick inte att ladda begäran diff --git a/app/src/main/res/values-sw/strings.xml b/app/src/main/res/values-sw/strings.xml index 3f20767c76..d5689c94cc 100644 --- a/app/src/main/res/values-sw/strings.xml +++ b/app/src/main/res/values-sw/strings.xml @@ -643,6 +643,8 @@ %1$s%% hadi sasa … Signal inahitaji idhini ya hifadhi ya nje ili kuunda nakalahifadhi, lakini imekataliwa kabisa. Tafadhali enda kwenye mipangilio ya programu, chagua \"Ruhusa\" na uwezeshe \"Hifadhi\". + + Set backup time @@ -2102,6 +2104,8 @@ Toleo jipya la Signal linapatikana. Gusa ili kusasisha. Signal imeshindwa kusasisha Tutajaribu tena baadae. + Signal successfully updated + You were automatically updated to version %1$s. Tuma ujumbe? @@ -2709,24 +2713,13 @@ - Ili kuthibitisha usimbaji fiche wa mwanzo hadi mwisho kwa %1$s, linganisha kadi ya rangi iliyo hapo juu na kifaa chake na ulinganishe nambari. Kama hivi visipolingana, telezesha na ujaribu jozi nyingine ya nambari ya usalama. Jozi moja tu inahitaji kulingana. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Gusa kuskani Match imeendana Imeshindwa kuthibitisha nambari ya usalama. Inapakia Weka alama kuwa imedhibitishwa Futa uthibitishwaji - - Nambari za usalama zinasasishwa. - - - Mabadiliko kwa nambari ya usalama - - Nambari za usalama zinasasishwa katika kipindi cha mpito ili kuwezesha vipengele vya faragha vijavyo katika Signal.\n\nIli kuthibitisha nambari za usalama, linganisha kadi ya rangi na kifaa cha muwasiliani wako. Kama hivi visipolingana, telezesha na ujaribu jozi nyingine ya nambari ya usalama. Jozi moja tu inahitaji kulingana. - - Unahitaji usaidizi? - - Nimeelewa Skani msimbo wa QR uliopo kwenye kifaa cha mwasiliani wako. @@ -5581,7 +5574,10 @@ Miungano yote imehakikishwa, bonyeza tuma kuendelea. - Una connections %1$d ambao huenda wamesakinisha upya Signal au kubadili vifaa. Kabla ya kushiriki stori yako nao, kagua nambari yao ya usalama au fikiria kuhusu kuwaondoa kwenye stori yako. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Thibitisha nambari salama @@ -5824,6 +5820,17 @@ Endelea Utumaji jumbe wa faragha, uliofadhiliwa na wewe. Hakuna matangazo, hakuna kufuatilia, hakuna kuenda dhidi ya maelewano. Changia sasa kuiunga mkono Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Kila mwezi @@ -5891,6 +5898,8 @@ Jifunze zaidi Endelea + + Read more Imeshindwa kupakua jukumu diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 29183687a6..27a0b6464c 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -643,6 +643,8 @@ இதுவரை %1$s%%… காப்புப்பிரதிகளை உருவாக்க Signal கு வெளிப்புற சேமிப்பக அனுமதி தேவைப்படுகிறது, ஆனால் அது நிரந்தரமாக மறுக்கப்பட்டது. பயன்பாடு அமைப்புகளைத் தொடரவும், \"அனுமதிகள்\" என்பதைத் தேர்ந்தெடுத்து \"சேமிப்பகத்தை\" இயக்கவும். + + Set backup time @@ -2102,6 +2104,8 @@ Signal இன் புதிய பதிப்பு கிடைக்கப்பெறுகிறது. புதுப்பிக்க அழுத்தவும். Signalஐப் புதுப்பிக்க முடியவில்லை பின்னர் மீண்டும் முயல்வோம். + Signal successfully updated + You were automatically updated to version %1$s. செய்தி அனுப்ப? @@ -2709,24 +2713,13 @@ - %1$s இன் எண்ட்-டு-எண்ட் என்க்ரிப்ஷனைச் சரிபார்க்க, மேலே உள்ள வண்ண அட்டையை அவற்றின் டிவைஸ் உடன் பொருத்தி எண்களை ஒப்பிடவும். இவை பொருந்தவில்லை என்றால், ஸ்வைப் செய்து மற்ற பாதுகாப்பு எண்கள் ஜோடியை முயற்சிக்கவும். ஒரு ஜோடி மட்டுமே பொருந்த வேண்டும். + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. ஸ்கேன் செய்ய தட்டவும் வெற்றிகரமான இணை பாதுகாப்பு எண்ணைச் சரிபார்க்கத் தவறியது ஏற்றுதல் … சரிபார்க்கப்பட்டதாகக் குறிக்கவும் சரிபார்ப்பை நீக்கவும் - - பாதுகாப்பு எண்கள் புதுப்பிக்கப்படுகின்றன. - - - பாதுகாப்பு எண்களில் செய்யப்படும் மாற்றங்கள் - - Signal இல் வரவிருக்கும் தனியுரிமை அம்சங்களை இயக்க, பாதுகாப்பு எண்கள் குறிப்பிட்ட நிலை மாற்றப்படும் காலத்தில் புதுப்பிக்கப்படவுள்ளன.\n\nபாதுகாப்பு எண்களைச் சரிபார்க்க, உங்கள் தொடர்பின் டிவைஸ் உடன் வண்ண அட்டையைப் பொருத்தவும். இவை பொருந்தவில்லை என்றால், ஸ்வைப் செய்து மற்ற பாதுகாப்பு எண்கள் ஜோடியை முயற்சிக்கவும். ஒரு ஜோடி மட்டுமே பொருந்த வேண்டும். - - உங்களுக்கு உதவி வேண்டுமா? - - அறிந்துகொண்டேன் உங்கள் தொடர்பு சாதனத்தில் QR குறியீட்டை ஸ்கேன் செய்யுங்கள். @@ -5581,7 +5574,10 @@ அனைத்து இணைப்புகளும் மதிப்பாய்வு செய்யப்பட்டுள்ளன, தொடர அனுப்பு என்பதைத் தட்டவும். - சிக்னலை மீண்டும் நிறுவிய அல்லது டிவைஸ்களை மாற்றிய %1$d இணைப்புகள் உங்களிடம் உள்ளன. உங்கள் ஸ்டோரியை அவர்களுடன் பகிர்ந்து கொள்வதற்கு முன் அவர்களது பாதுகாப்பு எண்களை மதிப்பாய்வு செய்யவும் அல்லது உங்கள் ஸ்டோரியிலிருந்து அவர்களை அகற்றவும். + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + பாதுகாப்பு எண்ணைச் சரிபார்க்கவும் @@ -5824,6 +5820,17 @@ தொடரவும் உங்களால் நிதியளிக்கப்பட்ட தனிப்பட்ட செய்தியிடல். விளம்பரங்கள் இல்லை, கண்காணிப்பு இல்லை, சமரசம் இல்லை. Signalஐ ஆதரிக்க இப்போதே நன்கொடை அளியுங்கள். + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + மாதாந்திரமாக @@ -5891,6 +5898,8 @@ மேலும் அறிக தொடர்க + + Read more ஆணையை ஏற்ற இயலவில்லை diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 8667129bdc..d4b24461de 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -643,6 +643,8 @@ %1$s%% ఇప్పటి వరకు… ప్రత్యామ్నాయను సృష్టించడానికి Signal బాహ్య నిల్వ అనుమతి అవసరం, కానీ ఇది శాశ్వతంగా తిరస్కరించబడింది. దయచేసి అనువర్తనం సెట్టింగ్లకు కొనసాగించండి, \"అనుమతులు\" ఎంచుకుని, \"నిల్వ\" ను ప్రారంభించండి. + + Set backup time @@ -2102,6 +2104,8 @@ Signal యొక్క కొత్త వెర్షన్ అందుబాటులో ఉంది. అప్‌డేట్ చేయడానికి తట్టండి. అప్‌డేట్ చేసేందుకు Signal విఫలమైంది మేము తర్వాత మళ్ళీ ప్రయత్నిస్తాము. + Signal successfully updated + You were automatically updated to version %1$s. సందేశం పంపాల? @@ -2709,24 +2713,13 @@ - %1$s‌తో పూర్తి స్థాయి ఎన్‌క్రిప్షన్‌ను ధృవీకరించడానికి, పైన ఉన్న రంగు కార్డును వారి పరికరంతో మ్యాచ్ చేయండి మరియు సంఖ్యలను పోల్చండి. ఒకవేళ ఇవి మ్యాచ్ కాకపోతే, భద్రతా సంఖ్యల మరో జతను స్వైప్ చేసి ప్రయత్నించండి. కేవలం ఒక జత మాత్రమే మ్యాచ్ కావాలి. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. స్కాన్ నొక్కండి విజయవంతంగా మ్యాచ్ అయింది భద్రతా సంఖ్యను ధృవీకరించడం విఫలమైంది లోడ్… ధృవీకరించినట్లు గుర్తించండి ధృవీకరణను క్లియర్ చేయండి - - భద్రతా సంఖ్యలు అప్‌డేట్ చేయబడుతున్నాయి. - - - భద్రతా సంఖ్యలకు మార్పులు - - Signal లో రాబోయే గోప్యతా విలక్షణతలను ప్రారంభించడానికి పరివర్తన వ్యవధిలో భద్రతా సంఖ్యలు అప్‌డేట్ చేయబడుతున్నాయి.\n\nభద్రతా సంఖ్యలను ధృవీకరించడానికి, మీ కాంటాక్ట్ యొక్క పరికరంతో రంగు కార్డును మ్యాచ్ చేయండి. ఒకవేళ ఇవి మ్యాచ్ కాకపోతే, భద్రతా సంఖ్యల మరో జతను స్వైప్ చేసి ప్రయత్నించండి. కేవలం ఒక జత మాత్రమే మ్యాచ్ కావాలి. - - సాయం అవసరమా? - - అర్థమైంది మీ సంప్రదింపు పరికరంలో QR కోడ్‌ను స్కాన్ చేయండి. @@ -5581,7 +5574,10 @@ అన్ని కనెక్షన్‌లు సమీక్షించబడ్డాయి, కొనసాగడానికి పంపండి మీద తట్టండి. - Signal ను తిరిగి ఇన్‌స్టాల్ చేసిన లేదా పరికరాలను మార్చిన %1$d కనెక్షన్స్ మీకు ఉన్నాయి. వారితో మీ స్టోరీను పంచుకోవడానికి ముందు వారి భద్రతా సంఖ్యలను సమీక్షించండి లేదా వారిని మీ స్టోరీ నుంచి తొలగించడానికి పరిగణించండి. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + భద్రత సంఖ్యను ధృవీకరించండి @@ -5824,6 +5820,17 @@ కొనసాగు మీ ద్వారా నిధులు సమకూర్చబడిన ప్రైవేట్ సందేశం పంపడం. ప్రకటనలు లేవు, ట్రాకింగ్ లేదు, రాజీ లేదు. Signal కు మద్దతు ఇవ్వడానికి ఇప్పుడే విరాళం ఇవ్వండి. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + నెలవారీ @@ -5891,6 +5898,8 @@ మరింత తెలుసుకోండి కొనసాగండి + + Read more ఆదేశాన్ని లోడ్ చేసేందుకు విఫలమైంది diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 45e7112a97..cb102b13c9 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -627,6 +627,8 @@ %1$s%% ในตอนนี้… เพื่อที่จะสำรองข้อมูล Signal ต้องได้รับอนุญาตให้เข้าถึงที่เก็บข้อมูลภายนอก แต่คำขอนั้นถูกปฏิเสธอย่างถาวร กรุณาไปที่เมนูตั้งค่าแอป เลือก \"การอนุญาต\" และเปิดใช้งาน \"ที่เก็บข้อมูล\" + + Set backup time @@ -2029,6 +2031,8 @@ Signal เวอร์ชันใหม่พร้อมให้บริการแล้ว แตะเพื่ออัปเดต อัปเดต Signal ไม่สำเร็จ เราจะลองใหม่อีกครั้งในภายหลัง + Signal successfully updated + You were automatically updated to version %1$s. ส่งข้อความหรือไม่? @@ -2622,24 +2626,13 @@ - เพื่อยืนยันว่าการติดต่อสื่อสารกับ %1$s ถูกเข้ารหัสตั้งแต่ต้นทางถึงปลายทาง ให้ตรวจสอบแถบสีด้านบนนี้กับแถบสีบนอุปกรณ์ของคนคนนั้น พร้อมเปรียบเทียบหมายเลขที่แสดงว่าตรงกันหรือไม่ หากข้อมูลไม่ตรงกัน ให้ปัดหน้าจอ แล้วลองจับคู่หมายเลขความปลอดภัยใหม่ การตรวจสอบหมายเลขความปลอดภัยให้ตรงกันได้หนึ่งคู่นั้นเพียงพอแล้ว + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. แตะเพื่อสแกน จับคู่สำเร็จ การตรวจยืนยันหมายเลขความปลอดภัยล้มเหลว กำลังโหลด… ทำเครื่องหมายว่าตรวจยืนยันแล้ว ล้างการตรวจยืนยัน - - กำลังอัปเดตหมายเลขความปลอดภัย - - - การเปลี่ยนแปลงเกี่ยวกับหมายเลขความปลอดภัย - - กำลังอัปเดตหมายเลขความปลอดภัยเพื่อให้พร้อมรองรับการใช้งานฟีเจอร์ด้านความเป็นส่วนตัวใหม่ๆ ของ Signal\n\nเพื่อยืนยันหมายเลขความปลอดภัย ให้ตรวจสอบแถบสีบนอุปกรณ์ของคุณกับแถบสีบนอุปกรณ์ของผู้ติดต่อว่าตรงกันหรือไม่ หากข้อมูลไม่ตรงกัน ให้ปัดหน้าจอ แล้วลองจับคู่หมายเลขความปลอดภัยใหม่ การตรวจสอบหมายเลขความปลอดภัยให้ตรงกันได้หนึ่งคู่นั้นเพียงพอแล้ว - - ต้องการความช่วยเหลือหรือไม่? - - เข้าใจแล้ว สแกนรหัส QR บนอุปกรณ์ของผู้ติดต่อของคุณ @@ -5455,7 +5448,9 @@ ตรวจสอบผู้ติดต่อทั้งหมดแล้ว แตะส่งเพื่อดำเนินการต่อ - คุณมีเครือข่าย %1$d คน ที่อาจติดตั้ง Signal ใหม่หรือเปลี่ยนอุปกรณ์ ก่อนที่จะแชร์สตอรี่กับเครือข่ายคนดังกล่าว ลองตรวจสอบหมายเลขความปลอดภัยหรือลบเครือข่ายคนนั้นออกจากสตอรี่ของคุณ + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + ตรวจยืนยันหมายเลขความปลอดภัย @@ -5695,6 +5690,17 @@ ดำเนินการต่อ ส่งข้อความอย่างเป็นส่วนตัว เป็นไปได้ด้วยทุนสนับสนุนจากคุณ ไม่มีโฆษณา ไม่มีการติดตาม ไม่มีทางเปลี่ยนแปลง บริจาควันนี้เพื่อร่วมสนับสนุน Signal + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + รายเดือน @@ -5761,6 +5767,8 @@ เรียนรู้เพิ่มเติม ดำเนินการต่อ + + Read more โหลดคำขอไม่สำเร็จ diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index dea3e3d4e4..46b4b5dc71 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -643,6 +643,8 @@ %1$s%% so far… Kailangan ng Signal ng pahintulot sa paggamit ng panlabas na storage upang makalikha ng mga backup, ngunit ito ay permanenteng ipinagbabawal. Pumunta sa app settings, piliin ang \"Pahintulot\", at i-enable ang \"Storage\". + + Set backup time @@ -2099,9 +2101,11 @@ Update sa Signal - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Available na ang bagong version ng Signal. I-tap para mag-update. + Failed ang pag-update ng Signal + Susubukan ulit namin ito mamaya. + Signal successfully updated + You were automatically updated to version %1$s. Ipadala ang mensahe? @@ -2709,24 +2713,13 @@ - Para i-verify ang end-to-end encryption n\'yo ni %1$s, i-match ang color card na nasa itaas ng device n\'ya at pagkumparahin ang numbers. Kung hindi magkapareho ang mga ito, subukan ang ibang pares ng safety numbers. Isang pares lang ang kailangan mag-match. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Pindutin para mag-scan Successful match Failed to verify safety number Naglo-load… Mark as verified Clear verification - - Ina-update ang safety numbers. - - - Mga Pagbabago sa safety numbers - - Ina-update ang safety numbers sa loob ng transition period para ma-enable ang upcoming privacy features sa Signal.\n\nPara i-verify ang safety numbers, i-match ang color card sa device ng contact mo. Kung hindi magkapareho ang mga ito, subukan ang ibang pares ng safety numbers. Isang pares lang ang kailangan mag-match. - - Kailangan mo ba ng tulong? - - OK I-scan ang QR Code sa device ng iyong kontak. @@ -5581,7 +5574,10 @@ Na-review na ang lahat ng connections, i-tap ang send para magpatuloy. - Mayroon kang %1$d connections na maaaring nag-reinstall ng Signal o nagpalit ng device. Reviewhin muna ang kanilang safety numbers bago mo i-share sa kanila ang story mo. Maaari mo rin silang tanggalin sa story mo. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Beripikahin ang numerong pangkaligtasan @@ -5824,6 +5820,17 @@ Magpatuloy Private messaging na suportado mo. Walang ads, walang tracking, walang kompromiso. Mag-donate ngayon para suportahan ang Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Monthly @@ -5851,8 +5858,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Gusto mo bang umalis sa Signal para kumpirmahin ang payment? + Kapag confirmed na ang payment, bumalik sa Signal para tapusin ang pag-process ng donation mo. @@ -5891,8 +5898,10 @@ Matuto pa Magpatuloy + + Read more - Failed to load mandate + Failed ang pag-load ng request @@ -5912,13 +5921,13 @@ Mag-donate %1$s - IBAN is too short + Masyadong maikli ang IBAN - IBAN is too long + Masyadong mahaba ang IBAN Hindi suportado ang IBAN country code - Invalid IBAN + Invalid ang IBAN @@ -5941,7 +5950,7 @@ Hanapin ang iyong account information - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Hanapin ang iyong IBAN sa itaas ng iyong bank statement. Naglalaman ang IBAN ng hanggang 34 characters. Magkapareho dapat ang pangalang inilagay mo at ang buong pangalan mo sa iyong bank account. Tawagan ang iyong bangko para sa karagdagang impormasyon. Pending ang donation @@ -5957,9 +5966,9 @@ Done - Donation couldn\'t be processed + Hindi ma-process ang donation mo - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Nagkaroon kami ng problema sa pag-process ng iyong bank transfer. Hindi ka na-charge dito. Subukan ang iba pang payment method o tawagan ang iyong bangko para sa karagdagang impormasyon. Subukang muli @@ -6386,17 +6395,17 @@ Approve - Turn on full screen notifications? + Gusto mo bang i-on ang full screen notifications? - Never miss a call from your contacts and groups. + \'Wag palampasin ang mga tawag ng contacts at groups mo. I-on - Turn on full screen notifications + I-on ang full screen notifications - To receive call notifications from your contacts and groups: + Para makatanggap ng call notifications mula sa iyong contacts at groups: - 2. %1$s Allow full screen notifications + 2. %1$s I-allow ang full screen notifications diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index f0eb9cd719..8190d3c3d9 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -643,6 +643,8 @@ Şu ana kadar %1$s%% … Signal, yedek oluşturabilmek için Depolama iznine ihtiyaç duyar, fakat bu izin kalıcı olarak reddedilmiş. Lütfen uygulama ayarları menüsüne girip \"İzinler\" kısmını seçin, ve \"Depolama\"yı etkinleştirin. + + Set backup time @@ -2099,9 +2101,11 @@ Signal güncellemesi - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Signal\'in yeni bir sürümü mevcut. Güncellemek için dokun. + Signal güncellenemedi + Daha sonra tekrar deneyeceğiz. + Signal successfully updated + You were automatically updated to version %1$s. İleti gönderilsin mi? @@ -2709,24 +2713,13 @@ - %1$s ile uçtan uca şifrelemeyi doğrulamak için yukarıdaki renk kartını cihazlarıyla eşleştir ve sayılarıyla karşılaştır. Bunlar eşleşmezse kaydır ve diğer güvenlik numarası çiftini dene. Yalnızca bir çiftin eşleşmesi gereklidir. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Taramak için dokunun Doğru eşleşme Güvenlik numarası doğrulanamadı Yükleniyor… Doğrulanmış olarak işaretle Doğrulamayı temizle - - Güvenlik numaraları güncelleniyor. - - - Güvenlik Numaralarındaki Değişiklikler - - Güvenlik numaraları, Signal\'de yakında kullanıma sunulacak olan gizlilik özelliklerini etkinleştirmek için bir geçiş döneminde güncellenmektedir.\n\nGüvenlik numaralarını doğrulamak için renk kartını kişinin cihazıyla eşleştir. Bunlar eşleşmezse kaydır ve diğer güvenlik numarası çiftini dene. Yalnızca bir çiftin eşleşmesi gereklidir. - - Yardıma mı ihtiyacınız var? - - Anladım Kişinizin cihazındaki karekodu tarayın. @@ -5581,7 +5574,10 @@ Tüm bağlantılar gözden geçirildi, devam etmek için gönder butonuna dokun. - Signal\'i yeniden yüklemiş veya cihazlarını değiştirmiş olabilecek %1$d bağlantın var. Hikayeni onlarla paylaşmadan önce güvenlik numaralarını gözden geçirebilir veya bu kişileri hikayenden çıkarmayı göz önünde bulundurabilirsin. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Güvenlik numarasını doğrulayın @@ -5824,6 +5820,17 @@ Devam Et Senin tarafından desteklenen, gizli mesajlaşma. Reklam yok, takip yok, taviz yok. Signal\'i desteklemek için şimdi bağış yap. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Aylık @@ -5851,8 +5858,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Ödemeyi onaylamak için Signal\'den ayrılmak istiyor musun? + Bu ödeme onaylandıktan sonra, bağışının işlenmesini tamamlamak için Signal\'e dön. @@ -5891,8 +5898,10 @@ Daha fazlasını öğren Devam et + + Read more - Failed to load mandate + Talimat yüklenemedi @@ -5912,13 +5921,13 @@ %1$s bağış yap - IBAN is too short + IBAN çok kısa - IBAN is too long + IBAN çok uzun IBAN ülke kodu desteklenmiyor - Invalid IBAN + Geçersiz IBAN @@ -5941,7 +5950,7 @@ Hesap bilgilerini bul - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + Banka ekstrenin üst kısmında IBAN numaranı ara. IBAN numaraları en fazla 34 karakterden oluşur. Girdiğin ad, banka hesabındaki tam adınla eşleşmelidir. Daha fazla bilgi için bankanla iletişime geçebilirsin. Bağış bekleniyor @@ -5957,9 +5966,9 @@ Tamam - Donation couldn\'t be processed + Bağış işlenemedi - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + Banka transferini işleme alırken sorun yaşıyoruz. Ödemen alınamadı. Başka bir ödeme yöntemi dene veya daha fazla bilgi için bankanla iletişime geç. Tekrar dene @@ -6386,17 +6395,17 @@ Onayla - Turn on full screen notifications? + Tam ekran bildirimleri açılsın mı? - Never miss a call from your contacts and groups. + Kişilerinden ve gruplarından gelen hiçbir aramayı kaçırma. - Turn on full screen notifications + Tam ekran bildirimlerini aç - To receive call notifications from your contacts and groups: + Kişilerinden ve gruplarından arama bildirimleri almak için: - 2. %1$s Allow full screen notifications + 2. %1$s Tam ekran bildirimlerine izin ver diff --git a/app/src/main/res/values-ug/strings.xml b/app/src/main/res/values-ug/strings.xml index 8b1472c17a..a6d98a702d 100644 --- a/app/src/main/res/values-ug/strings.xml +++ b/app/src/main/res/values-ug/strings.xml @@ -627,6 +627,8 @@ %1$s تاماملاندى… زاپاسلاشنى قۇرۇش ئۈچۈن Signal سىرتقى ساقلىغۇچ ھوقۇقىنى تەلەپ قىلىدۇ، ئەمما ئۇ مەڭگۈلۈك رەت قىلىندى. ئەپ تەڭشەكلىرىگە بېرىڭ، «ھوقۇقلار» نى تاللاڭ ۋە «ساقلىغۇچ» نى قوزغىتىڭ. + + Set backup time @@ -2026,9 +2028,11 @@ Signal يېڭىلاش - A new version of Signal is available. Tap to update. - Signal failed to update - We will try again later. + Signal نىڭ يېڭى نۇسخىسى بار. چېكىپ يېڭىلاڭ. + Signal نى يېڭىلىغىلى بولمىدى + كېيىنرەك قايتا سىناپ باقىمىز. + Signal successfully updated + You were automatically updated to version %1$s. ئۇچۇر ئەۋەتەمسىز؟ @@ -2622,24 +2626,13 @@ - %1$s بىلەن بولغان ئىككى نۇقتا ئارىسىدىكى مەخپىيلەشتۈرۈشنى دەلىللەش ئۈچۈن، ئۇلارنىڭ ئۈسكۈنىسىدە كۆرسىتىلگەن رەڭ كارتىلىرى ۋە نومۇرلارنى سېلىشتۇرۇڭ. ئەگەر ئۇلار ماس كەلمىسە، سىيرىپ باشقا بىر جۈپ بىخەتەرلىك نومۇرىنى سىناپ بېقىڭ. پەقەت بىر جۈپ ماس كەلسىلا بولىدۇ. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. چېكىلسە تارايدۇ ئوڭۇشلۇق ماسلاشتى بىخەتەرلىك نومۇرىنى دەلىللىيەلمىدى قاچىلىنىۋاتىدۇ… دەلىللەندى بەلگىسى سال دەلىللەشنى تازىلا - - بىخەتەرلىك نومۇرى يېڭىلىنىۋاتىدۇ. - - - بىخەتەرلىك نومۇرىنى ئۆزگەرتىش - - Signal دىكى يېڭى مەخپىيەتلىك ئىقتىدارلىرىنى قوزغىتىش ئۈچۈن بىخەتەرلىك نومۇرى بۇ ئۆتكۈنچى مەزگىلدە يېڭىلىنىپ بارىدۇ.\n\nبىخەتەرلىك نومۇرىنى دەلىللەش ئۈچۈن، ئالاقىدىشىڭىزنىڭ ئۈسكۈنىسىدىكى رەڭ كارتىلىرىنى ماسلاشتۇرۇڭ. ئەگەر بۇلار ماس كەلمىسە، باشقا بىر جۈپ بىخەتەرلىك نومۇرىنى سىناپ بېقىڭ. پەقەت بىر جۈپ ماس كەلسىلا بولىدۇ. - - ياردەم كېرەكمۇ؟ - - بىلدىم ئالاقەداشىڭىزنىڭ ئۈسكۈنىسىدىكى QR كودىنى تاراڭ. @@ -5455,7 +5448,9 @@ بارلىق ئالاقىداشلار تەكشۈرۈلدى. داۋاملاشتۇرۇش ئۈچۈن يوللاشنى چېكىڭ. - %1$d ئالاقىدىشىڭىز Signal نى قايتا قاچىلىغان ياكى ئۈسكۈنىسىنى ئۆزگەرتكەن بولۇشى مۇمكىن. ئۇلار بىلەن ھېكايىڭىزنى ئورتاقلىشىشتىن بۇرۇن ئۇلارنىڭ بىخەتەرلىك نومۇرىنى تەكشۈرۈپ كۆرۈڭ ياكى ئۇلارنى ھېكايىڭىزدىن چىقىرىۋېتىشنى ئويلىشىپ كۆرۈڭ. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + بىخەتەرلىك نومۇر دەلىللە @@ -5695,6 +5690,17 @@ داۋاملاشتۇر بىخەتەر ئۇچۇرلىشىش - سىزنىڭ ياردىمىڭىزدە. ئېلان ۋە ئىز قوغلاشقا ھېچقانداق يول يوق. Signal نى قوللاش ئۈچۈن ئىئانە قىلىڭ. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + ئايلىق @@ -5721,8 +5727,8 @@ iDEAL - Leave Signal to confirm payment? - Once this payment is confirmed, return to Signal to finish processing your donation. + Signal دىن چىقىپ پۇل تۆلەشنى جەزملەشتۈرەمسىز؟ + بۇ پۇل تۆلەش جەزملەشتۈرۈلگەندىن كېيىن Signal غا قايتىپ ئىئانىڭىزنى بىر تەرەپ قىلىشنى داۋاملاشتۇرۇڭ. @@ -5761,8 +5767,10 @@ تەپسىلاتى داۋاملاشتۇرۇش + + Read more - Failed to load mandate + تەلەپنى يۈكلىيەلمىدى @@ -5782,13 +5790,13 @@ %1$s ئىئانە قىلىش - IBAN is too short + IBAN بەك قىسقا - IBAN is too long + IBAN بەك ئۇزۇن IBAN دۆلەت كودىنى قوللىمايدۇ - Invalid IBAN + IBAN نومۇرى ئىناۋەتسىز @@ -5811,7 +5819,7 @@ ھېسابات ئۇچۇرلىرىڭىزنى ئىزدەش - Look for your IBAN at the top of your bank statement. IBANs contain up to 34 characters. The name you enter should match your full name on your bank account. Contact your bank for more information. + IBAN نومۇرىڭىز بانكا تالونىڭىزنىڭ ئۈستۈنكى قىسىمىدا بولىدۇ. IBAN نومۇرى كۆپ بولغاندا 34 ھەرىپ-بەلگە بولىدۇ. سىز كىرگۈزگەن ئىسىم بانكا ھېساباتىڭىزدىكى تولۇق ئىسمىڭىز بىلەن بىردەك بولۇشى كېرەك. تېخىمۇ كۆپ ئۇچۇر ئۈچۈن بانكا بىلەن ئالاقىلىشىڭ. ئىئانىنى بىر تەرەپ قىلىۋاتىدۇ @@ -5827,9 +5835,9 @@ تامام - Donation couldn\'t be processed + ئىئانىنى بىر تەرەپ قىلالمىدى - We\'re having trouble processing your bank transfer. You have not been charged. Try another payment method or contact your bank for more information. + بانكىدىن يۆتكىگەن پۇلنى بىر تەرەپ قىلىشتا مەسىلە كۆرۈلدى. سىزدىن پۇل تۇتۇلمىدى. باشقا پۇل تۆلەش ئۇسۇلىنى سىناپ بېقىڭ ياكى تەپسىلاتى ئۈچۈن بانكا بىلەن ئالاقىلىشىڭ. قايتا سىناڭ @@ -6250,17 +6258,17 @@ تەستىقلا - Turn on full screen notifications? + پۈتۈن ئېكران ئۇقتۇرۇشىنى ئاچامسىز؟ - Never miss a call from your contacts and groups. + ئالاقىداش ۋە گۇرۇپپىلاردىن كەلگەن چاقىرىقنى ئۆتكۈزىۋەتمەيسىز. ئېچىش - Turn on full screen notifications + پۈتۈن ئېكران ئۇقتۇرۇشىنى ئېچىش - To receive call notifications from your contacts and groups: + ئالاقىداش ۋە گۇرۇپپىلاردىن چاقىرىق ئۇقتۇرۇشلىرىنى تاپشۇرۇۋېلىش ئۈچۈن: - 2. %1$s Allow full screen notifications + 2. %1$s پۈتۈن ئېكران ئۇقتۇرۇشىغا رۇخسەت قىلىڭ diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index c1e144c3bd..72ad91378a 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -675,6 +675,8 @@ %1$s%% на цей час… Signal потребує дозволу \"Зберігання\", щоб створювати резервні копії, але наразі доступу немає. Будь ласка, перейдіть до налаштувань додатку, оберіть \"Дозволи\", та увімкніть \"Зберігання\". + + Set backup time @@ -2248,6 +2250,8 @@ Доступна нова версія Signal. Торкніться, щоб оновити. Не вдалося оновити Signal Ми спробуємо знову пізніше. + Signal successfully updated + You were automatically updated to version %1$s. Надіслати повідомлення? @@ -2883,24 +2887,13 @@ - Щоб перевірити наявність наскрізного шифрування з користувачем %1$s, порівняйте кольорову картку вище з карткою на пристрої користувача і перевірте, чи збігаються цифри. Якщо вони не збігатимуться, прогорніть і спробуйте іншу пару кодів безпеки. Для успішної перевірки достатньо збігу в одній парі. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Натисніть, щоб сканувати Збіг вдалий Не вдалось підтвердити код безпеки Завантаження… Позначити перевіреним Очистити верифікацію - - Коди безпеки оновлюються. - - - Зміни номерів безпеки - - Номери безпеки оновлюються протягом перехідного періоду, щоби нові функції конфіденційності Signal могли запрацювати.\n\nЩоб перевірити коди безпеки, порівняйте кольорову картку з карткою на пристрої вашого контакту. Якщо вони не збігатимуться, прогорніть і спробуйте іншу пару кодів безпеки. Для успішної перевірки достатньо збігу в одній парі. - - Потрібна допомога? - - Зрозуміло Відскануйте QR-код на пристрої вашого контакту. @@ -5833,7 +5826,12 @@ Усі довірені контакти було переглянуто. Натисніть «відправити», щоб продовжити. - Кілька ваших довірених контактів (%1$d) могли заново встановити Signal або змінити пристрої. Перш ніж поділитися своєю сторі, перегляньте код безпеки таких користувачів чи, можливо, забороніть їм перегляд. + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Підтвердити код безпеки @@ -6082,6 +6080,17 @@ Продовжити Конфіденційні повідомлення, які фінансуються лише вами. Без реклами, трекерів і компромісу. Підтримайте Signal донатом. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Щомісяця @@ -6151,6 +6160,8 @@ Подробиці Продовжити + + Read more Не вдалося завантажити запит diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index ef9b078f52..a1067a9179 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -643,6 +643,8 @@ %1$s%% اب تک… بیک اپ بنانے کیلئے Signal کو بیرونی اسٹوریج کی اجازت درکار ہوتی ہے ، لیکن مستقل طور پر اس کی تردید کردی گئی ہے۔ براہ کرم ایپ کی ترتیبات جاری رکھیں ، \"اجازت\" منتخب کریں اور \"اسٹوریج\" کو فعال کریں۔ + + Set backup time @@ -2102,6 +2104,8 @@ Signal کا نیا ورژن دستیاب ہے۔ اپ ڈیٹ کرنے کے لیے ٹیپ کریں۔ Signal اپ ڈیٹ ہونے میں ناکامی ہم کچھ دیر بعد دوبارہ کوشش کریں گے۔ + Signal successfully updated + You were automatically updated to version %1$s. پیغام بھیجیں؟ @@ -2709,24 +2713,13 @@ - %1$s کے ساتھ اینڈ ٹو اینڈ انکرپشن کی تصدیق کے لیے، اوپر موجود کلر کارڈ کو ان کی ڈیوائس کے ساتھ میچ کریں اور نمبرز کا موازنہ کریں۔ اگر یہ میچ نہیں ہوتے، تو سوائپ کریں اور حفاظتی نمبرز کے دوسرے جوڑے کو آزمائیں۔ صرف ایک جوڑے کو میچ کرنا درکار ہے۔ + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. اسکین کرنے کے لیے کلک کریں کامیاب میچ حفاظتی نمبر کی تصدیق میں ناکام ہو گئے لوڈ ہو رہا ہے۔۔۔ تصدیق کے طور پر نشان لگائیں تصدیق ہٹائیں - - حفاظتی نمبرز اپ ڈیٹ کیے جا رہے ہیں۔ - - - حفاظتی نمبرز میں تبدیلیاں - - Signal میں عنقریب ظاہر ہونے والے پرائیویسی کے فیچرز کو فعال کرنے کے لیے ایک عبوری مدت کے دوران حفاظتی نمبرز کو اپ ڈیٹ کیا جا رہا ہے۔\n\nحفاظتی نمبرز کی تصدیق کرنے کے لیے، اپنے رابطے کی ڈیوائس کے ساتھ رنگین کارڈ کو میچ کریں۔ اگر یہ میچ نہیں ہوتے، تو سوائپ کریں اور حفاظتی نمبرز کے دوسرے جوڑے کو آزمائیں۔ صرف ایک جوڑے کو میچ کرنا درکار ہے۔ - - مدد چاہیے؟ - - سمجھ گیا اپنی رابطہ ڈیوائس پر QR کوڈ سکین کریں۔ @@ -5581,7 +5574,10 @@ تمام کنکشنز کا جائزہ لیا گیا ہے، جاری رکھنے کے لیے بھیجیں پر ٹیپ کریں۔ - آپ کے %1$d کنکشنز نے شاید Signal کو دوبارہ انسٹال یا ڈیوائسزکو تبدیل کیا ہو گا۔ ان کے ساتھ اپنی سٹوری شیئر کرنے سے پہلے ان کے حفاظتی نمبرز کا جائزہ لیں یا انہیں اپنی سٹوری سے ہٹانے پر غور کریں۔ + + You have %1$d connection who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + حفاظتی نمبر کی تصدیق کریں @@ -5824,6 +5820,17 @@ جاری رکھیں پرائیوٹ میسجنگ، جسے آپ فنڈ کرتے ہیں۔ کوئی اشتہارات نہیں، کوئی ٹریکنگ نہیں، کوئی سمجھوتہ نہیں۔ Signal کو سپورٹ کرنے کے لیے ابھی عطیہ کریں۔ + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + ماہانہ @@ -5891,6 +5898,8 @@ مزید جانیں جاری رکھیں + + Read more مینڈیٹ کو لوڈ کرنے میں ناکامی diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index f303fbfdee..b87a56308c 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -627,6 +627,8 @@ %1$s%% đến giờ… Signal cần quyền truy cập bộ nhớ để tạo bản sao lưu, nhưng đã bị từ chối vĩnh viễn. Vui lòng mở cài đặt ứng dụng, chọn \"Quyền\" và bật \"Bộ nhớ\". + + Set backup time @@ -2029,6 +2031,8 @@ Đã có phiên bản mới của Signal. Nhấn để cập nhật. Cập nhật Signal không thành công Chúng tôi sẽ thử lại sau. + Signal successfully updated + You were automatically updated to version %1$s. Gửi tin nhắn? @@ -2622,24 +2626,13 @@ - Để xác minh bảo mật đầu cuối với %1$s, hãy khớp thẻ màu này với thiết bị của liên hệ của bạn. Nếu các mã số này không khớp, vuốt và thử các cặp mã số an toàn khác. Chỉ cần một cặp khớp nhau. + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. Nhấn để quét Kết nối thành công Xác thực số an toàn thất bại Đang tải… Đánh dấu đã xác minh Xóa xác nhận - - Các mã số an toàn đang được cập nhật. - - - Các thay đổi đối với Mã số an toàn - - Các mã số an toàn đang được cập nhật qua một giai đoạn chuyển giao để hỗ trợ các tính năng quyền riêng tư sắp ra mắt trong Signal.\n\nĐể xác minh các mã số an toàn, hãy khớp thẻ màu này với thiết bị của liên hệ của bạn. Nếu các mã số này không khớp, vuốt và thử các cặp mã số an toàn khác. Chỉ cần một cặp khớp nhau. - - Cần hỗ trợ? - - Đã hiểu Quét Mã QR trên thiết bị của người liên hệ của bạn. @@ -5455,7 +5448,9 @@ Tất cả liên hệ đã được xem xét, nhấn gửi để tiếp tục. - Bạn có %1$d liên hệ có thể đã cài đặt lại Signal hoặc đã đổi thiết bị. Trước khi chia sẻ story của bạn với họ, hãy xem xét mã số an toàn của họ và cân nhắc gỡ họ khỏi story của bạn. + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + Xác minh mã số an toàn @@ -5695,6 +5690,17 @@ Tiếp tục Nền tảng nhắn tin riêng tư, được tài trợ bởi chính bạn. Không quảng cáo, không trình theo dấu, không theo dõi. Ủng hộ ngay để hỗ trợ Signal. + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + Hàng tháng @@ -5761,6 +5767,8 @@ Tìm hiểu thêm Tiếp tục + + Read more Không thể xử lý yêu cầu ủy quyền diff --git a/app/src/main/res/values-yue/strings.xml b/app/src/main/res/values-yue/strings.xml index 5ad8c9e696..d8bf9d690e 100644 --- a/app/src/main/res/values-yue/strings.xml +++ b/app/src/main/res/values-yue/strings.xml @@ -627,6 +627,8 @@ 暫時去到 %1$s%%… Signal 要攞外部儲存裝置權限,先可以建立備份,但權限已被永久拒絕。請到呢個 app 嘅應用程式設定,揀選「權限」,然後啟用「儲存裝置」。 + + Set backup time @@ -2029,6 +2031,8 @@ Signal 出咗新版本喇。 㩒一下就可以更新。 Signal 更新失敗 我哋遲啲再試過啦。 + Signal successfully updated + You were automatically updated to version %1$s. 係咪要傳送訊息? @@ -2622,24 +2626,13 @@ - 如果想驗證你同 %1$s 之間嘅端對端加密設定,請將畫面上方嘅色卡同對方部機嘅色卡比對一下,然後比較埋兩組數字。如果兩邊唔吻合,可以掃一下試用另一對安全碼。只有一對安全碼吻合就得㗎喇。 + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. 撳一下去掃描 完全啱晒 驗證安全碼失敗 載入緊… 剔低話驗證咗 抹走先前個驗證 - - 安全碼更新緊。 - - - 安全碼變更 - - 安全碼喺過渡期間更新緊,以便啟用 Signal 即將推出嘅私隱功能。\n\n要驗證安全碼,請將色卡同聯絡人部機嘅色卡比對一下。如果兩邊唔吻合,可以掃一下試用另一對安全碼。只有一對安全碼吻合就得㗎喇。 - - 有冇啲咩幫到您? - - 明白 請掃一掃您嘅聯絡人部機上面個二維碼。 @@ -5455,7 +5448,9 @@ 已經審查晒所有人脈,㩒一吓傳送就可以繼續。 - 你有 %1$d 個人脈可能重新安裝咗 Signal 或者更換咗裝置。同佢哋分享你嘅限時動態之前,請先審查佢哋嘅安全碼,或者可以考慮喺你嘅限時動態入面將佢哋移除。 + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + 驗證安全碼 @@ -5695,6 +5690,17 @@ 繼續 由你贊助嘅私密通訊軟件。冇廣告、冇追蹤、絕不妥協。請立即捐款支持 Signal。 + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + 每月 @@ -5761,6 +5767,8 @@ 了解詳情 繼續 + + Read more 載入唔到授權 diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2f299b3a9d..06b26c8fdf 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -627,6 +627,8 @@ 目前已完成 %1$s%%… Signal 需外部存储权限,来创建备份,但该权限已永久禁用。请访问应用设置菜单,选择“权限”并启用“存储”。 + + Set backup time @@ -2029,6 +2031,8 @@ 我们推出了 Signal 的新版本。点击更新。 Signal 更新失败 我们稍后会再试一次。 + Signal successfully updated + You were automatically updated to version %1$s. 发送消息? @@ -2622,24 +2626,13 @@ - 如要验证您与%1$s的端对端加密安全性,请将上方的色卡与对方的设备匹配,并比对安全码。如果二者不匹配,请滑动并尝试另一对安全码。验证仅需匹配一对安全码。 + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. 点击扫描 成功匹配 验证安全码失败 正在加载… 标记为已验证 清除验证 - - 安全码正在更新中。 - - - 关于安全码的变更 - - 安全码将在过渡期内更新,以启用 Signal 即将推出的隐私功能。\n\n如要验证安全码,请将色卡与联系人的设备匹配。如果二者不匹配,请滑动并尝试另一对安全码。验证仅需匹配一对安全码。 - - 需要协助? - - 知道了 在你联系人设备上扫描QR码 @@ -5455,7 +5448,9 @@ 已检查所有联系人,请点击发送以继续操作。 - 您有 %1$d 位密友可能已重新安装 Signal 或更改设备。在与他们分享您的动态之前,请检查对方的安全码或考虑将他们从您的动态中移除。 + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + 验证安全代码 @@ -5695,6 +5690,17 @@ 继续 私密通信平台,依用户而生。无广告,无跟踪,服务不打折。立即捐款支持 Signal。 + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + 每個月的 @@ -5761,6 +5767,8 @@ 了解详情 继续 + + Read more 指令加载失败 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 5731c776f5..be60b45265 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -627,6 +627,8 @@ 目前進度 %1$s%%… Signal 需要外部儲存空間權限才可建立備份,但已被永久拒絕。請前往應用程式設定,選擇「權限」,然後啟用「儲存裝置」。 + + Set backup time @@ -2029,6 +2031,8 @@ 新版本的 Signal 現已提供。 輕觸以更新。 Signal 無法更新 我們將稍後再試。 + Signal successfully updated + You were automatically updated to version %1$s. 要傳送訊息嗎? @@ -2622,24 +2626,13 @@ - 若要驗證你與 %1$s 之間的端對端加密,請比對上方色卡與對方裝置上的色卡是否匹配,以及比較數字。如果這些無法匹配,請滑動並嘗試另一組安全碼。只需要匹配一對。 + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. 輕觸以掃描 比對成功 驗證安全碼失敗 正在載入… 標記為已驗證 清除驗證 - - 安全碼正在更新中。 - - - 安全碼變更 - - 安全碼會在過渡期間進行更新,以啟用 Signal 即將推出的隱私功能。\n\n要驗證安全碼,請將色卡與聯絡人的裝置配對。如果這些無法匹配,請滑動並嘗試另一組安全號碼。只需要匹配一對。 - - 需要說明嗎? - - 我知道了 請掃描您的聯絡人裝置上的二維碼。 @@ -5455,7 +5448,9 @@ 已檢查所有人脈,請點按傳送以繼續操作。 - 你有 %1$d 個人脈可能已重新安裝 Signal 或更換裝置。與他們分享你的限時動態之前,請先檢查他們的安全碼,或考慮將他們從你的限時動態中移除。 + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + 驗證安全碼 @@ -5695,6 +5690,17 @@ 繼續 我們是由你贊助的私密通訊軟體。無廣告、無追蹤、而且絕不妥協。請立即捐款支持 Signal。 + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + 每月 @@ -5761,6 +5767,8 @@ 了解更多 繼續 + + Read more 無法載入授權 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 2a691c855a..e6a208efa3 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -627,6 +627,8 @@ 目前進度%1$s%%… 為了要建立備份,Signal 需要外部空間的權限,但是已被永久拒絕。請到應用程式設定,選擇「權限」及開啟「儲存」。 + + Set backup time @@ -2029,6 +2031,8 @@ 新版本的 Signal 現已提供。 輕觸以更新。 Signal 無法更新 我們將稍後再試。 + Signal successfully updated + You were automatically updated to version %1$s. 傳送訊息? @@ -2622,24 +2626,13 @@ - 若要驗證你與 %1$s 之間的端對端加密,請比對上方色卡與對方裝置上的色卡是否匹配,以及比較數字。如果這些無法匹配,請滑動並嘗試另一組安全號碼。只需要匹配一對。 + To verify end-to-end encryption with %1$s, compare the numbers above with their device. You can also scan the code on their device. 點擊掃描 成功匹配 驗證安全碼失敗 載入中… 標記為已驗證 清除驗證碼 - - 安全號碼正在更新中。 - - - 安全號碼變更 - - 安全號碼會在過渡期間進行更新,以啟用 Signal 即將推出的隱私功能。\n\n要驗證安全號碼,請將色卡與聯絡人的裝置配對。如果這些無法匹配,請滑動並嘗試另一組安全號碼。只需要匹配一對。 - - 需要幫助嗎? - - 收到 掃描聯絡人裝置上的 QR code @@ -5455,7 +5448,9 @@ 所有聯絡人已審核完畢,點選「傳送」即可繼續。 - 你有 %1$d 位聯絡人可能已重新安裝 Signal 或更換裝置。在分享限動之前,請審核對方的安全碼,或直接將他們從你的限動中移除。 + + You have %1$d connections who may have reinstalled Signal or changed devices. Before sharing your story with them review their safety numbers or consider removing them from your story. + 驗證安全碼 @@ -5695,6 +5690,17 @@ 繼續 我們是由你贊助的私密通訊軟件。無廣告、無追蹤、而且絕不妥協。請即捐款支持 Signal。 + + You have a donation pending + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before updating your subscription. + + Bank transfers usually take 1 business day to process. Please wait until this payment completes before making another donation. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before updating your subscription. + + Your payment is still being processed. This can take a few minutes depending on your connection. Please wait until this payment completes before making another donation. + 每個月 @@ -5761,6 +5767,8 @@ 了解更多 繼續 + + Read more 無法載入授權 diff --git a/app/static-ips.gradle b/app/static-ips.gradle index 00de1483cb..268980e1fe 100644 --- a/app/static-ips.gradle +++ b/app/static-ips.gradle @@ -1,5 +1,5 @@ ext.service_ips='new String[]{"13.248.212.111","76.223.92.165"}' -ext.storage_ips='new String[]{"142.251.40.179"}' +ext.storage_ips='new String[]{"142.250.72.115"}' ext.cdn_ips='new String[]{"18.238.49.106","18.238.49.6","18.238.49.66","18.238.49.90"}' ext.cdn2_ips='new String[]{"104.18.37.148","172.64.150.108"}' ext.cdn3_ips='new String[]{"104.18.37.148","172.64.150.108"}' From bba3334df5014ef2c0e353f0a4e99cef04e5c23a Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Nov 2023 20:39:06 -0400 Subject: [PATCH 25/31] Bump version to 6.39.0 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 46af528b71..b110537ea2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,8 +33,8 @@ ktlint { version = "0.49.1" } -def canonicalVersionCode = 1353 -def canonicalVersionName = "6.38.2" +def canonicalVersionCode = 1354 +def canonicalVersionName = "6.39.0" def postFixSize = 100 def abiPostFix = ['universal' : 0, From b5c105150654c3c1c8aaf10a8a83939e75b115f4 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Thu, 2 Nov 2023 10:25:14 -0400 Subject: [PATCH 26/31] Attempt to fix AccountRecord restore crash. My guess is that we're seeing a crash when updating because we're using an out-of-date recipient snapshot that has an old/invalid storageId. This commit uses a fresher recipient, and it prefers using the raw record (what's in the DB) instead. --- .../securesms/jobs/StorageAccountRestoreJob.java | 2 +- .../org/thoughtcrime/securesms/keyvalue/AccountValues.kt | 2 +- .../thoughtcrime/securesms/recipients/LiveRecipient.java | 3 ++- .../org/thoughtcrime/securesms/recipients/Recipient.java | 2 +- .../securesms/storage/StorageSyncHelper.java | 9 ++++++++- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java index 3efb1dc0bd..abcdca8549 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageAccountRestoreJob.java @@ -105,7 +105,7 @@ protected void onRun() throws Exception { Log.i(TAG, "Applying changes locally..."); SignalDatabase.getRawDatabase().beginTransaction(); try { - StorageSyncHelper.applyAccountStorageSyncUpdates(context, Recipient.self(), accountRecord, false); + StorageSyncHelper.applyAccountStorageSyncUpdates(context, Recipient.self().fresh(), accountRecord, false); SignalDatabase.getRawDatabase().setTransactionSuccessful(); } finally { SignalDatabase.getRawDatabase().endTransaction(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt index 82e5a90d3e..1d0966073a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt @@ -199,7 +199,7 @@ internal class AccountValues internal constructor(store: KeyValueStore) : Signal fun generateAciIdentityKeyIfNecessary() { synchronized(this) { if (store.containsKey(KEY_ACI_IDENTITY_PUBLIC_KEY)) { - Log.w(TAG, "Tried to generate an ANI identity, but one was already set!", Throwable()) + Log.w(TAG, "Tried to generate an ACI identity, but one was already set!", Throwable()) return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java index d65e7b3933..4391f559f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/LiveRecipient.java @@ -157,8 +157,9 @@ public void removeForeverObserver(@NonNull RecipientForeverObserver observer) { } @WorkerThread - public void refresh() { + public LiveRecipient refresh() { refresh(getId()); + return this; } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index be8aecc437..1964d87f1b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -1196,7 +1196,7 @@ public boolean isResolving() { * Forces retrieving a fresh copy of the recipient, regardless of its state. */ public @NonNull Recipient fresh() { - return live().resolve(); + return live().refresh().resolve(); } public @NonNull LiveRecipient live() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java index 5964bda3ef..0633a43ccb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java @@ -36,6 +36,7 @@ import org.whispersystems.signalservice.internal.storage.protos.AccountRecord; import org.whispersystems.signalservice.internal.storage.protos.OptionalBool; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Locale; @@ -126,9 +127,15 @@ public static SignalStorageRecord buildAccountRecord(@NonNull Context context, @ record = recipientTable.getRecordForSync(self.getId()); } + if (record == null) { + Log.w(TAG, "[buildAccountRecord] Could not find a RecipientRecord for ourselves! ID: " + self.getId()); + } else if (!Arrays.equals(record.getStorageId(), self.getStorageServiceId())) { + Log.w(TAG, "[buildAccountRecord] StorageId on RecipientRecord did not match self! ID: " + self.getId()); + } + final boolean hasReadOnboardingStory = SignalStore.storyValues().getUserHasViewedOnboardingStory() || SignalStore.storyValues().getUserHasReadOnboardingStory(); - SignalAccountRecord.Builder account = new SignalAccountRecord.Builder(self.getStorageServiceId(), record != null ? record.getSyncExtras().getStorageProto() : null) + SignalAccountRecord.Builder account = new SignalAccountRecord.Builder(record != null ? record.getStorageId() : self.getStorageServiceId(), record != null ? record.getSyncExtras().getStorageProto() : null) .setProfileKey(self.getProfileKey()) .setGivenName(self.getProfileName().getGivenName()) .setFamilyName(self.getProfileName().getFamilyName()) From 99d0ee672511a49346d3b3ae24600b7f08f9d817 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Thu, 2 Nov 2023 11:57:58 -0400 Subject: [PATCH 27/31] Fix cursor crash in ConversationSettings. Best way to fix a cursor crash it to... stop using cursors. Fairly confident the crash was caused by us closing the cursor while it was read. And there just isn't a good way to avoid that with how it was written. So this ended up being a great excuse to move over to models. --- .../components/ThreadPhotoRailView.java | 41 +++++++++++-------- .../ConversationSettingsFragment.kt | 4 +- .../ConversationSettingsRepository.kt | 9 ++-- .../conversation/ConversationSettingsState.kt | 4 +- .../ConversationSettingsViewModel.kt | 35 +++++----------- .../preferences/SharedMediaPreference.kt | 5 +-- .../securesms/database/MediaTable.kt | 10 ++++- 7 files changed, 52 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ThreadPhotoRailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ThreadPhotoRailView.java index 8c1058d9cc..bf34013e30 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ThreadPhotoRailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ThreadPhotoRailView.java @@ -17,13 +17,15 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter; import org.thoughtcrime.securesms.database.MediaTable; import org.thoughtcrime.securesms.mediapreview.MediaPreviewCache; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.util.MediaUtil; +import java.util.ArrayList; +import java.util.List; + public class ThreadPhotoRailView extends FrameLayout { @NonNull private final RecyclerView recyclerView; @@ -56,11 +58,11 @@ public void setListener(@Nullable OnItemClickedListener listener) { } } - public void setCursor(@NonNull GlideRequests glideRequests, @Nullable Cursor cursor) { - this.recyclerView.setAdapter(new ThreadPhotoRailAdapter(getContext(), glideRequests, cursor, this.listener)); + public void setMediaRecords(@NonNull GlideRequests glideRequests, @NonNull List mediaRecords) { + this.recyclerView.setAdapter(new ThreadPhotoRailAdapter(getContext(), glideRequests, mediaRecords, this.listener)); } - private static class ThreadPhotoRailAdapter extends CursorRecyclerViewAdapter { + private static class ThreadPhotoRailAdapter extends RecyclerView.Adapter { @SuppressWarnings("unused") private static final String TAG = Log.tag(ThreadPhotoRailAdapter.class); @@ -69,18 +71,27 @@ private static class ThreadPhotoRailAdapter extends CursorRecyclerViewAdapter mediaRecords = new ArrayList<>(); + private ThreadPhotoRailAdapter(@NonNull Context context, @NonNull GlideRequests glideRequests, - @Nullable Cursor cursor, + @NonNull List mediaRecords, @Nullable OnItemClickedListener listener) { - super(context, cursor); this.glideRequests = glideRequests; this.clickedListener = listener; + + this.mediaRecords.clear(); + this.mediaRecords.addAll(mediaRecords); + } + + @Override + public int getItemCount() { + return mediaRecords.size(); } @Override - public ThreadPhotoViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) { + public @NonNull ThreadPhotoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.recipient_preference_photo_rail_item, parent, false); @@ -88,18 +99,14 @@ public ThreadPhotoViewHolder onCreateItemViewHolder(ViewGroup parent, int viewTy } @Override - public void onBindItemViewHolder(ThreadPhotoViewHolder viewHolder, @NonNull Cursor cursor) { - ThumbnailView imageView = viewHolder.imageView; - MediaTable.MediaRecord mediaRecord = MediaTable.MediaRecord.from(cursor); + public void onBindViewHolder(@NonNull ThreadPhotoViewHolder viewHolder, int position) { + MediaTable.MediaRecord mediaRecord = mediaRecords.get(position); Slide slide = MediaUtil.getSlideForAttachment(mediaRecord.getAttachment()); - if (slide != null) { - imageView.setImageResource(glideRequests, slide, false, false); - } - - imageView.setOnClickListener(v -> { - MediaPreviewCache.INSTANCE.setDrawable(imageView.getImageDrawable()); - if (clickedListener != null) clickedListener.onItemClicked(imageView, mediaRecord); + viewHolder.imageView.setImageResource(glideRequests, slide, false, false); + viewHolder.imageView.setOnClickListener(v -> { + MediaPreviewCache.INSTANCE.setDrawable(viewHolder.imageView.getImageDrawable()); + if (clickedListener != null) clickedListener.onItemClicked(viewHolder.imageView, mediaRecord); }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt index 44dc560358..19625ec2de 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt @@ -555,7 +555,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( } } - if (state.sharedMedia != null && state.sharedMedia.count > 0) { + if (state.sharedMedia.isNotEmpty()) { dividerPref() sectionHeaderPref(R.string.recipient_preference_activity__shared_media) @@ -563,7 +563,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( @Suppress("DEPRECATION") customPref( SharedMediaPreference.Model( - mediaCursor = state.sharedMedia, + mediaRecords = state.sharedMedia, mediaIds = state.sharedMediaIds, onMediaRecordClick = { view, mediaRecord, isLtr -> view.transitionName = "thumb" diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt index 0bff6d921c..ae48fef267 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsRepository.kt @@ -30,7 +30,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.recipients.RecipientUtil import org.thoughtcrime.securesms.util.FeatureFlags import java.io.IOException -import java.util.Optional private val TAG = Log.tag(ConversationSettingsRepository::class.java) @@ -56,11 +55,11 @@ class ConversationSettingsRepository( } @WorkerThread - fun getThreadMedia(threadId: Long): Optional { - return if (threadId <= 0) { - Optional.empty() + fun getThreadMedia(threadId: Long, limit: Int): Cursor? { + return if (threadId > 0) { + SignalDatabase.media.getGalleryMediaForThread(threadId, MediaTable.Sorting.Newest, limit) } else { - Optional.of(SignalDatabase.media.getGalleryMediaForThread(threadId, MediaTable.Sorting.Newest)) + null } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt index 3f787313c1..f7f637f967 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsState.kt @@ -1,9 +1,9 @@ package org.thoughtcrime.securesms.components.settings.conversation -import android.database.Cursor import org.thoughtcrime.securesms.components.settings.conversation.preferences.ButtonStripPreference import org.thoughtcrime.securesms.components.settings.conversation.preferences.CallPreference import org.thoughtcrime.securesms.components.settings.conversation.preferences.LegacyGroupPreference +import org.thoughtcrime.securesms.database.MediaTable import org.thoughtcrime.securesms.database.model.IdentityRecord import org.thoughtcrime.securesms.database.model.StoryViewState import org.thoughtcrime.securesms.groups.GroupId @@ -18,7 +18,7 @@ data class ConversationSettingsState( val buttonStripState: ButtonStripPreference.State = ButtonStripPreference.State(), val disappearingMessagesLifespan: Int = 0, val canModifyBlockedState: Boolean = false, - val sharedMedia: Cursor? = null, + val sharedMedia: List = emptyList(), val sharedMediaIds: List = listOf(), val displayInternalRecipientDetails: Boolean = false, val calls: List = emptyList(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt index c7a1fb10f1..cbf8ecbf2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsViewModel.kt @@ -13,13 +13,13 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.subjects.PublishSubject import io.reactivex.rxjava3.subjects.Subject -import org.signal.core.util.CursorUtil import org.signal.core.util.ThreadUtil import org.signal.core.util.concurrent.SignalExecutors +import org.signal.core.util.readToList import org.thoughtcrime.securesms.components.settings.conversation.preferences.ButtonStripPreference import org.thoughtcrime.securesms.components.settings.conversation.preferences.CallPreference import org.thoughtcrime.securesms.components.settings.conversation.preferences.LegacyGroupPreference -import org.thoughtcrime.securesms.database.AttachmentTable +import org.thoughtcrime.securesms.database.MediaTable import org.thoughtcrime.securesms.database.RecipientTable import org.thoughtcrime.securesms.database.model.StoryViewState import org.thoughtcrime.securesms.dependencies.ApplicationDependencies @@ -34,7 +34,6 @@ import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.livedata.LiveDataUtil import org.thoughtcrime.securesms.util.livedata.Store -import java.util.Optional sealed class ConversationSettingsViewModel( private val callMessageIds: LongArray, @@ -42,8 +41,6 @@ sealed class ConversationSettingsViewModel( specificSettingsState: SpecificSettingsState ) : ViewModel() { - private val openedMediaCursors = HashSet() - @Volatile private var cleared = false @@ -66,37 +63,26 @@ sealed class ConversationSettingsViewModel( val threadId: LiveData = state.map { it.threadId }.distinctUntilChanged() val updater: LiveData = LiveDataUtil.combineLatest(threadId, sharedMediaUpdateTrigger) { tId, _ -> tId } - val sharedMedia: LiveData> = LiveDataUtil.mapAsync(SignalExecutors.BOUNDED, updater) { tId -> - repository.getThreadMedia(tId) + val sharedMedia: LiveData> = LiveDataUtil.mapAsync(SignalExecutors.BOUNDED, updater) { tId -> + repository.getThreadMedia(threadId = tId, limit = 100)?.readToList { cursor -> + MediaTable.MediaRecord.from(cursor) + } ?: emptyList() } store.update(repository.getCallEvents(callMessageIds).toObservable()) { callRecords, state -> state.copy(calls = callRecords.map { (call, messageRecord) -> CallPreference.Model(call, messageRecord) }) } - store.update(sharedMedia) { cursor, state -> + store.update(sharedMedia) { mediaRecords, state -> if (!cleared) { - if (cursor.isPresent) { - openedMediaCursors.add(cursor.get()) - } - - val ids: List = cursor.map> { - val result = mutableListOf() - while (it.moveToNext()) { - result.add(CursorUtil.requireLong(it, AttachmentTable.ROW_ID)) - } - result - }.orElse(listOf()) - state.copy( - sharedMedia = cursor.orElse(null), - sharedMediaIds = ids, + sharedMedia = mediaRecords, + sharedMediaIds = mediaRecords.mapNotNull { it.attachment?.attachmentId?.rowId }, sharedMediaLoaded = true, displayInternalRecipientDetails = repository.isInternalRecipientDetailsEnabled() ) } else { - cursor.orElse(null).ensureClosed() - state.copy(sharedMedia = null) + state.copy(sharedMedia = emptyList()) } } } @@ -123,7 +109,6 @@ sealed class ConversationSettingsViewModel( override fun onCleared() { cleared = true - openedMediaCursors.forEach { it.ensureClosed() } store.clear() disposable.clear() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt index 484e2be188..5be0a777b7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/SharedMediaPreference.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.conversation.preferences -import android.database.Cursor import android.view.View import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ThreadPhotoRailView @@ -22,7 +21,7 @@ object SharedMediaPreference { } class Model( - val mediaCursor: Cursor, + val mediaRecords: List, val mediaIds: List, val onMediaRecordClick: (View, MediaTable.MediaRecord, Boolean) -> Unit ) : PreferenceModel() { @@ -41,7 +40,7 @@ object SharedMediaPreference { private val rail: ThreadPhotoRailView = itemView.findViewById(R.id.rail_view) override fun bind(model: Model) { - rail.setCursor(GlideApp.with(rail), model.mediaCursor) + rail.setMediaRecords(GlideApp.with(rail), model.mediaRecords) rail.setListener { v, m -> model.onMediaRecordClick(v, m, ViewUtil.isLtr(rail)) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt index f308da81ae..63ad86da12 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt @@ -143,13 +143,19 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD } } - fun getGalleryMediaForThread(threadId: Long, sorting: Sorting): Cursor { - val query = if (FeatureFlags.instantVideoPlayback()) { + @JvmOverloads + fun getGalleryMediaForThread(threadId: Long, sorting: Sorting, limit: Int = 0): Cursor { + var query = if (FeatureFlags.instantVideoPlayback()) { sorting.applyToQuery(applyEqualityOperator(threadId, GALLERY_MEDIA_QUERY_INCLUDING_TEMP_VIDEOS)) } else { sorting.applyToQuery(applyEqualityOperator(threadId, GALLERY_MEDIA_QUERY)) } val args = arrayOf(threadId.toString() + "") + + if (limit > 0) { + query = "$query LIMIT $limit" + } + return readableDatabase.rawQuery(query, args) } From 157777cac1484f1550c2e6ee6639e4f178884b82 Mon Sep 17 00:00:00 2001 From: Nicholas Date: Thu, 2 Nov 2023 15:47:31 -0400 Subject: [PATCH 28/31] Batch update DB upon group receipt. --- .../securesms/database/GroupReceiptTable.kt | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt index 41a67006e1..08a31c3a88 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt @@ -76,22 +76,46 @@ class GroupReceiptTable(context: Context?, databaseHelper: SignalDatabase?) : Da } fun setUnidentified(results: Collection>, mmsId: Long) { + val mmsMatchPrefix = "$MMS_ID = $mmsId AND" + val unidentifiedQueries = SqlUtil.buildCollectionQuery( + column = RECIPIENT_ID, + values = results.filter { it.second() }.map { it.first().serialize() }, + prefix = mmsMatchPrefix + ) + val identifiedQueries = SqlUtil.buildCollectionQuery( + column = RECIPIENT_ID, + values = results.filterNot { it.second() }.map { it.first().serialize() }, + prefix = mmsMatchPrefix + ) writableDatabase.withinTransaction { db -> - for (result in results) { + unidentifiedQueries.forEach { db.update(TABLE_NAME) - .values(UNIDENTIFIED to if (result.second()) 1 else 0) - .where("$MMS_ID = ? AND $RECIPIENT_ID = ?", mmsId.toString(), result.first().serialize()) + .values(UNIDENTIFIED to 1) + .where(it.where, it.whereArgs) + .run() + } + + identifiedQueries.forEach { + db.update(TABLE_NAME) + .values(UNIDENTIFIED to 0) + .where(it.where, it.whereArgs) .run() } } } fun setSkipped(recipients: Collection, mmsId: Long) { + val mmsMatchPrefix = "$MMS_ID = $mmsId AND" + val queries = SqlUtil.buildCollectionQuery( + column = RECIPIENT_ID, + values = recipients.map { it.serialize() }, + prefix = mmsMatchPrefix + ) writableDatabase.withinTransaction { db -> - for (recipient in recipients) { + queries.forEach { db.update(TABLE_NAME) .values(STATUS to STATUS_SKIPPED) - .where("$MMS_ID = ? AND $RECIPIENT_ID = ?", mmsId.toString(), recipient.serialize()) + .where(it.where, it.whereArgs) .run() } } From 5fc11baf9eb47f75c42ad0582794789bb840bd38 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Thu, 2 Nov 2023 18:59:42 -0400 Subject: [PATCH 29/31] Update translations and other static files. --- app/src/main/res/values-sr/strings.xml | 80 +++++++++++++------------- app/static-ips.gradle | 2 +- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 19cc24f99d..670e7cdd49 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -20,7 +20,7 @@ Да Не - Обриши + Избриши Сачекајте… Сачувај Моја белешка @@ -79,7 +79,7 @@ Галерија - Fajl + Фајл Контакт Локација Сигналу су потребне дозволе да прикаже ваше слике и видео. @@ -1032,8 +1032,8 @@ Звук обавештења Режим вибрирања - Прилагодити - Променити звук и вибрацију + Прилагоди + Промени звук и вибрацију Поставке позива Звоно Подразумеван @@ -2052,7 +2052,7 @@ Једнократна фотографија Једнократни видео запис Једнократни медиј - Ова порука је обрисана. + Ова порука је избрисана. Избрисали сте ову поруку. Послали сте захтев за активирање плаћања @@ -2077,7 +2077,7 @@ Фотографија GIF Гласовна порука - Fajl + Фајл Видео запис Сесија ћаскања је освежена @@ -2581,22 +2581,22 @@ Искључено - %1$d сек. - %1$d сек. + %1$d s + %1$d s %1$d s - %1$d мин. - %1$d мин. + %1$d min + %1$d min %1$d m - %1$d сат - %1$d сати + %1$d h + %1$d h %1$d h @@ -2609,8 +2609,8 @@ %1$d д - %1$d сед. - %1$d сед. + %1$d нед. + %1$d нед. %1$d с @@ -2689,7 +2689,7 @@ Шифровано Будите љубазни Љубитељ кафе - Доступан за ћаскање + Можемо да ћаскамо Правим паузу Радим на нечему новом @@ -2785,19 +2785,19 @@ Будите што описнији како бисте нам помогли да разумемо проблем. Изаберите опцију - Nešto ne radi - Zahtev za funkciju - Pitanje - Komentar + Нешто не ради + Захтев за функцију + Питање + Коментар Остало - Plaćanja (MobileCoin) + Плаћања (MobileCoin) Донације и значке Извоз SMS порука Слање евиденције за отклањање грешака за Signal Android - Спора обавештења + Обавештења касне Пад апликације @@ -2821,12 +2821,12 @@ Користи подразумевано - Користи посебно + Користи прилагођено - Искључи обавештења 1 сат - Искључи обавештења 8 сати - Искључи обавештења 1 дан - Искључи обавештења 7 сати + Искључи обавештења на 1 сат + Искључи обавештења на 8 сати + Искључи обавештења на 1 дан + Искључи обавештења на 7 сати Увек Подразумевана поставка @@ -2876,7 +2876,7 @@ Аутоматски закључај Signal након одређеног интервала неактивности Интервал истека лозинке Интервал неактивности - Обавештавања + Обавештења Боја ЛЕД светла Непозната Трептање ЛЕД светла @@ -3997,7 +3997,7 @@ Ресетовати боје ћаскања Ресетовати боје ћаскања Ресетовати боје ћаскања? - Поставити позадину + Постави позадину Тамни режим затамњује позадину Име контакта Ресетуј @@ -4454,18 +4454,18 @@ Тражити GIPHY - Тражити налепнице + Претрага налепница Нема резултата Нема резултата Непозната мелодија звона - Додавање садржаја у групну причу није успело + Додавање у групну причу није успело Само администратори ове групе могу да додају садржаје у ову причу - Aplikacija za kontakte nije pronađena + Апликација за контакте није пронађена Започните видео позив Започни гласовни позив @@ -4473,9 +4473,9 @@ Порука - Видео запис + Видео - Звучни запис + Звук Позови @@ -4483,7 +4483,7 @@ Обавештења су искључена - Претрага + Претражите Самонестајуће поруке Звук и обавештења @@ -4588,7 +4588,7 @@ Текст Сачувај Уклонити слику - Неуспех сачувавања аватара + Чување аватара није успело Преглед @@ -4606,17 +4606,17 @@ Поделите - Ићи на горе - Напред на + Иди на врх + Проследите кориснику Подели са - Додати поруку - Убрзавање прослеђивање + Додајте поруку + Брже прослеђивање Видео снимци ће бити скраћени на клипове од 30 секунди и послати као више прича. Видео снимци објављени у причама не могу бити дужи од 30 секунди. - Прослеђивање поруке је сада урађено сместа. + Прослеђене поруке се сада шаљу одмах. Пошаљи %1$d поруку Пошаљи поруке (%1$d) diff --git a/app/static-ips.gradle b/app/static-ips.gradle index 268980e1fe..03d01a314b 100644 --- a/app/static-ips.gradle +++ b/app/static-ips.gradle @@ -1,6 +1,6 @@ ext.service_ips='new String[]{"13.248.212.111","76.223.92.165"}' ext.storage_ips='new String[]{"142.250.72.115"}' -ext.cdn_ips='new String[]{"18.238.49.106","18.238.49.6","18.238.49.66","18.238.49.90"}' +ext.cdn_ips='new String[]{"18.161.21.122","18.161.21.4","18.161.21.66","18.161.21.70"}' ext.cdn2_ips='new String[]{"104.18.37.148","172.64.150.108"}' ext.cdn3_ips='new String[]{"104.18.37.148","172.64.150.108"}' ext.sfu_ips='new String[]{"35.186.192.249"}' From e486a4baef5d106252389763e368d1e9a662b3a9 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Thu, 2 Nov 2023 19:00:09 -0400 Subject: [PATCH 30/31] Bump version to 6.39.1 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b110537ea2..9eda125251 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,8 +33,8 @@ ktlint { version = "0.49.1" } -def canonicalVersionCode = 1354 -def canonicalVersionName = "6.39.0" +def canonicalVersionCode = 1355 +def canonicalVersionName = "6.39.1" def postFixSize = 100 def abiPostFix = ['universal' : 0, From eea908dfa34e239f6c96d4a3abc12500ce734459 Mon Sep 17 00:00:00 2001 From: Oscar Mira Date: Fri, 10 Nov 2023 02:23:23 +0100 Subject: [PATCH 31/31] Fix toggle buttons in settings --- .../securesms/components/settings/DSLSettingsAdapter.kt | 6 +++++- .../components/settings/app/help/HelpSettingsFragment.kt | 5 +++-- .../settings/app/privacy/PrivacySettingsFragment.kt | 9 ++++----- .../thoughtcrime/securesms/components/settings/dsl.kt | 6 ++++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsAdapter.kt index 48122bdfab..3e138583bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/DSLSettingsAdapter.kt @@ -214,7 +214,11 @@ class SwitchPreferenceViewHolder(itemView: View) : PreferenceViewHolder + switchWidget.setOnCheckedChangeListener { _, isChecked -> + if (!model.onToggle(isChecked)) { + // MOLLY: Set the toggle button back to the previous state + switchWidget.toggle() + } model.onClick() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt index 3d30aee5fb..fa0c3d8f0a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/help/HelpSettingsFragment.kt @@ -73,8 +73,7 @@ class HelpSettingsFragment : DSLSettingsFragment(R.string.preferences__help) { switchPref( title = DSLSettingsText.from(R.string.preferences__enable_debug_log), isChecked = state.logEnabled, - onClick = { - if (state.logEnabled) { + onToggle = { isChecked -> if (!isChecked) { MaterialAlertDialogBuilder(requireContext()) .setMessage(R.string.HelpSettingsFragment_disable_and_delete_debug_log) .setPositiveButton(android.R.string.ok) { dialog, _ -> @@ -83,8 +82,10 @@ class HelpSettingsFragment : DSLSettingsFragment(R.string.preferences__help) { } .setNegativeButton(android.R.string.cancel, null) .show() + false } else { viewModel.setLogEnabled(true) + true } } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt index df3264c199..ed03d76473 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/privacy/PrivacySettingsFragment.kt @@ -90,17 +90,16 @@ class PrivacySettingsFragment : DSLSettingsFragment(R.string.preferences__privac title = DSLSettingsText.from(R.string.preferences__passphrase_lock), summary = DSLSettingsText.from(R.string.preferences__protect_molly_database_with_a_passphrase), isChecked = state.passphraseLock, - onClick = { - val enabled = !state.passphraseLock - val mode = if (enabled) ChangePassphraseDialogFragment.MODE_ENABLE else ChangePassphraseDialogFragment.MODE_DISABLE - + onToggle = { isChecked -> + val mode = if (isChecked) ChangePassphraseDialogFragment.MODE_ENABLE else ChangePassphraseDialogFragment.MODE_DISABLE val dialog = ChangePassphraseDialogFragment.newInstance(mode) dialog.setMasterSecretChangedListener { masterSecret -> - viewModel.setPassphraseLockEnabled(enabled) + viewModel.setPassphraseLockEnabled(isChecked) (activity as PassphraseActivity).setMasterSecret(masterSecret) ConversationUtil.refreshRecipientShortcuts() } dialog.show(parentFragmentManager, "ChangePassphraseDialogFragment") + false } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/dsl.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/dsl.kt index f8e85a2f86..558eba0e35 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/dsl.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/dsl.kt @@ -81,9 +81,10 @@ class DSLConfiguration { icon: DSLSettingsIcon? = null, isEnabled: Boolean = true, isChecked: Boolean, - onClick: () -> Unit + onToggle: (Boolean) -> Boolean = { true }, + onClick: () -> Unit = { }, ) { - val preference = SwitchPreference(title, summary, icon, isEnabled, isChecked, onClick) + val preference = SwitchPreference(title, summary, icon, isEnabled, isChecked, onToggle, onClick) children.add(preference) } @@ -300,6 +301,7 @@ class SwitchPreference( override val icon: DSLSettingsIcon? = null, override val isEnabled: Boolean, val isChecked: Boolean, + val onToggle: (Boolean) -> Boolean, val onClick: () -> Unit ) : PreferenceModel() {