Merge remote-tracking branch 'origin/hotfix/2.11.3'

pull/1/head
Matthew Chen 7 years ago
commit ad3a1a671a

@ -107,6 +107,8 @@
453D28BA1D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = 453D28B91D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m */; }; 453D28BA1D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = 453D28B91D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m */; };
453D28BB1D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = 453D28B91D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m */; }; 453D28BB1D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = 453D28B91D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m */; };
4542F0941EB9372700C7EE92 /* SystemContactsFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542F0931EB9372700C7EE92 /* SystemContactsFetcher.swift */; }; 4542F0941EB9372700C7EE92 /* SystemContactsFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542F0931EB9372700C7EE92 /* SystemContactsFetcher.swift */; };
4542F0961EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542F0951EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift */; };
4542F0971EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542F0951EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift */; };
45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45464DBB1DFA041F001D3FD6 /* DataChannelMessage.swift */; }; 45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45464DBB1DFA041F001D3FD6 /* DataChannelMessage.swift */; };
45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45666EC51D99483D008FE134 /* OWSAvatarBuilder.m */; }; 45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45666EC51D99483D008FE134 /* OWSAvatarBuilder.m */; };
45666EC91D994C0D008FE134 /* OWSGroupAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45666EC81D994C0D008FE134 /* OWSGroupAvatarBuilder.m */; }; 45666EC91D994C0D008FE134 /* OWSGroupAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45666EC81D994C0D008FE134 /* OWSGroupAvatarBuilder.m */; };
@ -450,8 +452,8 @@
34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsNavigationController.m; sourceTree = "<group>"; }; 34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsNavigationController.m; sourceTree = "<group>"; };
34B3F86F1E8DF1700035BE1A /* SignalsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalsViewController.h; sourceTree = "<group>"; }; 34B3F86F1E8DF1700035BE1A /* SignalsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalsViewController.h; sourceTree = "<group>"; };
34B3F8701E8DF1700035BE1A /* SignalsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsViewController.m; sourceTree = "<group>"; }; 34B3F8701E8DF1700035BE1A /* SignalsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsViewController.m; sourceTree = "<group>"; };
34B3F8981E8DF1B90035BE1A /* TSMessageAdapterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSMessageAdapterTest.m; sourceTree = "<group>"; };
34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListViewController.h; sourceTree = "<group>"; }; 34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListViewController.h; sourceTree = "<group>"; };
34B3F8981E8DF1B90035BE1A /* TSMessageAdapterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSMessageAdapterTest.m; sourceTree = "<group>"; };
34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListViewController.m; sourceTree = "<group>"; }; 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListViewController.m; sourceTree = "<group>"; };
34B3F89D1E8DF5490035BE1A /* OWSTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSTableViewController.h; sourceTree = "<group>"; }; 34B3F89D1E8DF5490035BE1A /* OWSTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSTableViewController.h; sourceTree = "<group>"; };
34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSTableViewController.m; sourceTree = "<group>"; }; 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSTableViewController.m; sourceTree = "<group>"; };
@ -508,6 +510,7 @@
453D28B81D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessagesBubblesSizeCalculator.h; sourceTree = "<group>"; }; 453D28B81D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessagesBubblesSizeCalculator.h; sourceTree = "<group>"; };
453D28B91D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessagesBubblesSizeCalculator.m; sourceTree = "<group>"; }; 453D28B91D332DB100D523F0 /* OWSMessagesBubblesSizeCalculator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessagesBubblesSizeCalculator.m; sourceTree = "<group>"; };
4542F0931EB9372700C7EE92 /* SystemContactsFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemContactsFetcher.swift; sourceTree = "<group>"; }; 4542F0931EB9372700C7EE92 /* SystemContactsFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemContactsFetcher.swift; sourceTree = "<group>"; };
4542F0951EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Promise+retainUntilComplete.swift"; sourceTree = "<group>"; };
45464DBB1DFA041F001D3FD6 /* DataChannelMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataChannelMessage.swift; sourceTree = "<group>"; }; 45464DBB1DFA041F001D3FD6 /* DataChannelMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataChannelMessage.swift; sourceTree = "<group>"; };
454B35071D08EED80026D658 /* mk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = mk; path = translations/mk.lproj/Localizable.strings; sourceTree = "<group>"; }; 454B35071D08EED80026D658 /* mk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = mk; path = translations/mk.lproj/Localizable.strings; sourceTree = "<group>"; };
45666EC41D99483D008FE134 /* OWSAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAvatarBuilder.h; sourceTree = "<group>"; }; 45666EC41D99483D008FE134 /* OWSAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSAvatarBuilder.h; sourceTree = "<group>"; };
@ -1275,6 +1278,7 @@
76EB04FB18170B33006006FC /* Util.h */, 76EB04FB18170B33006006FC /* Util.h */,
45F170D51E315310003FC1F2 /* Weak.swift */, 45F170D51E315310003FC1F2 /* Weak.swift */,
45F170CB1E310E22003FC1F2 /* WeakTimer.swift */, 45F170CB1E310E22003FC1F2 /* WeakTimer.swift */,
4542F0951EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift */,
); );
path = util; path = util;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2019,6 +2023,7 @@
34B3F8791E8DF1700035BE1A /* CountryCodeViewController.m in Sources */, 34B3F8791E8DF1700035BE1A /* CountryCodeViewController.m in Sources */,
4CE0E3771B954546007210CF /* TSAnimatedAdapter.m in Sources */, 4CE0E3771B954546007210CF /* TSAnimatedAdapter.m in Sources */,
4531C9C41DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.m in Sources */, 4531C9C41DD8E6D800F08304 /* JSQMessagesCollectionViewCell+OWS.m in Sources */,
4542F0961EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift in Sources */,
4516E3FF1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */, 4516E3FF1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */,
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */, 4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
45387B041E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m in Sources */, 45387B041E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m in Sources */,
@ -2202,6 +2207,7 @@
45FBC5D21DF8592E00E9B410 /* SignalCall.swift in Sources */, 45FBC5D21DF8592E00E9B410 /* SignalCall.swift in Sources */,
451A13B21E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */, 451A13B21E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */,
45C681B81D305A580050903A /* OWSCall.m in Sources */, 45C681B81D305A580050903A /* OWSCall.m in Sources */,
4542F0971EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift in Sources */,
45855F381D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */, 45855F381D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */,
45DF5DF31DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */, 45DF5DF31DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */,
456AC8341E3A775E00A3C7FC /* Weak.swift in Sources */, 456AC8341E3A775E00A3C7FC /* Weak.swift in Sources */,

@ -38,7 +38,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.11.2</string> <string>2.11.3</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@ -55,7 +55,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.11.2.1</string> <string>2.11.3.0</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>LOGS_EMAIL</key> <key>LOGS_EMAIL</key>

@ -12,8 +12,6 @@ class SyncPushTokensJob: NSObject {
let accountManager: AccountManager let accountManager: AccountManager
let preferences: PropertyListPreferences let preferences: PropertyListPreferences
var uploadOnlyIfStale = true var uploadOnlyIfStale = true
// useful to ensure promise runs to completion
var retainCycle: SyncPushTokensJob?
required init(pushManager: PushManager, accountManager: AccountManager, preferences: PropertyListPreferences) { required init(pushManager: PushManager, accountManager: AccountManager, preferences: PropertyListPreferences) {
self.pushManager = pushManager self.pushManager = pushManager
@ -32,14 +30,12 @@ class SyncPushTokensJob: NSObject {
func run() -> Promise<Void> { func run() -> Promise<Void> {
Logger.debug("\(TAG) Starting.") Logger.debug("\(TAG) Starting.")
// Make sure we don't GC until completion.
self.retainCycle = self
// Required to potentially prompt user for notifications settings // Required to potentially prompt user for notifications settings
// before `requestPushTokens` will return. // before `requestPushTokens` will return.
self.pushManager.validateUserNotificationSettings() self.pushManager.validateUserNotificationSettings()
return self.requestPushTokens().then { (pushToken: String, voipToken: String) in let runPromise: Promise<Void> = self.requestPushTokens().then { (pushToken: String, voipToken: String) in
var shouldUploadTokens = !self.uploadOnlyIfStale var shouldUploadTokens = !self.uploadOnlyIfStale
if self.preferences.getPushToken() != pushToken || self.preferences.getVoipToken() != voipToken { if self.preferences.getPushToken() != pushToken || self.preferences.getVoipToken() != voipToken {
Logger.debug("\(self.TAG) push tokens changed.") Logger.debug("\(self.TAG) push tokens changed.")
@ -56,9 +52,10 @@ class SyncPushTokensJob: NSObject {
Logger.info("\(self.TAG) Recording tokens locally.") Logger.info("\(self.TAG) Recording tokens locally.")
return self.recordNewPushTokens(pushToken:pushToken, voipToken:voipToken) return self.recordNewPushTokens(pushToken:pushToken, voipToken:voipToken)
} }
}.always {
self.retainCycle = nil
} }
runPromise.retainUntilComplete()
return runPromise
} }
private func requestPushTokens() -> Promise<(pushToken: String, voipToken: String)> { private func requestPushTokens() -> Promise<(pushToken: String, voipToken: String)> {

@ -282,13 +282,6 @@ protocol CallServiceObserver: class {
callRecord.save() callRecord.save()
call.callRecord = callRecord call.callRecord = callRecord
guard self.peerConnectionClient == nil else {
let errorDescription = "\(TAG) peerconnection was unexpectedly already set."
Logger.error(errorDescription)
call.state = .localFailure
return Promise(error: CallError.assertionError(description: errorDescription))
}
return getIceServers().then { iceServers -> Promise<HardenedRTCSessionDescription> in return getIceServers().then { iceServers -> Promise<HardenedRTCSessionDescription> in
Logger.debug("\(self.TAG) got ice servers:\(iceServers)") Logger.debug("\(self.TAG) got ice servers:\(iceServers)")
@ -296,11 +289,15 @@ protocol CallServiceObserver: class {
throw CallError.obsoleteCall(description:"obsolete call in \(#function)") throw CallError.obsoleteCall(description:"obsolete call in \(#function)")
} }
guard self.peerConnectionClient == nil else {
let errorDescription = "\(self.TAG) peerconnection was unexpectedly already set."
Logger.error(errorDescription)
throw CallError.assertionError(description: errorDescription)
}
let useTurnOnly = Environment.getCurrent().preferences.doCallsHideIPAddress() let useTurnOnly = Environment.getCurrent().preferences.doCallsHideIPAddress()
let peerConnectionClient = PeerConnectionClient(iceServers: iceServers, delegate: self, callDirection: .outgoing, useTurnOnly: useTurnOnly) let peerConnectionClient = PeerConnectionClient(iceServers: iceServers, delegate: self, callDirection: .outgoing, useTurnOnly: useTurnOnly)
assert(self.peerConnectionClient == nil, "Unexpected PeerConnectionClient instance")
Logger.debug("\(self.TAG) setting peerConnectionClient in \(#function)") Logger.debug("\(self.TAG) setting peerConnectionClient in \(#function)")
self.peerConnectionClient = peerConnectionClient self.peerConnectionClient = peerConnectionClient
@ -372,9 +369,10 @@ protocol CallServiceObserver: class {
if pendingIceUpdateMessages.count > 0 { if pendingIceUpdateMessages.count > 0 {
let callMessage = OWSOutgoingCallMessage(thread: thread, iceUpdateMessages: pendingIceUpdateMessages) let callMessage = OWSOutgoingCallMessage(thread: thread, iceUpdateMessages: pendingIceUpdateMessages)
_ = messageSender.sendCallMessage(callMessage).catch { error in let sendPromise = messageSender.sendCallMessage(callMessage).catch { error in
Logger.error("\(self.TAG) failed to send ice updates in \(#function) with error: \(error)") Logger.error("\(self.TAG) failed to send ice updates in \(#function) with error: \(error)")
} }
sendPromise.retainUntilComplete()
} }
guard let peerConnectionClient = self.peerConnectionClient else { guard let peerConnectionClient = self.peerConnectionClient else {
@ -383,7 +381,7 @@ protocol CallServiceObserver: class {
} }
let sessionDescription = RTCSessionDescription(type: .answer, sdp: sessionDescription) let sessionDescription = RTCSessionDescription(type: .answer, sdp: sessionDescription)
_ = peerConnectionClient.setRemoteSessionDescription(sessionDescription).then { let setDescriptionPromise = peerConnectionClient.setRemoteSessionDescription(sessionDescription).then {
Logger.debug("\(self.TAG) successfully set remote description") Logger.debug("\(self.TAG) successfully set remote description")
}.catch { error in }.catch { error in
if let callError = error as? CallError { if let callError = error as? CallError {
@ -393,6 +391,7 @@ protocol CallServiceObserver: class {
self.handleFailedCall(failedCall: call, error: externalError) self.handleFailedCall(failedCall: call, error: externalError)
} }
} }
setDescriptionPromise.retainUntilComplete()
} }
/** /**
@ -428,7 +427,8 @@ protocol CallServiceObserver: class {
let busyMessage = OWSCallBusyMessage(callId: call.signalingId) let busyMessage = OWSCallBusyMessage(callId: call.signalingId)
let callMessage = OWSOutgoingCallMessage(thread: thread, busyMessage: busyMessage) let callMessage = OWSOutgoingCallMessage(thread: thread, busyMessage: busyMessage)
_ = messageSender.sendCallMessage(callMessage) let sendPromise = messageSender.sendCallMessage(callMessage)
sendPromise.retainUntilComplete()
handleMissedCall(call, thread: thread) handleMissedCall(call, thread: thread)
} }
@ -627,7 +627,8 @@ protocol CallServiceObserver: class {
if self.sendIceUpdatesImmediately { if self.sendIceUpdatesImmediately {
let callMessage = OWSOutgoingCallMessage(thread: thread, iceUpdateMessage: iceUpdateMessage) let callMessage = OWSOutgoingCallMessage(thread: thread, iceUpdateMessage: iceUpdateMessage)
_ = self.messageSender.sendCallMessage(callMessage) let sendPromise = self.messageSender.sendCallMessage(callMessage)
sendPromise.retainUntilComplete()
} else { } else {
// For outgoing messages, we wait to send ice updates until we're sure client received our call message. // For outgoing messages, we wait to send ice updates until we're sure client received our call message.
// e.g. if the client has blocked our message due to an identity change, we'd otherwise // e.g. if the client has blocked our message due to an identity change, we'd otherwise
@ -885,11 +886,12 @@ protocol CallServiceObserver: class {
// If the call hasn't started yet, we don't have a data channel to communicate the hang up. Use Signal Service Message. // If the call hasn't started yet, we don't have a data channel to communicate the hang up. Use Signal Service Message.
let hangupMessage = OWSCallHangupMessage(callId: call.signalingId) let hangupMessage = OWSCallHangupMessage(callId: call.signalingId)
let callMessage = OWSOutgoingCallMessage(thread: thread, hangupMessage: hangupMessage) let callMessage = OWSOutgoingCallMessage(thread: thread, hangupMessage: hangupMessage)
_ = self.messageSender.sendCallMessage(callMessage).then { let sendPromise = self.messageSender.sendCallMessage(callMessage).then {
Logger.debug("\(self.TAG) successfully sent hangup call message to \(thread)") Logger.debug("\(self.TAG) successfully sent hangup call message to \(thread)")
}.catch { error in }.catch { error in
Logger.error("\(self.TAG) failed to send hangup call message to \(thread) with error: \(error)") Logger.error("\(self.TAG) failed to send hangup call message to \(thread) with error: \(error)")
} }
sendPromise.retainUntilComplete()
terminateCall() terminateCall()
} }
@ -916,7 +918,9 @@ protocol CallServiceObserver: class {
return return
} }
peerConnectionClient.setAudioEnabled(enabled: !isMuted) if call.state == .connected {
peerConnectionClient.setAudioEnabled(enabled: !isMuted)
}
} }
/** /**
@ -971,7 +975,9 @@ protocol CallServiceObserver: class {
return return
} }
peerConnectionClient.setLocalVideoEnabled(enabled: shouldHaveLocalVideoTrack()) if call.state == .connected {
peerConnectionClient.setLocalVideoEnabled(enabled: shouldHaveLocalVideoTrack())
}
} }
func handleCallKitStartVideo() { func handleCallKitStartVideo() {

@ -29,8 +29,8 @@ class NonCallKitCallUIAdaptee: CallUIAdaptee {
self.callService.handleOutgoingCall(call).then { self.callService.handleOutgoingCall(call).then {
Logger.debug("\(self.TAG) handleOutgoingCall succeeded") Logger.debug("\(self.TAG) handleOutgoingCall succeeded")
}.catch { error in }.catch { error in
Logger.error("\(self.TAG) handleOutgoingCall failed with error: \(error)") Logger.error("\(self.TAG) handleOutgoingCall failed with error: \(error)")
} }
return call return call

@ -239,7 +239,9 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate {
// We can't wait for long before fulfilling the CXAction, else CallKit will show a "Failed Call". We don't // We can't wait for long before fulfilling the CXAction, else CallKit will show a "Failed Call". We don't
// actually need to wait for the outcome of the handleOutgoingCall promise, because it handles any errors by // actually need to wait for the outcome of the handleOutgoingCall promise, because it handles any errors by
// manually failing the call. // manually failing the call.
_ = self.callService.handleOutgoingCall(call) let callPromise = self.callService.handleOutgoingCall(call)
callPromise.retainUntilComplete()
action.fulfill() action.fulfill()
self.provider.reportOutgoingCall(with: call.localId, startedConnectingAt: nil) self.provider.reportOutgoingCall(with: call.localId, startedConnectingAt: nil)

@ -0,0 +1,20 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import PromiseKit
public extension Promise {
/**
* Sometimes there isn't a straight forward candidate to retain a promise, in that case we tell the
* promise to self retain, until it completes to avoid the risk it's GC'd before completion.
*/
func retainUntilComplete() {
// Unfortunately, there is (currently) no way to surpress the
// compiler warning: "Variable 'retainCycle' was written to, but never read"
var retainCycle: Promise<T>? = self
self.always {
retainCycle = nil
}
}
}

@ -50,49 +50,49 @@
"ATTACHMENT" = "مرفقة"; "ATTACHMENT" = "مرفقة";
/* Title for the 'attachment approval' dialog. */ /* Title for the 'attachment approval' dialog. */
"ATTACHMENT_APPROVAL_DIALOG_TITLE" = "Attachment"; "ATTACHMENT_APPROVAL_DIALOG_TITLE" = "ملحق";
/* Format string for file extension label in call interstitial view */ /* Format string for file extension label in call interstitial view */
"ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT" = "File type: %@"; "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT" = "نوع الملف: %@";
/* Format string for file size label in call interstitial view. Embeds: {{file size as 'N mb' or 'N kb'}}. */ /* Format string for file size label in call interstitial view. Embeds: {{file size as 'N mb' or 'N kb'}}. */
"ATTACHMENT_APPROVAL_FILE_SIZE_FORMAT" = "Size: %@"; "ATTACHMENT_APPROVAL_FILE_SIZE_FORMAT" = "الحجم: %@";
/* Label for 'send' button in the 'attachment approval' dialog. */ /* Label for 'send' button in the 'attachment approval' dialog. */
"ATTACHMENT_APPROVAL_SEND_BUTTON" = "Send"; "ATTACHMENT_APPROVAL_SEND_BUTTON" = "ارسل";
/* Generic filename for an attachment with no known name */ /* Generic filename for an attachment with no known name */
"ATTACHMENT_DEFAULT_FILENAME" = "Attachment"; "ATTACHMENT_DEFAULT_FILENAME" = "ملحق";
/* Status label when an attachment download has failed. */ /* Status label when an attachment download has failed. */
"ATTACHMENT_DOWNLOADING_STATUS_FAILED" = "Failed. Tap to retry."; "ATTACHMENT_DOWNLOADING_STATUS_FAILED" = "لم ينجح تنزيل الملحق. انقر لإعادة المحاولة.";
/* Status label when an attachment is currently downloading */ /* Status label when an attachment is currently downloading */
"ATTACHMENT_DOWNLOADING_STATUS_IN_PROGRESS" = "Downloading..."; "ATTACHMENT_DOWNLOADING_STATUS_IN_PROGRESS" = "جاري التنزيل";
/* Status label when an attachment is enqueued, but hasn't yet started downloading */ /* Status label when an attachment is enqueued, but hasn't yet started downloading */
"ATTACHMENT_DOWNLOADING_STATUS_QUEUED" = "Queued"; "ATTACHMENT_DOWNLOADING_STATUS_QUEUED" = "في قائمة التنزيل";
/* The title of the 'attachment error' alert. */ /* The title of the 'attachment error' alert. */
"ATTACHMENT_ERROR_ALERT_TITLE" = "Error Sending Attachment"; "ATTACHMENT_ERROR_ALERT_TITLE" = "خطأ في ارسال الملحق";
/* Attachment error message for image attachments which could not be converted to JPEG */ /* Attachment error message for image attachments which could not be converted to JPEG */
"ATTACHMENT_ERROR_COULD_NOT_CONVERT_TO_JPEG" = "Image attachment could not be resized."; "ATTACHMENT_ERROR_COULD_NOT_CONVERT_TO_JPEG" = "لا يمكن إعادة تحجيم الصورة الملحقة ";
/* Attachment error message for image attachments which cannot be parsed */ /* Attachment error message for image attachments which cannot be parsed */
"ATTACHMENT_ERROR_COULD_NOT_PARSE_IMAGE" = "Image attachment could not be parsed."; "ATTACHMENT_ERROR_COULD_NOT_PARSE_IMAGE" = "لا يمكن تحليل الصورة الملحقة";
/* Attachment error message for attachments whose data exceed file size limits */ /* Attachment error message for attachments whose data exceed file size limits */
"ATTACHMENT_ERROR_FILE_SIZE_TOO_LARGE" = "Attachment is too large."; "ATTACHMENT_ERROR_FILE_SIZE_TOO_LARGE" = "حجم الملحق كبير جدا";
/* Attachment error message for attachments with invalid data */ /* Attachment error message for attachments with invalid data */
"ATTACHMENT_ERROR_INVALID_DATA" = "Attachment has invalid contents."; "ATTACHMENT_ERROR_INVALID_DATA" = "الملحق يحتوي على بيانات غير صحيحة.";
/* Attachment error message for attachments with an invalid file format */ /* Attachment error message for attachments with an invalid file format */
"ATTACHMENT_ERROR_INVALID_FILE_FORMAT" = "Attachment has invalid file format."; "ATTACHMENT_ERROR_INVALID_FILE_FORMAT" = "صيغة ملف الملحق غير صحيحة.";
/* Attachment error message for attachments without any data */ /* Attachment error message for attachments without any data */
"ATTACHMENT_ERROR_MISSING_DATA" = "Attachment is empty."; "ATTACHMENT_ERROR_MISSING_DATA" = "الملحق خالي.";
/* Accessibility hint describing what you can do with the attachment button */ /* Accessibility hint describing what you can do with the attachment button */
"ATTACHMENT_HINT" = "اختر أو إلتقط صورة ثمّ أرسلها"; "ATTACHMENT_HINT" = "اختر أو إلتقط صورة ثمّ أرسلها";
@ -101,109 +101,109 @@
"ATTACHMENT_LABEL" = "المرفق"; "ATTACHMENT_LABEL" = "المرفق";
/* Alert title when picking a document fails for an unknown reason */ /* Alert title when picking a document fails for an unknown reason */
"ATTACHMENT_PICKER_DOCUMENTS_FAILED_ALERT_TITLE" = "Failed to choose document."; "ATTACHMENT_PICKER_DOCUMENTS_FAILED_ALERT_TITLE" = "فشل في اختيار الوثيقة ";
/* Alert body when picking a document fails because user picked a directory/bundle */ /* Alert body when picking a document fails because user picked a directory/bundle */
"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_BODY" = "Signal can't handle that file as is. Try zipping it before sending."; "ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_BODY" = "لا يمكن لـ Signal التعامل مع ملف من هذا النوع. حاول ضغط الملف قبل ارساله.";
/* Alert title when picking a document fails because user picked a directory/bundle */ /* Alert title when picking a document fails because user picked a directory/bundle */
"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_TITLE" = "Unsupported File"; "ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_TITLE" = "ملف غير مدعم";
/* An explanation of the consequences of blocking another user. */ /* An explanation of the consequences of blocking another user. */
"BLOCK_BEHAVIOR_EXPLANATION" = "Blocked users will not be able to call you or send you messages."; "BLOCK_BEHAVIOR_EXPLANATION" = "لن يتمكن المستخدم المحظور من الاتصال بك أو بعث الرسائل إليك.";
/* Button label for the 'block' button */ /* Button label for the 'block' button */
"BLOCK_LIST_BLOCK_BUTTON" = "Block"; "BLOCK_LIST_BLOCK_BUTTON" = "حظر";
/* A format for the 'block user' action sheet title. Embeds {{the blocked user's name or phone number}}. */ /* A format for the 'block user' action sheet title. Embeds {{the blocked user's name or phone number}}. */
"BLOCK_LIST_BLOCK_TITLE_FORMAT" = "Block %@?"; "BLOCK_LIST_BLOCK_TITLE_FORMAT" = "حظر %@؟";
/* Button label for the 'unblock' button */ /* Button label for the 'unblock' button */
"BLOCK_LIST_UNBLOCK_BUTTON" = "Unblock"; "BLOCK_LIST_UNBLOCK_BUTTON" = "رفع الحظر";
/* A format for the 'unblock user' action sheet title. Embeds {{the blocked user's name or phone number}}. */ /* A format for the 'unblock user' action sheet title. Embeds {{the blocked user's name or phone number}}. */
"BLOCK_LIST_UNBLOCK_TITLE_FORMAT" = "Unblock %@?"; "BLOCK_LIST_UNBLOCK_TITLE_FORMAT" = "رفع الحظر %@؟";
/* A format for the message of the alert if user tries to block a user who is already blocked. Embeds {{the blocked user's name or phone number}}. */ /* A format for the message of the alert if user tries to block a user who is already blocked. Embeds {{the blocked user's name or phone number}}. */
"BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_MESSAGE_FORMAT" = "%@ is already blocked."; "BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_MESSAGE_FORMAT" = "%@ تم الحظر مسبقاً.";
/* A title of the alert if user tries to block a user who is already blocked. */ /* A title of the alert if user tries to block a user who is already blocked. */
"BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_TITLE" = "Already Blocked"; "BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_TITLE" = "محظور مسبقاً";
/* A label for the block button in the block list view */ /* A label for the block button in the block list view */
"BLOCK_LIST_VIEW_BLOCK_BUTTON" = "Block"; "BLOCK_LIST_VIEW_BLOCK_BUTTON" = "حظر";
/* The title of the 'block user failed' alert. */ /* The title of the 'block user failed' alert. */
"BLOCK_LIST_VIEW_BLOCK_FAILED_ALERT_MESSAGE" = "Failed to Block User."; "BLOCK_LIST_VIEW_BLOCK_FAILED_ALERT_MESSAGE" = "لم ينجح حظر المستخدم.";
/* The title of the 'block user failed' alert. */ /* The title of the 'block user failed' alert. */
"BLOCK_LIST_VIEW_BLOCK_FAILED_ALERT_TITLE" = "Error"; "BLOCK_LIST_VIEW_BLOCK_FAILED_ALERT_TITLE" = "خطأ";
/* The message format of the 'user blocked' alert. Embeds {{the blocked user's name or phone number}}. */ /* The message format of the 'user blocked' alert. Embeds {{the blocked user's name or phone number}}. */
"BLOCK_LIST_VIEW_BLOCKED_ALERT_MESSAGE_FORMAT" = "%@ has been blocked"; "BLOCK_LIST_VIEW_BLOCKED_ALERT_MESSAGE_FORMAT" = "%@ تم الحظر";
/* The title of the 'user blocked' alert. */ /* The title of the 'user blocked' alert. */
"BLOCK_LIST_VIEW_BLOCKED_ALERT_TITLE" = "User Blocked"; "BLOCK_LIST_VIEW_BLOCKED_ALERT_TITLE" = "المستخدم محظور";
/* The message of the 'You can't block yourself' alert. */ /* The message of the 'You can't block yourself' alert. */
"BLOCK_LIST_VIEW_CANT_BLOCK_SELF_ALERT_MESSAGE" = "You can't block yourself."; "BLOCK_LIST_VIEW_CANT_BLOCK_SELF_ALERT_MESSAGE" = "لا يمكنك حظر نفسك.";
/* The title of the 'You can't block yourself' alert. */ /* The title of the 'You can't block yourself' alert. */
"BLOCK_LIST_VIEW_CANT_BLOCK_SELF_ALERT_TITLE" = "Error"; "BLOCK_LIST_VIEW_CANT_BLOCK_SELF_ALERT_TITLE" = "خطأ";
/* A title for the contacts section of the block list view. */ /* A title for the contacts section of the block list view. */
"BLOCK_LIST_VIEW_CONTACTS_SECTION_TITLE" = "Contacts"; "BLOCK_LIST_VIEW_CONTACTS_SECTION_TITLE" = "جهات الاتصال";
/* The title of the 'unblock user failed' alert. */ /* The title of the 'unblock user failed' alert. */
"BLOCK_LIST_VIEW_UNBLOCK_FAILED_ALERT_MESSAGE" = "Failed to Unblock User."; "BLOCK_LIST_VIEW_UNBLOCK_FAILED_ALERT_MESSAGE" = "لم ينجح رفع الحظر عن المستخدم.";
/* The title of the 'unblock user failed' alert. */ /* The title of the 'unblock user failed' alert. */
"BLOCK_LIST_VIEW_UNBLOCK_FAILED_ALERT_TITLE" = "Error"; "BLOCK_LIST_VIEW_UNBLOCK_FAILED_ALERT_TITLE" = "خطأ";
/* The message format of the 'user unblocked' alert. Embeds {{the blocked user's name or phone number}}. */ /* The message format of the 'user unblocked' alert. Embeds {{the blocked user's name or phone number}}. */
"BLOCK_LIST_VIEW_UNBLOCKED_ALERT_MESSAGE_FORMAT" = "%@ has been unblocked."; "BLOCK_LIST_VIEW_UNBLOCKED_ALERT_MESSAGE_FORMAT" = "%@ تم رفع الحظر.";
/* The title of the 'user unblocked' alert. */ /* The title of the 'user unblocked' alert. */
"BLOCK_LIST_VIEW_UNBLOCKED_ALERT_TITLE" = "User Unblocked"; "BLOCK_LIST_VIEW_UNBLOCKED_ALERT_TITLE" = "المستخدم غير محظور";
/* Action sheet that will block an unknown user. */ /* Action sheet that will block an unknown user. */
"BLOCK_OFFER_ACTIONSHEET_BLOCK_ACTION" = "Block"; "BLOCK_OFFER_ACTIONSHEET_BLOCK_ACTION" = "حظر";
/* Title format for action sheet that offers to block an unknown user.Embeds {{the unknown user's name or phone number}}. */ /* Title format for action sheet that offers to block an unknown user.Embeds {{the unknown user's name or phone number}}. */
"BLOCK_OFFER_ACTIONSHEET_TITLE_FORMAT" = "Block %@?"; "BLOCK_OFFER_ACTIONSHEET_TITLE_FORMAT" = "حظر %@؟";
/* Alert message when calling and permissions for microphone are missing */ /* Alert message when calling and permissions for microphone are missing */
"CALL_AUDIO_PERMISSION_MESSAGE" = "Signal requires access to your microphone to make calls. You can grant this permission in the Settings app."; "CALL_AUDIO_PERMISSION_MESSAGE" = "تتطلب Signal الإِذن باتاحة الميكرفون التابع لك لإجراء المكالمات. يمكنك منح الإذن من برنامج ضبط الإعدادات. ";
/* Alert title when calling and permissions for microphone are missing */ /* Alert title when calling and permissions for microphone are missing */
"CALL_AUDIO_PERMISSION_TITLE" = "Microphone Access Required"; "CALL_AUDIO_PERMISSION_TITLE" = "الإذن لاستخدام الميكرفون مطلوب";
/* Accessibilty label for placing call button */ /* Accessibilty label for placing call button */
"CALL_LABEL" = "إتصل"; "CALL_LABEL" = "إتصل";
/* Call setup status label after outgoing call times out */ /* Call setup status label after outgoing call times out */
"CALL_SCREEN_STATUS_NO_ANSWER" = "No Answer."; "CALL_SCREEN_STATUS_NO_ANSWER" = "لم يتم الرد على المكالمة.";
/* embeds {{Call Status}} in call screen label. For ongoing calls, {{Call Status}} is a seconds timer like 01:23, otherwise {{Call Status}} is a short text like 'Ringing', 'Busy', or 'Failed Call' */ /* embeds {{Call Status}} in call screen label. For ongoing calls, {{Call Status}} is a seconds timer like 01:23, otherwise {{Call Status}} is a short text like 'Ringing', 'Busy', or 'Failed Call' */
"CALL_STATUS_FORMAT" = "Signal %@"; "CALL_STATUS_FORMAT" = "Signal %@";
/* Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy. */ /* Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy. */
"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL" = "You can answer calls directly from your lock screen and see the name and phone number for incoming calls if you change your settings.\n\nSee the privacy settings for details."; "CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL" = "يمكنك الرد على المكالمات من شاشة جهازك المقفلة مباشرةً، كما يمكن أن ترى أسم المتصل ورقمه ضمن المكالمات الواردة إِذا قمت بتغيير الإعدادات.\n\nللمزيد من التفاصيل اطلع على إعدادات الخصوصية.";
/* Reminder to the user of the benefits of disabling CallKit privacy. */ /* Reminder to the user of the benefits of disabling CallKit privacy. */
"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_PRIVACY" = "You can see the name and phone number for incoming calls if you change your settings.\n\nSee the privacy settings for details."; "CALL_VIEW_SETTINGS_NAG_DESCRIPTION_PRIVACY" = "يمكنك أن ترى الأسم والرقم المكالمات الواردة إِذا قمت بتغيير الإعدادات.\n\nللمزيد من التفاصيل اطلع على إعدادات الخصوصية.";
/* Label for button that dismiss the call view's settings nag. */ /* Label for button that dismiss the call view's settings nag. */
"CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON" = "Not Now"; "CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON" = "ليس الآن";
/* Label for button that shows the privacy settings */ /* Label for button that shows the privacy settings */
"CALL_VIEW_SETTINGS_NAG_SHOW_CALL_SETTINGS" = "Show Privacy Settings"; "CALL_VIEW_SETTINGS_NAG_SHOW_CALL_SETTINGS" = "اظهار إِعدادات الخصوصية";
/* notification action */ /* notification action */
"CALLBACK_BUTTON_TITLE" = "إعادة الإتصال"; "CALLBACK_BUTTON_TITLE" = "إعادة الإتصال";
/* The generic name used for calls if CallKit privacy is enabled */ /* The generic name used for calls if CallKit privacy is enabled */
"CALLKIT_ANONYMOUS_CONTACT_NAME" = "Signal User"; "CALLKIT_ANONYMOUS_CONTACT_NAME" = "مستخدم Signal";
/* Activity Sheet label */ /* Activity Sheet label */
"COMPARE_SAFETY_NUMBER_ACTION" = "المقارنة مع الحافظة"; "COMPARE_SAFETY_NUMBER_ACTION" = "المقارنة مع الحافظة";
@ -227,10 +227,10 @@
"CONFIRMATION_TITLE" = "تأكيد"; "CONFIRMATION_TITLE" = "تأكيد";
/* An indicator that a contact has been blocked. */ /* An indicator that a contact has been blocked. */
"CONTACT_CELL_IS_BLOCKED" = "Blocked"; "CONTACT_CELL_IS_BLOCKED" = "محظور";
/* An indicator that a contact is a member of the current group. */ /* An indicator that a contact is a member of the current group. */
"CONTACT_CELL_IS_IN_GROUP" = "Group Member"; "CONTACT_CELL_IS_IN_GROUP" = "عضو في المجموعة";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"CONTACT_DETAIL_COMM_TYPE_INSECURE" = "رقم غير مسجّل"; "CONTACT_DETAIL_COMM_TYPE_INSECURE" = "رقم غير مسجّل";
@ -245,37 +245,37 @@
"CONVERSATION_SETTINGS" = "إعدادات المحادثة"; "CONVERSATION_SETTINGS" = "إعدادات المحادثة";
/* table cell label in conversation settings */ /* table cell label in conversation settings */
"CONVERSATION_SETTINGS_BLOCK_THIS_USER" = "Block this user"; "CONVERSATION_SETTINGS_BLOCK_THIS_USER" = "حظر هذا المستخدم";
/* Title of the 'mute this thread' action sheet. */ /* Title of the 'mute this thread' action sheet. */
"CONVERSATION_SETTINGS_MUTE_ACTION_SHEET_TITLE" = "Mute"; "CONVERSATION_SETTINGS_MUTE_ACTION_SHEET_TITLE" = "كتم";
/* label for 'mute thread' cell in conversation settings */ /* label for 'mute thread' cell in conversation settings */
"CONVERSATION_SETTINGS_MUTE_LABEL" = "Mute"; "CONVERSATION_SETTINGS_MUTE_LABEL" = "كتم";
/* Indicates that the current thread is not muted. */ /* Indicates that the current thread is not muted. */
"CONVERSATION_SETTINGS_MUTE_NOT_MUTED" = "Not muted"; "CONVERSATION_SETTINGS_MUTE_NOT_MUTED" = "لم يتم الكتم ";
/* Label for button to mute a thread for a day. */ /* Label for button to mute a thread for a day. */
"CONVERSATION_SETTINGS_MUTE_ONE_DAY_ACTION" = "Mute for one day"; "CONVERSATION_SETTINGS_MUTE_ONE_DAY_ACTION" = "كتم ليوم واحد";
/* Label for button to mute a thread for a hour. */ /* Label for button to mute a thread for a hour. */
"CONVERSATION_SETTINGS_MUTE_ONE_HOUR_ACTION" = "Mute for one hour"; "CONVERSATION_SETTINGS_MUTE_ONE_HOUR_ACTION" = "كتم لساعة واحدة";
/* Label for button to mute a thread for a minute. */ /* Label for button to mute a thread for a minute. */
"CONVERSATION_SETTINGS_MUTE_ONE_MINUTE_ACTION" = "Mute for one minute"; "CONVERSATION_SETTINGS_MUTE_ONE_MINUTE_ACTION" = "كتم لدقيقة واحدة";
/* Label for button to mute a thread for a week. */ /* Label for button to mute a thread for a week. */
"CONVERSATION_SETTINGS_MUTE_ONE_WEEK_ACTION" = "Mute for one week"; "CONVERSATION_SETTINGS_MUTE_ONE_WEEK_ACTION" = "كتم لأسبوع واحد";
/* Label for button to mute a thread for a year. */ /* Label for button to mute a thread for a year. */
"CONVERSATION_SETTINGS_MUTE_ONE_YEAR_ACTION" = "Mute for one year"; "CONVERSATION_SETTINGS_MUTE_ONE_YEAR_ACTION" = "كتم لسنة واحدة";
/* Indicates that this thread is muted until a given date or time. Embeds {{The date or time which the thread is muted until}}. */ /* Indicates that this thread is muted until a given date or time. Embeds {{The date or time which the thread is muted until}}. */
"CONVERSATION_SETTINGS_MUTED_UNTIL_FORMAT" = "until %@"; "CONVERSATION_SETTINGS_MUTED_UNTIL_FORMAT" = "حتى %@";
/* Label for button to unmute a thread. */ /* Label for button to unmute a thread. */
"CONVERSATION_SETTINGS_UNMUTE_ACTION" = "Unmute"; "CONVERSATION_SETTINGS_UNMUTE_ACTION" = "رفع الكتم";
/* ActionSheet title */ /* ActionSheet title */
"CORRUPTED_SESSION_DESCRIPTION" = "إعادة تعيين جلستك سيسمح لك باستقبال الرسائل الحديثة من %@, لكن لن تتمكن من استعادة أي من الرسائل التالفة."; "CORRUPTED_SESSION_DESCRIPTION" = "إعادة تعيين جلستك سيسمح لك باستقبال الرسائل الحديثة من %@, لكن لن تتمكن من استعادة أي من الرسائل التالفة.";
@ -284,7 +284,7 @@
"COUNTRYCODE_SELECT_TITLE" = "اختر رمز الدولة"; "COUNTRYCODE_SELECT_TITLE" = "اختر رمز الدولة";
/* Accessibility label for the create group new group button */ /* Accessibility label for the create group new group button */
"CREATE_NEW_GROUP" = "Create new group"; "CREATE_NEW_GROUP" = "انشاء مجموعة جديدة";
/* {{number of days}} embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 days}}'. See other *_TIME_AMOUNT strings */ /* {{number of days}} embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 days}}'. See other *_TIME_AMOUNT strings */
"DAYS_TIME_AMOUNT" = "%u يوم"; "DAYS_TIME_AMOUNT" = "%u يوم";
@ -317,19 +317,19 @@
"EDIT_GROUP_ACTION" = "تعديل المجموعة"; "EDIT_GROUP_ACTION" = "تعديل المجموعة";
/* A format for the message of the alert if user tries to add a user to a group who is already in the group. Embeds {{the blocked user's name or phone number}}. */ /* A format for the message of the alert if user tries to add a user to a group who is already in the group. Embeds {{the blocked user's name or phone number}}. */
"EDIT_GROUP_VIEW_ALREADY_IN_GROUP_ALERT_MESSAGE_FORMAT" = "%@ is already a member of this group."; "EDIT_GROUP_VIEW_ALREADY_IN_GROUP_ALERT_MESSAGE_FORMAT" = "%@ عضو في هذه المجموعة أصلاً.";
/* A title of the alert if user tries to add a user to a group who is already in the group. */ /* A title of the alert if user tries to add a user to a group who is already in the group. */
"EDIT_GROUP_VIEW_ALREADY_IN_GROUP_ALERT_TITLE" = "Already a Group Member"; "EDIT_GROUP_VIEW_ALREADY_IN_GROUP_ALERT_TITLE" = "عضو في المجموعة مسبقاً";
/* Short name for edit menu item to copy contents of media message. */ /* Short name for edit menu item to copy contents of media message. */
"EDIT_ITEM_COPY_ACTION" = "Copy"; "EDIT_ITEM_COPY_ACTION" = "نسخ";
/* Short name for edit menu item to save contents of media message. */ /* Short name for edit menu item to save contents of media message. */
"EDIT_ITEM_SAVE_ACTION" = "حفظ"; "EDIT_ITEM_SAVE_ACTION" = "حفظ";
/* Short name for edit menu item to share contents of media message. */ /* Short name for edit menu item to share contents of media message. */
"EDIT_ITEM_SHARE_ACTION" = "Share"; "EDIT_ITEM_SHARE_ACTION" = "تبادل";
/* body of email sent to contacts when inviting to install Signal. Embeds {{link to install Signal}} and {{link to WhisperSystems home page}} */ /* body of email sent to contacts when inviting to install Signal. Embeds {{link to install Signal}} and {{link to WhisperSystems home page}} */
"EMAIL_INVITE_BODY" = "مرحبّا,\n\nمؤخرًا أصبحت أستخدم Signal لجعل محادثاتي على الـiPhone سرية. أرغب أن تثبّته أنت كذلك حتى نتأكد أنا وأنت أننا فقط من يمكنه قراءة رسائلنا أو سماع مكالماتنا.\n\nSignal متاح للـiPhone واﻷندرويد. احصل عليه من هنا: %@\n\nيعمل Signal كما تطبيق تراسلك الحالي. يستطيع إرسال الصور والفيديو, إجاراء المكالمات, وبدء محادثة جماعية. وأفضل جزء هو, لا أحد آخر قادرعلى رؤية أي شيء من ذلك, ولا حتى صنّاع Signal!\n\nتستطيع قراءة المزيد عن Open Whisper Systems, صنّاع Signal, هنا: %@"; "EMAIL_INVITE_BODY" = "مرحبّا,\n\nمؤخرًا أصبحت أستخدم Signal لجعل محادثاتي على الـiPhone سرية. أرغب أن تثبّته أنت كذلك حتى نتأكد أنا وأنت أننا فقط من يمكنه قراءة رسائلنا أو سماع مكالماتنا.\n\nSignal متاح للـiPhone واﻷندرويد. احصل عليه من هنا: %@\n\nيعمل Signal كما تطبيق تراسلك الحالي. يستطيع إرسال الصور والفيديو, إجاراء المكالمات, وبدء محادثة جماعية. وأفضل جزء هو, لا أحد آخر قادرعلى رؤية أي شيء من ذلك, ولا حتى صنّاع Signal!\n\nتستطيع قراءة المزيد عن Open Whisper Systems, صنّاع Signal, هنا: %@";
@ -368,25 +368,25 @@
"EMPTY_INBOX_TITLE" = "خالٍ تماماً"; "EMPTY_INBOX_TITLE" = "خالٍ تماماً";
/* Call setup status label */ /* Call setup status label */
"END_CALL_RESPONDER_IS_BUSY" = "Busy."; "END_CALL_RESPONDER_IS_BUSY" = "مشغول.";
/* Call setup status label */ /* Call setup status label */
"END_CALL_UNCATEGORIZED_FAILURE" = "Call Failed."; "END_CALL_UNCATEGORIZED_FAILURE" = "لم ينجح الاتصال الهاتفي.";
/* Generic notice when message failed to send. */ /* Generic notice when message failed to send. */
"ERROR_DESCRIPTION_CLIENT_SENDING_FAILURE" = "فشل إرسال الرسالة."; "ERROR_DESCRIPTION_CLIENT_SENDING_FAILURE" = "فشل إرسال الرسالة.";
/* Error mesage indicating that message send is disabled due to prekey update failures */ /* Error mesage indicating that message send is disabled due to prekey update failures */
"ERROR_DESCRIPTION_MESSAGE_SEND_DISABLED_PREKEY_UPDATE_FAILURES" = "Unable to send due to stale privacy data."; "ERROR_DESCRIPTION_MESSAGE_SEND_DISABLED_PREKEY_UPDATE_FAILURES" = "غير قادر على الارسال بسبب بيانات الخصوصية القديمة.";
/* Error mesage indicating that message send failed due to block list */ /* Error mesage indicating that message send failed due to block list */
"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_BLOCK_LIST" = "Failed to message user because you blocked them."; "ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_BLOCK_LIST" = "لم ينجح بعث الرسالة لأن المستخدم محظور.";
/* Generic error used whenver Signal can't contact the server */ /* Generic error used whenver Signal can't contact the server */
"ERROR_DESCRIPTION_NO_INTERNET" = "Signal غير قادر على الاتصال بالإنترنت. من فضلك حاول من شبكة WiFi أخرى أو استخدم بيانات الهاتف."; "ERROR_DESCRIPTION_NO_INTERNET" = "Signal غير قادر على الاتصال بالإنترنت. من فضلك حاول من شبكة WiFi أخرى أو استخدم بيانات الهاتف.";
/* Error indicating that an outgoing message had no valid recipients. */ /* Error indicating that an outgoing message had no valid recipients. */
"ERROR_DESCRIPTION_NO_VALID_RECIPIENTS" = "Message send failed due to a lack of valid recipients."; "ERROR_DESCRIPTION_NO_VALID_RECIPIENTS" = "لم ينجح بعث الرسالة لعدم صحة معلومات المستلمين. ";
/* Error message when attempting to send message */ /* Error message when attempting to send message */
"ERROR_DESCRIPTION_SENDING_UNAUTHORIZED" = "جهازك لم يعد مسجّلًا برقم هاتفك. عليك حذف وإعادة تثبيت Signal."; "ERROR_DESCRIPTION_SENDING_UNAUTHORIZED" = "جهازك لم يعد مسجّلًا برقم هاتفك. عليك حذف وإعادة تثبيت Signal.";
@ -395,10 +395,10 @@
"ERROR_DESCRIPTION_SERVER_FAILURE" = "خطأ في المخدم، الرجاء تكرار المحاولة لاحقاً."; "ERROR_DESCRIPTION_SERVER_FAILURE" = "خطأ في المخدم، الرجاء تكرار المحاولة لاحقاً.";
/* Worst case generic error message */ /* Worst case generic error message */
"ERROR_DESCRIPTION_UNKNOWN_ERROR" = "An unknown error occured."; "ERROR_DESCRIPTION_UNKNOWN_ERROR" = "حدث خطأ غير معروف.";
/* Error message when attempting to send message */ /* Error message when attempting to send message */
"ERROR_DESCRIPTION_UNREGISTERED_RECIPIENT" = "Contact is not a Signal user."; "ERROR_DESCRIPTION_UNREGISTERED_RECIPIENT" = "جهة الاتصال ليست من مستخدمي Signal.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"ERROR_MESSAGE_DUPLICATE_MESSAGE" = "تم تلقي رسالة مكررة."; "ERROR_MESSAGE_DUPLICATE_MESSAGE" = "تم تلقي رسالة مكررة.";
@ -431,19 +431,19 @@
"EXISTING_USER_REGISTRATION_ALERT_TITLE" = "تفعيل %@ سوف يعطّل Signal على أي جهاز آخر مرتبط بهذا الرقم حاليّا."; "EXISTING_USER_REGISTRATION_ALERT_TITLE" = "تفعيل %@ سوف يعطّل Signal على أي جهاز آخر مرتبط بهذا الرقم حاليّا.";
/* Message for the alert indicating the 'export with signal' file had an invalid filename. */ /* Message for the alert indicating the 'export with signal' file had an invalid filename. */
"EXPORT_WITH_SIGNAL_ERROR_MESSAGE_INVALID_FILENAME" = "Invalid filename."; "EXPORT_WITH_SIGNAL_ERROR_MESSAGE_INVALID_FILENAME" = "أسم الملف غير صحيح.";
/* Message for the alert indicating the 'export with signal' attachment couldn't be loaded. */ /* Message for the alert indicating the 'export with signal' attachment couldn't be loaded. */
"EXPORT_WITH_SIGNAL_ERROR_MESSAGE_MISSING_ATTACHMENT" = "Couldn't load file."; "EXPORT_WITH_SIGNAL_ERROR_MESSAGE_MISSING_ATTACHMENT" = "لم ينجح تحميل الملف.";
/* Message for the alert indicating the 'export with signal' data couldn't be loaded. */ /* Message for the alert indicating the 'export with signal' data couldn't be loaded. */
"EXPORT_WITH_SIGNAL_ERROR_MESSAGE_MISSING_DATA" = "Couldn't load file."; "EXPORT_WITH_SIGNAL_ERROR_MESSAGE_MISSING_DATA" = "لم ينجح تحميل لملف.";
/* Message for the alert indicating the 'export with signal' file had unknown type. */ /* Message for the alert indicating the 'export with signal' file had unknown type. */
"EXPORT_WITH_SIGNAL_ERROR_MESSAGE_UNKNOWN_TYPE" = "Unknown file type."; "EXPORT_WITH_SIGNAL_ERROR_MESSAGE_UNKNOWN_TYPE" = "نوع الملف غير معروف.";
/* Title for the alert indicating the 'export with signal' attachment had an error. */ /* Title for the alert indicating the 'export with signal' attachment had an error. */
"EXPORT_WITH_SIGNAL_ERROR_TITLE" = "Error"; "EXPORT_WITH_SIGNAL_ERROR_TITLE" = "خطأ";
/* action sheet header when re-sending message which failed because of too many attempts */ /* action sheet header when re-sending message which failed because of too many attempts */
"FAILED_SENDING_BECAUSE_RATE_LIMIT" = "الكثير من الأخطاء مع جهة الاتصال هذه. فضلّا حاول مرة أخرى بعد لحظات."; "FAILED_SENDING_BECAUSE_RATE_LIMIT" = "الكثير من الأخطاء مع جهة الاتصال هذه. فضلّا حاول مرة أخرى بعد لحظات.";
@ -461,10 +461,10 @@
"FINISH_GROUP_CREATION_LABEL" = "إتمام إنشاء المجموعة"; "FINISH_GROUP_CREATION_LABEL" = "إتمام إنشاء المجموعة";
/* A default label for attachment whose file extension cannot be determined. */ /* A default label for attachment whose file extension cannot be determined. */
"GENERIC_ATTACHMENT_DEFAULT_TYPE" = "?"; "GENERIC_ATTACHMENT_DEFAULT_TYPE" = "؟";
/* A label for generic attachments. */ /* A label for generic attachments. */
"GENERIC_ATTACHMENT_LABEL" = "Attachment"; "GENERIC_ATTACHMENT_LABEL" = "ملحق";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GROUP_AVATAR_CHANGED" = "تغيرت الصورة الرمزية."; "GROUP_AVATAR_CHANGED" = "تغيرت الصورة الرمزية.";
@ -488,16 +488,16 @@
"GROUP_MEMBER_LEFT" = "%@ غادر المجموعة"; "GROUP_MEMBER_LEFT" = "%@ غادر المجموعة";
/* Button label for the 'call group member' button */ /* Button label for the 'call group member' button */
"GROUP_MEMBERS_CALL" = "Call"; "GROUP_MEMBERS_CALL" = "اتصال هاتفي";
/* header for table which lists the members of this group thread */ /* header for table which lists the members of this group thread */
"GROUP_MEMBERS_HEADER" = "أعضاء المجموعة"; "GROUP_MEMBERS_HEADER" = "أعضاء المجموعة";
/* Button label for the 'send message to group member' button */ /* Button label for the 'send message to group member' button */
"GROUP_MEMBERS_SEND_MESSAGE" = "Send Message"; "GROUP_MEMBERS_SEND_MESSAGE" = "بعث الرسالة";
/* Button label for the 'show contact info' button */ /* Button label for the 'show contact info' button */
"GROUP_MEMBERS_VIEW_CONTACT_INFO" = "Contact Info"; "GROUP_MEMBERS_VIEW_CONTACT_INFO" = "معلومات جهات الاتصال";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GROUP_REMOVING" = "مغادرة مجموعة %@"; "GROUP_REMOVING" = "مغادرة مجموعة %@";
@ -515,7 +515,7 @@
"GROUP_YOU_LEFT" = "لقد غادرت المجموعة"; "GROUP_YOU_LEFT" = "لقد غادرت المجموعة";
/* A label for conversations with blocked users. */ /* A label for conversations with blocked users. */
"HOME_VIEW_BLOCKED_CONTACT_CONVERSATION" = "Blocked"; "HOME_VIEW_BLOCKED_CONTACT_CONVERSATION" = "محظور";
/* {{number of hours}} embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 hours}}'. See other *_TIME_AMOUNT strings */ /* {{number of hours}} embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 hours}}'. See other *_TIME_AMOUNT strings */
"HOURS_TIME_AMOUNT" = "%u ساعات"; "HOURS_TIME_AMOUNT" = "%u ساعات";
@ -533,7 +533,7 @@
"IN_CALL_TALKING" = "آمن. فعال."; "IN_CALL_TALKING" = "آمن. فعال.";
/* Call setup status label */ /* Call setup status label */
"IN_CALL_TERMINATED" = "Call Ended."; "IN_CALL_TERMINATED" = "انتهت المكالمة.";
/* notification body */ /* notification body */
"INCOMING_CALL" = "مكالمة واردة"; "INCOMING_CALL" = "مكالمة واردة";
@ -542,13 +542,13 @@
"INCOMING_CALL_FROM" = "مكالمة واردة من %@"; "INCOMING_CALL_FROM" = "مكالمة واردة من %@";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"INCOMING_INCOMPLETE_CALL" = "Incomplete incoming call from"; "INCOMING_INCOMPLETE_CALL" = "مكالمة غير كاملة واردة من";
/* Text for button at the top of the contact picker */ /* Text for button at the top of the contact picker */
"INVITE_FRIENDS_CONTACT_TABLE_BUTTON" = "دعوة اﻷصدقاء لـSignal"; "INVITE_FRIENDS_CONTACT_TABLE_BUTTON" = "دعوة اﻷصدقاء لـSignal";
/* Search */ /* Search */
"INVITE_FRIENDS_PICKER_SEARCHBAR_PLACEHOLDER" = "Search"; "INVITE_FRIENDS_PICKER_SEARCHBAR_PLACEHOLDER" = "بحث";
/* Navbar title */ /* Navbar title */
"INVITE_FRIENDS_PICKER_TITLE" = "أدع أصدقائك"; "INVITE_FRIENDS_PICKER_TITLE" = "أدع أصدقائك";
@ -614,7 +614,7 @@
"MEDIA_FROM_CAMERA_BUTTON" = "الكاميرا"; "MEDIA_FROM_CAMERA_BUTTON" = "الكاميرا";
/* action sheet button title when choosing attachment type */ /* action sheet button title when choosing attachment type */
"MEDIA_FROM_DOCUMENT_PICKER_BUTTON" = "Document"; "MEDIA_FROM_DOCUMENT_PICKER_BUTTON" = "وثيقة";
/* media picker option to choose from library */ /* media picker option to choose from library */
"MEDIA_FROM_LIBRARY_BUTTON" = "مكتبة الصور"; "MEDIA_FROM_LIBRARY_BUTTON" = "مكتبة الصور";
@ -623,34 +623,34 @@
"MESSAGE_COMPOSEVIEW_TITLE" = "رسالة جديدة"; "MESSAGE_COMPOSEVIEW_TITLE" = "رسالة جديدة";
/* message footer for delivered messages */ /* message footer for delivered messages */
"MESSAGE_STATUS_DELIVERED" = "Delivered"; "MESSAGE_STATUS_DELIVERED" = "تم الاستلام";
/* message footer for failed messages */ /* message footer for failed messages */
"MESSAGE_STATUS_FAILED" = "Sending failed. Tap to retry."; "MESSAGE_STATUS_FAILED" = "لم ينجح الارسال. انقر لإعادة المحاولة.";
/* message footer for sent messages */ /* message footer for sent messages */
"MESSAGE_STATUS_SENT" = "Sent"; "MESSAGE_STATUS_SENT" = "تم الارسال";
/* message footer while attachment is uploading */ /* message footer while attachment is uploading */
"MESSAGE_STATUS_UPLOADING" = "Uploading..."; "MESSAGE_STATUS_UPLOADING" = "جاري التحميل";
/* Indicates that this 1:1 conversation has been blocked. */ /* Indicates that this 1:1 conversation has been blocked. */
"MESSAGES_VIEW_CONTACT_BLOCKED" = "You Blocked this User"; "MESSAGES_VIEW_CONTACT_BLOCKED" = "حظرت هذا المستخدم ";
/* Action sheet title after tapping on failed download. */ /* Action sheet title after tapping on failed download. */
"MESSAGES_VIEW_FAILED_DOWNLOAD_ACTIONSHEET_TITLE" = "Download Failed."; "MESSAGES_VIEW_FAILED_DOWNLOAD_ACTIONSHEET_TITLE" = "لم ينجح التنزيل.";
/* Action sheet button text */ /* Action sheet button text */
"MESSAGES_VIEW_FAILED_DOWNLOAD_RETRY_ACTION" = "Download Again"; "MESSAGES_VIEW_FAILED_DOWNLOAD_RETRY_ACTION" = "إعادة التنزيل";
/* Indicates that a single member of this group has been blocked. */ /* Indicates that a single member of this group has been blocked. */
"MESSAGES_VIEW_GROUP_1_MEMBER_BLOCKED" = "You Blocked 1 Member of this Group"; "MESSAGES_VIEW_GROUP_1_MEMBER_BLOCKED" = "قمت بحظر 1 عضو من هذه المجموعة";
/* Indicates that some members of this group has been blocked. Embeds {{the number of blocked users in this group}}. */ /* Indicates that some members of this group has been blocked. Embeds {{the number of blocked users in this group}}. */
"MESSAGES_VIEW_GROUP_N_MEMBERS_BLOCKED_FORMAT" = "You Blocked %d Members of this Group"; "MESSAGES_VIEW_GROUP_N_MEMBERS_BLOCKED_FORMAT" = "حظرت %d أعضاء من هذه المجموعة";
/* The subtitle for the messages view title indicates that the title can be tapped to access settings for this conversation. */ /* The subtitle for the messages view title indicates that the title can be tapped to access settings for this conversation. */
"MESSAGES_VIEW_TITLE_SUBTITLE" = "Tap here for settings"; "MESSAGES_VIEW_TITLE_SUBTITLE" = "انقر هنا لفتح الإعدادات";
/* {{number of minutes}} embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 minutes}}'. See other *_TIME_AMOUNT strings */ /* {{number of minutes}} embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 minutes}}'. See other *_TIME_AMOUNT strings */
"MINUTES_TIME_AMOUNT" = "%u دقيقة"; "MINUTES_TIME_AMOUNT" = "%u دقيقة";
@ -660,29 +660,29 @@
/* Alert body /* Alert body
Alert body when camera is not authorized */ Alert body when camera is not authorized */
"MISSING_CAMERA_PERMISSION_MESSAGE" = "Signal needs access to your camera for video calls. You can grant this permission in the Settings app >> Privacy >> Camera >> Signal"; "MISSING_CAMERA_PERMISSION_MESSAGE" = "Singal بحاجة إِلى استخدام كاميرتك لإجراء الاتصالات الفيديوية. يمكنك السماح بذلك من برنامج الإعدادات >> الخصوصية >> الكاميرا >> Signal";
/* Alert title /* Alert title
Alert title when camera is not authorized */ Alert title when camera is not authorized */
"MISSING_CAMERA_PERMISSION_TITLE" = "يحتاج Signal للوصول للكاميرا"; "MISSING_CAMERA_PERMISSION_TITLE" = "يحتاج Signal للوصول للكاميرا";
/* notification title. Embeds {{Caller's Name}} */ /* notification title. Embeds {{Caller's Name}} */
"MSGVIEW_MISSED_CALL_WITH_NAME" = "Missed call from %@."; "MSGVIEW_MISSED_CALL_WITH_NAME" = "مكالمة فائتة من %@";
/* notification title. */ /* notification title. */
"MSGVIEW_MISSED_CALL_WITHOUT_NAME" = "Missed call from Signal User."; "MSGVIEW_MISSED_CALL_WITHOUT_NAME" = "مكالمة فائتة من مستخدم Signal";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"MSGVIEW_RECEIVED_CALL" = "مكالمة واردة من %@"; "MSGVIEW_RECEIVED_CALL" = "مكالمة واردة من %@";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"MSGVIEW_THEY_TRIED_TO_CALL_YOU" = "%@ tried to call you."; "MSGVIEW_THEY_TRIED_TO_CALL_YOU" = "%@ حاول الاتصال بك.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"MSGVIEW_YOU_CALLED" = "لقد اتصلت ب %@"; "MSGVIEW_YOU_CALLED" = "لقد اتصلت ب %@";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"MSGVIEW_YOU_TRIED_TO_CALL" = "You tried to call %@."; "MSGVIEW_YOU_TRIED_TO_CALL" = "حاولت الاتصال %@.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"MULTIDEVICE_PAIRING_MAX_DESC" = "لا يمكنك ربط أي أجهزة أخرى."; "MULTIDEVICE_PAIRING_MAX_DESC" = "لا يمكنك ربط أي أجهزة أخرى.";
@ -691,7 +691,7 @@
"MULTIDEVICE_PAIRING_MAX_RECOVERY" = "لقد وصلت للحد اﻷقصى من اﻷجهزة المرتبطة بحسابك. من فضلك أزل جهاز أو حاول مرة أخرى لاحقًا."; "MULTIDEVICE_PAIRING_MAX_RECOVERY" = "لقد وصلت للحد اﻷقصى من اﻷجهزة المرتبطة بحسابك. من فضلك أزل جهاز أو حاول مرة أخرى لاحقًا.";
/* An explanation of the consequences of muting a thread. */ /* An explanation of the consequences of muting a thread. */
"MUTE_BEHAVIOR_EXPLANATION" = "You will not receive notifications for muted conversations."; "MUTE_BEHAVIOR_EXPLANATION" = "لن تستلم تنبيهات من المحادثات التي تم كتمها.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"NETWORK_ERROR_RECOVERY" = "من فضلك تأكد من اتصالك بالانترنت وحاول مرة أخرى."; "NETWORK_ERROR_RECOVERY" = "من فضلك تأكد من اتصالك بالانترنت وحاول مرة أخرى.";
@ -712,7 +712,7 @@
"NETWORK_STATUS_TEXT" = "يمكنك التأكد من حالة الشبكة من خلال الشريط الملون أعلى صندوق الوارد"; "NETWORK_STATUS_TEXT" = "يمكنك التأكد من حالة الشبكة من خلال الشريط الملون أعلى صندوق الوارد";
/* Text for button to start a new conversation with a non-contact */ /* Text for button to start a new conversation with a non-contact */
"NEW_CONVERSATION_FOR_NON_CONTACT_FORMAT" = "New conversation with %@"; "NEW_CONVERSATION_FOR_NON_CONTACT_FORMAT" = "محادثة جديدة مع %@";
/* Action Sheet title prompting the user for a group avatar */ /* Action Sheet title prompting the user for a group avatar */
"NEW_GROUP_ADD_PHOTO_ACTION" = "ضع صورة للمجموعة"; "NEW_GROUP_ADD_PHOTO_ACTION" = "ضع صورة للمجموعة";
@ -727,7 +727,7 @@
"NEW_GROUP_REQUEST_ADDPEOPLE" = "إضافة أشخاص"; "NEW_GROUP_REQUEST_ADDPEOPLE" = "إضافة أشخاص";
/* Label for a button that lets users search for contacts by phone number */ /* Label for a button that lets users search for contacts by phone number */
"NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "Find Contacts by Phone Number"; "NO_CONTACTS_SEARCH_BY_PHONE_NUMBER" = "العثور على أسماء من يتم الاتصال بهم عن طريق رقم الهاتف";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"NOTIFICATION_SEND_FAILED" = "فشل إرسال رسالتك إلى %@."; "NOTIFICATION_SEND_FAILED" = "فشل إرسال رسالتك إلى %@.";
@ -773,13 +773,13 @@
"OUTGOING_CALL" = "مكالمة صادرة"; "OUTGOING_CALL" = "مكالمة صادرة";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"OUTGOING_INCOMPLETE_CALL" = "Incomplete outgoing call"; "OUTGOING_INCOMPLETE_CALL" = "مكالمة صادرة غير كاملة";
/* A display format for oversize text messages. */ /* A display format for oversize text messages. */
"OVERSIZE_TEXT_DISPLAY_FORMAT" = "%@… [Tap For More]"; "OVERSIZE_TEXT_DISPLAY_FORMAT" = "%@… [انقر لرؤية المزيد]";
/* The title of the 'oversize text message' view. */ /* The title of the 'oversize text message' view. */
"OVERSIZE_TEXT_MESSAGE_VIEW_TITLE" = "Message"; "OVERSIZE_TEXT_MESSAGE_VIEW_TITLE" = "رسالة ";
/* Alert body when verifying with {{contact name}} */ /* Alert body when verifying with {{contact name}} */
"PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "لا يبدو هذا رقم اﻷمان الخاص بك مع %@. هل تتحقق من جهة الاتصال الصحيحة؟"; "PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "لا يبدو هذا رقم اﻷمان الخاص بك مع %@. هل تتحقق من جهة الاتصال الصحيحة؟";
@ -854,10 +854,10 @@
"REGISTER_CONTACTS_WELCOME" = "مرحبًا!"; "REGISTER_CONTACTS_WELCOME" = "مرحبًا!";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"REGISTER_FAILED_TRY_AGAIN" = "Try Again"; "REGISTER_FAILED_TRY_AGAIN" = "حاول مرة أُخرى";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"REGISTER_RATE_LIMITING_BODY" = "You have tried too often. Please wait a minute before trying again."; "REGISTER_RATE_LIMITING_BODY" = "حاولت مراراً وتكراراً . الرجاء الانتظار لدقيقة واحدة قبل إعادة المحاولة.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"REGISTERED_NUMBER_TEXT" = "رقم مسجّل"; "REGISTERED_NUMBER_TEXT" = "رقم مسجّل";
@ -932,16 +932,16 @@
"SECURE_SESSION_RESET" = "لقد تم إعادة تعيين دورة الاتصال الآمنة"; "SECURE_SESSION_RESET" = "لقد تم إعادة تعيين دورة الاتصال الآمنة";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SEND_AGAIN_BUTTON" = "Send Again"; "SEND_AGAIN_BUTTON" = "ارسل مرة أُخرى";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SEND_BUTTON_TITLE" = "إرسال"; "SEND_BUTTON_TITLE" = "إرسال";
/* Header title for the 'send external file' view. */ /* Header title for the 'send external file' view. */
"SEND_EXTERNAL_FILE_HEADER_TITLE" = "Select a Recipient for:"; "SEND_EXTERNAL_FILE_HEADER_TITLE" = "اختر مستلم لـ:";
/* Title for the 'send external file' view. */ /* Title for the 'send external file' view. */
"SEND_EXTERNAL_FILE_VIEW_TITLE" = "Send File"; "SEND_EXTERNAL_FILE_VIEW_TITLE" = "ارسل الملف";
/* Alert body after invite failed */ /* Alert body after invite failed */
"SEND_INVITE_FAILURE" = "فشل إرسال الدعوة, فضلّا أعد المحاولة لاحقًا."; "SEND_INVITE_FAILURE" = "فشل إرسال الدعوة, فضلّا أعد المحاولة لاحقًا.";
@ -950,7 +950,7 @@
"SEND_INVITE_SUCCESS" = "لقد دعوت صديقك لاستخدام Signal!"; "SEND_INVITE_SUCCESS" = "لقد دعوت صديقك لاستخدام Signal!";
/* Text for button to send a Signal invite via SMS. %@ is placeholder for the receipient's phone number. */ /* Text for button to send a Signal invite via SMS. %@ is placeholder for the receipient's phone number. */
"SEND_INVITE_VIA_SMS_BUTTON_FORMAT" = "Send Invite via SMS to: %@"; "SEND_INVITE_VIA_SMS_BUTTON_FORMAT" = "ارسل الدعوة عبر رسالة نصية: %@";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SEND_SMS_CONFIRM_TITLE" = "إرسال دعوة لصديق عن طريق رسالة نصية غير آمنة؟"; "SEND_SMS_CONFIRM_TITLE" = "إرسال دعوة لصديق عن طريق رسالة نصية غير آمنة؟";
@ -962,13 +962,13 @@
"SETTINGS_ABOUT" = "حول"; "SETTINGS_ABOUT" = "حول";
/* Title for the 'block contact' section of the 'add to block list' view. */ /* Title for the 'block contact' section of the 'add to block list' view. */
"SETTINGS_ADD_TO_BLOCK_LIST_BLOCK_CONTACT_TITLE" = "Block Contact"; "SETTINGS_ADD_TO_BLOCK_LIST_BLOCK_CONTACT_TITLE" = "حظر المتصل";
/* Title for the 'block phone number' section of the 'add to block list' view. */ /* Title for the 'block phone number' section of the 'add to block list' view. */
"SETTINGS_ADD_TO_BLOCK_LIST_BLOCK_PHONE_NUMBER_TITLE" = "Block Phone Number"; "SETTINGS_ADD_TO_BLOCK_LIST_BLOCK_PHONE_NUMBER_TITLE" = "حظر رقم الهاتف";
/* Title for the 'add to block list' view. */ /* Title for the 'add to block list' view. */
"SETTINGS_ADD_TO_BLOCK_LIST_TITLE" = "Block"; "SETTINGS_ADD_TO_BLOCK_LIST_TITLE" = "حظر";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SETTINGS_ADVANCED_DEBUGLOG" = "تفعيل سجل التصحيح"; "SETTINGS_ADVANCED_DEBUGLOG" = "تفعيل سجل التصحيح";
@ -980,13 +980,13 @@
"SETTINGS_ADVANCED_TITLE" = "إعدادات متقدمة"; "SETTINGS_ADVANCED_TITLE" = "إعدادات متقدمة";
/* A label for the 'add phone number' button in the block list table. */ /* A label for the 'add phone number' button in the block list table. */
"SETTINGS_BLOCK_LIST_ADD_BUTTON" = "Add…"; "SETTINGS_BLOCK_LIST_ADD_BUTTON" = "إضافة";
/* A label that indicates the user has no Signal contacts. */ /* A label that indicates the user has no Signal contacts. */
"SETTINGS_BLOCK_LIST_NO_CONTACTS" = "You have no contacts on Signal."; "SETTINGS_BLOCK_LIST_NO_CONTACTS" = "جهات الاتصال الخاصة بك غير موجودة على Signal.";
/* Label for the block list section of the settings view */ /* Label for the block list section of the settings view */
"SETTINGS_BLOCK_LIST_TITLE" = "Blocked"; "SETTINGS_BLOCK_LIST_TITLE" = "تم الحظر";
/* User settings section footer, a detailed explanation */ /* User settings section footer, a detailed explanation */
"SETTINGS_BLOCK_ON_IDENITY_CHANGE_DETAIL" = "موافقتك مطلوبة قبل التواصل مع شخص لديه رقم أمان جديد, غالبًا بسبب إعادته تثبيت Signal."; "SETTINGS_BLOCK_ON_IDENITY_CHANGE_DETAIL" = "موافقتك مطلوبة قبل التواصل مع شخص لديه رقم أمان جديد, غالبًا بسبب إعادته تثبيت Signal.";
@ -995,13 +995,13 @@
"SETTINGS_BLOCK_ON_IDENTITY_CHANGE_TITLE" = "يتطلّب التأكيد عند التغيير"; "SETTINGS_BLOCK_ON_IDENTITY_CHANGE_TITLE" = "يتطلّب التأكيد عند التغيير";
/* Accessibility hint for the settings button */ /* Accessibility hint for the settings button */
"SETTINGS_BUTTON_ACCESSIBILITY" = "Settings"; "SETTINGS_BUTTON_ACCESSIBILITY" = "الإعدادات";
/* Table cell label */ /* Table cell label */
"SETTINGS_CALLING_HIDES_IP_ADDRESS_PREFERENCE_TITLE" = "Always Relay Calls"; "SETTINGS_CALLING_HIDES_IP_ADDRESS_PREFERENCE_TITLE" = "مناوبة المكالمات الهاتفية دوماً";
/* User settings section footer, a detailed explanation */ /* User settings section footer, a detailed explanation */
"SETTINGS_CALLING_HIDES_IP_ADDRESS_PREFERENCE_TITLE_DETAIL" = "Relay all calls through the Signal server to avoid revealing your IP address to your contact. Enabling will reduce call quality."; "SETTINGS_CALLING_HIDES_IP_ADDRESS_PREFERENCE_TITLE_DETAIL" = "مناوبة جميع المكالمات عن طريق شبكة خدمة Signal لتجنب ظهور عنوان الـ IP الخاص بك إِلى جهات الاتصال. سيُقلل التمكين من جودة المكالمة.";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SETTINGS_CLEAR_HISTORY" = "امسح سجل التاريخ"; "SETTINGS_CLEAR_HISTORY" = "امسح سجل التاريخ";
@ -1040,10 +1040,10 @@
"SETTINGS_NOTIFICATIONS" = "الإشعارات"; "SETTINGS_NOTIFICATIONS" = "الإشعارات";
/* Label for 'CallKit privacy' preference */ /* Label for 'CallKit privacy' preference */
"SETTINGS_PRIVACY_CALLKIT_PRIVACY_TITLE" = "Show Caller's Name & Number"; "SETTINGS_PRIVACY_CALLKIT_PRIVACY_TITLE" = "اظهار أسم المتصل ورقمه";
/* Short table cell label */ /* Short table cell label */
"SETTINGS_PRIVACY_CALLKIT_TITLE" = "iOS Call Integration"; "SETTINGS_PRIVACY_CALLKIT_TITLE" = "نظام التشغيل iOS لدمج المكالمة";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SETTINGS_PRIVACY_TITLE" = "الخصوصية"; "SETTINGS_PRIVACY_TITLE" = "الخصوصية";
@ -1055,13 +1055,13 @@
"SETTINGS_SCREEN_SECURITY" = "تفعيل خاصية تأمين الشاشة"; "SETTINGS_SCREEN_SECURITY" = "تفعيل خاصية تأمين الشاشة";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SETTINGS_SCREEN_SECURITY_DETAIL" = "Prevent Signal previews from appearing in the app switcher."; "SETTINGS_SCREEN_SECURITY_DETAIL" = "منع ظهور استعراضات Signal في محول البرنامج.";
/* Settings table section footer. */ /* Settings table section footer. */
"SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "iOS Call Integration shows Signal calls on your lock screen and in the system's call history. You may optionally show your contact's name and number. If iCloud is enabled, this call history will be shared with Apple."; "SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "يعرض دمج المكالمة التابع لـ iOS مكالمات Signal الهاتفية على الشاشة المقفلة وفي سجل اتصالات النظام. يمكنك أن تختار اظهار أسم المتصل ورقمه. في حال تمكين iCloud يتم تبادل تاريخ المكالمات مع Apple.";
/* settings topic header for table section */ /* settings topic header for table section */
"SETTINGS_SECTION_TITLE_CALLING" = "Calling"; "SETTINGS_SECTION_TITLE_CALLING" = "جاري الاتصال";
/* Section header */ /* Section header */
"SETTINGS_SECURITY_TITLE" = "تأمين الشاشة"; "SETTINGS_SECURITY_TITLE" = "تأمين الشاشة";
@ -1118,7 +1118,7 @@
"UNKNOWN_ATTACHMENT_LABEL" = "مرفق غير معلوم"; "UNKNOWN_ATTACHMENT_LABEL" = "مرفق غير معلوم";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"UNKNOWN_CONTACT_BLOCK_OFFER" = "User not in your contacts. Would you like to block this user?"; "UNKNOWN_CONTACT_BLOCK_OFFER" = "المستخدم ليس ضمن أسماء قائمة جهات الاتصال التابعة لك. هل ترغب في حظر هذا المستخدم؟";
/* Displayed if for some reason we can't determine a contacts phone number *or* name */ /* Displayed if for some reason we can't determine a contacts phone number *or* name */
"UNKNOWN_CONTACT_NAME" = "جهة اتصال مجهولة"; "UNKNOWN_CONTACT_NAME" = "جهة اتصال مجهولة";
@ -1151,40 +1151,40 @@
"UPDATE_BUTTON_TITLE" = "تحديث"; "UPDATE_BUTTON_TITLE" = "تحديث";
/* Description of CallKit to upgrading (existing) users */ /* Description of CallKit to upgrading (existing) users */
"UPGRADE_EXPERIENCE_CALLKIT_DESCRIPTION" = "Answering calls from your lock screen is easy with iOS call integration. We anonymize your caller by default, so it's private too."; "UPGRADE_EXPERIENCE_CALLKIT_DESCRIPTION" = "بدمج المكالمات عبر نظام تشغيل iOS يصبح من السهل الرد على المكالمات الهاتفية والشاشة مقفلة. نقوم باخفاء هوية المتصل أساساً، لذا فهي خاصة أيضاً. ";
/* button label shown once when when user upgrades app, in context of call kit */ /* button label shown once when when user upgrades app, in context of call kit */
"UPGRADE_EXPERIENCE_CALLKIT_PRIVACY_SETTINGS_BUTTON" = "Learn more in your privacy settings."; "UPGRADE_EXPERIENCE_CALLKIT_PRIVACY_SETTINGS_BUTTON" = "تعلم المزيد عن إعدادات الخصوصية.";
/* Header for upgrade experience */ /* Header for upgrade experience */
"UPGRADE_EXPERIENCE_CALLKIT_TITLE" = "Just Swipe to Answer"; "UPGRADE_EXPERIENCE_CALLKIT_TITLE" = "تصفح بسلاسة لتعرف الإجابة ببساطة";
/* Description of video calling to upgrading (existing) users */ /* Description of video calling to upgrading (existing) users */
"UPGRADE_EXPERIENCE_VIDEO_DESCRIPTION" = "Signal now supports secure video calling. Just start a call like normal, tap the camera button, and wave hello."; "UPGRADE_EXPERIENCE_VIDEO_DESCRIPTION" = "تدعم Signal حالياً الاتصال الفيديوي الآمن. إِبدأ بمجرد إجراء الاتصال الهاتفي المعتاد، وانقر على زرّ الكاميرا، ثم لوِّح لتلقي التحية. ";
/* Header for upgrade experience */ /* Header for upgrade experience */
"UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Hello Secure Video Calls!"; "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "أهلاً بالاتصالات الفيديوية الآمنة! ";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"Upgrading Signal ..." = "ترقية Signal ..."; "Upgrading Signal ..." = "ترقية Signal ...";
/* button text for back button on verification view */ /* button text for back button on verification view */
"VERIFICATION_BACK_BUTTON" = "Back"; "VERIFICATION_BACK_BUTTON" = "الرجوع";
/* Text field placeholder for SMS verification code during registration */ /* Text field placeholder for SMS verification code during registration */
"VERIFICATION_CHALLENGE_DEFAULT_TEXT" = "رمز التحقق"; "VERIFICATION_CHALLENGE_DEFAULT_TEXT" = "رمز التحقق";
/* button text during registration to request phone number verification be done via phone call */ /* button text during registration to request phone number verification be done via phone call */
"VERIFICATION_CHALLENGE_SEND_VIA_VOICE" = "Call Me Instead"; "VERIFICATION_CHALLENGE_SEND_VIA_VOICE" = "اتصل بي بدلاً من ذلك";
/* button text during registration to request another SMS code be sent */ /* button text during registration to request another SMS code be sent */
"VERIFICATION_CHALLENGE_SUBMIT_AGAIN" = "Resend Code by SMS"; "VERIFICATION_CHALLENGE_SUBMIT_AGAIN" = "إعادة ارسال الشفرة عبر الرسائل النصية";
/* button text during registration to submit your SMS verification code */ /* button text during registration to submit your SMS verification code */
"VERIFICATION_CHALLENGE_SUBMIT_CODE" = "تقديم رمز التحقق"; "VERIFICATION_CHALLENGE_SUBMIT_CODE" = "تقديم رمز التحقق";
/* Label indicating the phone number currently being verified. */ /* Label indicating the phone number currently being verified. */
"VERIFICATION_PHONE_NUMBER_FORMAT" = "Enter the verification code we sent to %@."; "VERIFICATION_PHONE_NUMBER_FORMAT" = "ادخال شفرة التحقق التي أرسلناها إلى %@.";
/* table cell label in conversation settings */ /* table cell label in conversation settings */
"VERIFY_PRIVACY" = "التحقق من الرقم اﻷمان"; "VERIFY_PRIVACY" = "التحقق من الرقم اﻷمان";

@ -188,10 +188,10 @@
"CALL_STATUS_FORMAT" = "Signal %@"; "CALL_STATUS_FORMAT" = "Signal %@";
/* Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy. */ /* Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy. */
"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL" = "You can answer calls directly from your lock screen and see the name and phone number for incoming calls if you change your settings.\n\nSee the privacy settings for details."; "CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL" = "Você pode atender chamadas diretamente da sua tela bloqueada e ver o nome e o número de telefone de chamadas recebidas se você mudar suas configurações.\n\nPara detalhes, veja as configurações de privacidade.";
/* Reminder to the user of the benefits of disabling CallKit privacy. */ /* Reminder to the user of the benefits of disabling CallKit privacy. */
"CALL_VIEW_SETTINGS_NAG_DESCRIPTION_PRIVACY" = "You can see the name and phone number for incoming calls if you change your settings.\n\nSee the privacy settings for details."; "CALL_VIEW_SETTINGS_NAG_DESCRIPTION_PRIVACY" = "Você pode ver o nome e o número de telefone de chamadas recebidas se você mudar suas configurações.\n\nPara detalhes, veja as configurações de privacidade.";
/* Label for button that dismiss the call view's settings nag. */ /* Label for button that dismiss the call view's settings nag. */
"CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON" = "Agora não"; "CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON" = "Agora não";
@ -1043,7 +1043,7 @@
"SETTINGS_PRIVACY_CALLKIT_PRIVACY_TITLE" = "Exibir o nome e número do contato"; "SETTINGS_PRIVACY_CALLKIT_PRIVACY_TITLE" = "Exibir o nome e número do contato";
/* Short table cell label */ /* Short table cell label */
"SETTINGS_PRIVACY_CALLKIT_TITLE" = "iOS Call Integration"; "SETTINGS_PRIVACY_CALLKIT_TITLE" = "Integração de Chamada do iOS";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SETTINGS_PRIVACY_TITLE" = "Privacidade"; "SETTINGS_PRIVACY_TITLE" = "Privacidade";
@ -1055,10 +1055,10 @@
"SETTINGS_SCREEN_SECURITY" = "Habilitar Segurança de Tela"; "SETTINGS_SCREEN_SECURITY" = "Habilitar Segurança de Tela";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"SETTINGS_SCREEN_SECURITY_DETAIL" = "Prevent Signal previews from appearing in the app switcher."; "SETTINGS_SCREEN_SECURITY_DETAIL" = "Impeça que pré-vizualizações apareçam no seletor de aplicativos.";
/* Settings table section footer. */ /* Settings table section footer. */
"SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "iOS Call Integration shows Signal calls on your lock screen and in the system's call history. You may optionally show your contact's name and number. If iCloud is enabled, this call history will be shared with Apple."; "SETTINGS_SECTION_CALL_KIT_DESCRIPTION" = "A Integração de Chamadas do iOS exibe chamadas do Signal na tela bloqueada e no histórico de chamadas do sistema. Você pode optar por exibir o nome e o número do seu contato. Se o iCloud estiver ativado, esse histórico de ligações será compartilhado com a Apple.";
/* settings topic header for table section */ /* settings topic header for table section */
"SETTINGS_SECTION_TITLE_CALLING" = "Chamando"; "SETTINGS_SECTION_TITLE_CALLING" = "Chamando";
@ -1151,7 +1151,7 @@
"UPDATE_BUTTON_TITLE" = "Atualizar"; "UPDATE_BUTTON_TITLE" = "Atualizar";
/* Description of CallKit to upgrading (existing) users */ /* Description of CallKit to upgrading (existing) users */
"UPGRADE_EXPERIENCE_CALLKIT_DESCRIPTION" = "Answering calls from your lock screen is easy with iOS call integration. We anonymize your caller by default, so it's private too."; "UPGRADE_EXPERIENCE_CALLKIT_DESCRIPTION" = "Atender ligações da sua tela bloqueada é fácil com a integração de chamada do iOS. Nós anonimizamos a identidade daquele que liga para que ela também seja privada.";
/* button label shown once when when user upgrades app, in context of call kit */ /* button label shown once when when user upgrades app, in context of call kit */
"UPGRADE_EXPERIENCE_CALLKIT_PRIVACY_SETTINGS_BUTTON" = "Saiba mais nas configurações de privacidade."; "UPGRADE_EXPERIENCE_CALLKIT_PRIVACY_SETTINGS_BUTTON" = "Saiba mais nas configurações de privacidade.";

@ -110,7 +110,7 @@
"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_TITLE" = "Неподдерживаемый файл"; "ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_TITLE" = "Неподдерживаемый файл";
/* An explanation of the consequences of blocking another user. */ /* An explanation of the consequences of blocking another user. */
"BLOCK_BEHAVIOR_EXPLANATION" = "Заблокированные пользователь не смогут звонить или отправлять сообщения Вам."; "BLOCK_BEHAVIOR_EXPLANATION" = "Заблокированные пользователи не смогут звонить или отправлять сообщения Вам.";
/* Button label for the 'block' button */ /* Button label for the 'block' button */
"BLOCK_LIST_BLOCK_BUTTON" = "Заблокировать"; "BLOCK_LIST_BLOCK_BUTTON" = "Заблокировать";
@ -245,16 +245,16 @@
"CONVERSATION_SETTINGS" = "Настройки разговоров"; "CONVERSATION_SETTINGS" = "Настройки разговоров";
/* table cell label in conversation settings */ /* table cell label in conversation settings */
"CONVERSATION_SETTINGS_BLOCK_THIS_USER" = "Заблокировать этого пользователя"; "CONVERSATION_SETTINGS_BLOCK_THIS_USER" = "Заблокировать";
/* Title of the 'mute this thread' action sheet. */ /* Title of the 'mute this thread' action sheet. */
"CONVERSATION_SETTINGS_MUTE_ACTION_SHEET_TITLE" = "Беззвучный режим"; "CONVERSATION_SETTINGS_MUTE_ACTION_SHEET_TITLE" = "Без звука";
/* label for 'mute thread' cell in conversation settings */ /* label for 'mute thread' cell in conversation settings */
"CONVERSATION_SETTINGS_MUTE_LABEL" = "Беззвучный режим"; "CONVERSATION_SETTINGS_MUTE_LABEL" = "Без звука";
/* Indicates that the current thread is not muted. */ /* Indicates that the current thread is not muted. */
"CONVERSATION_SETTINGS_MUTE_NOT_MUTED" = "Звук уведомлений включен"; "CONVERSATION_SETTINGS_MUTE_NOT_MUTED" = "Выкл.";
/* Label for button to mute a thread for a day. */ /* Label for button to mute a thread for a day. */
"CONVERSATION_SETTINGS_MUTE_ONE_DAY_ACTION" = "Беззвучный режим на 1 день"; "CONVERSATION_SETTINGS_MUTE_ONE_DAY_ACTION" = "Беззвучный режим на 1 день";

Loading…
Cancel
Save