Merge remote-tracking branch 'origin/release/2.36.0'
This commit is contained in:
commit
d26c095fe7
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 30865575d8f4ef74dc51e5bde3eab1cf7d458784
|
||||
Subproject commit 434610837e73668d186716fd2e5b8913c84ef46a
|
|
@ -47,7 +47,7 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.36.0.5</string>
|
||||
<string>2.36.0.7</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LOGS_EMAIL</key>
|
||||
|
@ -69,7 +69,7 @@
|
|||
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>api-staging.directory.signal.org </key>
|
||||
<key>api-staging.directory.signal.org</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
|
|
|
@ -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];
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
@ -613,15 +614,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<Void> {
|
||||
|
@ -633,12 +626,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<Void> 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 +651,12 @@ class NotificationActionHandler {
|
|||
signalApp.presentConversation(forThreadId: threadId, animated: shouldAnimate)
|
||||
return Promise.value(())
|
||||
}
|
||||
|
||||
private func markAsRead(thread: TSThread) -> Promise<Void> {
|
||||
return dbConnection.readWritePromise { transaction in
|
||||
thread.markAllAsRead(with: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ThreadUtil {
|
||||
|
|
|
@ -222,6 +222,17 @@ 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()
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -181,6 +181,7 @@ extension UserNotificationPresenterAdaptee: NotificationPresenterAdaptee {
|
|||
AssertIsOnMainThread()
|
||||
notificationCenter.removeAllPendingNotificationRequests()
|
||||
notificationCenter.removeAllDeliveredNotifications()
|
||||
LegacyNotificationPresenterAdaptee.clearExistingNotifications()
|
||||
}
|
||||
|
||||
func shouldPresentNotification(category: AppNotificationCategory, userInfo: [AnyHashable: Any]) -> Bool {
|
||||
|
|
|
@ -291,7 +291,9 @@ class PhotoLibrary: NSObject, PHPhotoLibraryChangeObserver {
|
|||
var collections = [PhotoCollection]()
|
||||
var collectionIds = Set<String>()
|
||||
|
||||
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<PHAssetCollection>) -> Void = { (fetchResult) in
|
||||
// undocumented constant
|
||||
let processPHAssetCollections: ((fetchResult: PHFetchResult<PHAssetCollection>, 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<PHCollection>) -> Void = { (fetchResult) in
|
||||
let processPHCollections: ((fetchResult: PHFetchResult<PHCollection>, hideIfEmpty: Bool)) -> Void = { arg in
|
||||
let (fetchResult, hideIfEmpty) = arg
|
||||
|
||||
for index in 0..<fetchResult.count {
|
||||
processPHCollection(fetchResult.object(at: index))
|
||||
processPHCollection((collection: fetchResult.object(at: index), hideIfEmpty: hideIfEmpty))
|
||||
}
|
||||
}
|
||||
let fetchOptions = PHFetchOptions()
|
||||
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "endDate", ascending: true)]
|
||||
|
||||
// Try to add "Camera Roll" first.
|
||||
processPHAssetCollections(PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: fetchOptions))
|
||||
processPHAssetCollections((fetchResult: PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: fetchOptions),
|
||||
hideIfEmpty: false))
|
||||
|
||||
// Favorites
|
||||
processPHAssetCollections(PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumFavorites, options: fetchOptions))
|
||||
processPHAssetCollections((fetchResult: PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumFavorites, options: fetchOptions),
|
||||
hideIfEmpty: true))
|
||||
|
||||
// Smart albums.
|
||||
processPHAssetCollections(PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: fetchOptions))
|
||||
processPHAssetCollections((fetchResult: PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: fetchOptions),
|
||||
hideIfEmpty: true))
|
||||
|
||||
// User-created albums.
|
||||
processPHCollections(PHAssetCollection.fetchTopLevelUserCollections(with: fetchOptions))
|
||||
processPHCollections((fetchResult: PHAssetCollection.fetchTopLevelUserCollections(with: fetchOptions),
|
||||
hideIfEmpty: true))
|
||||
|
||||
return collections
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (void)resetAppData;
|
||||
|
||||
+ (void)clearAllNotifications;
|
||||
|
||||
- (void)showHomeView;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.";
|
||||
|
|
|
@ -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!";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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).";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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).";
|
||||
|
|
|
@ -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ä";
|
||||
|
@ -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.";
|
||||
|
@ -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.";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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" = "שליחת ההזמנה נכשלה, אנא נסה שוב מאוחר יותר.";
|
||||
|
|
|
@ -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.";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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.";
|
||||
|
|
|
@ -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…";
|
||||
|
|
|
@ -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";
|
||||
|
@ -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ą";
|
||||
|
@ -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 %@.";
|
||||
|
@ -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.";
|
||||
|
|
|
@ -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.";
|
||||
|
|
|
@ -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" = "Ошибка отправки приглашения, пожалуйста, повторить попытку.";
|
||||
|
|
|
@ -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.";
|
||||
|
|
|
@ -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.";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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" = "发送邀请失败, 请稍候再试.";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
@ -385,78 +406,96 @@ NSErrorDomain const ContactDiscoveryServiceErrorDomain = @"SignalServiceKit.Cont
|
|||
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;
|
||||
NSArray<NSHTTPCookie *> *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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String>
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,8 @@ typedef NS_ENUM(NSUInteger, TSVerificationTransport) { TSVerificationTransportVo
|
|||
cookies:(NSArray<NSHTTPCookie *> *)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
|
||||
|
||||
|
|
|
@ -498,10 +498,26 @@ 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<NSString *, NSString *> *parameters;
|
||||
if (reason == nil) {
|
||||
parameters = @{};
|
||||
} else {
|
||||
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];
|
||||
}
|
||||
|
||||
#pragma mark - UD
|
||||
|
|
|
@ -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<Void>)
|
||||
}
|
||||
|
||||
func readWritePromise(_ block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> Promise<Void> {
|
||||
return Promise { resolver in
|
||||
self.asyncReadWrite(block, completionBlock: resolver.fulfill)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.36.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.36.0.5</string>
|
||||
<string>2.36.0.7</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
|
Loading…
Reference in New Issue