From 1de0ede52d17bf00c7f04cd89b3c86f91d67b654 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 6 Feb 2019 19:18:20 -0700 Subject: [PATCH 01/14] Specific CDS feedback --- .../src/Contacts/ContactDiscoveryService.h | 5 +- .../src/Contacts/ContactDiscoveryService.m | 137 +++++++++++++----- .../OWSContactDiscoveryOperation.swift | 60 +++++++- .../Network/API/Requests/OWSRequestFactory.h | 5 +- .../Network/API/Requests/OWSRequestFactory.m | 16 +- 5 files changed, 168 insertions(+), 55 deletions(-) diff --git a/SignalServiceKit/src/Contacts/ContactDiscoveryService.h b/SignalServiceKit/src/Contacts/ContactDiscoveryService.h index 60031ea0c..2b19fc8bd 100644 --- a/SignalServiceKit/src/Contacts/ContactDiscoveryService.h +++ b/SignalServiceKit/src/Contacts/ContactDiscoveryService.h @@ -1,12 +1,13 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // NS_ASSUME_NONNULL_BEGIN +extern NSErrorUserInfoKey const ContactDiscoveryServiceErrorKey_Reason; extern NSErrorDomain const ContactDiscoveryServiceErrorDomain; typedef NS_ERROR_ENUM(ContactDiscoveryServiceErrorDomain, ContactDiscoveryServiceError){ - ContactDiscoveryServiceErrorAttestationFailed = 100, + ContactDiscoveryServiceErrorAttestationFailed = 100, ContactDiscoveryServiceErrorAssertionError = 101 }; @class ECKeyPair; diff --git a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m index 2153936bd..e34114488 100644 --- a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m +++ b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m @@ -18,8 +18,16 @@ NS_ASSUME_NONNULL_BEGIN +NSErrorUserInfoKey const ContactDiscoveryServiceErrorKey_Reason = @"ContactDiscoveryServiceErrorKey_Reason"; NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.ContactDiscoveryService"; +NSError *ContactDiscoveryServiceErrorMakeWithReason(NSInteger code, NSString *reason) +{ + return [NSError errorWithDomain:ContactDiscoveryServiceErrorDomain + code:code + userInfo:@{ ContactDiscoveryServiceErrorKey_Reason : reason }]; +} + @interface RemoteAttestationAuth () @property (nonatomic) NSString *username; @@ -53,17 +61,21 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont + (nullable RemoteAttestationKeys *)keysForKeyPair:(ECKeyPair *)keyPair serverEphemeralPublic:(NSData *)serverEphemeralPublic serverStaticPublic:(NSData *)serverStaticPublic + error:(NSError **)error { if (!keyPair) { - OWSFailDebug(@"Missing keyPair"); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"Missing keyPair"); return nil; } if (serverEphemeralPublic.length < 1) { - OWSFailDebug(@"Invalid serverEphemeralPublic"); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"Invalid serverEphemeralPublic"); return nil; } if (serverStaticPublic.length < 1) { - OWSFailDebug(@"Invalid serverStaticPublic"); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"Invalid serverStaticPublic"); return nil; } RemoteAttestationKeys *keys = [RemoteAttestationKeys new]; @@ -71,6 +83,8 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont keys.serverEphemeralPublic = serverEphemeralPublic; keys.serverStaticPublic = serverStaticPublic; if (![keys deriveKeys]) { + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"failed to derive keys"); return nil; } return keys; @@ -350,16 +364,22 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont [[TSNetworkManager sharedManager] makeRequest:request success:^(NSURLSessionDataTask *task, id responseJson) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSError *_Nullable error; RemoteAttestation *_Nullable attestation = [self parseAttestationResponseJson:responseJson response:task.response keyPair:keyPair enclaveId:enclaveId - auth:auth]; + auth:auth + error:&error]; if (!attestation) { - NSError *error = [NSError errorWithDomain:ContactDiscoveryServiceErrorDomain - code:ContactDiscoveryServiceErrorAttestationFailed - userInfo:nil]; + if (!error) { + OWSFailDebug(@"error was unexpectedly nil"); + error = ContactDiscoveryServiceErrorMakeWithReason(ContactDiscoveryServiceErrorAssertionError, + @"failure when parsing attestation - no reason given"); + } else { + OWSFailDebug(@"error with attestation: %@", error); + } error.isRetryable = NO; failureHandler(error); return; @@ -378,6 +398,7 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont keyPair:(ECKeyPair *)keyPair enclaveId:(NSString *)enclaveId auth:(RemoteAttestationAuth *)auth + error:(NSError **)error { OWSAssertDebug(responseJson); OWSAssertDebug(response); @@ -392,71 +413,89 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:httpResponse.allHeaderFields forURL:httpResponse.URL]; if (cookies.count < 1) { - OWSFailDebug(@"couldn't parse cookie."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse cookie."); return nil; } if (![responseJson isKindOfClass:[NSDictionary class]]) { + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"invalid json response"); return nil; } NSDictionary *responseDict = responseJson; NSData *_Nullable serverEphemeralPublic = [responseDict base64DataForKey:@"serverEphemeralPublic" expectedLength:32]; if (!serverEphemeralPublic) { - OWSFailDebug(@"couldn't parse serverEphemeralPublic."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse serverEphemeralPublic."); return nil; } NSData *_Nullable serverStaticPublic = [responseDict base64DataForKey:@"serverStaticPublic" expectedLength:32]; if (!serverStaticPublic) { - OWSFailDebug(@"couldn't parse serverStaticPublic."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse serverStaticPublic."); return nil; } NSData *_Nullable encryptedRequestId = [responseDict base64DataForKey:@"ciphertext"]; if (!encryptedRequestId) { - OWSFailDebug(@"couldn't parse encryptedRequestId."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse encryptedRequestId."); return nil; } NSData *_Nullable encryptedRequestIv = [responseDict base64DataForKey:@"iv" expectedLength:12]; if (!encryptedRequestIv) { - OWSFailDebug(@"couldn't parse encryptedRequestIv."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse encryptedRequestIv."); return nil; } NSData *_Nullable encryptedRequestTag = [responseDict base64DataForKey:@"tag" expectedLength:16]; if (!encryptedRequestTag) { - OWSFailDebug(@"couldn't parse encryptedRequestTag."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse encryptedRequestTag."); return nil; } NSData *_Nullable quoteData = [responseDict base64DataForKey:@"quote"]; if (!quoteData) { - OWSFailDebug(@"couldn't parse quote data."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse quote data."); return nil; } NSString *_Nullable signatureBody = [responseDict stringForKey:@"signatureBody"]; if (![signatureBody isKindOfClass:[NSString class]]) { - OWSFailDebug(@"couldn't parse signatureBody."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse signatureBody."); return nil; } NSData *_Nullable signature = [responseDict base64DataForKey:@"signature"]; if (!signature) { - OWSFailDebug(@"couldn't parse signature."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse signature."); return nil; } NSString *_Nullable encodedCertificates = [responseDict stringForKey:@"certificates"]; if (![encodedCertificates isKindOfClass:[NSString class]]) { - OWSFailDebug(@"couldn't parse encodedCertificates."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse encodedCertificates."); return nil; } NSString *_Nullable certificates = [encodedCertificates stringByRemovingPercentEncoding]; if (!certificates) { - OWSFailDebug(@"couldn't parse certificates."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't parse certificates."); return nil; } RemoteAttestationKeys *_Nullable keys = [RemoteAttestationKeys keysForKeyPair:keyPair serverEphemeralPublic:serverEphemeralPublic - serverStaticPublic:serverStaticPublic]; - if (!keys) { - OWSFailDebug(@"couldn't derive keys."); + serverStaticPublic:serverStaticPublic + error:error]; + if (!keys || *error != nil) { + if (*error == nil) { + OWSFailDebug(@"missing error specifics"); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"Couldn't derive keys. No reason given"); + } return nil; } @@ -470,20 +509,28 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont encryptedRequestTag:encryptedRequestTag keys:keys]; if (!requestId) { - OWSFailDebug(@"couldn't decrypt request id."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"couldn't decrypt request id."); return nil; } if (![self verifyServerQuote:quote keys:keys enclaveId:enclaveId]) { - OWSFailDebug(@"couldn't verify quote."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAttestationFailed, @"couldn't verify quote."); return nil; } if (![self verifyIasSignatureWithCertificates:certificates signatureBody:signatureBody signature:signature - quoteData:quoteData]) { - OWSFailDebug(@"couldn't verify ias signature."); + quoteData:quoteData + error:error]) { + + if (*error == nil) { + OWSFailDebug(@"missing error specifics"); + *error = ContactDiscoveryServiceErrorMakeWithReason(ContactDiscoveryServiceErrorAssertionError, + @"verifyIasSignatureWithCertificates failed. No reason given"); + } return nil; } @@ -503,61 +550,71 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont signatureBody:(NSString *)signatureBody signature:(NSData *)signature quoteData:(NSData *)quoteData + error:(NSError **)error { OWSAssertDebug(certificates.length > 0); OWSAssertDebug(signatureBody.length > 0); OWSAssertDebug(signature.length > 0); OWSAssertDebug(quoteData); - NSError *error; + NSError *signingError; CDSSigningCertificate *_Nullable certificate = - [CDSSigningCertificate parseCertificateFromPem:certificates error:&error]; - if (error) { - OWSFailDebug(@"error when parsing signing certificate. %@", error.localizedDescription); + [CDSSigningCertificate parseCertificateFromPem:certificates error:&signingError]; + if (signingError) { + *error = signingError; return NO; } if (!certificate) { - OWSFailDebug(@"could not parse signing certificate."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"could not parse signing certificate."); return NO; } if (![certificate verifySignatureOfBody:signatureBody signature:signature]) { - OWSFailDebug(@"could not verify signature."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAttestationFailed, @"could not verify signature."); return NO; } SignatureBodyEntity *_Nullable signatureBodyEntity = [self parseSignatureBodyEntity:signatureBody]; if (!signatureBodyEntity) { - OWSFailDebug(@"could not parse signature body."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"could not parse signature body."); return NO; } // Compare the first N bytes of the quote data with the signed quote body. const NSUInteger kQuoteBodyComparisonLength = 432; if (signatureBodyEntity.isvEnclaveQuoteBody.length < kQuoteBodyComparisonLength) { - OWSFailDebug(@"isvEnclaveQuoteBody has unexpected length."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"isvEnclaveQuoteBody has unexpected length."); return NO; } // NOTE: This version is separate from and does _NOT_ match the CDS quote version. const NSUInteger kSignatureBodyVersion = 3; if (![signatureBodyEntity.version isEqual:@(kSignatureBodyVersion)]) { - OWSFailDebug(@"signatureBodyEntity has unexpected version."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"signatureBodyEntity has unexpected version."); return NO; } if (quoteData.length < kQuoteBodyComparisonLength) { - OWSFailDebug(@"quoteData has unexpected length."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"quoteData has unexpected length."); return NO; } NSData *isvEnclaveQuoteBodyForComparison = [signatureBodyEntity.isvEnclaveQuoteBody subdataWithRange:NSMakeRange(0, kQuoteBodyComparisonLength)]; NSData *quoteDataForComparison = [quoteData subdataWithRange:NSMakeRange(0, kQuoteBodyComparisonLength)]; if (![isvEnclaveQuoteBodyForComparison ows_constantTimeIsEqualToData:quoteDataForComparison]) { - OWSFailDebug(@"isvEnclaveQuoteBody and quoteData do not match."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAttestationFailed, @"isvEnclaveQuoteBody and quoteData do not match."); return NO; } if (![@"OK" isEqualToString:signatureBodyEntity.isvEnclaveQuoteStatus]) { - OWSFailDebug(@"invalid isvEnclaveQuoteStatus: %@.", signatureBodyEntity.isvEnclaveQuoteStatus); + NSString *reason = + [NSString stringWithFormat:@"invalid isvEnclaveQuoteStatus: %@", signatureBodyEntity.isvEnclaveQuoteStatus]; + *error = ContactDiscoveryServiceErrorMakeWithReason(ContactDiscoveryServiceErrorAttestationFailed, reason); return NO; } @@ -567,7 +624,8 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont [dateFormatter setDateFormat:@"yyy-MM-dd'T'HH:mm:ss.SSSSSS"]; NSDate *timestampDate = [dateFormatter dateFromString:signatureBodyEntity.timestamp]; if (!timestampDate) { - OWSFailDebug(@"could not parse signature body timestamp."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAssertionError, @"could not parse signature body timestamp."); return NO; } @@ -581,7 +639,8 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont BOOL isExpired = [now isAfterDate:timestampDatePlus1Day]; if (isExpired) { - OWSFailDebug(@"Signature is expired."); + *error = ContactDiscoveryServiceErrorMakeWithReason( + ContactDiscoveryServiceErrorAttestationFailed, @"Signature is expired."); return NO; } diff --git a/SignalServiceKit/src/Contacts/OWSContactDiscoveryOperation.swift b/SignalServiceKit/src/Contacts/OWSContactDiscoveryOperation.swift index b55b7eaab..e3dd4c81e 100644 --- a/SignalServiceKit/src/Contacts/OWSContactDiscoveryOperation.swift +++ b/SignalServiceKit/src/Contacts/OWSContactDiscoveryOperation.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -400,11 +400,11 @@ class CDSBatchOperation: OWSOperation { class CDSFeedbackOperation: OWSOperation { - enum FeedbackResult: String { + enum FeedbackResult { case ok case mismatch - case attestationError = "attestation-error" - case unexpectedError = "unexpected-error" + case attestationError(reason: String) + case unexpectedError(reason: String) } private let legacyRegisteredRecipientIds: Set @@ -455,10 +455,22 @@ class CDSFeedbackOperation: OWSOperation { case ContactDiscoveryError.serverError, ContactDiscoveryError.clientError: // Server already has this information, no need submit feedback self.reportSuccess() - case ContactDiscoveryServiceError.attestationFailed: - self.makeRequest(result: .attestationError) + case let cdsError as ContactDiscoveryServiceError: + let reason = cdsError.reason + switch cdsError.code { + case .assertionError: + self.makeRequest(result: .unexpectedError(reason: "CDS assertionError: \(reason ?? "unknown")")) + case .attestationFailed: + self.makeRequest(result: .attestationError(reason: "CDS attestationFailed: \(reason ?? "unknown")")) + } + case ContactDiscoveryError.assertionError(let assertionDescription): + self.makeRequest(result: .unexpectedError(reason: "assertionError: \(assertionDescription)")) + case ContactDiscoveryError.parseError(description: let parseErrorDescription): + self.makeRequest(result: .unexpectedError(reason: "parseError: \(parseErrorDescription)")) default: - self.makeRequest(result: .unexpectedError) + let nsError = error as NSError + let reason = "unexpectedError code:\(nsError.code)" + self.makeRequest(result: .unexpectedError(reason: reason)) } return @@ -474,7 +486,18 @@ class CDSFeedbackOperation: OWSOperation { } func makeRequest(result: FeedbackResult) { - let request = OWSRequestFactory.cdsFeedbackRequest(result: result.rawValue) + let reason: String? + switch result { + case .ok: + reason = nil + case .mismatch: + reason = nil + case .attestationError(let attestationErrorReason): + reason = attestationErrorReason + case .unexpectedError(let unexpectedErrorReason): + reason = unexpectedErrorReason + } + let request = OWSRequestFactory.cdsFeedbackRequest(status: result.statusPath, reason: reason) self.networkManager.makeRequest(request, success: { _, _ in self.reportSuccess() }, failure: { _, error in self.reportError(error) }) @@ -488,3 +511,24 @@ extension Array { } } } + +extension CDSFeedbackOperation.FeedbackResult { + var statusPath: String { + switch self { + case .ok: + return "ok" + case .mismatch: + return "mismatch" + case .attestationError: + return "attestation-error" + case .unexpectedError: + return "unexpected-error" + } + } +} + +extension ContactDiscoveryServiceError { + var reason: String? { + return userInfo[ContactDiscoveryServiceErrorKey_Reason] as? String + } +} diff --git a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h index b7ef07a7c..197009257 100644 --- a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h +++ b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // NS_ASSUME_NONNULL_BEGIN @@ -102,7 +102,8 @@ typedef NS_ENUM(NSUInteger, TSVerificationTransport) { TSVerificationTransportVo cookies:(NSArray *)cookies; + (TSRequest *)remoteAttestationAuthRequest; -+ (TSRequest *)cdsFeedbackRequestWithResult:(NSString *)result NS_SWIFT_NAME(cdsFeedbackRequest(result:)); ++ (TSRequest *)cdsFeedbackRequestWithStatus:(NSString *)status + reason:(nullable NSString *)reason NS_SWIFT_NAME(cdsFeedbackRequest(status:reason:)); #pragma mark - UD diff --git a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m index bc2e4b6ae..c9e394a96 100644 --- a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m +++ b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "OWSRequestFactory.h" @@ -490,10 +490,18 @@ NS_ASSUME_NONNULL_BEGIN return [TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"GET" parameters:@{}]; } -+ (TSRequest *)cdsFeedbackRequestWithResult:(NSString *)result ++ (TSRequest *)cdsFeedbackRequestWithStatus:(NSString *)status + reason:(nullable NSString *)reason { - NSString *path = [NSString stringWithFormat:@"/v1/directory/feedback/%@", result]; - return [TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"PUT" parameters:@{}]; + + NSDictionary *parameters; + if (reason == nil) { + parameters = @{}; + } else { + parameters = @{ @"reason": reason }; + } + NSString *path = [NSString stringWithFormat:@"/v1/directory/feedback-v2/%@", status]; + return [TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"PUT" parameters:parameters]; } #pragma mark - UD From 62784a477afb1a5de8a2c6c4c56b0c583c9a8248 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 11 Feb 2019 16:28:05 -0700 Subject: [PATCH 02/14] fix staging url --- Signal/Signal-Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 319894846..4ac614c6b 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -69,7 +69,7 @@ NSThirdPartyExceptionRequiresForwardSecrecy - api-staging.directory.signal.org + api-staging.directory.signal.org NSExceptionAllowsInsecureHTTPLoads From 0d5d5c6932b3e04a7f5f57087d5215c3a2a3bbc5 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 12 Feb 2019 10:04:56 -0700 Subject: [PATCH 03/14] limit reason length --- .../src/Contacts/ContactDiscoveryService.m | 2 +- .../src/Network/API/Requests/OWSRequestFactory.m | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m index e34114488..cb373c9ed 100644 --- a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m +++ b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m @@ -406,7 +406,7 @@ NSError *ContactDiscoveryServiceErrorMakeWithReason(NSInteger code, NSString *re OWSAssertDebug(enclaveId.length > 0); if (![response isKindOfClass:[NSHTTPURLResponse class]]) { - OWSFailDebug(@"unexpected response type."); + *error = ContactDiscoveryServiceErrorMakeWithReason(ContactDiscoveryServiceErrorAssertionError, @"unexpected response type."); return nil; } NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; diff --git a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m index c9e394a96..1b0c08600 100644 --- a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m +++ b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m @@ -498,7 +498,15 @@ NS_ASSUME_NONNULL_BEGIN if (reason == nil) { parameters = @{}; } else { - parameters = @{ @"reason": reason }; + const NSUInteger kServerReasonLimit = 1000; + NSString *limitedReason; + if (reason.length < kServerReasonLimit) { + limitedReason = reason; + } else { + OWSFailDebug(@"failure: reason should be under 1000"); + limitedReason = [reason substringToIndex:kServerReasonLimit - 1]; + } + parameters = @{ @"reason": limitedReason }; } NSString *path = [NSString stringWithFormat:@"/v1/directory/feedback-v2/%@", status]; return [TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"PUT" parameters:parameters]; From cb3a36ba3d2b50af416a4dd8c3ec83d25df6275e Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 12 Feb 2019 16:57:37 -0700 Subject: [PATCH 04/14] Platform specific notification clearing --- Signal/src/AppDelegate.m | 5 +++-- .../LegacyNotificationsAdaptee.swift | 7 +++++++ Signal/src/environment/SignalApp.h | 1 - Signal/src/environment/SignalApp.m | 18 ++---------------- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index ca35cfd8b..a12247045 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -732,7 +732,7 @@ static NSTimeInterval launchStartedAt; OWSLogInfo(@"running post launch block for unregistered user."); // Unregistered user should have no unread messages. e.g. if you delete your account. - [SignalApp clearAllNotifications]; + [AppEnvironment.shared.notificationPresenter clearAllNotifications]; [self.socketManager requestSocketOpen]; @@ -791,6 +791,7 @@ static NSTimeInterval launchStartedAt; OWSLogWarn(@"applicationWillResignActive."); [self updateShouldEnableLandscape]; + [self clearAllNotificationsAndRestoreBadgeCount]; [DDLog flushLog]; } @@ -799,8 +800,8 @@ static NSTimeInterval launchStartedAt; { OWSAssertIsOnMainThread(); - [SignalApp clearAllNotifications]; [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + [AppEnvironment.shared.notificationPresenter clearAllNotifications]; [OWSMessageUtils.sharedManager updateApplicationBadgeCount]; }]; } diff --git a/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift b/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift index 5ec257521..cc326e3b3 100644 --- a/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift +++ b/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift @@ -222,6 +222,13 @@ extension LegacyNotificationPresenterAdaptee: NotificationPresenterAdaptee { for (_, notification) in notifications { cancelNotification(notification) } + // This will cancel all "scheduled" local notifications that haven't + // been presented yet. + UIApplication.shared.cancelAllLocalNotifications() + // To clear all already presented local notifications, we need to + // set the app badge number to zero after setting it to a non-zero value. + UIApplication.shared.applicationIconBadgeNumber = 1 + UIApplication.shared.applicationIconBadgeNumber = 0 } } diff --git a/Signal/src/environment/SignalApp.h b/Signal/src/environment/SignalApp.h index ebf2ae8a4..b3b5fb9dc 100644 --- a/Signal/src/environment/SignalApp.h +++ b/Signal/src/environment/SignalApp.h @@ -50,7 +50,6 @@ NS_ASSUME_NONNULL_BEGIN + (void)resetAppData; -+ (void)clearAllNotifications; - (void)showHomeView; diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index 1b7f2a2df..1eb5f764b 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "SignalApp.h" @@ -138,26 +138,12 @@ NS_ASSUME_NONNULL_BEGIN [OWSStorage resetAllStorage]; [OWSUserProfile resetProfileStorage]; [Environment.shared.preferences clear]; - - [self clearAllNotifications]; + [AppEnvironment.shared.notificationPresenter clearAllNotifications]; [DebugLogger.sharedLogger wipeLogs]; exit(0); } -+ (void)clearAllNotifications -{ - OWSLogInfo(@"clearAllNotifications."); - - // This will cancel all "scheduled" local notifications that haven't - // been presented yet. - [UIApplication.sharedApplication cancelAllLocalNotifications]; - // To clear all already presented local notifications, we need to - // set the app badge number to zero after setting it to a non-zero value. - [UIApplication sharedApplication].applicationIconBadgeNumber = 1; - [UIApplication sharedApplication].applicationIconBadgeNumber = 0; -} - - (void)showHomeView { HomeViewController *homeView = [HomeViewController new]; From 5e0c10a1a9cce1abf8eb891192e18955918da328 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 12 Feb 2019 17:11:27 -0700 Subject: [PATCH 05/14] remove any lingering legacy notifications in modern notification adapter --- .../Notifications/LegacyNotificationsAdaptee.swift | 4 ++++ .../Notifications/UserNotificationsAdaptee.swift | 1 + 2 files changed, 5 insertions(+) diff --git a/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift b/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift index cc326e3b3..f44aac478 100644 --- a/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift +++ b/Signal/src/UserInterface/Notifications/LegacyNotificationsAdaptee.swift @@ -222,6 +222,10 @@ extension LegacyNotificationPresenterAdaptee: NotificationPresenterAdaptee { for (_, notification) in notifications { cancelNotification(notification) } + type(of: self).clearExistingNotifications() + } + + public class func clearExistingNotifications() { // This will cancel all "scheduled" local notifications that haven't // been presented yet. UIApplication.shared.cancelAllLocalNotifications() diff --git a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift index 6b037c8aa..412ed633c 100644 --- a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift +++ b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift @@ -181,6 +181,7 @@ extension UserNotificationPresenterAdaptee: NotificationPresenterAdaptee { AssertIsOnMainThread() notificationCenter.removeAllPendingNotificationRequests() notificationCenter.removeAllDeliveredNotifications() + LegacyNotificationPresenterAdaptee.clearExistingNotifications() } func shouldPresentNotification(category: AppNotificationCategory, userInfo: [AnyHashable: Any]) -> Bool { From eae341a72382c309fd69a384d55ce4169c730ce0 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 12 Feb 2019 17:20:39 -0700 Subject: [PATCH 06/14] sync translations --- .../translations/ca.lproj/Localizable.strings | 10 +- .../translations/cs.lproj/Localizable.strings | 176 +++++++++--------- .../translations/da.lproj/Localizable.strings | 26 +-- .../translations/el.lproj/Localizable.strings | 2 +- .../translations/es.lproj/Localizable.strings | 4 +- .../translations/et.lproj/Localizable.strings | 2 +- .../translations/fi.lproj/Localizable.strings | 10 +- .../translations/he.lproj/Localizable.strings | 10 +- .../translations/it.lproj/Localizable.strings | 10 +- .../translations/nb.lproj/Localizable.strings | 10 +- .../translations/nl.lproj/Localizable.strings | 20 +- .../translations/pl.lproj/Localizable.strings | 10 +- .../pt_BR.lproj/Localizable.strings | 26 +-- .../translations/sv.lproj/Localizable.strings | 12 +- .../translations/tr.lproj/Localizable.strings | 20 +- .../zh_CN.lproj/Localizable.strings | 10 +- 16 files changed, 179 insertions(+), 179 deletions(-) diff --git a/Signal/translations/ca.lproj/Localizable.strings b/Signal/translations/ca.lproj/Localizable.strings index 2feb281f8..5aed148c1 100644 --- a/Signal/translations/ca.lproj/Localizable.strings +++ b/Signal/translations/ca.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Es necessita accés al micròfon"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Trucada entrant"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Telefona"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Trucada perduda perquè el número de seguretat de l'emissor ha canviat."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Trucada perduda"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Sense resposta"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Membre"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ a %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Nom d'aquest grup"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Envia"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "El teu missatge no s'ha enviat."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Ha fallat l'enviament de la invitació, torneu a provar-ho més tard."; diff --git a/Signal/translations/cs.lproj/Localizable.strings b/Signal/translations/cs.lproj/Localizable.strings index 6d683556f..fe3f85752 100644 --- a/Signal/translations/cs.lproj/Localizable.strings +++ b/Signal/translations/cs.lproj/Localizable.strings @@ -8,7 +8,7 @@ "ACTION_AUDIO_CALL" = "Hovor Signal"; /* Label for 'invite' button in contact view. */ -"ACTION_INVITE" = "Pozvat do aplikace Signal"; +"ACTION_INVITE" = "Pozvat do Signalu"; /* Label for 'send message' button in contact view. Label for button that lets you send a message to a contact. */ @@ -60,7 +60,7 @@ "APN_Message" = "Nová zpráva!"; /* Message for the 'app launch failed' alert. */ -"APP_LAUNCH_FAILURE_ALERT_MESSAGE" = "Aplikaci Signal nelze spustit. Odešlete prosím debug log na support@signal.org, pokusíme se problém opravit."; +"APP_LAUNCH_FAILURE_ALERT_MESSAGE" = "Signal nelze spustit. Odešlete prosím debug log na support@signal.org, pokusíme se problém opravit."; /* Title for the 'app launch failed' alert. */ "APP_LAUNCH_FAILURE_ALERT_TITLE" = "Chyba"; @@ -75,7 +75,7 @@ "APP_UPDATE_NAG_ALERT_MESSAGE_FORMAT" = "V App Storu je nyní dostupná verze %@."; /* Title for the 'new app version available' alert. */ -"APP_UPDATE_NAG_ALERT_TITLE" = "Je dostupná nová verze aplikace Signal"; +"APP_UPDATE_NAG_ALERT_TITLE" = "Je dostupná nová verze Signalu"; /* Label for the 'update' button in the 'new app version available' alert. */ "APP_UPDATE_NAG_ALERT_UPDATE_BUTTON" = "Aktualizovat"; @@ -294,7 +294,7 @@ "BLOCK_OFFER_ACTIONSHEET_TITLE_FORMAT" = "Zablokovat %@?"; /* An explanation of the consequences of blocking another user. */ -"BLOCK_USER_BEHAVIOR_EXPLANATION" = "Zablokovaní uživatelé vám nebudou moci zavolat nebo vám posílat zprávy."; +"BLOCK_USER_BEHAVIOR_EXPLANATION" = "Zablokovaní uživatelé vám nebudou moci zavolat nebo posílat zprávy."; /* Label for 'continue' button. */ "BUTTON_CONTINUE" = "Pokračovat"; @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Vyžadován přístup k mikrofonu"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Příchozí hovor"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Zavolat"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Zmeškaný hovor. Změnilo se bezpečnostní číslo volajícího."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Zmeškaný hovor"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Žádná odpověď"; @@ -363,10 +363,10 @@ "CALL_VIEW_MUTE_LABEL" = "Ztlumit"; /* Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy. */ -"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL" = "Můžete povolit integraci s iOS hovory v nastavení soukromí aplikace Signal, abyste mohli přijímat příchozí hovory ze zamčené obrazovky."; +"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL" = "Můžete povolit integraci s iOS hovory v nastavení soukromí Signalu, abyste mohli přijímat příchozí hovory ze zamčené obrazovky."; /* Reminder to the user of the benefits of disabling CallKit privacy. */ -"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_PRIVACY" = "Můžete povolit integraci s iOS hovory v nastavení soukromí aplikace Signal, abyste mohli vidět jméno a telefonní číslo pro příchozí hovory."; +"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_PRIVACY" = "Můžete povolit integraci s iOS hovory v nastavení soukromí Signalu, abyste uviděli jméno a telefonní číslo příchozích hovorů."; /* Label for button that dismiss the call view's settings nag. */ "CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON" = "Nyní ne"; @@ -375,13 +375,13 @@ "CALL_VIEW_SETTINGS_NAG_SHOW_CALL_SETTINGS" = "Zobrazit nastavení soukromí"; /* Accessibility label to toggle front- vs. rear-facing camera */ -"CALL_VIEW_SWITCH_CAMERA_DIRECTION" = "Přepnout kameru"; +"CALL_VIEW_SWITCH_CAMERA_DIRECTION" = "Převrátit kameru"; /* Accessibility label to switch to audio only */ "CALL_VIEW_SWITCH_TO_AUDIO_LABEL" = "Přepnout na audio hovor"; /* Accessibility label to switch to video call */ -"CALL_VIEW_SWITCH_TO_VIDEO_LABEL" = "Přepnout na video hovor"; +"CALL_VIEW_SWITCH_TO_VIDEO_LABEL" = "Přepnout na videohovor"; /* Label for the 'return to call' banner. */ "CALL_WINDOW_RETURN_TO_CALL" = "Klepněte pro návrat k hovoru"; @@ -390,7 +390,7 @@ "CALLBACK_BUTTON_TITLE" = "Zavolat zpět"; /* The generic name used for calls if CallKit privacy is enabled */ -"CALLKIT_ANONYMOUS_CONTACT_NAME" = "Uživatel aplikace Signal"; +"CALLKIT_ANONYMOUS_CONTACT_NAME" = "Uživatel Signalu"; /* Message for alert explaining that a user cannot be verified. */ "CANT_VERIFY_IDENTITY_ALERT_MESSAGE" = "Tento uživatel nemůže být ověřen, dokud neodešlete zprávu."; @@ -414,13 +414,13 @@ "CHECK_FOR_BACKUP_RESTORE" = "Obnovení"; /* Error indicating that the app could not determine that user's iCloud account status */ -"CLOUDKIT_STATUS_COULD_NOT_DETERMINE" = "Nebylo možné zjistit stav účtu iCloud. Přihlašte se do svého účtu iCloud v nastavení iOS pro zálohování dat v Signalu."; +"CLOUDKIT_STATUS_COULD_NOT_DETERMINE" = "Nebylo možné zjistit stav účtu iCloud. Přihlašte se do svého účtu iCloud v nastavení iOS pro zálohování dat Signalu."; /* Error indicating that user does not have an iCloud account. */ -"CLOUDKIT_STATUS_NO_ACCOUNT" = "Žádný účet iCloud. Přihlašte se do svého účtu iCloud v nastavení iOS pro zálohování dat v Signalu."; +"CLOUDKIT_STATUS_NO_ACCOUNT" = "Žádný účet iCloud. Přihlašte se do svého účtu iCloud v nastavení iOS pro zálohování dat Signalu."; /* Error indicating that the app was prevented from accessing the user's iCloud account. */ -"CLOUDKIT_STATUS_RESTRICTED" = "Signalu byl odepřen přístup k účtu iCloud pro vytvoření zálohy. Povolte Signalu přístup k vašemu účtu iCloud v nastavení iOS pro zálohování dat."; +"CLOUDKIT_STATUS_RESTRICTED" = "Signalu byl odepřen přístup k účtu iCloud pro vytvoření zálohy. Pro zálohování dat povolte Signalu přístup k vašemu účtu iCloud v nastavení iOS."; /* The first of two messages demonstrating the chosen conversation color, by rendering this message in an outgoing message bubble. */ "COLOR_PICKER_DEMO_MESSAGE_1" = "Vyberte barvu odchozích zpráv v této konverzaci."; @@ -486,7 +486,7 @@ "CONTACT_EDIT_NAME_BUTTON" = "Upravit"; /* Label for a contact's email address. */ -"CONTACT_EMAIL" = "Email"; +"CONTACT_EMAIL" = "E-mail"; /* Label for the 'city' field of a contact's address. */ "CONTACT_FIELD_ADDRESS_CITY" = "Město"; @@ -516,13 +516,13 @@ "CONTACT_FIELD_GIVEN_NAME" = "Křestní jméno"; /* Label for the 'middle name' field of a contact. */ -"CONTACT_FIELD_MIDDLE_NAME" = "Prostřední jméno"; +"CONTACT_FIELD_MIDDLE_NAME" = "Druhé jméno"; /* Label for the 'name prefix' field of a contact. */ -"CONTACT_FIELD_NAME_PREFIX" = "Titul před jménem"; +"CONTACT_FIELD_NAME_PREFIX" = "Před jménem"; /* Label for the 'name suffix' field of a contact. */ -"CONTACT_FIELD_NAME_SUFFIX" = "Titul za jménem"; +"CONTACT_FIELD_NAME_SUFFIX" = "Za jménem"; /* Label for the 'organization' field of a contact. */ "CONTACT_FIELD_ORGANIZATION" = "Organizace"; @@ -552,7 +552,7 @@ "CONTACT_SHARE_NO_FIELDS_SELECTED" = "Nebylo vybráno žádné pole kontaktu."; /* Label for 'open address in maps app' button in contact view. */ -"CONTACT_VIEW_OPEN_ADDRESS_IN_MAPS_APP" = "Otevřít v mapách"; +"CONTACT_VIEW_OPEN_ADDRESS_IN_MAPS_APP" = "Otevřít v Mapách"; /* Label for 'open email in email app' button in contact view. */ "CONTACT_VIEW_OPEN_EMAIL_IN_EMAIL_APP" = "Poslat email"; @@ -570,7 +570,7 @@ "CONVERSATION_SETTINGS" = "Nastavení konverzace"; /* Label for 'new contact' button in conversation settings view. */ -"CONVERSATION_SETTINGS_ADD_TO_EXISTING_CONTACT" = "Přidat k existujícímu kontaktu"; +"CONVERSATION_SETTINGS_ADD_TO_EXISTING_CONTACT" = "Přidat ke kontaktu"; /* table cell label in conversation settings */ "CONVERSATION_SETTINGS_BLOCK_THIS_GROUP" = "Zablokovat tuto skupinu"; @@ -594,7 +594,7 @@ "CONVERSATION_SETTINGS_MUTE_LABEL" = "Ztlumit"; /* Indicates that the current thread is not muted. */ -"CONVERSATION_SETTINGS_MUTE_NOT_MUTED" = "Neztlumen"; +"CONVERSATION_SETTINGS_MUTE_NOT_MUTED" = "Není ztlumeno"; /* Label for button to mute a thread for a day. */ "CONVERSATION_SETTINGS_MUTE_ONE_DAY_ACTION" = "Ztlumit na den"; @@ -672,7 +672,7 @@ "DATABASE_VIEW_OVERLAY_SUBTITLE" = "Toto může pár minut trvat."; /* Title shown while the app is updating its database. */ -"DATABASE_VIEW_OVERLAY_TITLE" = "Optimalizuji databázi"; +"DATABASE_VIEW_OVERLAY_TITLE" = "Optimalizace databáze"; /* Format string for a relative time, expressed as a certain number of hours in the past. Embeds {{The number of hours}}. */ "DATE_HOURS_AGO_FORMAT" = "před %@h"; @@ -739,7 +739,7 @@ "DEREGISTRATION_REREGISTER_WITH_SAME_PHONE_NUMBER" = "Znovu zaregistrovat toto telefonní číslo"; /* Label warning the user that they have been de-registered. */ -"DEREGISTRATION_WARNING" = "Zařízení již není registrováno. Vaše telefonní číslo může být registrováno v aplikaci Signal na jiném zařízení. Klepněte pro opětovnou registraci."; +"DEREGISTRATION_WARNING" = "Zařízení již není registrováno. Je možné, že je vaše telefonní číslo registrováno v aplikaci Signal na jiném zařízení. Klepněte pro opětovnou registraci."; /* {{Short Date}} when device last communicated with Signal Server. */ "DEVICE_LAST_ACTIVE_AT_LABEL" = "Naposledy aktivní: %@"; @@ -757,7 +757,7 @@ "DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT" = "Zprávy v konverzaci zmizí za %@."; /* subheading in conversation settings */ -"DISAPPEARING_MESSAGES_DESCRIPTION" = "Pokud je povoleno, odeslané a přiaté zprávy v této konverzaci zmizí, jakmile budou viděny."; +"DISAPPEARING_MESSAGES_DESCRIPTION" = "Pokud je povoleno, odeslané a přijaté zprávy v této konverzaci zmizí, jakmile budou zobrazeny."; /* Accessibility hint that contains current timeout information */ "DISAPPEARING_MESSAGES_HINT" = "Nyní zprávy zmizí po %@"; @@ -775,7 +775,7 @@ "EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_BODY" = "Můžete povolit přístup v nastavení iOS."; /* Alert title for when the user has just tried to edit a contacts after declining to give Signal contacts permissions */ -"EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_TITLE" = "Aplikace Signal pro úpravu informací kontaktu vyžaduje přístup ke kontaktům."; +"EDIT_CONTACT_WITHOUT_CONTACTS_PERMISSION_ALERT_TITLE" = "Signal pro úpravu informací o kontaktu vyžaduje přístup ke kontaktům."; /* table cell label in conversation settings */ "EDIT_GROUP_ACTION" = "Upravit skupinu"; @@ -799,7 +799,7 @@ "EDIT_GROUP_UPDATE_BUTTON" = "Aktualizovat"; /* The alert message if user tries to exit update group view without saving changes. */ -"EDIT_GROUP_VIEW_UNSAVED_CHANGES_MESSAGE" = "Chcete uložit změny vykonané na této skupině?"; +"EDIT_GROUP_VIEW_UNSAVED_CHANGES_MESSAGE" = "Změnil(a) jste tuto skupinu. Chcete tyto změny uložit?"; /* The alert title if user tries to exit update group view without saving changes. */ "EDIT_GROUP_VIEW_UNSAVED_CHANGES_TITLE" = "Neuložené změny"; @@ -823,7 +823,7 @@ "EMPTY_ARCHIVE_TITLE" = "Vyčistit váš seznam konverzací."; /* Full width label displayed when attempting to compose message */ -"EMPTY_CONTACTS_LABEL_LINE1" = "Žádný z vašich kontaktů nemá aplikaci Signal."; +"EMPTY_CONTACTS_LABEL_LINE1" = "Žádný z vašich kontaktů nemá Signal."; /* Full width label displayed when attempting to compose message */ "EMPTY_CONTACTS_LABEL_LINE2" = "Proč někoho nepozvete?"; @@ -832,13 +832,13 @@ "EMPTY_INBOX_NEW_USER_TEXT" = "Klepněte na tlačítko vytvořit."; /* Header text a new user sees when viewing an empty inbox */ -"EMPTY_INBOX_NEW_USER_TITLE" = "Zahajte vaši první konverzaci Signal!"; +"EMPTY_INBOX_NEW_USER_TITLE" = "Začněte vaši první konverzaci na Signalu!"; /* Body text an existing user sees when viewing an empty inbox */ "EMPTY_INBOX_TEXT" = "Nula nula nic."; /* Header text an existing user sees when viewing an empty inbox */ -"EMPTY_INBOX_TITLE" = "Schránka prázdná, nikde nic."; +"EMPTY_INBOX_TITLE" = "Schránka prázdná, velký kulový."; /* Indicates that user should confirm their 'two factor auth pin'. */ "ENABLE_2FA_VIEW_CONFIRM_PIN_INSTRUCTIONS" = "Potvrďte Váš PIN."; @@ -862,13 +862,13 @@ "ENABLE_2FA_VIEW_PIN_DOES_NOT_MATCH" = "Zadaný PIN nesouhlasí."; /* Indicates that user should select a 'two factor auth pin'. */ -"ENABLE_2FA_VIEW_SELECT_PIN_INSTRUCTIONS" = "Zadejte PIN registrace. Při změně přístroje s tímto telefonním číslem budete na tento PIN dotázán."; +"ENABLE_2FA_VIEW_SELECT_PIN_INSTRUCTIONS" = "Zadejte PIN zámku registrace. Při příští registraci pod tímto telefonním číslem budete na PIN dotázán(a)."; /* Indicates that user has 'two factor auth pin' disabled. */ -"ENABLE_2FA_VIEW_STATUS_DISABLED_INSTRUCTIONS" = "Pro zvýšení bezpečnosti zapněte registrační PIN, který bude vyžadován při změně přístroje s tímto telefonním číslem v aplikaci Signal."; +"ENABLE_2FA_VIEW_STATUS_DISABLED_INSTRUCTIONS" = "Pro zvýšení bezpečnosti povolte PIN zámku registrace, který bude v aplikaci Signal vyžadován při příští registraci pod tímto telefonním číslem."; /* Indicates that user has 'two factor auth pin' enabled. */ -"ENABLE_2FA_VIEW_STATUS_ENABLED_INSTRUCTIONS" = "Registrační zámek je povolen. Budete požádán(a) o zadání PINu při změně přístroje s tímto telefonním číslem v aplikaci Signal."; +"ENABLE_2FA_VIEW_STATUS_ENABLED_INSTRUCTIONS" = "Zámek registrace je povolen. Budete požádán(a) o zadání PINu při příští registraci pod tímto telefonním číslem."; /* Title for the 'enable two factor auth PIN' views. */ "ENABLE_2FA_VIEW_TITLE" = "Zámek registrace"; @@ -880,7 +880,7 @@ "END_CALL_UNCATEGORIZED_FAILURE" = "Hovor selhal."; /* Error indicating that the phone's contacts could not be retrieved. */ -"ERROR_COULD_NOT_FETCH_CONTACTS" = "Nelze přistoupit ke kontaktům"; +"ERROR_COULD_NOT_FETCH_CONTACTS" = "Nelze přistoupit ke kontaktům."; /* Generic notice when message failed to send. */ "ERROR_DESCRIPTION_CLIENT_SENDING_FAILURE" = "Nepodařilo se odeslat zprávu."; @@ -898,7 +898,7 @@ "ERROR_DESCRIPTION_NO_INTERNET" = "Signal se nemohl připojit k internetu. Prosím zkuste to znovu."; /* Error indicating that an outgoing message had no valid recipients. */ -"ERROR_DESCRIPTION_NO_VALID_RECIPIENTS" = "Poslání zprávy selhalo z důvodu platných příjemců."; +"ERROR_DESCRIPTION_NO_VALID_RECIPIENTS" = "Odesílání zprávy selhalo z důvodu neplatných příjemců."; /* Error indicating that a socket request failed. */ "ERROR_DESCRIPTION_REQUEST_FAILED" = "Síťová žádost selhala."; @@ -919,10 +919,10 @@ "ERROR_DESCRIPTION_UNKNOWN_ERROR" = "Došlo k neznámé chybě."; /* Error message when attempting to send message */ -"ERROR_DESCRIPTION_UNREGISTERED_RECIPIENT" = "Kontakt není uživatelem aplikace Signal."; +"ERROR_DESCRIPTION_UNREGISTERED_RECIPIENT" = "Kontakt není uživatelem Signalu."; /* Error message when unable to receive an attachment because the sending client is too old. */ -"ERROR_MESSAGE_ATTACHMENT_FROM_OLD_CLIENT" = "Chyba přílohy: Odesílatel musí aktualizovat aplikaci Signal a odeslat zprávu znovu."; +"ERROR_MESSAGE_ATTACHMENT_FROM_OLD_CLIENT" = "Chyba přílohy: Požádejte odesílatele, aby aktualizoval(a) Signal a odeslal(a) zprávu znovu."; /* No comment provided by engineer. */ "ERROR_MESSAGE_DUPLICATE_MESSAGE" = "Přijata duplikovaná zpráva."; @@ -1084,13 +1084,13 @@ "IMAGE_EDITOR_BRUSH_BUTTON" = "Brush"; /* Label for crop button in image editor. */ -"IMAGE_EDITOR_CROP_BUTTON" = "Crop"; +"IMAGE_EDITOR_CROP_BUTTON" = "Oříznout"; /* Momentarily shown to the user when attempting to select more images than is allowed. Embeds {{max number of items}} that can be shared. */ -"IMAGE_PICKER_CAN_SELECT_NO_MORE_TOAST_FORMAT" = "You can't share more than %@ items."; +"IMAGE_PICKER_CAN_SELECT_NO_MORE_TOAST_FORMAT" = "Nemůžete sdílet více než %@ položek."; /* alert title */ -"IMAGE_PICKER_FAILED_TO_PROCESS_ATTACHMENTS" = "Failed to select attachment."; +"IMAGE_PICKER_FAILED_TO_PROCESS_ATTACHMENTS" = "Nepodařilo se odeslat přílohu."; /* Call setup status label */ "IN_CALL_CONNECTING" = "Připojování…"; @@ -1135,7 +1135,7 @@ "INVITE_FLOW_REQUIRES_CONTACT_ACCESS_TITLE" = "Povolit přístup ke kontaktům"; /* Label for the cell that presents the 'invite contacts' workflow. */ -"INVITE_FRIENDS_CONTACT_TABLE_BUTTON" = "Pozvat přátele do aplikace Signal"; +"INVITE_FRIENDS_CONTACT_TABLE_BUTTON" = "Pozvat přátele do Signalu"; /* Search */ "INVITE_FRIENDS_PICKER_SEARCHBAR_PLACEHOLDER" = "Hledat"; @@ -1162,7 +1162,7 @@ "LINK_DEVICE_INVALID_CODE_BODY" = "Tento QR kód je neplatný. Ujistěte se prosím, že snímáte QR kód ze zařízení, které chcete připojit."; /* report an invalid linking code */ -"LINK_DEVICE_INVALID_CODE_TITLE" = "Propojení zařízení selhalo"; +"LINK_DEVICE_INVALID_CODE_TITLE" = "Připojení zařízení selhalo"; /* confirm the users intent to link a new device */ "LINK_DEVICE_PERMISSION_ALERT_BODY" = "Toto zařízení uvidí vaše skupiny a kontakty, bude mít přístup k vaším konverzacím a bude moct posílat zprávy ve vašem jménu."; @@ -1174,7 +1174,7 @@ "LINK_DEVICE_RESTART" = "Zkusit znovu"; /* QR Scanning screen instructions, placed alongside a camera view for scanning QR Codes */ -"LINK_DEVICE_SCANNING_INSTRUCTIONS" = "Pro připojení naskenujte QR kód zobrazený na zařízení, které chcete připojit."; +"LINK_DEVICE_SCANNING_INSTRUCTIONS" = "Naskenujte QR kód zobrazený na zařízení, které chcete připojit."; /* Subheading for 'Link New Device' navigation */ "LINK_NEW_DEVICE_SUBTITLE" = "Naskenovat QR kód"; @@ -1183,13 +1183,13 @@ "LINK_NEW_DEVICE_TITLE" = "Připojit nové zařízení"; /* Label for link previews with an unknown host. */ -"LINK_PREVIEW_UNKNOWN_DOMAIN" = "Link Preview"; +"LINK_PREVIEW_UNKNOWN_DOMAIN" = "Náhled odkazu"; /* Menu item and navbar title for the device manager */ "LINKED_DEVICES_TITLE" = "Připojená zařízení"; /* Alert Title */ -"LINKING_DEVICE_FAILED_TITLE" = "Propojení zařízení selhalo"; +"LINKING_DEVICE_FAILED_TITLE" = "Připojení zařízení selhalo"; /* table cell label in conversation settings */ "LIST_GROUP_MEMBERS_ACTION" = "Členové skupiny"; @@ -1240,7 +1240,7 @@ "MESSAGE_ACTION_DELETE_MESSAGE" = "Smazat tuto zprávu"; /* Action sheet button subtitle */ -"MESSAGE_ACTION_DELETE_MESSAGE_SUBTITLE" = "Bude pouze smazána na tomto zařízení."; +"MESSAGE_ACTION_DELETE_MESSAGE_SUBTITLE" = "Bude smazána pouze na tomto zařízení."; /* Action sheet button title */ "MESSAGE_ACTION_DETAILS" = "Více informací"; @@ -1380,7 +1380,7 @@ /* Alert title Alert title when camera is not authorized */ -"MISSING_CAMERA_PERMISSION_TITLE" = "Aplikace Signal vyžaduje přístup k vašemu fotoaparátu."; +"MISSING_CAMERA_PERMISSION_TITLE" = "Signal vyžaduje přístup k vašemu fotoaparátu."; /* Alert body when user has previously denied media library access */ "MISSING_MEDIA_LIBRARY_PERMISSION_MESSAGE" = "Tento souhlas můžete udělit v nastavení iOS."; @@ -1389,10 +1389,10 @@ "MISSING_MEDIA_LIBRARY_PERMISSION_TITLE" = "Tato funkce Signalu vyžaduje přístup k fotografiím."; /* alert title: cannot link - reached max linked devices */ -"MULTIDEVICE_PAIRING_MAX_DESC" = "Nemůžete propojit další zařízení."; +"MULTIDEVICE_PAIRING_MAX_DESC" = "Nemůžete připojit žádné další zařízení."; /* alert body: cannot link - reached max linked devices */ -"MULTIDEVICE_PAIRING_MAX_RECOVERY" = "Dosáhl(a) jste limitu počtu zařízení, které můžete připojit k vašemu účtu. Prosím odstraňte některé ze zařízení a zkuste to znovu."; +"MULTIDEVICE_PAIRING_MAX_RECOVERY" = "Dosáhl(a) jste maximálního počtu zařízení, které můžete připojit k vašemu účtu. Prosím odstraňte některé ze zařízení a zkuste to znovu."; /* An explanation of the consequences of muting a thread. */ "MUTE_BEHAVIOR_EXPLANATION" = "Pro ztlumené konverzace nebudete dostávat oznámení."; @@ -1440,10 +1440,10 @@ "NEW_GROUP_MEMBER_LABEL" = "Člen"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ v %@"; /* Placeholder text for group name field */ -"NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Pojmenujte tento skupinový chat"; +"NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Pojmenujte tuto skupinu"; /* a title for the non-contacts section of the 'new group' view. */ "NEW_GROUP_NON_CONTACTS_SECTION_TITLE" = "Ostatní uživatelé"; @@ -1467,7 +1467,7 @@ "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Najít kontakty pomocí telefonního čísla"; /* Label for 1:1 conversation with yourself. */ -"NOTE_TO_SELF" = "Note to Self"; +"NOTE_TO_SELF" = "Poznámka sobě"; /* Lock screen notification text presented after user powers on their device without unlocking. Embeds {{device model}} (either 'iPad' or 'iPhone') */ "NOTIFICATION_BODY_PHONE_LOCKED_FORMAT" = "Je možné, že byly přijaty nové zprávy zatímco váš %@ byl restartován."; @@ -1500,13 +1500,13 @@ "OPEN_SETTINGS_BUTTON" = "Nastavení"; /* Info Message when {{other user}} disables or doesn't support disappearing messages */ -"OTHER_DISABLED_DISAPPEARING_MESSAGES_CONFIGURATION" = "%@ zakázal mizející zprávy."; +"OTHER_DISABLED_DISAPPEARING_MESSAGES_CONFIGURATION" = "%@ zakázal(a) mizející zprávy."; /* Info Message when {{other user}} updates message expiration to {{time amount}}, see the *_TIME_AMOUNT strings for context. */ -"OTHER_UPDATED_DISAPPEARING_MESSAGES_CONFIGURATION" = "%@ nastavil čas mizejících zpráv na %@."; +"OTHER_UPDATED_DISAPPEARING_MESSAGES_CONFIGURATION" = "%@ nastavil(a) čas mizejících zpráv na %@."; /* Label warning the user that the Signal service may be down. */ -"OUTAGE_WARNING" = "Aplikace Signal se potýká s technickými problémy. Úsilovně pracujeme na co nejrychlejším obnovení služby."; +"OUTAGE_WARNING" = "Signal se potýká s technickými problémy. Usilovně pracujeme na co nejrychlejším obnovení služby."; /* info message text in conversation view */ "OUTGOING_CALL" = "Odchozí hovor"; @@ -1590,22 +1590,22 @@ "PRIVACY_VERIFICATION_FAILED_MISMATCHED_SAFETY_NUMBERS_IN_CLIPBOARD" = "Číslo ve vaší schránce nevypadá jako správné bezpečnostní číslo této konverzace."; /* Alert body for user error */ -"PRIVACY_VERIFICATION_FAILED_NO_SAFETY_NUMBERS_IN_CLIPBOARD" = "Aplikace Signal nemohla ve vaší schránce nalézt žádné bezpečnostní číslo. Zkopírovali jste ho správně?"; +"PRIVACY_VERIFICATION_FAILED_NO_SAFETY_NUMBERS_IN_CLIPBOARD" = "Signal nemohl ve vaší schránce nalézt žádné bezpečnostní číslo. Zkopíroval(a) jste ho správně?"; /* Alert body when verifying with {{contact name}} */ "PRIVACY_VERIFICATION_FAILED_THEY_HAVE_WRONG_KEY_FOR_ME" = "Každá dvojice uživatelů Signalu sdílí odlišné bezpečnostní číslo. Ověřte, že %@ zobrazuje *vaše* bezpečnostní číslo."; /* alert body */ -"PRIVACY_VERIFICATION_FAILED_WITH_OLD_LOCAL_VERSION" = "Používáte starou verzi aplikace Signal, před ověřením ji musíte aktualizovat."; +"PRIVACY_VERIFICATION_FAILED_WITH_OLD_LOCAL_VERSION" = "Používáte starou verzi Signalu, před ověřením ji musíte aktualizovat."; /* alert body */ "PRIVACY_VERIFICATION_FAILED_WITH_OLD_REMOTE_VERSION" = "Váš kontakt používá starou verzi Signalu a musí ji aktualizovat, než bude možné ověření."; /* alert body */ -"PRIVACY_VERIFICATION_FAILURE_INVALID_QRCODE" = "Naskenovaný kód nevypadá jako bezpečnostní číslo. Používate oba aktuální verzi aplikace Signal?"; +"PRIVACY_VERIFICATION_FAILURE_INVALID_QRCODE" = "Naskenovaný kód nevypadá jako bezpečnostní číslo. Používate oba aktuální verzi Signalu?"; /* Paragraph(s) shown alongside the safety number when verifying privacy with {{contact name}} */ -"PRIVACY_VERIFICATION_INSTRUCTIONS" = "Pokud chcete ověřit bezpečnost koncového šifrování s %@, porovnete čísla výše s čísli na druhém zařízení..\n\nNebo můžete naskenovat kód z druhého telefonu, nebo on může naskenovat ten váš."; +"PRIVACY_VERIFICATION_INSTRUCTIONS" = "Pokud chcete ověřit bezpečnost koncového šifrování s %@, porovnete čísla výše s čísli na druhém zařízení.\n\nTaké můžete naskenovat kód z jejich telefonu, nebo je požádat o naskenování vašeho kódu."; /* Navbar title */ "PRIVACY_VERIFICATION_TITLE" = "Ověření bezpečnostního čísla"; @@ -1671,7 +1671,7 @@ "QUESTIONMARK_PUNCTUATION" = "?"; /* Indicates the author of a quoted message. Embeds {{the author's name or phone number}}. */ -"QUOTED_REPLY_AUTHOR_INDICATOR_FORMAT" = "Odpověď na %@"; +"QUOTED_REPLY_AUTHOR_INDICATOR_FORMAT" = "Odpověď uživateli %@"; /* message header label when someone else is quoting you */ "QUOTED_REPLY_AUTHOR_INDICATOR_YOU" = "Odpověď vám"; @@ -1707,10 +1707,10 @@ "REGISTER_2FA_FORGOT_PIN" = "Zapoměl jsem PIN."; /* Alert message explaining what happens if you forget your 'two-factor auth pin'. */ -"REGISTER_2FA_FORGOT_PIN_ALERT_MESSAGE" = "Registrace tohoto telefonního čísla bude možná bez zámku registrace po uplynutí 7 dní po poslední aktivitě čísla v aplikaci Signal."; +"REGISTER_2FA_FORGOT_PIN_ALERT_MESSAGE" = "Registrace tohoto telefonního čísla bude možná bez PINu zámku registrace po uplynutí 7 dní od poslední aktivity telefonního čísla na Signalu."; /* Instructions to enter the 'two-factor auth pin' in the 2FA registration view. */ -"REGISTER_2FA_INSTRUCTIONS" = "Toto telefonní číslo má povolený zámek registrace. Prosím zadejte registrační PIN.\n\nVáš registrační PIN se liší od automatického kódu, který byl zadán na Váš přístroj při posledním kroku."; +"REGISTER_2FA_INSTRUCTIONS" = "Toto telefonní číslo má povolený zámek registrace. Prosím zadejte PIN zámku registrace.\n\nPIN zámku registrace se liší od ověřovacího kódu, který vám byl odeslán při předchozím kroku."; /* Title for alert indicating that attempt to register with 'two-factor auth' failed. */ "REGISTER_2FA_REGISTRATION_FAILED_ALERT_TITLE" = "Registrace neúspěšná"; @@ -1785,7 +1785,7 @@ "REGISTRATION_VERIFICATION_FAILED_WRONG_CODE_DESCRIPTION" = "Čísla, která jste zadal(a) neodpovídají tomu, co jsme poslali. Nechcete to zkontrolovat?"; /* Error message indicating that registration failed due to a missing or incorrect 2FA PIN. */ -"REGISTRATION_VERIFICATION_FAILED_WRONG_PIN" = "Neplatný registrační PIN."; +"REGISTRATION_VERIFICATION_FAILED_WRONG_PIN" = "Neplatný PIN zámku registrace."; /* No comment provided by engineer. */ "REGISTRATION_VERIFY_DEVICE" = "Zaregistrovat se"; @@ -1809,16 +1809,16 @@ "RELAY_REGISTERED_ERROR_RECOVERY" = "Telefonní číslo, které se snažíte zaregistrovat, je již zaregistrováno na jiném serveru. Zrušte jeho registraci z tohoto serveru a zkuste to znovu."; /* Body text for when user is periodically prompted to enter their registration lock PIN */ -"REMINDER_2FA_BODY" = "Registrační zámek je na Vašem telefonním čísle povolen. Aby Vám pomohla zapamatovat si kód, Vás bude aplikace Signal pravidelně žádat o jeho zadávání."; +"REMINDER_2FA_BODY" = "Registrační zámek je povolen pro vaše telefonní číslo. Signal vás bude pravidelně žádat o zadání kódu, aby vám pomohl si ho zapamatovat."; /* Body header for when user is periodically prompted to enter their registration lock PIN */ "REMINDER_2FA_BODY_HEADER" = "Připomenutí:"; /* Alert message explaining what happens if you forget your 'two-factor auth pin' */ -"REMINDER_2FA_FORGOT_PIN_ALERT_MESSAGE" = "Registračná zámek pomáhá zabezpečit Vaše telefonní číslo před neautorizovanými pokusy o registraci. Tato funkce může být kdykoliv vypnuta v nastavení soukromí v aplikaci Signal."; +"REMINDER_2FA_FORGOT_PIN_ALERT_MESSAGE" = "Zámek registrace pomáhá zabezpečit vaše telefonní číslo před neoprávněnými pokusy o registraci. Tato funkce může být kdykoliv zakázána v nastavení soukromí Signalu."; /* Navbar title for when user is periodically prompted to enter their registration lock PIN */ -"REMINDER_2FA_NAV_TITLE" = "Zadejte Váš registrační PIN."; +"REMINDER_2FA_NAV_TITLE" = "Zadejte váš PIN zámku registrace"; /* Alert body after wrong guess for 'two-factor auth pin' reminder activity */ "REMINDER_2FA_WRONG_PIN_ALERT_BODY" = "Nový PIN můžete nastavit v nastavení soukromí."; @@ -1842,7 +1842,7 @@ "SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION" = "Přesto odeslat"; /* Snippet to share {{safety number}} with a friend. sent e.g. via SMS */ -"SAFETY_NUMBER_SHARE_FORMAT" = "Naše bezpečnostní číslo v aplikaci Signal:\n%@"; +"SAFETY_NUMBER_SHARE_FORMAT" = "Naše bezpečnostní číslo v Signalu:\n%@"; /* Action sheet heading */ "SAFETY_NUMBERS_ACTIONSHEET_TITLE" = "Vaše bezpečnostní číslo s %@ se změnilo. Možná ho chcete ověřit."; @@ -1866,13 +1866,13 @@ "SCREEN_LOCK_ERROR_LOCAL_AUTHENTICATION_LOCKOUT" = "Příliš mnoho pokusů o autentifikaci. Prosím zkuste později."; /* Indicates that Touch ID/Face ID/Phone Passcode are not available on this device. */ -"SCREEN_LOCK_ERROR_LOCAL_AUTHENTICATION_NOT_AVAILABLE" = "Musíte nejdříve povolit zámek v iOS aplikaci Nastavení, před povolením aplikace zámek displeje."; +"SCREEN_LOCK_ERROR_LOCAL_AUTHENTICATION_NOT_AVAILABLE" = "Pokud chcete používat zámek displeje, nejprve zapněte kódový zámek v nastavení iOS."; /* Indicates that Touch ID/Face ID/Phone Passcode is not configured on this device. */ -"SCREEN_LOCK_ERROR_LOCAL_AUTHENTICATION_NOT_ENROLLED" = "Musíte nejdříve povolit zámek v iOS aplikaci Nastavení, před povolením aplikace zámek displeje."; +"SCREEN_LOCK_ERROR_LOCAL_AUTHENTICATION_NOT_ENROLLED" = "Pokud chcete používat zámek displeje, nejprve zapněte kódový zámek v nastavení iOS."; /* Indicates that Touch ID/Face ID/Phone Passcode passcode is not set. */ -"SCREEN_LOCK_ERROR_LOCAL_AUTHENTICATION_PASSCODE_NOT_SET" = "Musíte nejdříve povolit zámek v iOS aplikaci Nastavení, před povolením aplikace zámek displeje."; +"SCREEN_LOCK_ERROR_LOCAL_AUTHENTICATION_PASSCODE_NOT_SET" = "Pokud chcete používat zámek displeje, nejprve zapněte kódový zámek v nastavení iOS."; /* Description of how and why Signal iOS uses Touch ID/Face ID/Phone Passcode to unlock 'screen lock'. */ "SCREEN_LOCK_REASON_UNLOCK_SCREEN_LOCK" = "Autentifikovat pro otevření Signalu."; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Zaslat"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Vaše zpráva nemohla být odeslána."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Odeslání pozvánky selhalo, zkuste to později."; @@ -1929,7 +1929,7 @@ "SEND_SMS_CONFIRM_TITLE" = "Pozvat kamaráda přes zabezpečenou SMS?"; /* No comment provided by engineer. */ -"SEND_SMS_INVITE_TITLE" = "Chcete pozvat toto číslo do aplikace Signal:"; +"SEND_SMS_INVITE_TITLE" = "Chcete pozvat následující číslo do Signalu:"; /* Navbar title */ "SETTINGS_ABOUT" = "O aplikaci"; @@ -2028,7 +2028,7 @@ "SETTINGS_BLOCK_LIST_ADD_BUTTON" = "Přidat zablokovaného uživatele"; /* A label that indicates the user has no Signal contacts. */ -"SETTINGS_BLOCK_LIST_NO_CONTACTS" = "V aplikaci Signal nemáte žádné kontakty."; +"SETTINGS_BLOCK_LIST_NO_CONTACTS" = "Nemáte žádné kontakty v Signalu."; /* A label that indicates the user's search has no matching results. */ "SETTINGS_BLOCK_LIST_NO_SEARCH_RESULTS" = "Žádné výsledky vyhledávání"; @@ -2037,7 +2037,7 @@ "SETTINGS_BLOCK_LIST_TITLE" = "Blokovaní"; /* Table cell label */ -"SETTINGS_CALLING_HIDES_IP_ADDRESS_PREFERENCE_TITLE" = "Vždy přeposílat hovory"; +"SETTINGS_CALLING_HIDES_IP_ADDRESS_PREFERENCE_TITLE" = "Vždy přenášet hovory"; /* User settings section footer, a detailed explanation */ "SETTINGS_CALLING_HIDES_IP_ADDRESS_PREFERENCE_TITLE_DETAIL" = "Přenášet všechna volání přes server Signal, aby nedošlo k odhalení vaší IP adresy volanému. Povolením dojde ke zhoršení kvality hovoru."; @@ -2055,7 +2055,7 @@ "SETTINGS_DELETE_DATA_BUTTON" = "Smazat veškerá data"; /* Alert message before user confirms clearing history */ -"SETTINGS_DELETE_HISTORYLOG_CONFIRMATION" = "Opravdu chcete smazat celou historii (zprávy, přílohy, volání atd.)? Tuto akci nelze vzít zpět."; +"SETTINGS_DELETE_HISTORYLOG_CONFIRMATION" = "Opravdu chcete smazat veškerou historii (zprávy, přílohy, volání atd.)? Tuto akci nelze vzít zpět."; /* Confirmation text for button which deletes all message, calling, attachments, etc. */ "SETTINGS_DELETE_HISTORYLOG_CONFIRMATION_BUTTON" = "Smazat vše"; @@ -2082,13 +2082,13 @@ "SETTINGS_LEGAL_TERMS_CELL" = "Podmínky & Zásady ochrany osobních údajů"; /* Setting for enabling & disabling link previews. */ -"SETTINGS_LINK_PREVIEWS" = "Odeslat náhledy odkazu"; +"SETTINGS_LINK_PREVIEWS" = "Odeslat náhledy odkazů"; /* Footer for setting for enabling & disabling link previews. */ "SETTINGS_LINK_PREVIEWS_FOOTER" = "Náhledy jsou podporovány pro odkazy na Imgur, Instagram, Reddit, a YouTube."; /* Header for setting for enabling & disabling link previews. */ -"SETTINGS_LINK_PREVIEWS_HEADER" = "Link Previews"; +"SETTINGS_LINK_PREVIEWS_HEADER" = "Náhledy odkazů"; /* Title for settings activity */ "SETTINGS_NAV_BAR_TITLE" = "Nastavení"; @@ -2106,7 +2106,7 @@ "SETTINGS_PRIVACY_CALLKIT_PRIVACY_TITLE" = "Zobrazit jméno & číslo volajícího"; /* Settings table section footer. */ -"SETTINGS_PRIVACY_CALLKIT_SYSTEM_CALL_LOG_PREFERENCE_DESCRIPTION" = "Zobrazit hovory v \"Poslední volané\" v aplikaci Telefon"; +"SETTINGS_PRIVACY_CALLKIT_SYSTEM_CALL_LOG_PREFERENCE_DESCRIPTION" = "Zobrazit hovory v historii v aplikaci Telefon."; /* Short table cell label */ "SETTINGS_PRIVACY_CALLKIT_SYSTEM_CALL_LOG_PREFERENCE_TITLE" = "Zobrazit hovory v \"Poslední volané\""; @@ -2217,13 +2217,13 @@ "SHARE_EXTENSION_LOADING" = "Načítání..."; /* Message indicating that the share extension cannot be used until the user has registered in the main app. */ -"SHARE_EXTENSION_NOT_REGISTERED_MESSAGE" = "Spustit aplikaci Signal pro registraci."; +"SHARE_EXTENSION_NOT_REGISTERED_MESSAGE" = "Otevřete Signal pro registraci."; /* Title indicating that the share extension cannot be used until the user has registered in the main app. */ "SHARE_EXTENSION_NOT_REGISTERED_TITLE" = "Není registrováno"; /* Message indicating that the share extension cannot be used until the main app has been launched at least once. */ -"SHARE_EXTENSION_NOT_YET_MIGRATED_MESSAGE" = "Spustit aplikaci Signal pro registraci nebo aktualizaci."; +"SHARE_EXTENSION_NOT_YET_MIGRATED_MESSAGE" = "Otevřete Signal pro registraci nebo aktualizaci."; /* Title indicating that the share extension cannot be used until the main app has been launched at least once. */ "SHARE_EXTENSION_NOT_YET_MIGRATED_TITLE" = "Nepřipraveno"; @@ -2247,7 +2247,7 @@ "SHOW_THREAD_BUTTON_TITLE" = "Zobrazit konverzaci"; /* body sent to contacts when inviting to Install Signal */ -"SMS_INVITE_BODY" = "Pozval jsem tě do aplikace Signal! Zde je odkaz:"; +"SMS_INVITE_BODY" = "Zvu tě do aplikace Signal! Tady je odkaz:"; /* Label for the 'no sound' option that allows users to disable sounds for notifications, etc. */ "SOUNDS_NONE" = "Žádné"; @@ -2328,13 +2328,13 @@ "UNLINK_ACTION" = "Odpojit"; /* Alert message to confirm unlinking a device */ -"UNLINK_CONFIRMATION_ALERT_BODY" = "Pokud bude toto zařízení odpojeno, nebude možné dále odesílat a přijímat zprávy."; +"UNLINK_CONFIRMATION_ALERT_BODY" = "Pokud bude zařízení odpojeno, nebude možné dále odesílat nebo přijímat zprávy."; /* Alert title for confirming device deletion */ "UNLINK_CONFIRMATION_ALERT_TITLE" = "Odpojit \"%@\"?"; /* Alert title when unlinking device fails */ -"UNLINKING_FAILED_ALERT_TITLE" = "Aplikaci Signal se nepodařilo odpojit vaše zařízení."; +"UNLINKING_FAILED_ALERT_TITLE" = "Signalu se nepodařilo odpojit vaše zařízení."; /* Label text in device manager for a device with no name */ "UNNAMED_DEVICE" = "Nepojmenované zařízení"; @@ -2367,13 +2367,13 @@ "UPGRADE_EXPERIENCE_ENABLE_TYPING_INDICATOR_BUTTON" = "Zapnout indikátory psaní"; /* Body text for upgrading users */ -"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Volitelné náhledy odkazu jsou nyní podporovány na některých populárních internetových stránkách."; +"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Volitelné náhledy odkazů jsou nyní podporovány na některých populárních internetových stránkách."; /* Subtitle for upgrading users */ -"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_SUBTITLE" = "You can disable or enable this feature anytime in your Signal settings (Privacy > Send link previews)."; +"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_SUBTITLE" = "Tuto funkci můžete kdykoliv zakázat nebo povolit v nastavení soukromí Signalu (Soukromí > Odeslat náhledy odkazů)."; /* Header for upgrading users */ -"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_TITLE" = "Link Previews"; +"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_TITLE" = "Náhledy odkazů"; /* Description for notification audio customization */ "UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_DESCRIPTION" = "Nyní můžete zvolit výchozí zvuky chatů, či zvuky pro každou konverzaci zvlášť. Zvuky u hovorů budou stejné, jako byly zvoleny u každého systémového kontaktu zvlášť."; @@ -2388,7 +2388,7 @@ "UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_BUTTON" = "Nastavit váš profil"; /* Description of new profile feature for upgrading (existing) users */ -"UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_DESCRIPTION" = "Nyní můžete s vašimi přáteli v aplikaci Signal sdílet profilovou fotku a jméno."; +"UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_DESCRIPTION" = "Nyní můžete s vašimi přáteli na Signalu sdílet profilovou fotku a jméno."; /* Header for upgrade experience */ "UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_TITLE" = "Připraveni?"; @@ -2409,7 +2409,7 @@ "UPGRADE_EXPERIENCE_INTRODUCING_TYPING_INDICATORS_TITLE" = "Představujeme indikátory psaní"; /* Description of video calling to upgrading (existing) users */ -"UPGRADE_EXPERIENCE_VIDEO_DESCRIPTION" = "Aplikace Signal nyní podporuje bezpečné video hovory. Začněte hovor jako obvykle, klepněte na tlačítko kamery a zamávejte na pozdrav."; +"UPGRADE_EXPERIENCE_VIDEO_DESCRIPTION" = "Signal nyní podporuje bezpečné video hovory. Začněte hovor jako obvykle, klepněte na tlačítko kamery a zamávejte na pozdrav."; /* Header for upgrade experience */ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Ahoj, bezpečné videohovory!"; diff --git a/Signal/translations/da.lproj/Localizable.strings b/Signal/translations/da.lproj/Localizable.strings index 10ea65cb6..0a031a30e 100644 --- a/Signal/translations/da.lproj/Localizable.strings +++ b/Signal/translations/da.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Adgang til mikrofonen er påkrævet"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Indkommende opkald"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Ring op"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Ubesvaret opkald, fordi opkalderens sikkerhedsnummer er ændret."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Ubesvaret opkald"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Intet svar"; @@ -1395,7 +1395,7 @@ "MULTIDEVICE_PAIRING_MAX_RECOVERY" = "Du har nået det maksimale antal enheder, du i øjeblikket kan tilkoble til din konto. Fjern en enhed, og prøv igen."; /* An explanation of the consequences of muting a thread. */ -"MUTE_BEHAVIOR_EXPLANATION" = "Du modtager ikke underretninger for dæmpede samtaler."; +"MUTE_BEHAVIOR_EXPLANATION" = "Du modtager ikke meddelelser for dæmpede samtaler."; /* A button to skip a view. */ "NAVIGATION_ITEM_SKIP_BUTTON" = "Spring over"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Medlem"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ til %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Navngiv gruppesamtalen"; @@ -1662,7 +1662,7 @@ "PUSH_MANAGER_REPLY" = "Svar"; /* Title of alert shown when push tokens sync job succeeds. */ -"PUSH_REGISTER_SUCCESS" = "Genregistreret til push-notifikationer."; +"PUSH_REGISTER_SUCCESS" = "Genregistreret til push-meddelelser."; /* Used in table section header and alert view title contexts */ "PUSH_REGISTER_TITLE" = "Push meddelelser"; @@ -1731,7 +1731,7 @@ "REGISTER_RATE_LIMITING_ERROR" = "Du har forsøgt for ofte. Vent venligst et minut."; /* Title of alert shown when push tokens sync job fails. */ -"REGISTRATION_BODY" = "Kunne ikke genregistrere til push-notifikationer."; +"REGISTRATION_BODY" = "Kunne ikke genregistrere til push-meddelelser."; /* Label for the country code field */ "REGISTRATION_DEFAULT_COUNTRY_NAME" = "Landekode"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Send"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Din besked kunne ikke sendes."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Kunne ikke sende invitation. Prøv igen senere."; @@ -2094,10 +2094,10 @@ "SETTINGS_NAV_BAR_TITLE" = "Indstillinger"; /* table section footer */ -"SETTINGS_NOTIFICATION_CONTENT_DESCRIPTION" = "Opkalds- og meddelelsesnotifikationer kan vises, mens telefonen er låst. Du vil muligvis begrænse, hvad der vises i disse notifikationer."; +"SETTINGS_NOTIFICATION_CONTENT_DESCRIPTION" = "Opkalds- og besked-meddelelser kan vises, mens telefonen er låst. Du vil muligvis begrænse, hvad der vises i disse meddelelser."; /* table section header */ -"SETTINGS_NOTIFICATION_CONTENT_TITLE" = "Notifikations Indhold "; +"SETTINGS_NOTIFICATION_CONTENT_TITLE" = "Meddelelses indhold"; /* No comment provided by engineer. */ "SETTINGS_NOTIFICATIONS" = "Meddelelser"; @@ -2130,7 +2130,7 @@ "SETTINGS_SCREEN_LOCK_ACTIVITY_TIMEOUT" = "Skærmlås timeout"; /* Footer for the 'screen lock' section of the privacy settings. */ -"SETTINGS_SCREEN_LOCK_SECTION_FOOTER" = "Lås op Signals skærmen ved hjælp af Touch ID, Face ID eller din iOS-enhedens adgangskode. Du kan stadig svare på indgående opkald og modtage meddelelsesnotifikationer, mens Skærmlås er aktiveret. Signal's underretningsindstillinger giver dig mulighed for at tilpasse de oplysninger, der vises."; +"SETTINGS_SCREEN_LOCK_SECTION_FOOTER" = "Lås op Signals skærm ved hjælp af Touch ID, Face ID eller din iOS-enhedens adgangskode. Du kan stadig svare på indgående opkald og modtage besked-meddelelser, mens Skærmlås er aktiveret. Signals meddelelsesindstillinger giver dig mulighed for at tilpasse de oplysninger, der vises."; /* Title for the 'screen lock' section of the privacy settings. */ "SETTINGS_SCREEN_LOCK_SECTION_TITLE" = "Skærmlås"; @@ -2148,7 +2148,7 @@ "SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "iOS opkaldsintegration viser Signal-opkald på din låseskærm og i systemets opkaldshistorik. Du kan eventuelt vise din kontaktpersons navn og nummer. Hvis iCloud er aktiveret, deles denne opkaldshistorik med Apple."; /* Label for the notifications section of conversation settings view. */ -"SETTINGS_SECTION_NOTIFICATIONS" = "Notifikationer"; +"SETTINGS_SECTION_NOTIFICATIONS" = "Meddelelser"; /* Header Label for the sounds section of settings views. */ "SETTINGS_SECTION_SOUNDS" = "Lyde"; @@ -2379,7 +2379,7 @@ "UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_DESCRIPTION" = "Du kan nu vælge standard og samtale-specifikke meddelelseslyde, og opkald vil respektere den ringetone, du har valgt for hver systemkontakt."; /* button label shown one time, after upgrade */ -"UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_SETTINGS_BUTTON" = "Gennemse notifikationsindstillinger"; +"UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_SETTINGS_BUTTON" = "Gennemse meddelelsesindstillinger"; /* Header for upgrade experience */ "UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_TITLE" = "Opdater opkalds- og beskedlyde"; diff --git a/Signal/translations/el.lproj/Localizable.strings b/Signal/translations/el.lproj/Localizable.strings index e9aef7334..79932fe5b 100644 --- a/Signal/translations/el.lproj/Localizable.strings +++ b/Signal/translations/el.lproj/Localizable.strings @@ -2367,7 +2367,7 @@ "UPGRADE_EXPERIENCE_ENABLE_TYPING_INDICATOR_BUTTON" = "Ενεργοποίηση δεικτών πληκτρολόγησης"; /* Body text for upgrading users */ -"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Optional link previews are now supported for some of the most popular sites on the Internet."; +"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Οι προεπισκοπήσεις συνδέσμων υποστηρίζονται πλέον προαιρετικά για μερικές από τις γνωστότερες ιστοσελίδες του διαδικτύου. "; /* Subtitle for upgrading users */ "UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_SUBTITLE" = "You can disable or enable this feature anytime in your Signal settings (Privacy > Send link previews)."; diff --git a/Signal/translations/es.lproj/Localizable.strings b/Signal/translations/es.lproj/Localizable.strings index 1e2680838..aa484c7a6 100644 --- a/Signal/translations/es.lproj/Localizable.strings +++ b/Signal/translations/es.lproj/Localizable.strings @@ -1467,7 +1467,7 @@ "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Encontrar por núm. de teléfono"; /* Label for 1:1 conversation with yourself. */ -"NOTE_TO_SELF" = "Tú mismo"; +"NOTE_TO_SELF" = "Mensajes a ti mism@"; /* Lock screen notification text presented after user powers on their device without unlocking. Embeds {{device model}} (either 'iPad' or 'iPhone') */ "NOTIFICATION_BODY_PHONE_LOCKED_FORMAT" = "Has recibido mensajes mientras tu %@ estaba reiniciándose."; @@ -2466,7 +2466,7 @@ "VOICE_MESSAGE_FILE_NAME" = "Nota de voz"; /* Message for the alert indicating the 'voice message' needs to be held to be held down to record. */ -"VOICE_MESSAGE_TOO_SHORT_ALERT_MESSAGE" = "Toca y mantén pulsado el icono del micrófono para grabar una nota de voz."; +"VOICE_MESSAGE_TOO_SHORT_ALERT_MESSAGE" = "Toca y mantén pulsado el icono del micrófono para grabar una nota de voz corta. Toca, arrastra hacia arriba y suelta para grabar notas de voz más largas."; /* Title for the alert indicating the 'voice message' needs to be held to be held down to record. */ "VOICE_MESSAGE_TOO_SHORT_ALERT_TITLE" = "Nota de voz"; diff --git a/Signal/translations/et.lproj/Localizable.strings b/Signal/translations/et.lproj/Localizable.strings index 20c0c2426..cd41a9164 100644 --- a/Signal/translations/et.lproj/Localizable.strings +++ b/Signal/translations/et.lproj/Localizable.strings @@ -2367,7 +2367,7 @@ "UPGRADE_EXPERIENCE_ENABLE_TYPING_INDICATOR_BUTTON" = "Lülita kirjutamisindikaatorid sisse"; /* Body text for upgrading users */ -"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Optional link previews are now supported for some of the most popular sites on the Internet."; +"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Valikulised linkide eelvaated on nüüd toetatud populaarseimate saitide puhul."; /* Subtitle for upgrading users */ "UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_SUBTITLE" = "You can disable or enable this feature anytime in your Signal settings (Privacy > Send link previews)."; diff --git a/Signal/translations/fi.lproj/Localizable.strings b/Signal/translations/fi.lproj/Localizable.strings index 04342dd8f..6746a2de9 100644 --- a/Signal/translations/fi.lproj/Localizable.strings +++ b/Signal/translations/fi.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Mikrofonin käyttöoikeutta tarvitaan"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Saapuva puhelu"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Soita"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Vastaamatta jäänyt puhelu, koska soittajan turvanumero on vaihtunut."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Vastaamatta jäänyt puhelu "; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Ei vastausta"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Jäsen"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ ryhmälle %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Nimeä tämä ryhmä"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Lähetä"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Viestin lähettäminen epäonnistui."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Kutsun lähettäminen epäonnistui. Yritä myöhemmin uudelleen."; diff --git a/Signal/translations/he.lproj/Localizable.strings b/Signal/translations/he.lproj/Localizable.strings index d484448f4..abe573716 100644 --- a/Signal/translations/he.lproj/Localizable.strings +++ b/Signal/translations/he.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "נדרשת גישה למיקרופון"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ שיחה נכנסת"; /* Accessibility label for placing call button */ "CALL_LABEL" = "חייג"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ שיחה לא נענתה מאחר שמספר הביטחון של המתקשר השתנה."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ שיחה שלא נענתה"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "אין מענה"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "חבר קבוצה"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ אל %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "תן שם לשיחת קבוצה זו"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "שלח"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "ההודעה שלך נכשלה להישלח."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "שליחת ההזמנה נכשלה, אנא נסה שוב מאוחר יותר."; diff --git a/Signal/translations/it.lproj/Localizable.strings b/Signal/translations/it.lproj/Localizable.strings index 1834f171f..8105500e1 100644 --- a/Signal/translations/it.lproj/Localizable.strings +++ b/Signal/translations/it.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Accesso microfono richiesto"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Chiamata in arrivo"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Chiama"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Chiamata persa perché il codice di sicurezza del chiamante è cambiato."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Chiamata persa"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Nessuna risposta"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Membro"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ su %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Nome chat di gruppo"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Invia"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Invio del messaggio fallito."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Invio dell'invito fallito, riprova più tardi"; diff --git a/Signal/translations/nb.lproj/Localizable.strings b/Signal/translations/nb.lproj/Localizable.strings index a9295a2ce..c279c0a8d 100644 --- a/Signal/translations/nb.lproj/Localizable.strings +++ b/Signal/translations/nb.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Krever tilgang til mikrofon"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Innkommende anrop"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Ring"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Tapt anrop grunnet endring av din kontakts sikkerhetsnummer"; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Ubesvart anrop"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Ingen svar"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Medlem"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ til %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Navngi gruppesamtalen"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Send"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Sending mislyktes"; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Sending av invitasjon mislyktes, vennligst prøv igjen senere."; diff --git a/Signal/translations/nl.lproj/Localizable.strings b/Signal/translations/nl.lproj/Localizable.strings index d944d31b6..e0e9b3f16 100644 --- a/Signal/translations/nl.lproj/Localizable.strings +++ b/Signal/translations/nl.lproj/Localizable.strings @@ -462,7 +462,7 @@ "CONFIRM_LINK_NEW_DEVICE_ACTION" = "Nieuw apparaat koppelen"; /* Action sheet body presented when a user's SN has recently changed. Embeds {{contact's name or phone number}} */ -"CONFIRM_SENDING_TO_CHANGED_IDENTITY_BODY_FORMAT" = "%@ is mogelijk van apparaat veranderd. Verifieer jullie veiligheidsnummers om zeker te zijn van je privacy."; +"CONFIRM_SENDING_TO_CHANGED_IDENTITY_BODY_FORMAT" = "%@ heet mogelijk de app opnieuw geïnstalleerd of heeft een ander apparaat in gebruik genomen. Verifieer jullie veiligheidsnummers om zeker te zijn dat je met de juiste persoon communiceert."; /* Action sheet title presented when a user's SN has recently changed. Embeds {{contact's name or phone number}} */ "CONFIRM_SENDING_TO_CHANGED_IDENTITY_TITLE_FORMAT" = "Veiligheidsnummer met %@ is veranderd"; @@ -1036,7 +1036,7 @@ "GROUP_MEMBERS_CALL" = "Bellen"; /* Label for the button that clears all verification errors in the 'group members' view. */ -"GROUP_MEMBERS_RESET_NO_LONGER_VERIFIED" = "Alle verificatiefouten wissen"; +"GROUP_MEMBERS_RESET_NO_LONGER_VERIFIED" = "Alle groepsleden als niet geverifieerd markeren"; /* Label for the 'reset all no-longer-verified group members' confirmation alert. */ "GROUP_MEMBERS_RESET_NO_LONGER_VERIFIED_ALERT_MESSAGE" = "Dit zal de verificatie wissen voor alle groepsleden wier veiligheidsnummers veranderd zijn sinds ze als geverifieerd zijn gemarkeerd."; @@ -1045,7 +1045,7 @@ "GROUP_MEMBERS_SECTION_TITLE_MEMBERS" = "Leden"; /* Title for the 'no longer verified' section of the 'group members' view. */ -"GROUP_MEMBERS_SECTION_TITLE_NO_LONGER_VERIFIED" = "Niet meer gemarkeerd als geverifieerd"; +"GROUP_MEMBERS_SECTION_TITLE_NO_LONGER_VERIFIED" = "Niet langer gemarkeerd als geverifieerd"; /* Button label for the 'send message to group member' button */ "GROUP_MEMBERS_SEND_MESSAGE" = "Bericht verzenden"; @@ -1336,13 +1336,13 @@ "MESSAGE_TEXT_FIELD_PLACEHOLDER" = "Nieuw bericht"; /* Indicates that one member of this group conversation is no longer verified. Embeds {{user's name or phone number}}. */ -"MESSAGES_VIEW_1_MEMBER_NO_LONGER_VERIFIED_FORMAT" = "%@ is niet meer gemarkeerd als geverifieerd. Tik voor opties."; +"MESSAGES_VIEW_1_MEMBER_NO_LONGER_VERIFIED_FORMAT" = "%@ is niet langer gemarkeerd als geverifieerd. Tik voor opties."; /* Indicates that this 1:1 conversation has been blocked. */ "MESSAGES_VIEW_CONTACT_BLOCKED" = "Je hebt deze gebruiker geblokkeerd"; /* Indicates that this 1:1 conversation is no longer verified. Embeds {{user's name or phone number}}. */ -"MESSAGES_VIEW_CONTACT_NO_LONGER_VERIFIED_FORMAT" = "%@ is niet meer gemarkeerd als geverifieerd. Tik voor opties."; +"MESSAGES_VIEW_CONTACT_NO_LONGER_VERIFIED_FORMAT" = "%@ is niet langer gemarkeerd als geverifieerd. Tik voor opties."; /* Indicates that a single member of this group has been blocked. */ "MESSAGES_VIEW_GROUP_1_MEMBER_BLOCKED" = "Je hebt één lid van deze groep geblokkeerd"; @@ -1357,7 +1357,7 @@ "MESSAGES_VIEW_GROUP_PROFILE_WHITELIST_BANNER" = "Je profiel met deze groep delen?"; /* Indicates that more than one member of this group conversation is no longer verified. */ -"MESSAGES_VIEW_N_MEMBERS_NO_LONGER_VERIFIED" = "Meer dan een lid van deze groep is niet meer gemarkeerd als geverifieerd. Tik voor opties."; +"MESSAGES_VIEW_N_MEMBERS_NO_LONGER_VERIFIED" = "Meer dan een lid van deze groep is niet langer gemarkeerd als geverifieerd. Tik voor opties."; /* The subtitle for the messages view title indicates that the title can be tapped to access settings for this conversation. */ "MESSAGES_VIEW_TITLE_SUBTITLE" = "Tik hier voor instellingen"; @@ -1584,7 +1584,7 @@ "PRIVACY_UNVERIFY_BUTTON" = "Verificatie wissen"; /* Alert body when verifying with {{contact name}} */ -"PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "Dit lijkt niet op je veiligheidsnummer met %@. Verifieer je wel het juiste contact?"; +"PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "Dit lijkt niet op je veiligheidsnummer met %@. Verifieer je wel de juiste contactpersoon?"; /* Alert body */ "PRIVACY_VERIFICATION_FAILED_MISMATCHED_SAFETY_NUMBERS_IN_CLIPBOARD" = "Het nummer in je klembord lijkt niet op het juiste veiligheidsnummer voor dit gesprek."; @@ -1599,7 +1599,7 @@ "PRIVACY_VERIFICATION_FAILED_WITH_OLD_LOCAL_VERSION" = "Je gebruikt een oude versie van Signal. Om te kunnen verifiëren moet je Signal eerst bijwerken."; /* alert body */ -"PRIVACY_VERIFICATION_FAILED_WITH_OLD_REMOTE_VERSION" = "Je partner gebruikt een oude versie van Signal. Om te kunnen bevestigen moet hij/zij Signal eerst bijwerken."; +"PRIVACY_VERIFICATION_FAILED_WITH_OLD_REMOTE_VERSION" = "Je gesprekspartner gebruikt een oude versie van Signal. Om te kunnen verifiëren moet hij/zij Signal eerst bijwerken."; /* alert body */ "PRIVACY_VERIFICATION_FAILURE_INVALID_QRCODE" = "De gescande code lijkt niet op een veiligheidsnummer. Gebruiken jullie allebei de laatste versie van Signal?"; @@ -1845,7 +1845,7 @@ "SAFETY_NUMBER_SHARE_FORMAT" = "Ons Signal-veiligheidsnummer:\n%@"; /* Action sheet heading */ -"SAFETY_NUMBERS_ACTIONSHEET_TITLE" = "Je veiligheidsnummer met %@ is veranderd. Je verifieert het best."; +"SAFETY_NUMBERS_ACTIONSHEET_TITLE" = "Je veiligheidsnummer met %@ is veranderd. Het wordt aanbevolen het nieuwe nummer te verifiëren."; /* label presented once scanning (camera) view is visible. */ "SCAN_CODE_INSTRUCTIONS" = "Scan de QR-code op het apparaat van je contact."; @@ -2211,7 +2211,7 @@ "SHARE_ACTION_TWEET" = "Twitter"; /* alert body when sharing file failed because of untrusted/changed identity keys */ -"SHARE_EXTENSION_FAILED_SENDING_BECAUSE_UNTRUSTED_IDENTITY_FORMAT" = "Je veiligheidsnummer met %@ is recent veranderd. Je verifieert het best in de hoofdapp vooraleer je je bericht opnieuw stuurt."; +"SHARE_EXTENSION_FAILED_SENDING_BECAUSE_UNTRUSTED_IDENTITY_FORMAT" = "Je veiligheidsnummer met %@ is recentelijk veranderd. Het wordt aanbevolen om dit nieuwe nummer te verifiëren is de Signal app."; /* Indicates that the share extension is still loading. */ "SHARE_EXTENSION_LOADING" = "Aan het laden…"; diff --git a/Signal/translations/pl.lproj/Localizable.strings b/Signal/translations/pl.lproj/Localizable.strings index b0d31ef50..a8bb1485c 100644 --- a/Signal/translations/pl.lproj/Localizable.strings +++ b/Signal/translations/pl.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Wymagany dostęp do mikrofonu"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Połączenie przychodzące"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Połączenie"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Nieodebrane połączenie z powodu zmiany numeru bezpieczeństwa dzwoniącego."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Nieodebrane połączenie"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Brak odpowiedzi"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Członek"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ do %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Nazwij tę rozmowę grupową"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Wyślij"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Twoja wiadomość nie została wysłana."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Wysyłanie zaproszenia nie powiodło się, spróbuj później."; diff --git a/Signal/translations/pt_BR.lproj/Localizable.strings b/Signal/translations/pt_BR.lproj/Localizable.strings index 714a31e2a..c1e36f4d8 100644 --- a/Signal/translations/pt_BR.lproj/Localizable.strings +++ b/Signal/translations/pt_BR.lproj/Localizable.strings @@ -72,7 +72,7 @@ "APP_UPDATE_NAG_ALERT_DISMISS_BUTTON" = "Agora Não"; /* Message format for the 'new app version available' alert. Embeds: {{The latest app version number}} */ -"APP_UPDATE_NAG_ALERT_MESSAGE_FORMAT" = "A versão %@ está disponível na App Store."; +"APP_UPDATE_NAG_ALERT_MESSAGE_FORMAT" = "A versão %@ está disponível agora na App Store."; /* Title for the 'new app version available' alert. */ "APP_UPDATE_NAG_ALERT_TITLE" = "Uma Nova Versão do Signal Está Disponível"; @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Necessário acesso ao microfone"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Recebendo ligação"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Chamar"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Chamada perdida porque o número de segurança do chamador mudou."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Ligação perdida"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Sem Resposta."; @@ -339,7 +339,7 @@ "CALL_STATUS_FORMAT" = "Signal %@"; /* Label for call button for alert offering to call a user. */ -"CALL_USER_ALERT_CALL_BUTTON" = "Chamar"; +"CALL_USER_ALERT_CALL_BUTTON" = "Ligar"; /* Message format for alert offering to call a user. Embeds {{the user's display name or phone number}}. */ "CALL_USER_ALERT_MESSAGE_FORMAT" = "Gostaria de chamar %@?"; @@ -1081,7 +1081,7 @@ "HOME_VIEW_TITLE_INBOX" = "Signal"; /* Label for brush button in image editor. */ -"IMAGE_EDITOR_BRUSH_BUTTON" = "Brush"; +"IMAGE_EDITOR_BRUSH_BUTTON" = "Escova "; /* Label for crop button in image editor. */ "IMAGE_EDITOR_CROP_BUTTON" = "Cortar"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Membro"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ para %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Nomear esse grupo de bate-papo"; @@ -1467,7 +1467,7 @@ "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Encontrar Contatos pelo Número do Telefone"; /* Label for 1:1 conversation with yourself. */ -"NOTE_TO_SELF" = "Note to Self"; +"NOTE_TO_SELF" = "Recado para mim"; /* Lock screen notification text presented after user powers on their device without unlocking. Embeds {{device model}} (either 'iPad' or 'iPhone') */ "NOTIFICATION_BODY_PHONE_LOCKED_FORMAT" = "Pode ser que você tenha recebido mensagens enquanto seu %@ reiniciava."; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Enviar"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Sua mensagem não pôde ser enviada."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Falha no envie de convite. Tente novamente mais tarde."; @@ -2085,7 +2085,7 @@ "SETTINGS_LINK_PREVIEWS" = "Enviar pré-visualizações de links"; /* Footer for setting for enabling & disabling link previews. */ -"SETTINGS_LINK_PREVIEWS_FOOTER" = "Previews are supported for Imgur, Instagram, Reddit, and YouTube links."; +"SETTINGS_LINK_PREVIEWS_FOOTER" = "Visualizações são suportadas para Imgur, Instagram, Reddit e links do YouTube."; /* Header for setting for enabling & disabling link previews. */ "SETTINGS_LINK_PREVIEWS_HEADER" = "Pré-visualizações de links"; @@ -2367,10 +2367,10 @@ "UPGRADE_EXPERIENCE_ENABLE_TYPING_INDICATOR_BUTTON" = "Ativar indicadores de digitação"; /* Body text for upgrading users */ -"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Optional link previews are now supported for some of the most popular sites on the Internet."; +"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_DESCRIPTION" = "Agora é possível mostrar pré-visualizações de links de alguns dos sites mais populares da internet."; /* Subtitle for upgrading users */ -"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_SUBTITLE" = "You can disable or enable this feature anytime in your Signal settings (Privacy > Send link previews)."; +"UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_SUBTITLE" = "Você pode desativar ou habilitar essa característica a qualquer momento em suas configurações do Signal (Privacidade > Mandar link de visualizações)."; /* Header for upgrading users */ "UPGRADE_EXPERIENCE_INTRODUCING_LINK_PREVIEWS_TITLE" = "Pré-visualizações de links"; @@ -2472,7 +2472,7 @@ "VOICE_MESSAGE_TOO_SHORT_ALERT_TITLE" = "Mensagem de voz"; /* Activity indicator title, shown upon returning to the device manager, until you complete the provisioning process on desktop */ -"WAITING_TO_COMPLETE_DEVICE_LINK_TEXT" = "Termine a configuração no Signal Desktop"; +"WAITING_TO_COMPLETE_DEVICE_LINK_TEXT" = "Termine a configuração no Signal Desktop."; /* Info Message when you disable disappearing messages */ "YOU_DISABLED_DISAPPEARING_MESSAGES_CONFIGURATION" = "Você desabilitou mensagens efêmeras."; diff --git a/Signal/translations/sv.lproj/Localizable.strings b/Signal/translations/sv.lproj/Localizable.strings index a90dba036..88e89571c 100644 --- a/Signal/translations/sv.lproj/Localizable.strings +++ b/Signal/translations/sv.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Åtkomst till mikrofon krävs"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Inkommande samtal"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Ring"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missade samtalet, för den andra personens säkerhetsnummer har ändrats."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missat samtal"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Inget svar"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Medlem"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ till %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Namnge gruppchatten"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Skicka"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Ditt meddelande kunde inte skickas."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Kunde inte skicka inbjudan, vänligen försök senare."; @@ -2436,7 +2436,7 @@ "VERIFICATION_CHALLENGE_SUBMIT_CODE" = "Skicka"; /* Label indicating the phone number currently being verified. */ -"VERIFICATION_PHONE_NUMBER_FORMAT" = "Skriv verifieringskoden vi skickade till %@."; +"VERIFICATION_PHONE_NUMBER_FORMAT" = "Ange verifieringskoden vi skickade till %@."; /* Format for info message indicating that the verification state was unverified on this device. Embeds {{user's name or phone number}}. */ "VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_LOCAL" = "Du markerade %@ som ej verifierad."; diff --git a/Signal/translations/tr.lproj/Localizable.strings b/Signal/translations/tr.lproj/Localizable.strings index d636f3246..8e5dd53ce 100644 --- a/Signal/translations/tr.lproj/Localizable.strings +++ b/Signal/translations/tr.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Mikrofon Erişimi Gerekiyor"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Gelen Arama"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Ara"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Arayanın güvenlik numarası değiştiğinden arama karşılanmadı."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Cevapsız Arama"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Yanıt Yok"; @@ -423,7 +423,7 @@ "CLOUDKIT_STATUS_RESTRICTED" = "Signal'in iCloud erişimi engellenmiş. Signal verilerinizi yedeklemek için iOS ayarlar uygulamasından Signal'in iCloud hesabınıza erişimine izni verin."; /* The first of two messages demonstrating the chosen conversation color, by rendering this message in an outgoing message bubble. */ -"COLOR_PICKER_DEMO_MESSAGE_1" = "Bu sohbete gönderilen mesajarın rengini seçin."; +"COLOR_PICKER_DEMO_MESSAGE_1" = "Bu sohbete gönderilen mesajların rengini seçin."; /* The second of two messages demonstrating the chosen conversation color, by rendering this message in an incoming message bubble. */ "COLOR_PICKER_DEMO_MESSAGE_2" = "Seçtiğiniz rengi sadece siz göreceksiniz."; @@ -733,7 +733,7 @@ "DEBUG_LOG_GITHUB_ISSUE_ALERT_MESSAGE" = "Gist bağlantısı panonuza kopyalandı. GitHub sorunlar listesine yönlendirilmek üzeresiniz."; /* Title of the alert before redirecting to GitHub Issues. */ -"DEBUG_LOG_GITHUB_ISSUE_ALERT_TITLE" = "GıtHub'a Yönlendirme"; +"DEBUG_LOG_GITHUB_ISSUE_ALERT_TITLE" = "GitHub'a Yönlendirme"; /* Label for button that lets users re-register using the same phone number. */ "DEREGISTRATION_REREGISTER_WITH_SAME_PHONE_NUMBER" = "Bu telefon numarasını tekrar kaydet"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Üye"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@, %@ grubuna"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Grup sohbetini adlandır"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Gönder"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Mesajınız gönderilemedi."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Davetiye gönderilemedi, lütfen daha sonra tekrar deneyin."; @@ -2145,7 +2145,7 @@ "SETTINGS_SCREEN_SECURITY_DETAIL" = "Uygulama geçişleri esnasında Signal önizlemelerinin görülmez."; /* Settings table section footer. */ -"SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "IOS Çağrı Entegrasyonu, Signal çağrılarını kilit ekranınızda ve sistemin arama geçmişinde gösterir. İsteğe bağlı olarak kişinin adını ve numarasını da gösterebilirsiniz. ICloud etkinleştirilmiş ise, bu arama geçmişi Apple ile paylaşılacaktır."; +"SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "iOS Çağrı Entegrasyonu, Signal çağrılarını kilit ekranınızda ve sistemin arama geçmişinde gösterir. İsteğe bağlı olarak kişinin adını ve numarasını da gösterebilirsiniz. ICloud etkinleştirilmiş ise, bu arama geçmişi Apple ile paylaşılacaktır."; /* Label for the notifications section of conversation settings view. */ "SETTINGS_SECTION_NOTIFICATIONS" = "Bildirimler"; @@ -2355,7 +2355,7 @@ "UPDATE_GROUP_CANT_REMOVE_MEMBERS_ALERT_TITLE" = "Desteklenmiyor"; /* Description of CallKit to upgrading (existing) users */ -"UPGRADE_EXPERIENCE_CALLKIT_DESCRIPTION" = "IOS çağrı entegrasyonu ile kilit ekranınızdan gelen aramaları cevaplamak kolaydır. Varsayılan olarak arayan bilgilerini saklarız."; +"UPGRADE_EXPERIENCE_CALLKIT_DESCRIPTION" = "iOS çağrı entegrasyonu ile kilit ekranınızdan gelen aramaları cevaplamak kolaydır. Varsayılan olarak arayan bilgilerini saklarız."; /* button label shown once when when user upgrades app, in context of call kit */ "UPGRADE_EXPERIENCE_CALLKIT_PRIVACY_SETTINGS_BUTTON" = "Daha fazlasını gizlilik ayarlarınızdan öğrenin."; @@ -2415,7 +2415,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Merhaba Güvenli Görüntülü Aramalar!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal iOS 9 veya daha sonrasını gerektirir. Lütfen iOS Ayarlar uygulamasından Yazılım Güncelleştirme özeliğini kullanın."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal iOS 9 veya daha sonrasını gerektirir. Lütfen iOS Ayarlar uygulamasından Yazılım Güncelleme özeliğini kullanın."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "iOS'u Güncelle"; diff --git a/Signal/translations/zh_CN.lproj/Localizable.strings b/Signal/translations/zh_CN.lproj/Localizable.strings index 7c52b3d22..ac4d9da46 100644 --- a/Signal/translations/zh_CN.lproj/Localizable.strings +++ b/Signal/translations/zh_CN.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "请求访问麦克风"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "来电"; /* Accessibility label for placing call button */ "CALL_LABEL" = "打电话"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "未接来电,因为对方的安全码发生了变化。"; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "未接来电"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "无应答"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "成员"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@至%@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "为此群组命名"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "发送"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "您的信息发送失败。"; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "发送邀请失败, 请稍候再试."; From db2294888797c6391cbd52a35f1dcc01e3727cb0 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 12 Feb 2019 15:06:15 -0700 Subject: [PATCH 07/14] Fix crash after deleting message w/ link preview --- Signal/src/views/LinkPreviewView.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Signal/src/views/LinkPreviewView.swift b/Signal/src/views/LinkPreviewView.swift index 9360513af..d61ed8135 100644 --- a/Signal/src/views/LinkPreviewView.swift +++ b/Signal/src/views/LinkPreviewView.swift @@ -211,7 +211,8 @@ public class LinkPreviewSent: NSObject, LinkPreviewState { return nil } guard let image = UIImage(contentsOfFile: imageFilepath) else { - owsFail("Could not load image: \(imageFilepath)") + owsFailDebug("Could not load image: \(imageFilepath)") + return nil } return image } From 38da911d4f32555910da0bee9c86dc5fca212acc Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 12 Feb 2019 15:28:55 -0700 Subject: [PATCH 08/14] Don't crash when user has 0 saved photos --- .../PhotoLibrary/PhotoLibrary.swift | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Signal/src/ViewControllers/PhotoLibrary/PhotoLibrary.swift b/Signal/src/ViewControllers/PhotoLibrary/PhotoLibrary.swift index 0a2d13729..077934954 100644 --- a/Signal/src/ViewControllers/PhotoLibrary/PhotoLibrary.swift +++ b/Signal/src/ViewControllers/PhotoLibrary/PhotoLibrary.swift @@ -291,7 +291,9 @@ class PhotoLibrary: NSObject, PHPhotoLibraryChangeObserver { var collections = [PhotoCollection]() var collectionIds = Set() - let processPHCollection: (PHCollection) -> Void = { (collection) in + let processPHCollection: ((collection: PHCollection, hideIfEmpty: Bool)) -> Void = { arg in + let (collection, hideIfEmpty) = arg + // De-duplicate by id. let collectionId = collection.localIdentifier guard !collectionIds.contains(collectionId) else { @@ -304,15 +306,14 @@ class PhotoLibrary: NSObject, PHPhotoLibraryChangeObserver { return } let photoCollection = PhotoCollection(collection: assetCollection) - // Hide empty collections. - guard photoCollection.contents().assetCount > 0 else { + guard !hideIfEmpty || photoCollection.contents().assetCount > 0 else { return } collections.append(photoCollection) } - let processPHAssetCollections: (PHFetchResult) -> Void = { (fetchResult) in - // undocumented constant + let processPHAssetCollections: ((fetchResult: PHFetchResult, hideIfEmpty: Bool)) -> Void = { arg in + let (fetchResult, hideIfEmpty) = arg fetchResult.enumerateObjects { (assetCollection, _, _) in // We're already sorting albums by last-updated. "Recently Added" is mostly redundant @@ -320,33 +321,40 @@ class PhotoLibrary: NSObject, PHPhotoLibraryChangeObserver { return } + // undocumented constant let kRecentlyDeletedAlbumSubtype = PHAssetCollectionSubtype(rawValue: 1000000201) guard assetCollection.assetCollectionSubtype != kRecentlyDeletedAlbumSubtype else { return } - processPHCollection(assetCollection) + processPHCollection((collection: assetCollection, hideIfEmpty: hideIfEmpty)) } } - let processPHCollections: (PHFetchResult) -> Void = { (fetchResult) in + let processPHCollections: ((fetchResult: PHFetchResult, hideIfEmpty: Bool)) -> Void = { arg in + let (fetchResult, hideIfEmpty) = arg + for index in 0.. Date: Tue, 12 Feb 2019 17:22:21 -0700 Subject: [PATCH 09/14] "Bump build to 2.36.0.6." --- Signal/Signal-Info.plist | 2 +- SignalShareExtension/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 4ac614c6b..148d4a7e4 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 2.36.0.5 + 2.36.0.6 ITSAppUsesNonExemptEncryption LOGS_EMAIL diff --git a/SignalShareExtension/Info.plist b/SignalShareExtension/Info.plist index 97ad7716a..244a828ca 100644 --- a/SignalShareExtension/Info.plist +++ b/SignalShareExtension/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 2.36.0 CFBundleVersion - 2.36.0.5 + 2.36.0.6 ITSAppUsesNonExemptEncryption NSAppTransportSecurity From 6c08f98fbbc4268541a2694c0e2cec822b6ba8fd Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 14 Feb 2019 18:36:45 -0700 Subject: [PATCH 10/14] replying to notification marks thread as read --- .../Notifications/AppNotifications.swift | 32 ++++++++++--------- .../src/Util/YapDatabase+Promise.swift | 20 ++++++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 SignalServiceKit/src/Util/YapDatabase+Promise.swift diff --git a/Signal/src/UserInterface/Notifications/AppNotifications.swift b/Signal/src/UserInterface/Notifications/AppNotifications.swift index 9f957e0cf..afe1ebc6b 100644 --- a/Signal/src/UserInterface/Notifications/AppNotifications.swift +++ b/Signal/src/UserInterface/Notifications/AppNotifications.swift @@ -613,15 +613,7 @@ class NotificationActionHandler { throw NotificationError.failDebug("unable to find thread with id: \(threadId)") } - return Promise { resolver in - self.dbConnection.asyncReadWrite({ transaction in - thread.markAllAsRead(with: transaction) - }, - completionBlock: { - self.notificationPresenter.cancelNotifications(threadId: threadId) - resolver.fulfill(()) - }) - } + return markAsRead(thread: thread) } func reply(userInfo: [AnyHashable: Any], replyText: String) throws -> Promise { @@ -633,12 +625,16 @@ class NotificationActionHandler { throw NotificationError.failDebug("unable to find thread with id: \(threadId)") } - return ThreadUtil.sendMessageNonDurably(text: replyText, - thread: thread, - quotedReplyModel: nil, - messageSender: messageSender).recover { error in - Logger.warn("Failed to send reply message from notification with error: \(error)") - self.notificationPresenter.notifyForFailedSend(inThread: thread) + return markAsRead(thread: thread).then { () -> Promise in + let sendPromise = ThreadUtil.sendMessageNonDurably(text: replyText, + thread: thread, + quotedReplyModel: nil, + messageSender: self.messageSender) + + return sendPromise.recover { error in + Logger.warn("Failed to send reply message from notification with error: \(error)") + self.notificationPresenter.notifyForFailedSend(inThread: thread) + } } } @@ -654,6 +650,12 @@ class NotificationActionHandler { signalApp.presentConversation(forThreadId: threadId, animated: shouldAnimate) return Promise.value(()) } + + private func markAsRead(thread: TSThread) -> Promise { + return dbConnection.readWritePromise { transaction in + thread.markAllAsRead(with: transaction) + } + } } extension ThreadUtil { diff --git a/SignalServiceKit/src/Util/YapDatabase+Promise.swift b/SignalServiceKit/src/Util/YapDatabase+Promise.swift new file mode 100644 index 000000000..2fe3351a2 --- /dev/null +++ b/SignalServiceKit/src/Util/YapDatabase+Promise.swift @@ -0,0 +1,20 @@ +// +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. +// + +import Foundation +import PromiseKit + +public extension YapDatabaseConnection { + + @objc + func readWritePromise(_ block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> AnyPromise { + return AnyPromise(readWritePromise(block) as Promise) + } + + func readWritePromise(_ block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> Promise { + return Promise { resolver in + self.asyncReadWrite(block, completionBlock: resolver.fulfill) + } + } +} From 1844bdbebf7e450feb324ae9e7d942f4cd743f65 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 15 Feb 2019 17:16:35 -0700 Subject: [PATCH 11/14] update pods --- Pods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pods b/Pods index 30865575d..434610837 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 30865575d8f4ef74dc51e5bde3eab1cf7d458784 +Subproject commit 434610837e73668d186716fd2e5b8913c84ef46a From 0d5f9e01034041ee3c96df4f485f481e4fa5b994 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 15 Feb 2019 17:18:46 -0700 Subject: [PATCH 12/14] Disable UserNotifications for this release --- Signal/src/UserInterface/Notifications/AppNotifications.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Signal/src/UserInterface/Notifications/AppNotifications.swift b/Signal/src/UserInterface/Notifications/AppNotifications.swift index afe1ebc6b..280c250fc 100644 --- a/Signal/src/UserInterface/Notifications/AppNotifications.swift +++ b/Signal/src/UserInterface/Notifications/AppNotifications.swift @@ -137,7 +137,8 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { @objc public override init() { - if #available(iOS 10, *) { + let userNotificationsFeatureEnabled = false + if userNotificationsFeatureEnabled, #available(iOS 10, *) { self.adaptee = UserNotificationPresenterAdaptee() } else { self.adaptee = LegacyNotificationPresenterAdaptee() From 4aaac90d3166c1ca3a7718588419ed3b54fbd10c Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 15 Feb 2019 17:26:14 -0700 Subject: [PATCH 13/14] sync translations --- Signal/translations/fi.lproj/Localizable.strings | 2 +- Signal/translations/fr.lproj/Localizable.strings | 4 ++-- Signal/translations/hu.lproj/Localizable.strings | 2 +- Signal/translations/pl.lproj/Localizable.strings | 4 ++-- Signal/translations/ru.lproj/Localizable.strings | 10 +++++----- Signal/translations/sl.lproj/Localizable.strings | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Signal/translations/fi.lproj/Localizable.strings b/Signal/translations/fi.lproj/Localizable.strings index 6746a2de9..a53ef464f 100644 --- a/Signal/translations/fi.lproj/Localizable.strings +++ b/Signal/translations/fi.lproj/Localizable.strings @@ -1467,7 +1467,7 @@ "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Etsi yhteystietoja puhelinnumerolla"; /* Label for 1:1 conversation with yourself. */ -"NOTE_TO_SELF" = "Muistutus itselleni"; +"NOTE_TO_SELF" = "Viestit itselleni"; /* Lock screen notification text presented after user powers on their device without unlocking. Embeds {{device model}} (either 'iPad' or 'iPhone') */ "NOTIFICATION_BODY_PHONE_LOCKED_FORMAT" = "Olet saattanut saada uusia viestejä sillä aikaa, kun %@:si uudelleenkäynnistyi."; diff --git a/Signal/translations/fr.lproj/Localizable.strings b/Signal/translations/fr.lproj/Localizable.strings index dc8596246..77fbab320 100644 --- a/Signal/translations/fr.lproj/Localizable.strings +++ b/Signal/translations/fr.lproj/Localizable.strings @@ -342,7 +342,7 @@ "CALL_USER_ALERT_CALL_BUTTON" = "Appeler"; /* Message format for alert offering to call a user. Embeds {{the user's display name or phone number}}. */ -"CALL_USER_ALERT_MESSAGE_FORMAT" = "Souhaitez-vous appeler%@ ?"; +"CALL_USER_ALERT_MESSAGE_FORMAT" = "Souhaitez-vous appeler %@ ?"; /* Title for alert offering to call a user. */ "CALL_USER_ALERT_TITLE" = "Appeler ?"; @@ -1006,7 +1006,7 @@ "GIF_VIEW_SEARCH_ERROR" = "Erreur. Touchez pour ressayer."; /* Indicates that the user's search had no results. */ -"GIF_VIEW_SEARCH_NO_RESULTS" = "Aucun résultat"; +"GIF_VIEW_SEARCH_NO_RESULTS" = "Il n’y a aucun résultat."; /* Placeholder text for the search field in GIF view */ "GIF_VIEW_SEARCH_PLACEHOLDER_TEXT" = "Saisir votre recherche"; diff --git a/Signal/translations/hu.lproj/Localizable.strings b/Signal/translations/hu.lproj/Localizable.strings index c3ba0ca62..dbed66afb 100644 --- a/Signal/translations/hu.lproj/Localizable.strings +++ b/Signal/translations/hu.lproj/Localizable.strings @@ -1467,7 +1467,7 @@ "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Kontaktok keresése telefonszám alapján"; /* Label for 1:1 conversation with yourself. */ -"NOTE_TO_SELF" = "Note to Self"; +"NOTE_TO_SELF" = "Privát feljegyzés"; /* Lock screen notification text presented after user powers on their device without unlocking. Embeds {{device model}} (either 'iPad' or 'iPhone') */ "NOTIFICATION_BODY_PHONE_LOCKED_FORMAT" = "You may have received messages while your %@ was restarting."; diff --git a/Signal/translations/pl.lproj/Localizable.strings b/Signal/translations/pl.lproj/Localizable.strings index a8bb1485c..fbf2fafe9 100644 --- a/Signal/translations/pl.lproj/Localizable.strings +++ b/Signal/translations/pl.lproj/Localizable.strings @@ -183,7 +183,7 @@ "BACKUP_EXPORT_ERROR_INVALID_CLOUDKIT_RESPONSE" = "Nieprawidłowa odpowiedź serwera"; /* Indicates that the cloud is being cleaned up. */ -"BACKUP_EXPORT_PHASE_CLEAN_UP" = "Czyszczenie kopii zapasowych"; +"BACKUP_EXPORT_PHASE_CLEAN_UP" = "Czyszczenie kopii zapasowej"; /* Indicates that the backup export is being configured. */ "BACKUP_EXPORT_PHASE_CONFIGURATION" = "Uruchamianie kopii zapasowej"; @@ -1467,7 +1467,7 @@ "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Odszukaj kontakty po numerze telefonu"; /* Label for 1:1 conversation with yourself. */ -"NOTE_TO_SELF" = "Note to Self"; +"NOTE_TO_SELF" = "Uwaga dla siebie"; /* Lock screen notification text presented after user powers on their device without unlocking. Embeds {{device model}} (either 'iPad' or 'iPhone') */ "NOTIFICATION_BODY_PHONE_LOCKED_FORMAT" = "Możliwe, że otrzymałeś wiadomości podczas restartowania %@."; diff --git a/Signal/translations/ru.lproj/Localizable.strings b/Signal/translations/ru.lproj/Localizable.strings index bafd00db1..d83eccb1a 100644 --- a/Signal/translations/ru.lproj/Localizable.strings +++ b/Signal/translations/ru.lproj/Localizable.strings @@ -321,16 +321,16 @@ "CALL_AUDIO_PERMISSION_TITLE" = "Требуется доступ к микрофону"; /* notification body */ -"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Incoming Call"; +"CALL_INCOMING_NOTIFICATION_BODY" = "☎️ Входящий вызов"; /* Accessibility label for placing call button */ "CALL_LABEL" = "Позвонить"; /* notification body */ -"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Missed call because the caller's safety number changed."; +"CALL_MISSED_BECAUSE_OF_IDENTITY_CHANGE_NOTIFICATION_BODY" = "☎️ Пропущенный вызов по причине изменения кода безопасности звонящего."; /* notification body */ -"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Missed Call"; +"CALL_MISSED_NOTIFICATION_BODY" = "☎️ Пропущенный вызов"; /* Call setup status label after outgoing call times out */ "CALL_SCREEN_STATUS_NO_ANSWER" = "Нет ответа"; @@ -1440,7 +1440,7 @@ "NEW_GROUP_MEMBER_LABEL" = "Участники"; /* notification title. Embeds {{author name}} and {{group name}} */ -"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ to %@"; +"NEW_GROUP_MESSAGE_NOTIFICATION_TITLE" = "%@ в %@"; /* Placeholder text for group name field */ "NEW_GROUP_NAMEGROUP_REQUEST_DEFAULT" = "Дайте имя этой группе"; @@ -1914,7 +1914,7 @@ "SEND_BUTTON_TITLE" = "Отправить"; /* notification body */ -"SEND_FAILED_NOTIFICATION_BODY" = "Your message failed to send."; +"SEND_FAILED_NOTIFICATION_BODY" = "Ваше сообщение не было отправлено."; /* Alert body after invite failed */ "SEND_INVITE_FAILURE" = "Ошибка отправки приглашения, пожалуйста, повторить попытку."; diff --git a/Signal/translations/sl.lproj/Localizable.strings b/Signal/translations/sl.lproj/Localizable.strings index 28b0d0f18..5b68433ff 100644 --- a/Signal/translations/sl.lproj/Localizable.strings +++ b/Signal/translations/sl.lproj/Localizable.strings @@ -1467,7 +1467,7 @@ "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Poišči stike z vnosom telefonske številke"; /* Label for 1:1 conversation with yourself. */ -"NOTE_TO_SELF" = "Note to Self"; +"NOTE_TO_SELF" = "Sporočilo sebi"; /* Lock screen notification text presented after user powers on their device without unlocking. Embeds {{device model}} (either 'iPad' or 'iPhone') */ "NOTIFICATION_BODY_PHONE_LOCKED_FORMAT" = "Možno je, da ste med ponovnim zagonom naprave %@ prejeli kakšno sporočilo."; From 35f79c1e9f6d4037e007f35b26eac655efe497d9 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 15 Feb 2019 17:26:24 -0700 Subject: [PATCH 14/14] "Bump build to 2.36.0.7." --- Signal/Signal-Info.plist | 2 +- SignalShareExtension/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 148d4a7e4..4e0aaaa44 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 2.36.0.6 + 2.36.0.7 ITSAppUsesNonExemptEncryption LOGS_EMAIL diff --git a/SignalShareExtension/Info.plist b/SignalShareExtension/Info.plist index 244a828ca..a4b9ea1c7 100644 --- a/SignalShareExtension/Info.plist +++ b/SignalShareExtension/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 2.36.0 CFBundleVersion - 2.36.0.6 + 2.36.0.7 ITSAppUsesNonExemptEncryption NSAppTransportSecurity