mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 16edc24c16 | |||
| 1cb3c25478 | |||
| 13912a4af9 | |||
| 601b4cd619 | |||
| d2b4b7bed6 | |||
| fa95e4e9ad | |||
| 88fdc1ef75 | |||
| 7ab6e44a6e | |||
| 26986686ca | |||
| e76dc33cf0 | |||
| aa2eafdacb | |||
| 2c3c97f5cc | |||
| 83f42704ea | |||
| 7ff6ef09fe | |||
| dbe4504f05 | |||
| 9a87f344b5 | |||
| 2127c7dcce | |||
| e3528d3ffe | |||
| ec014d721e | |||
| 75bacb7923 | |||
| 0d8c179861 | |||
| e9a99dfb3c | |||
| baa585357f | |||
| cebb4aa93b | |||
| df53ae9d4f | |||
| 21b1904b0e | |||
| b1ef442f1e | |||
| 4020cb074f | |||
| 0c69f6553a | |||
| 03865b4a18 | |||
| ac5f0bc7bb | |||
| 12423f4afa | |||
| fabbe0285d | |||
| b01efd9d0a | |||
| fc28ff0f15 | |||
| 213f6cf372 | |||
| a764e1906d | |||
| 54b40a5838 | |||
| 35fc0544a0 | |||
| 6907f02ea6 | |||
| c6ece8afdd | |||
| a00e5901de | |||
| ad2a0024f2 | |||
| c5261a416f | |||
| 193e17f7af | |||
| 87fd642951 | |||
| fb044000d2 | |||
| 69791dbdcf | |||
| dc11202250 | |||
| 96ac0a7715 | |||
| bdb6bd6e20 | |||
| 7ccd80bf23 | |||
| 6118fca000 |
@@ -29,12 +29,12 @@ struct ContentView: View {
|
||||
@AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false
|
||||
@AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = false
|
||||
@AppStorage(DEFAULT_NOTIFICATION_ALERT_SHOWN) private var notificationAlertShown = false
|
||||
@State private var showSettings = false
|
||||
@State private var showWhatsNew = false
|
||||
@State private var showChooseLAMode = false
|
||||
@State private var showSetPasscode = false
|
||||
@State private var waitingForOrPassedAuth = true
|
||||
@State private var chatListActionSheet: ChatListActionSheet? = nil
|
||||
@State private var chatListUserPickerSheet: UserPickerSheet? = nil
|
||||
|
||||
private let callTopPadding: CGFloat = 40
|
||||
|
||||
@@ -86,7 +86,7 @@ struct ContentView: View {
|
||||
callView(call)
|
||||
}
|
||||
|
||||
if !showSettings, let la = chatModel.laRequest {
|
||||
if chatListUserPickerSheet == nil, let la = chatModel.laRequest {
|
||||
LocalAuthView(authRequest: la)
|
||||
.onDisappear {
|
||||
// this flag is separate from accessAuthenticated to show initializationView while we wait for authentication
|
||||
@@ -109,9 +109,6 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $alertManager.presentAlert) { alertManager.alertView! }
|
||||
.sheet(isPresented: $showSettings) {
|
||||
SettingsView(showSettings: $showSettings)
|
||||
}
|
||||
.confirmationDialog("SimpleX Lock mode", isPresented: $showChooseLAMode, titleVisibility: .visible) {
|
||||
Button("System authentication") { initialEnableLA() }
|
||||
Button("Passcode entry") { showSetPasscode = true }
|
||||
@@ -253,7 +250,7 @@ struct ContentView: View {
|
||||
|
||||
private func mainView() -> some View {
|
||||
ZStack(alignment: .top) {
|
||||
ChatListView(showSettings: $showSettings).privacySensitive(protectScreen)
|
||||
ChatListView(activeUserPickerSheet: $chatListUserPickerSheet).privacySensitive(protectScreen)
|
||||
.onAppear {
|
||||
requestNtfAuthorization()
|
||||
// Local Authentication notice is to be shown on next start after onboarding is complete
|
||||
@@ -300,9 +297,18 @@ struct ContentView: View {
|
||||
if let contactId = contacts?.first?.personHandle?.value,
|
||||
let chat = chatModel.getChat(contactId),
|
||||
case let .direct(contact) = chat.chatInfo {
|
||||
logger.debug("callToRecentContact: schedule call")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
let activeCall = chatModel.activeCall
|
||||
// This line works when a user clicks on a video button in CallKit UI while in call.
|
||||
// The app tries to make another call to the same contact and overwite activeCall instance making its state broken
|
||||
if let activeCall, contactId == activeCall.contact.id, mediaType == .video, !activeCall.hasVideo {
|
||||
Task {
|
||||
await chatModel.callCommand.processCommand(.media(source: .camera, enable: true))
|
||||
}
|
||||
} else if activeCall == nil {
|
||||
logger.debug("callToRecentContact: schedule call")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -526,7 +526,7 @@ final class ChatModel: ObservableObject {
|
||||
}
|
||||
|
||||
func updateCurrentUserUiThemes(uiThemes: ThemeModeOverrides?) {
|
||||
guard var current = currentUser else { return }
|
||||
guard var current = currentUser, current.uiThemes != uiThemes else { return }
|
||||
current.uiThemes = uiThemes
|
||||
let i = users.firstIndex(where: { $0.user.userId == current.userId })
|
||||
if let i {
|
||||
|
||||
@@ -462,7 +462,7 @@ func apiGetNtfToken() -> (DeviceToken?, NtfTknStatus?, NotificationsMode, String
|
||||
let r = chatSendCmdSync(.apiGetNtfToken)
|
||||
switch r {
|
||||
case let .ntfToken(token, status, ntfMode, ntfServer): return (token, status, ntfMode, ntfServer)
|
||||
case .chatCmdError(_, .errorAgent(.CMD(.PROHIBITED))): return (nil, nil, .off, nil)
|
||||
case .chatCmdError(_, .errorAgent(.CMD(.PROHIBITED, _))): return (nil, nil, .off, nil)
|
||||
default:
|
||||
logger.debug("apiGetNtfToken response: \(String(describing: r))")
|
||||
return (nil, nil, .off, nil)
|
||||
@@ -585,12 +585,18 @@ func apiContactInfo(_ contactId: Int64) async throws -> (ConnectionStats?, Profi
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiGroupMemberInfo(_ groupId: Int64, _ groupMemberId: Int64) throws -> (GroupMember, ConnectionStats?) {
|
||||
func apiGroupMemberInfoSync(_ groupId: Int64, _ groupMemberId: Int64) throws -> (GroupMember, ConnectionStats?) {
|
||||
let r = chatSendCmdSync(.apiGroupMemberInfo(groupId: groupId, groupMemberId: groupMemberId))
|
||||
if case let .groupMemberInfo(_, _, member, connStats_) = r { return (member, connStats_) }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiGroupMemberInfo(_ groupId: Int64, _ groupMemberId: Int64) async throws -> (GroupMember, ConnectionStats?) {
|
||||
let r = await chatSendCmd(.apiGroupMemberInfo(groupId: groupId, groupMemberId: groupMemberId))
|
||||
if case let .groupMemberInfo(_, _, member, connStats_) = r { return (member, connStats_) }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiContactQueueInfo(_ contactId: Int64) async throws -> (RcvMsgInfo?, ServerQueueInfo) {
|
||||
let r = await chatSendCmd(.apiContactQueueInfo(contactId: contactId))
|
||||
if case let .queueInfo(_, rcvMsgInfo, queueInfo) = r { return (rcvMsgInfo, queueInfo) }
|
||||
@@ -645,8 +651,8 @@ func apiGetContactCode(_ contactId: Int64) async throws -> (Contact, String) {
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiGetGroupMemberCode(_ groupId: Int64, _ groupMemberId: Int64) throws -> (GroupMember, String) {
|
||||
let r = chatSendCmdSync(.apiGetGroupMemberCode(groupId: groupId, groupMemberId: groupMemberId))
|
||||
func apiGetGroupMemberCode(_ groupId: Int64, _ groupMemberId: Int64) async throws -> (GroupMember, String) {
|
||||
let r = await chatSendCmd(.apiGetGroupMemberCode(groupId: groupId, groupMemberId: groupMemberId))
|
||||
if case let .groupMemberCode(_, _, member, connectionCode) = r { return (member, connectionCode) }
|
||||
throw r
|
||||
}
|
||||
@@ -2084,7 +2090,6 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
await withCall(contact) { call in
|
||||
await MainActor.run {
|
||||
call.callState = .offerReceived
|
||||
call.peerMedia = callType.media
|
||||
call.sharedKey = sharedKey
|
||||
}
|
||||
let useRelay = UserDefaults.standard.bool(forKey: DEFAULT_WEBRTC_POLICY_RELAY)
|
||||
|
||||
@@ -17,8 +17,8 @@ struct ActiveCallView: View {
|
||||
@ObservedObject var call: Call
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@State private var client: WebRTCClient? = nil
|
||||
@State private var activeCall: WebRTCClient.Call? = nil
|
||||
@State private var localRendererAspectRatio: CGFloat? = nil
|
||||
@State var remoteContentMode: UIView.ContentMode = .scaleAspectFill
|
||||
@Binding var canConnectCall: Bool
|
||||
@State var prevColorScheme: ColorScheme = .dark
|
||||
@State var pipShown = false
|
||||
@@ -27,24 +27,39 @@ struct ActiveCallView: View {
|
||||
var body: some View {
|
||||
ZStack(alignment: .topLeading) {
|
||||
ZStack(alignment: .bottom) {
|
||||
if let client = client, [call.peerMedia, call.localMedia].contains(.video), activeCall != nil {
|
||||
if let client = client, call.hasVideo {
|
||||
GeometryReader { g in
|
||||
let width = g.size.width * 0.3
|
||||
ZStack(alignment: .topTrailing) {
|
||||
CallViewRemote(client: client, activeCall: $activeCall, activeCallViewIsCollapsed: $m.activeCallViewIsCollapsed, pipShown: $pipShown)
|
||||
CallViewLocal(client: client, activeCall: $activeCall, localRendererAspectRatio: $localRendererAspectRatio, pipShown: $pipShown)
|
||||
.cornerRadius(10)
|
||||
.frame(width: width, height: width / (localRendererAspectRatio ?? 1))
|
||||
.padding([.top, .trailing], 17)
|
||||
ZStack(alignment: .center) {
|
||||
// For some reason, when the view in GeometryReader and ZStack is visible, it steals clicks on a back button, so showing something on top like this with background color helps (.clear color doesn't work)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.background(Color.primary.opacity(0.000001))
|
||||
|
||||
CallViewRemote(client: client, call: call, activeCallViewIsCollapsed: $m.activeCallViewIsCollapsed, contentMode: $remoteContentMode, pipShown: $pipShown)
|
||||
.onTapGesture {
|
||||
remoteContentMode = remoteContentMode == .scaleAspectFill ? .scaleAspectFit : .scaleAspectFill
|
||||
}
|
||||
|
||||
Group {
|
||||
let localVideoTrack = client.activeCall?.localVideoTrack ?? client.notConnectedCall?.localCameraAndTrack?.1
|
||||
if localVideoTrack != nil {
|
||||
CallViewLocal(client: client, localRendererAspectRatio: $localRendererAspectRatio, pipShown: $pipShown)
|
||||
.onDisappear {
|
||||
localRendererAspectRatio = nil
|
||||
}
|
||||
} else {
|
||||
Rectangle().fill(.black)
|
||||
}
|
||||
}
|
||||
.cornerRadius(10)
|
||||
.frame(width: width, height: localRendererAspectRatio == nil ? (g.size.width < g.size.height ? width * 1.33 : width / 1.33) : width / (localRendererAspectRatio ?? 1))
|
||||
.padding([.top, .trailing], 17)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let call = m.activeCall, let client = client, (!pipShown || !call.supportsVideo) {
|
||||
if let call = m.activeCall, let client = client, (!pipShown || !call.hasVideo) {
|
||||
ActiveCallOverlay(call: call, client: client)
|
||||
}
|
||||
}
|
||||
@@ -54,6 +69,9 @@ struct ActiveCallView: View {
|
||||
.onAppear {
|
||||
logger.debug("ActiveCallView: appear client is nil \(client == nil), scenePhase \(String(describing: scenePhase)), canConnectCall \(canConnectCall)")
|
||||
AppDelegate.keepScreenOn(true)
|
||||
Task {
|
||||
await askRequiredPermissions()
|
||||
}
|
||||
createWebRTCClient()
|
||||
dismissAllSheets()
|
||||
hideKeyboard()
|
||||
@@ -84,7 +102,7 @@ struct ActiveCallView: View {
|
||||
|
||||
private func createWebRTCClient() {
|
||||
if client == nil && canConnectCall {
|
||||
client = WebRTCClient($activeCall, { msg in await MainActor.run { processRtcMessage(msg: msg) } }, $localRendererAspectRatio)
|
||||
client = WebRTCClient({ msg in await MainActor.run { processRtcMessage(msg: msg) } }, $localRendererAspectRatio)
|
||||
Task {
|
||||
await m.callCommand.setClient(client)
|
||||
}
|
||||
@@ -99,7 +117,7 @@ struct ActiveCallView: View {
|
||||
logger.debug("ActiveCallView: response \(msg.resp.respType)")
|
||||
switch msg.resp {
|
||||
case let .capabilities(capabilities):
|
||||
let callType = CallType(media: call.localMedia, capabilities: capabilities)
|
||||
let callType = CallType(media: call.initialCallType, capabilities: capabilities)
|
||||
Task {
|
||||
do {
|
||||
try await apiSendCallInvitation(call.contact, callType)
|
||||
@@ -110,7 +128,7 @@ struct ActiveCallView: View {
|
||||
call.callState = .invitationSent
|
||||
call.localCapabilities = capabilities
|
||||
}
|
||||
if call.supportsVideo && !AVAudioSession.sharedInstance().hasExternalAudioDevice() {
|
||||
if call.hasVideo && !AVAudioSession.sharedInstance().hasExternalAudioDevice() {
|
||||
try? AVAudioSession.sharedInstance().setCategory(.playback, options: [.allowBluetooth, .allowAirPlay, .allowBluetoothA2DP])
|
||||
}
|
||||
CallSoundsPlayer.shared.startConnectingCallSound()
|
||||
@@ -120,7 +138,7 @@ struct ActiveCallView: View {
|
||||
Task {
|
||||
do {
|
||||
try await apiSendCallOffer(call.contact, offer, iceCandidates,
|
||||
media: call.localMedia, capabilities: capabilities)
|
||||
media: call.initialCallType, capabilities: capabilities)
|
||||
} catch {
|
||||
logger.error("apiSendCallOffer \(responseError(error))")
|
||||
}
|
||||
@@ -164,6 +182,9 @@ struct ActiveCallView: View {
|
||||
}
|
||||
if state.connectionState == "closed" {
|
||||
closeCallView(client)
|
||||
if let callUUID = m.activeCall?.callUUID {
|
||||
CallController.shared.endCall(callUUID: callUUID)
|
||||
}
|
||||
m.activeCall = nil
|
||||
m.activeCallViewIsCollapsed = false
|
||||
}
|
||||
@@ -182,6 +203,14 @@ struct ActiveCallView: View {
|
||||
CallSoundsPlayer.shared.vibrate(long: false)
|
||||
wasConnected = true
|
||||
}
|
||||
case let .peerMedia(source, enabled):
|
||||
switch source {
|
||||
case .mic: call.peerMediaSources.mic = enabled
|
||||
case .camera: call.peerMediaSources.camera = enabled
|
||||
case .screenAudio: call.peerMediaSources.screenAudio = enabled
|
||||
case .screenVideo: call.peerMediaSources.screenVideo = enabled
|
||||
case .unknown: ()
|
||||
}
|
||||
case .ended:
|
||||
closeCallView(client)
|
||||
call.callState = .ended
|
||||
@@ -226,6 +255,26 @@ struct ActiveCallView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func askRequiredPermissions() async {
|
||||
let mic = await WebRTCClient.isAuthorized(for: .audio)
|
||||
await MainActor.run {
|
||||
call.localMediaSources.mic = mic
|
||||
}
|
||||
let cameraAuthorized = AVCaptureDevice.authorizationStatus(for: .video) == .authorized
|
||||
var camera = call.initialCallType == .audio || cameraAuthorized
|
||||
if call.initialCallType == .video && !cameraAuthorized {
|
||||
camera = await WebRTCClient.isAuthorized(for: .video)
|
||||
await MainActor.run {
|
||||
if camera, let client {
|
||||
client.setCameraEnabled(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !mic || !camera {
|
||||
WebRTCClient.showUnauthorizedAlert(for: !mic ? .audio : .video)
|
||||
}
|
||||
}
|
||||
|
||||
private func closeCallView(_ client: WebRTCClient) {
|
||||
if m.activeCall != nil {
|
||||
m.showCallView = false
|
||||
@@ -241,44 +290,16 @@ struct ActiveCallOverlay: View {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
switch call.localMedia {
|
||||
case .video:
|
||||
switch call.hasVideo {
|
||||
case true:
|
||||
videoCallInfoView(call)
|
||||
.foregroundColor(.white)
|
||||
.opacity(0.8)
|
||||
.padding()
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack {
|
||||
toggleAudioButton()
|
||||
Spacer()
|
||||
if deviceManager.availableInputs.allSatisfy({ $0.portType == .builtInMic }) {
|
||||
toggleSpeakerButton()
|
||||
.frame(width: 40, height: 40)
|
||||
} else if call.hasMedia {
|
||||
AudioDevicePicker()
|
||||
.scaleEffect(2)
|
||||
.frame(maxWidth: 40, maxHeight: 40)
|
||||
} else {
|
||||
Color.clear.frame(width: 40, height: 40)
|
||||
}
|
||||
Spacer()
|
||||
endCallButton()
|
||||
Spacer()
|
||||
if call.videoEnabled {
|
||||
flipCameraButton()
|
||||
} else {
|
||||
Color.clear.frame(width: 40, height: 40)
|
||||
}
|
||||
Spacer()
|
||||
toggleVideoButton()
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.bottom, 16)
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
|
||||
case .audio:
|
||||
.padding(.horizontal)
|
||||
// Fixed vertical padding required for preserving position of buttons row when changing audio-to-video and back in landscape orientation.
|
||||
// Otherwise, bigger padding is added by SwiftUI when switching call types
|
||||
.padding(.vertical, 10)
|
||||
case false:
|
||||
ZStack(alignment: .topLeading) {
|
||||
Button {
|
||||
chatModel.activeCallViewIsCollapsed = true
|
||||
@@ -293,35 +314,32 @@ struct ActiveCallOverlay: View {
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.opacity(0.8)
|
||||
.padding()
|
||||
.padding(.horizontal)
|
||||
.padding(.vertical, 10)
|
||||
.frame(maxHeight: .infinity)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
ZStack(alignment: .bottom) {
|
||||
toggleAudioButton()
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
endCallButton()
|
||||
// Check if the only input is microphone. And in this case show toggle button,
|
||||
// If there are more inputs, it probably means something like bluetooth headphones are available
|
||||
// and in this case show iOS button for choosing different output.
|
||||
// There is no way to get available outputs, only inputs
|
||||
if deviceManager.availableInputs.allSatisfy({ $0.portType == .builtInMic }) {
|
||||
toggleSpeakerButton()
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
} else if call.hasMedia {
|
||||
AudioDevicePicker()
|
||||
.scaleEffect(2)
|
||||
.frame(maxWidth: 50, maxHeight: 40)
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
} else {
|
||||
Color.clear.frame(width: 50, height: 40)
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 60)
|
||||
.padding(.horizontal, 48)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack {
|
||||
toggleMicButton()
|
||||
Spacer()
|
||||
audioDeviceButton()
|
||||
Spacer()
|
||||
endCallButton()
|
||||
Spacer()
|
||||
if call.localMediaSources.camera {
|
||||
flipCameraButton()
|
||||
} else {
|
||||
Color.clear.frame(width: 60, height: 60)
|
||||
}
|
||||
Spacer()
|
||||
toggleCameraButton()
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.bottom, 16)
|
||||
.frame(maxWidth: 440, alignment: .center)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.onAppear {
|
||||
@@ -383,36 +401,54 @@ struct ActiveCallOverlay: View {
|
||||
|
||||
private func endCallButton() -> some View {
|
||||
let cc = CallController.shared
|
||||
return callButton("phone.down.fill", width: 60, height: 60) {
|
||||
return callButton("phone.down.fill", .red, padding: 10) {
|
||||
if let uuid = call.callUUID {
|
||||
cc.endCall(callUUID: uuid)
|
||||
} else {
|
||||
cc.endCall(call: call) {}
|
||||
}
|
||||
}
|
||||
.foregroundColor(.red)
|
||||
}
|
||||
|
||||
private func toggleAudioButton() -> some View {
|
||||
controlButton(call, call.audioEnabled ? "mic.fill" : "mic.slash") {
|
||||
private func toggleMicButton() -> some View {
|
||||
controlButton(call, call.localMediaSources.mic ? "mic.fill" : "mic.slash", padding: 14) {
|
||||
Task {
|
||||
client.setAudioEnabled(!call.audioEnabled)
|
||||
DispatchQueue.main.async {
|
||||
call.audioEnabled = !call.audioEnabled
|
||||
}
|
||||
if await WebRTCClient.isAuthorized(for: .audio) {
|
||||
client.setAudioEnabled(!call.localMediaSources.mic)
|
||||
} else { WebRTCClient.showUnauthorizedAlert(for: .audio) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func audioDeviceButton() -> some View {
|
||||
// Check if the only input is microphone. And in this case show toggle button,
|
||||
// If there are more inputs, it probably means something like bluetooth headphones are available
|
||||
// and in this case show iOS button for choosing different output.
|
||||
// There is no way to get available outputs, only inputs
|
||||
Group {
|
||||
if deviceManager.availableInputs.allSatisfy({ $0.portType == .builtInMic }) {
|
||||
toggleSpeakerButton()
|
||||
} else {
|
||||
audioDevicePickerButton()
|
||||
}
|
||||
}
|
||||
.onChange(of: call.localMediaSources.hasVideo) { hasVideo in
|
||||
let current = AVAudioSession.sharedInstance().currentRoute.outputs.first?.portType
|
||||
let speakerEnabled = current == .builtInSpeaker
|
||||
let receiverEnabled = current == .builtInReceiver
|
||||
// react automatically only when receiver were selected, otherwise keep an external device selected
|
||||
if !speakerEnabled && hasVideo && receiverEnabled {
|
||||
client.setSpeakerEnabledAndConfigureSession(!speakerEnabled, skipExternalDevice: true)
|
||||
call.speakerEnabled = !speakerEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func toggleSpeakerButton() -> some View {
|
||||
controlButton(call, call.speakerEnabled ? "speaker.wave.2.fill" : "speaker.wave.1.fill") {
|
||||
Task {
|
||||
let speakerEnabled = AVAudioSession.sharedInstance().currentRoute.outputs.first?.portType == .builtInSpeaker
|
||||
client.setSpeakerEnabledAndConfigureSession(!speakerEnabled)
|
||||
DispatchQueue.main.async {
|
||||
call.speakerEnabled = !speakerEnabled
|
||||
}
|
||||
}
|
||||
controlButton(call, !call.peerMediaSources.mic ? "speaker.slash" : call.speakerEnabled ? "speaker.wave.2.fill" : "speaker.wave.1.fill", padding: !call.peerMediaSources.mic ? 16 : call.speakerEnabled ? 15 : 17) {
|
||||
let speakerEnabled = AVAudioSession.sharedInstance().currentRoute.outputs.first?.portType == .builtInSpeaker
|
||||
client.setSpeakerEnabledAndConfigureSession(!speakerEnabled)
|
||||
call.speakerEnabled = !speakerEnabled
|
||||
}
|
||||
.onAppear {
|
||||
deviceManager.call = call
|
||||
@@ -420,53 +456,67 @@ struct ActiveCallOverlay: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func toggleVideoButton() -> some View {
|
||||
controlButton(call, call.videoEnabled ? "video.fill" : "video.slash") {
|
||||
private func toggleCameraButton() -> some View {
|
||||
controlButton(call, call.localMediaSources.camera ? "video.fill" : "video.slash", padding: call.localMediaSources.camera ? 16 : 14) {
|
||||
Task {
|
||||
client.setVideoEnabled(!call.videoEnabled)
|
||||
DispatchQueue.main.async {
|
||||
call.videoEnabled = !call.videoEnabled
|
||||
}
|
||||
if await WebRTCClient.isAuthorized(for: .video) {
|
||||
client.setCameraEnabled(!call.localMediaSources.camera)
|
||||
} else { WebRTCClient.showUnauthorizedAlert(for: .video) }
|
||||
}
|
||||
}
|
||||
.disabled(call.initialCallType == .audio && client.activeCall?.peerHasOldVersion == true)
|
||||
}
|
||||
|
||||
@ViewBuilder private func flipCameraButton() -> some View {
|
||||
controlButton(call, "arrow.triangle.2.circlepath") {
|
||||
controlButton(call, "arrow.triangle.2.circlepath", padding: 12) {
|
||||
Task {
|
||||
client.flipCamera()
|
||||
if await WebRTCClient.isAuthorized(for: .video) {
|
||||
client.flipCamera()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func controlButton(_ call: Call, _ imageName: String, _ perform: @escaping () -> Void) -> some View {
|
||||
if call.hasMedia {
|
||||
callButton(imageName, width: 50, height: 38, perform)
|
||||
.foregroundColor(.white)
|
||||
.opacity(0.85)
|
||||
} else {
|
||||
Color.clear.frame(width: 50, height: 38)
|
||||
}
|
||||
@ViewBuilder private func controlButton(_ call: Call, _ imageName: String, padding: CGFloat, _ perform: @escaping () -> Void) -> some View {
|
||||
callButton(imageName, call.peerMediaSources.hasVideo ? Color.black.opacity(0.2) : Color.white.opacity(0.2), padding: padding, perform)
|
||||
}
|
||||
|
||||
private func callButton(_ imageName: String, width: CGFloat, height: CGFloat, _ perform: @escaping () -> Void) -> some View {
|
||||
@ViewBuilder private func audioDevicePickerButton() -> some View {
|
||||
AudioDevicePicker()
|
||||
.opacity(0.8)
|
||||
.scaleEffect(2)
|
||||
.padding(10)
|
||||
.frame(width: 60, height: 60)
|
||||
.background(call.peerMediaSources.hasVideo ? Color.black.opacity(0.2) : Color.white.opacity(0.2))
|
||||
.clipShape(.circle)
|
||||
}
|
||||
|
||||
private func callButton(_ imageName: String, _ background: Color, padding: CGFloat, _ perform: @escaping () -> Void) -> some View {
|
||||
Button {
|
||||
perform()
|
||||
} label: {
|
||||
Image(systemName: imageName)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(maxWidth: width, maxHeight: height)
|
||||
.padding(padding)
|
||||
.frame(width: 60, height: 60)
|
||||
.background(background)
|
||||
}
|
||||
.foregroundColor(whiteColorWithAlpha)
|
||||
.clipShape(.circle)
|
||||
}
|
||||
|
||||
private var whiteColorWithAlpha: Color {
|
||||
get { Color(red: 204 / 255, green: 204 / 255, blue: 204 / 255) }
|
||||
}
|
||||
}
|
||||
|
||||
struct ActiveCallOverlay_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group{
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callUUID: UUID().uuidString.lowercased(), callState: .offerSent, localMedia: .video), client: WebRTCClient(Binding.constant(nil), { _ in }, Binding.constant(nil)))
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callUUID: UUID().uuidString.lowercased(), callState: .offerSent, initialCallType: .video), client: WebRTCClient({ _ in }, Binding.constant(nil)))
|
||||
.background(.black)
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callUUID: UUID().uuidString.lowercased(), callState: .offerSent, localMedia: .audio), client: WebRTCClient(Binding.constant(nil), { _ in }, Binding.constant(nil)))
|
||||
ActiveCallOverlay(call: Call(direction: .incoming, contact: Contact.sampleData, callUUID: UUID().uuidString.lowercased(), callState: .offerSent, initialCallType: .audio), client: WebRTCClient({ _ in }, Binding.constant(nil)))
|
||||
.background(.black)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
}
|
||||
|
||||
func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {
|
||||
if callManager.enableMedia(media: .audio, enable: !action.isMuted, callUUID: action.callUUID.uuidString.lowercased()) {
|
||||
if callManager.enableMedia(source: .mic, enable: !action.isMuted, callUUID: action.callUUID.uuidString.lowercased()) {
|
||||
action.fulfill()
|
||||
} else {
|
||||
action.fail()
|
||||
@@ -121,8 +121,8 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession)
|
||||
RTCAudioSession.sharedInstance().isAudioEnabled = true
|
||||
do {
|
||||
let supportsVideo = ChatModel.shared.activeCall?.supportsVideo == true
|
||||
if supportsVideo {
|
||||
let hasVideo = ChatModel.shared.activeCall?.hasVideo == true
|
||||
if hasVideo {
|
||||
try audioSession.setCategory(.playAndRecord, mode: .videoChat, options: [.defaultToSpeaker, .mixWithOthers, .allowBluetooth, .allowAirPlay, .allowBluetoothA2DP])
|
||||
} else {
|
||||
try audioSession.setCategory(.playAndRecord, mode: .voiceChat, options: [.mixWithOthers, .allowBluetooth, .allowAirPlay, .allowBluetoothA2DP])
|
||||
@@ -133,7 +133,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
try? await Task.sleep(nanoseconds: UInt64(i) * 300_000000)
|
||||
if let preferred = audioSession.preferredInputDevice() {
|
||||
await MainActor.run { try? audioSession.setPreferredInput(preferred) }
|
||||
} else if supportsVideo {
|
||||
} else if hasVideo {
|
||||
await MainActor.run { try? audioSession.overrideOutputAudioPort(.speaker) }
|
||||
}
|
||||
}
|
||||
@@ -357,11 +357,9 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse
|
||||
self.provider.reportCall(with: uuid, updated: update)
|
||||
}
|
||||
} else if callManager.startOutgoingCall(callUUID: callUUID) {
|
||||
if callManager.startOutgoingCall(callUUID: callUUID) {
|
||||
logger.debug("CallController.startCall: call started")
|
||||
} else {
|
||||
logger.error("CallController.startCall: no active call")
|
||||
}
|
||||
logger.debug("CallController.startCall: call started")
|
||||
} else {
|
||||
logger.error("CallController.startCall: no active call")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import SimpleXChat
|
||||
class CallManager {
|
||||
func newOutgoingCall(_ contact: Contact, _ media: CallMediaType) -> String {
|
||||
let uuid = UUID().uuidString.lowercased()
|
||||
let call = Call(direction: .outgoing, contact: contact, callUUID: uuid, callState: .waitCapabilities, localMedia: media)
|
||||
let call = Call(direction: .outgoing, contact: contact, callUUID: uuid, callState: .waitCapabilities, initialCallType: media)
|
||||
call.speakerEnabled = media == .video
|
||||
ChatModel.shared.activeCall = call
|
||||
return uuid
|
||||
@@ -22,7 +22,7 @@ class CallManager {
|
||||
let m = ChatModel.shared
|
||||
if let call = m.activeCall, call.callUUID == callUUID {
|
||||
m.showCallView = true
|
||||
Task { await m.callCommand.processCommand(.capabilities(media: call.localMedia)) }
|
||||
Task { await m.callCommand.processCommand(.capabilities(media: call.initialCallType)) }
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -44,7 +44,7 @@ class CallManager {
|
||||
contact: invitation.contact,
|
||||
callUUID: invitation.callUUID,
|
||||
callState: .invitationAccepted,
|
||||
localMedia: invitation.callType.media,
|
||||
initialCallType: invitation.callType.media,
|
||||
sharedKey: invitation.sharedKey
|
||||
)
|
||||
call.speakerEnabled = invitation.callType.media == .video
|
||||
@@ -68,10 +68,10 @@ class CallManager {
|
||||
}
|
||||
}
|
||||
|
||||
func enableMedia(media: CallMediaType, enable: Bool, callUUID: String) -> Bool {
|
||||
func enableMedia(source: CallMediaSource, enable: Bool, callUUID: String) -> Bool {
|
||||
if let call = ChatModel.shared.activeCall, call.callUUID == callUUID {
|
||||
let m = ChatModel.shared
|
||||
Task { await m.callCommand.processCommand(.media(media: media, enable: enable)) }
|
||||
Task { await m.callCommand.processCommand(.media(source: source, enable: enable)) }
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -10,40 +10,49 @@ import AVKit
|
||||
|
||||
struct CallViewRemote: UIViewRepresentable {
|
||||
var client: WebRTCClient
|
||||
var activeCall: Binding<WebRTCClient.Call?>
|
||||
@ObservedObject var call: Call
|
||||
@State var enablePip: (Bool) -> Void = {_ in }
|
||||
@Binding var activeCallViewIsCollapsed: Bool
|
||||
@Binding var contentMode: UIView.ContentMode
|
||||
@Binding var pipShown: Bool
|
||||
|
||||
init(client: WebRTCClient, activeCall: Binding<WebRTCClient.Call?>, activeCallViewIsCollapsed: Binding<Bool>, pipShown: Binding<Bool>) {
|
||||
self.client = client
|
||||
self.activeCall = activeCall
|
||||
self._activeCallViewIsCollapsed = activeCallViewIsCollapsed
|
||||
self._pipShown = pipShown
|
||||
}
|
||||
|
||||
func makeUIView(context: Context) -> UIView {
|
||||
let view = UIView()
|
||||
if let call = activeCall.wrappedValue {
|
||||
let remoteRenderer = RTCMTLVideoView(frame: view.frame)
|
||||
remoteRenderer.videoContentMode = .scaleAspectFill
|
||||
client.addRemoteRenderer(call, remoteRenderer)
|
||||
addSubviewAndResize(remoteRenderer, into: view)
|
||||
let remoteCameraRenderer = RTCMTLVideoView(frame: view.frame)
|
||||
remoteCameraRenderer.videoContentMode = contentMode
|
||||
remoteCameraRenderer.tag = 0
|
||||
|
||||
if AVPictureInPictureController.isPictureInPictureSupported() {
|
||||
makeViewWithRTCRenderer(call, remoteRenderer, view, context)
|
||||
}
|
||||
let screenVideo = call.peerMediaSources.screenVideo
|
||||
let remoteScreenRenderer = RTCMTLVideoView(frame: view.frame)
|
||||
remoteScreenRenderer.videoContentMode = contentMode
|
||||
remoteScreenRenderer.tag = 1
|
||||
remoteScreenRenderer.alpha = screenVideo ? 1 : 0
|
||||
|
||||
context.coordinator.cameraRenderer = remoteCameraRenderer
|
||||
context.coordinator.screenRenderer = remoteScreenRenderer
|
||||
client.addRemoteCameraRenderer(remoteCameraRenderer)
|
||||
client.addRemoteScreenRenderer(remoteScreenRenderer)
|
||||
if screenVideo {
|
||||
addSubviewAndResize(remoteScreenRenderer, remoteCameraRenderer, into: view)
|
||||
} else {
|
||||
addSubviewAndResize(remoteCameraRenderer, remoteScreenRenderer, into: view)
|
||||
}
|
||||
|
||||
if AVPictureInPictureController.isPictureInPictureSupported() {
|
||||
makeViewWithRTCRenderer(remoteCameraRenderer, remoteScreenRenderer, view, context)
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
func makeViewWithRTCRenderer(_ call: WebRTCClient.Call, _ remoteRenderer: RTCMTLVideoView, _ view: UIView, _ context: Context) {
|
||||
let pipRemoteRenderer = RTCMTLVideoView(frame: view.frame)
|
||||
pipRemoteRenderer.videoContentMode = .scaleAspectFill
|
||||
|
||||
func makeViewWithRTCRenderer(_ remoteCameraRenderer: RTCMTLVideoView, _ remoteScreenRenderer: RTCMTLVideoView, _ view: UIView, _ context: Context) {
|
||||
let pipRemoteCameraRenderer = RTCMTLVideoView(frame: view.frame)
|
||||
pipRemoteCameraRenderer.videoContentMode = .scaleAspectFill
|
||||
|
||||
let pipRemoteScreenRenderer = RTCMTLVideoView(frame: view.frame)
|
||||
pipRemoteScreenRenderer.videoContentMode = .scaleAspectFill
|
||||
|
||||
let pipVideoCallViewController = AVPictureInPictureVideoCallViewController()
|
||||
pipVideoCallViewController.preferredContentSize = CGSize(width: 1080, height: 1920)
|
||||
addSubviewAndResize(pipRemoteRenderer, into: pipVideoCallViewController.view)
|
||||
let pipContentSource = AVPictureInPictureController.ContentSource(
|
||||
activeVideoCallSourceView: view,
|
||||
contentViewController: pipVideoCallViewController
|
||||
@@ -55,7 +64,9 @@ struct CallViewRemote: UIViewRepresentable {
|
||||
context.coordinator.pipController = pipController
|
||||
context.coordinator.willShowHide = { show in
|
||||
if show {
|
||||
client.addRemoteRenderer(call, pipRemoteRenderer)
|
||||
client.addRemoteCameraRenderer(pipRemoteCameraRenderer)
|
||||
client.addRemoteScreenRenderer(pipRemoteScreenRenderer)
|
||||
context.coordinator.relayout()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
activeCallViewIsCollapsed = true
|
||||
}
|
||||
@@ -67,13 +78,29 @@ struct CallViewRemote: UIViewRepresentable {
|
||||
}
|
||||
context.coordinator.didShowHide = { show in
|
||||
if show {
|
||||
remoteRenderer.isHidden = true
|
||||
remoteCameraRenderer.isHidden = true
|
||||
remoteScreenRenderer.isHidden = true
|
||||
} else {
|
||||
client.removeRemoteRenderer(call, pipRemoteRenderer)
|
||||
remoteRenderer.isHidden = false
|
||||
client.removeRemoteCameraRenderer(pipRemoteCameraRenderer)
|
||||
client.removeRemoteScreenRenderer(pipRemoteScreenRenderer)
|
||||
remoteCameraRenderer.isHidden = false
|
||||
remoteScreenRenderer.isHidden = false
|
||||
}
|
||||
pipShown = show
|
||||
}
|
||||
context.coordinator.relayout = {
|
||||
let camera = call.peerMediaSources.camera
|
||||
let screenVideo = call.peerMediaSources.screenVideo
|
||||
pipRemoteCameraRenderer.alpha = camera ? 1 : 0
|
||||
pipRemoteScreenRenderer.alpha = screenVideo ? 1 : 0
|
||||
if screenVideo {
|
||||
addSubviewAndResize(pipRemoteScreenRenderer, pipRemoteCameraRenderer, pip: true, into: pipVideoCallViewController.view)
|
||||
} else {
|
||||
addSubviewAndResize(pipRemoteCameraRenderer, pipRemoteScreenRenderer, pip: true, into: pipVideoCallViewController.view)
|
||||
}
|
||||
(pipVideoCallViewController.view.subviews[0] as! RTCMTLVideoView).videoContentMode = contentMode
|
||||
(pipVideoCallViewController.view.subviews[1] as! RTCMTLVideoView).videoContentMode = .scaleAspectFill
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
enablePip = { enable in
|
||||
if enable != pipShown /* pipController.isPictureInPictureActive */ {
|
||||
@@ -88,24 +115,50 @@ struct CallViewRemote: UIViewRepresentable {
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator()
|
||||
Coordinator(client)
|
||||
}
|
||||
|
||||
func updateUIView(_ view: UIView, context: Context) {
|
||||
logger.debug("CallView.updateUIView remote")
|
||||
let camera = view.subviews.first(where: { $0.tag == 0 })!
|
||||
let screen = view.subviews.first(where: { $0.tag == 1 })!
|
||||
let screenVideo = call.peerMediaSources.screenVideo
|
||||
if screenVideo && screen.alpha == 0 {
|
||||
screen.alpha = 1
|
||||
addSubviewAndResize(screen, camera, into: view)
|
||||
} else if !screenVideo && screen.alpha == 1 {
|
||||
screen.alpha = 0
|
||||
addSubviewAndResize(camera, screen, into: view)
|
||||
}
|
||||
(view.subviews[0] as! RTCMTLVideoView).videoContentMode = contentMode
|
||||
(view.subviews[1] as! RTCMTLVideoView).videoContentMode = .scaleAspectFill
|
||||
|
||||
camera.alpha = call.peerMediaSources.camera ? 1 : 0
|
||||
screen.alpha = call.peerMediaSources.screenVideo ? 1 : 0
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if activeCallViewIsCollapsed != pipShown {
|
||||
enablePip(activeCallViewIsCollapsed)
|
||||
} else if pipShown {
|
||||
context.coordinator.relayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Coordinator
|
||||
class Coordinator: NSObject, AVPictureInPictureControllerDelegate {
|
||||
var cameraRenderer: RTCMTLVideoView?
|
||||
var screenRenderer: RTCMTLVideoView?
|
||||
var client: WebRTCClient
|
||||
var pipController: AVPictureInPictureController? = nil
|
||||
var willShowHide: (Bool) -> Void = { _ in }
|
||||
var didShowHide: (Bool) -> Void = { _ in }
|
||||
|
||||
var relayout: () -> Void = {}
|
||||
|
||||
required init(_ client: WebRTCClient) {
|
||||
self.client = client
|
||||
}
|
||||
|
||||
func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
|
||||
willShowHide(true)
|
||||
}
|
||||
@@ -127,11 +180,20 @@ struct CallViewRemote: UIViewRepresentable {
|
||||
}
|
||||
|
||||
deinit {
|
||||
// TODO: deinit is not called when changing call type from audio to video and back,
|
||||
// which causes many renderers can be created and added to stream (if enabling/disabling
|
||||
// video while not yet connected in outgoing call)
|
||||
pipController?.stopPictureInPicture()
|
||||
pipController?.canStartPictureInPictureAutomaticallyFromInline = false
|
||||
pipController?.contentSource = nil
|
||||
pipController?.delegate = nil
|
||||
pipController = nil
|
||||
if let cameraRenderer {
|
||||
client.removeRemoteCameraRenderer(cameraRenderer)
|
||||
}
|
||||
if let screenRenderer {
|
||||
client.removeRemoteScreenRenderer(screenRenderer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,51 +210,109 @@ struct CallViewRemote: UIViewRepresentable {
|
||||
|
||||
struct CallViewLocal: UIViewRepresentable {
|
||||
var client: WebRTCClient
|
||||
var activeCall: Binding<WebRTCClient.Call?>
|
||||
var localRendererAspectRatio: Binding<CGFloat?>
|
||||
@State var pipStateChanged: (Bool) -> Void = {_ in }
|
||||
@Binding var pipShown: Bool
|
||||
|
||||
init(client: WebRTCClient, activeCall: Binding<WebRTCClient.Call?>, localRendererAspectRatio: Binding<CGFloat?>, pipShown: Binding<Bool>) {
|
||||
init(client: WebRTCClient, localRendererAspectRatio: Binding<CGFloat?>, pipShown: Binding<Bool>) {
|
||||
self.client = client
|
||||
self.activeCall = activeCall
|
||||
self.localRendererAspectRatio = localRendererAspectRatio
|
||||
self._pipShown = pipShown
|
||||
}
|
||||
|
||||
func makeUIView(context: Context) -> UIView {
|
||||
let view = UIView()
|
||||
if let call = activeCall.wrappedValue {
|
||||
let localRenderer = RTCEAGLVideoView(frame: .zero)
|
||||
client.addLocalRenderer(call, localRenderer)
|
||||
client.startCaptureLocalVideo(call)
|
||||
addSubviewAndResize(localRenderer, into: view)
|
||||
DispatchQueue.main.async {
|
||||
pipStateChanged = { shown in
|
||||
localRenderer.isHidden = shown
|
||||
}
|
||||
let localRenderer = RTCEAGLVideoView(frame: .zero)
|
||||
context.coordinator.renderer = localRenderer
|
||||
client.addLocalRenderer(localRenderer)
|
||||
addSubviewAndResize(localRenderer, nil, into: view)
|
||||
DispatchQueue.main.async {
|
||||
pipStateChanged = { shown in
|
||||
localRenderer.isHidden = shown
|
||||
}
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(client)
|
||||
}
|
||||
|
||||
func updateUIView(_ view: UIView, context: Context) {
|
||||
logger.debug("CallView.updateUIView local")
|
||||
pipStateChanged(pipShown)
|
||||
}
|
||||
|
||||
// MARK: - Coordinator
|
||||
class Coordinator: NSObject, AVPictureInPictureControllerDelegate {
|
||||
var renderer: RTCEAGLVideoView?
|
||||
var client: WebRTCClient
|
||||
|
||||
required init(_ client: WebRTCClient) {
|
||||
self.client = client
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let renderer {
|
||||
client.removeLocalRenderer(renderer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func addSubviewAndResize(_ view: UIView, into containerView: UIView) {
|
||||
containerView.addSubview(view)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
containerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|",
|
||||
options: [],
|
||||
metrics: nil,
|
||||
views: ["view": view]))
|
||||
private func addSubviewAndResize(_ fullscreen: UIView, _ end: UIView?, pip: Bool = false, into containerView: UIView) {
|
||||
if containerView.subviews.firstIndex(of: fullscreen) == 0 && ((end == nil && containerView.subviews.count == 1) || (end != nil && containerView.subviews.firstIndex(of: end!) == 1)) {
|
||||
// Nothing to do, elements on their places
|
||||
return
|
||||
}
|
||||
containerView.removeConstraints(containerView.constraints)
|
||||
containerView.subviews.forEach { sub in sub.removeFromSuperview()}
|
||||
|
||||
containerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|",
|
||||
containerView.addSubview(fullscreen)
|
||||
fullscreen.translatesAutoresizingMaskIntoConstraints = false
|
||||
fullscreen.layer.cornerRadius = 0
|
||||
fullscreen.layer.masksToBounds = false
|
||||
|
||||
if let end {
|
||||
containerView.addSubview(end)
|
||||
end.translatesAutoresizingMaskIntoConstraints = false
|
||||
end.layer.cornerRadius = pip ? 8 : 10
|
||||
end.layer.masksToBounds = true
|
||||
}
|
||||
|
||||
let constraintFullscreenV = NSLayoutConstraint.constraints(
|
||||
withVisualFormat: "V:|[fullscreen]|",
|
||||
options: [],
|
||||
metrics: nil,
|
||||
views: ["view": view]))
|
||||
views: ["fullscreen": fullscreen]
|
||||
)
|
||||
let constraintFullscreenH = NSLayoutConstraint.constraints(
|
||||
withVisualFormat: "H:|[fullscreen]|",
|
||||
options: [],
|
||||
metrics: nil,
|
||||
views: ["fullscreen": fullscreen]
|
||||
)
|
||||
|
||||
containerView.addConstraints(constraintFullscreenV)
|
||||
containerView.addConstraints(constraintFullscreenH)
|
||||
|
||||
if let end {
|
||||
let constraintEndWidth = NSLayoutConstraint(
|
||||
item: end, attribute: .width, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: pip ? 0.5 : 0.3, constant: 0
|
||||
)
|
||||
let constraintEndHeight = NSLayoutConstraint(
|
||||
item: end, attribute: .height, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: pip ? 0.5 * 1.33 : 0.3 * 1.33, constant: 0
|
||||
)
|
||||
let constraintEndX = NSLayoutConstraint(
|
||||
item: end, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: pip ? 0.5 : 0.7, constant: pip ? -8 : -17
|
||||
)
|
||||
let constraintEndY = NSLayoutConstraint(
|
||||
item: end, attribute: .bottom, relatedBy: .equal, toItem: containerView, attribute: .bottom, multiplier: 1, constant: pip ? -8 : -92
|
||||
)
|
||||
containerView.addConstraint(constraintEndWidth)
|
||||
containerView.addConstraint(constraintEndHeight)
|
||||
containerView.addConstraint(constraintEndX)
|
||||
containerView.addConstraint(constraintEndY)
|
||||
}
|
||||
containerView.layoutIfNeeded()
|
||||
}
|
||||
|
||||
@@ -19,14 +19,13 @@ class Call: ObservableObject, Equatable {
|
||||
var direction: CallDirection
|
||||
var contact: Contact
|
||||
var callUUID: String?
|
||||
var localMedia: CallMediaType
|
||||
var initialCallType: CallMediaType
|
||||
@Published var localMediaSources: CallMediaSources
|
||||
@Published var callState: CallState
|
||||
@Published var localCapabilities: CallCapabilities?
|
||||
@Published var peerMedia: CallMediaType?
|
||||
@Published var peerMediaSources: CallMediaSources = CallMediaSources()
|
||||
@Published var sharedKey: String?
|
||||
@Published var audioEnabled = true
|
||||
@Published var speakerEnabled = false
|
||||
@Published var videoEnabled: Bool
|
||||
@Published var connectionInfo: ConnectionInfo?
|
||||
@Published var connectedAt: Date? = nil
|
||||
|
||||
@@ -35,32 +34,33 @@ class Call: ObservableObject, Equatable {
|
||||
contact: Contact,
|
||||
callUUID: String?,
|
||||
callState: CallState,
|
||||
localMedia: CallMediaType,
|
||||
initialCallType: CallMediaType,
|
||||
sharedKey: String? = nil
|
||||
) {
|
||||
self.direction = direction
|
||||
self.contact = contact
|
||||
self.callUUID = callUUID
|
||||
self.callState = callState
|
||||
self.localMedia = localMedia
|
||||
self.initialCallType = initialCallType
|
||||
self.sharedKey = sharedKey
|
||||
self.videoEnabled = localMedia == .video
|
||||
self.localMediaSources = CallMediaSources(
|
||||
mic: AVCaptureDevice.authorizationStatus(for: .audio) == .authorized,
|
||||
camera: initialCallType == .video && AVCaptureDevice.authorizationStatus(for: .video) == .authorized)
|
||||
}
|
||||
|
||||
var encrypted: Bool { get { localEncrypted && sharedKey != nil } }
|
||||
var localEncrypted: Bool { get { localCapabilities?.encryption ?? false } }
|
||||
private var localEncrypted: Bool { get { localCapabilities?.encryption ?? false } }
|
||||
var encryptionStatus: LocalizedStringKey {
|
||||
get {
|
||||
switch callState {
|
||||
case .waitCapabilities: return ""
|
||||
case .invitationSent: return localEncrypted ? "e2e encrypted" : "no e2e encryption"
|
||||
case .invitationAccepted: return sharedKey == nil ? "contact has no e2e encryption" : "contact has e2e encryption"
|
||||
default: return !localEncrypted ? "no e2e encryption" : sharedKey == nil ? "contact has no e2e encryption" : "e2e encrypted"
|
||||
default: return !localEncrypted ? "no e2e encryption" : sharedKey == nil ? "contact has no e2e encryption" : "e2e encrypted"
|
||||
}
|
||||
}
|
||||
}
|
||||
var hasMedia: Bool { get { callState == .offerSent || callState == .negotiated || callState == .connected } }
|
||||
var supportsVideo: Bool { get { peerMedia == .video || localMedia == .video } }
|
||||
var hasVideo: Bool { get { localMediaSources.hasVideo || peerMediaSources.hasVideo } }
|
||||
}
|
||||
|
||||
enum CallDirection {
|
||||
@@ -105,18 +105,28 @@ struct WVAPIMessage: Equatable, Decodable, Encodable {
|
||||
var command: WCallCommand?
|
||||
}
|
||||
|
||||
struct CallMediaSources: Equatable, Codable {
|
||||
var mic: Bool = false
|
||||
var camera: Bool = false
|
||||
var screenAudio: Bool = false
|
||||
var screenVideo: Bool = false
|
||||
|
||||
var hasVideo: Bool { get { camera || screenVideo } }
|
||||
}
|
||||
|
||||
enum WCallCommand: Equatable, Encodable, Decodable {
|
||||
case capabilities(media: CallMediaType)
|
||||
case start(media: CallMediaType, aesKey: String? = nil, iceServers: [RTCIceServer]? = nil, relay: Bool? = nil)
|
||||
case offer(offer: String, iceCandidates: String, media: CallMediaType, aesKey: String? = nil, iceServers: [RTCIceServer]? = nil, relay: Bool? = nil)
|
||||
case answer(answer: String, iceCandidates: String)
|
||||
case ice(iceCandidates: String)
|
||||
case media(media: CallMediaType, enable: Bool)
|
||||
case media(source: CallMediaSource, enable: Bool)
|
||||
case end
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case type
|
||||
case media
|
||||
case source
|
||||
case aesKey
|
||||
case offer
|
||||
case answer
|
||||
@@ -167,9 +177,9 @@ enum WCallCommand: Equatable, Encodable, Decodable {
|
||||
case let .ice(iceCandidates):
|
||||
try container.encode("ice", forKey: .type)
|
||||
try container.encode(iceCandidates, forKey: .iceCandidates)
|
||||
case let .media(media, enable):
|
||||
case let .media(source, enable):
|
||||
try container.encode("media", forKey: .type)
|
||||
try container.encode(media, forKey: .media)
|
||||
try container.encode(source, forKey: .media)
|
||||
try container.encode(enable, forKey: .enable)
|
||||
case .end:
|
||||
try container.encode("end", forKey: .type)
|
||||
@@ -205,9 +215,9 @@ enum WCallCommand: Equatable, Encodable, Decodable {
|
||||
let iceCandidates = try container.decode(String.self, forKey: CodingKeys.iceCandidates)
|
||||
self = .ice(iceCandidates: iceCandidates)
|
||||
case "media":
|
||||
let media = try container.decode(CallMediaType.self, forKey: CodingKeys.media)
|
||||
let source = try container.decode(CallMediaSource.self, forKey: CodingKeys.source)
|
||||
let enable = try container.decode(Bool.self, forKey: CodingKeys.enable)
|
||||
self = .media(media: media, enable: enable)
|
||||
self = .media(source: source, enable: enable)
|
||||
case "end":
|
||||
self = .end
|
||||
default:
|
||||
@@ -224,6 +234,7 @@ enum WCallResponse: Equatable, Decodable {
|
||||
case ice(iceCandidates: String)
|
||||
case connection(state: ConnectionState)
|
||||
case connected(connectionInfo: ConnectionInfo)
|
||||
case peerMedia(source: CallMediaSource, enabled: Bool)
|
||||
case ended
|
||||
case ok
|
||||
case error(message: String)
|
||||
@@ -238,6 +249,8 @@ enum WCallResponse: Equatable, Decodable {
|
||||
case state
|
||||
case connectionInfo
|
||||
case message
|
||||
case source
|
||||
case enabled
|
||||
}
|
||||
|
||||
var respType: String {
|
||||
@@ -249,6 +262,7 @@ enum WCallResponse: Equatable, Decodable {
|
||||
case .ice: return "ice"
|
||||
case .connection: return "connection"
|
||||
case .connected: return "connected"
|
||||
case .peerMedia: return "peerMedia"
|
||||
case .ended: return "ended"
|
||||
case .ok: return "ok"
|
||||
case .error: return "error"
|
||||
@@ -283,6 +297,10 @@ enum WCallResponse: Equatable, Decodable {
|
||||
case "connected":
|
||||
let connectionInfo = try container.decode(ConnectionInfo.self, forKey: CodingKeys.connectionInfo)
|
||||
self = .connected(connectionInfo: connectionInfo)
|
||||
case "peerMedia":
|
||||
let source = try container.decode(CallMediaSource.self, forKey: CodingKeys.source)
|
||||
let enabled = try container.decode(Bool.self, forKey: CodingKeys.enabled)
|
||||
self = .peerMedia(source: source, enabled: enabled)
|
||||
case "ended":
|
||||
self = .ended
|
||||
case "ok":
|
||||
@@ -324,6 +342,10 @@ extension WCallResponse: Encodable {
|
||||
case let .connected(connectionInfo):
|
||||
try container.encode("connected", forKey: .type)
|
||||
try container.encode(connectionInfo, forKey: .connectionInfo)
|
||||
case let .peerMedia(source, enabled):
|
||||
try container.encode("peerMedia", forKey: .type)
|
||||
try container.encode(source, forKey: .source)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
case .ended:
|
||||
try container.encode("ended", forKey: .type)
|
||||
case .ok:
|
||||
@@ -376,7 +398,7 @@ actor WebRTCCommandProcessor {
|
||||
func shouldRunCommand(_ client: WebRTCClient, _ c: WCallCommand) -> Bool {
|
||||
switch c {
|
||||
case .capabilities, .start, .offer, .end: true
|
||||
default: client.activeCall.wrappedValue != nil
|
||||
default: client.activeCall != nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,15 +23,24 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
struct Call {
|
||||
var connection: RTCPeerConnection
|
||||
var iceCandidates: IceCandidates
|
||||
var localMedia: CallMediaType
|
||||
var localCamera: RTCVideoCapturer?
|
||||
var localVideoSource: RTCVideoSource?
|
||||
var localStream: RTCVideoTrack?
|
||||
var remoteStream: RTCVideoTrack?
|
||||
var device: AVCaptureDevice.Position = .front
|
||||
var localAudioTrack: RTCAudioTrack?
|
||||
var localVideoTrack: RTCVideoTrack?
|
||||
var remoteAudioTrack: RTCAudioTrack?
|
||||
var remoteVideoTrack: RTCVideoTrack?
|
||||
var remoteScreenAudioTrack: RTCAudioTrack?
|
||||
var remoteScreenVideoTrack: RTCVideoTrack?
|
||||
var device: AVCaptureDevice.Position
|
||||
var aesKey: String?
|
||||
var frameEncryptor: RTCFrameEncryptor?
|
||||
var frameDecryptor: RTCFrameDecryptor?
|
||||
var peerHasOldVersion: Bool
|
||||
}
|
||||
|
||||
struct NotConnectedCall {
|
||||
var audioTrack: RTCAudioTrack?
|
||||
var localCameraAndTrack: (RTCVideoCapturer, RTCVideoTrack)?
|
||||
var device: AVCaptureDevice.Position = .front
|
||||
}
|
||||
|
||||
actor IceCandidates {
|
||||
@@ -51,17 +60,20 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
private let rtcAudioSession = RTCAudioSession.sharedInstance()
|
||||
private let audioQueue = DispatchQueue(label: "chat.simplex.app.audio")
|
||||
private var sendCallResponse: (WVAPIMessage) async -> Void
|
||||
var activeCall: Binding<Call?>
|
||||
var activeCall: Call?
|
||||
var notConnectedCall: NotConnectedCall?
|
||||
private var localRendererAspectRatio: Binding<CGFloat?>
|
||||
|
||||
var cameraRenderers: [RTCVideoRenderer] = []
|
||||
var screenRenderers: [RTCVideoRenderer] = []
|
||||
|
||||
@available(*, unavailable)
|
||||
override init() {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
|
||||
required init(_ activeCall: Binding<Call?>, _ sendCallResponse: @escaping (WVAPIMessage) async -> Void, _ localRendererAspectRatio: Binding<CGFloat?>) {
|
||||
required init(_ sendCallResponse: @escaping (WVAPIMessage) async -> Void, _ localRendererAspectRatio: Binding<CGFloat?>) {
|
||||
self.sendCallResponse = sendCallResponse
|
||||
self.activeCall = activeCall
|
||||
self.localRendererAspectRatio = localRendererAspectRatio
|
||||
rtcAudioSession.useManualAudio = CallController.useCallKit()
|
||||
rtcAudioSession.isAudioEnabled = !CallController.useCallKit()
|
||||
@@ -78,39 +90,45 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
func initializeCall(_ iceServers: [WebRTC.RTCIceServer]?, _ mediaType: CallMediaType, _ aesKey: String?, _ relay: Bool?) -> Call {
|
||||
let connection = createPeerConnection(iceServers ?? getWebRTCIceServers() ?? defaultIceServers, relay)
|
||||
connection.delegate = self
|
||||
createAudioSender(connection)
|
||||
var localStream: RTCVideoTrack? = nil
|
||||
var remoteStream: RTCVideoTrack? = nil
|
||||
let device = notConnectedCall?.device ?? .front
|
||||
var localCamera: RTCVideoCapturer? = nil
|
||||
var localVideoSource: RTCVideoSource? = nil
|
||||
if mediaType == .video {
|
||||
(localStream, remoteStream, localCamera, localVideoSource) = createVideoSender(connection)
|
||||
var localAudioTrack: RTCAudioTrack? = nil
|
||||
var localVideoTrack: RTCVideoTrack? = nil
|
||||
if let localCameraAndTrack = notConnectedCall?.localCameraAndTrack {
|
||||
(localCamera, localVideoTrack) = localCameraAndTrack
|
||||
} else if notConnectedCall == nil && mediaType == .video {
|
||||
(localCamera, localVideoTrack) = createVideoTrackAndStartCapture(device)
|
||||
}
|
||||
if let audioTrack = notConnectedCall?.audioTrack {
|
||||
localAudioTrack = audioTrack
|
||||
} else if notConnectedCall == nil {
|
||||
localAudioTrack = createAudioTrack()
|
||||
}
|
||||
notConnectedCall?.localCameraAndTrack = nil
|
||||
notConnectedCall?.audioTrack = nil
|
||||
|
||||
var frameEncryptor: RTCFrameEncryptor? = nil
|
||||
var frameDecryptor: RTCFrameDecryptor? = nil
|
||||
if aesKey != nil {
|
||||
let encryptor = RTCFrameEncryptor.init(sizeChange: Int32(WebRTCClient.ivTagBytes))
|
||||
encryptor.delegate = self
|
||||
frameEncryptor = encryptor
|
||||
connection.senders.forEach { $0.setRtcFrameEncryptor(encryptor) }
|
||||
|
||||
let decryptor = RTCFrameDecryptor.init(sizeChange: -Int32(WebRTCClient.ivTagBytes))
|
||||
decryptor.delegate = self
|
||||
frameDecryptor = decryptor
|
||||
// Has no video receiver in outgoing call if applied here, see [peerConnection(_ connection: RTCPeerConnection, didChange newState]
|
||||
// connection.receivers.forEach { $0.setRtcFrameDecryptor(decryptor) }
|
||||
}
|
||||
return Call(
|
||||
connection: connection,
|
||||
iceCandidates: IceCandidates(),
|
||||
localMedia: mediaType,
|
||||
localCamera: localCamera,
|
||||
localVideoSource: localVideoSource,
|
||||
localStream: localStream,
|
||||
remoteStream: remoteStream,
|
||||
localAudioTrack: localAudioTrack,
|
||||
localVideoTrack: localVideoTrack,
|
||||
device: device,
|
||||
aesKey: aesKey,
|
||||
frameEncryptor: frameEncryptor,
|
||||
frameDecryptor: frameDecryptor
|
||||
frameDecryptor: frameDecryptor,
|
||||
peerHasOldVersion: false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -151,18 +169,24 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
|
||||
func sendCallCommand(command: WCallCommand) async {
|
||||
var resp: WCallResponse? = nil
|
||||
let pc = activeCall.wrappedValue?.connection
|
||||
let pc = activeCall?.connection
|
||||
switch command {
|
||||
case .capabilities:
|
||||
case let .capabilities(media): // outgoing
|
||||
let localCameraAndTrack: (RTCVideoCapturer, RTCVideoTrack)? = media == .video
|
||||
? createVideoTrackAndStartCapture(.front)
|
||||
: nil
|
||||
notConnectedCall = NotConnectedCall(audioTrack: createAudioTrack(), localCameraAndTrack: localCameraAndTrack, device: .front)
|
||||
resp = .capabilities(capabilities: CallCapabilities(encryption: WebRTCClient.enableEncryption))
|
||||
case let .start(media: media, aesKey, iceServers, relay):
|
||||
case let .start(media: media, aesKey, iceServers, relay): // incoming
|
||||
logger.debug("starting incoming call - create webrtc session")
|
||||
if activeCall.wrappedValue != nil { endCall() }
|
||||
if activeCall != nil { endCall() }
|
||||
let encryption = WebRTCClient.enableEncryption
|
||||
let call = initializeCall(iceServers?.toWebRTCIceServers(), media, encryption ? aesKey : nil, relay)
|
||||
activeCall.wrappedValue = call
|
||||
activeCall = call
|
||||
setupLocalTracks(true, call)
|
||||
let (offer, error) = await call.connection.offer()
|
||||
if let offer = offer {
|
||||
setupEncryptionForLocalTracks(call)
|
||||
resp = .offer(
|
||||
offer: compressToBase64(input: encodeJSON(CustomRTCSessionDescription(type: offer.type.toSdpType(), sdp: offer.sdp))),
|
||||
iceCandidates: compressToBase64(input: encodeJSON(await self.getInitialIceCandidates())),
|
||||
@@ -172,18 +196,24 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
} else {
|
||||
resp = .error(message: "offer error: \(error?.localizedDescription ?? "unknown error")")
|
||||
}
|
||||
case let .offer(offer, iceCandidates, media, aesKey, iceServers, relay):
|
||||
if activeCall.wrappedValue != nil {
|
||||
case let .offer(offer, iceCandidates, media, aesKey, iceServers, relay): // outgoing
|
||||
if activeCall != nil {
|
||||
resp = .error(message: "accept: call already started")
|
||||
} else if !WebRTCClient.enableEncryption && aesKey != nil {
|
||||
resp = .error(message: "accept: encryption is not supported")
|
||||
} else if let offer: CustomRTCSessionDescription = decodeJSON(decompressFromBase64(input: offer)),
|
||||
let remoteIceCandidates: [RTCIceCandidate] = decodeJSON(decompressFromBase64(input: iceCandidates)) {
|
||||
let call = initializeCall(iceServers?.toWebRTCIceServers(), media, WebRTCClient.enableEncryption ? aesKey : nil, relay)
|
||||
activeCall.wrappedValue = call
|
||||
activeCall = call
|
||||
let pc = call.connection
|
||||
if let type = offer.type, let sdp = offer.sdp {
|
||||
if (try? await pc.setRemoteDescription(RTCSessionDescription(type: type.toWebRTCSdpType(), sdp: sdp))) != nil {
|
||||
setupLocalTracks(false, call)
|
||||
setupEncryptionForLocalTracks(call)
|
||||
pc.transceivers.forEach { transceiver in
|
||||
transceiver.setDirection(.sendRecv, error: nil)
|
||||
}
|
||||
await adaptToOldVersion(pc.transceivers.count <= 2)
|
||||
let (answer, error) = await pc.answer()
|
||||
if let answer = answer {
|
||||
self.addIceCandidates(pc, remoteIceCandidates)
|
||||
@@ -200,7 +230,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .answer(answer, iceCandidates):
|
||||
case let .answer(answer, iceCandidates): // incoming
|
||||
if pc == nil {
|
||||
resp = .error(message: "answer: call not started")
|
||||
} else if pc?.localDescription == nil {
|
||||
@@ -212,6 +242,9 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
let type = answer.type, let sdp = answer.sdp,
|
||||
let pc = pc {
|
||||
if (try? await pc.setRemoteDescription(RTCSessionDescription(type: type.toWebRTCSdpType(), sdp: sdp))) != nil {
|
||||
var currentDirection: RTCRtpTransceiverDirection = .sendOnly
|
||||
pc.transceivers[2].currentDirection(¤tDirection)
|
||||
await adaptToOldVersion(currentDirection == .sendOnly)
|
||||
addIceCandidates(pc, remoteIceCandidates)
|
||||
resp = .ok
|
||||
} else {
|
||||
@@ -226,13 +259,11 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
} else {
|
||||
resp = .error(message: "ice: call not started")
|
||||
}
|
||||
case let .media(media, enable):
|
||||
if activeCall.wrappedValue == nil {
|
||||
case let .media(source, enable):
|
||||
if activeCall == nil {
|
||||
resp = .error(message: "media: call not started")
|
||||
} else if activeCall.wrappedValue?.localMedia == .audio && media == .video {
|
||||
resp = .error(message: "media: no video")
|
||||
} else {
|
||||
enableMedia(media, enable)
|
||||
await enableMedia(source, enable)
|
||||
resp = .ok
|
||||
}
|
||||
case .end:
|
||||
@@ -247,7 +278,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
|
||||
func getInitialIceCandidates() async -> [RTCIceCandidate] {
|
||||
await untilIceComplete(timeoutMs: 750, stepMs: 150) {}
|
||||
let candidates = await activeCall.wrappedValue?.iceCandidates.getAndClear() ?? []
|
||||
let candidates = await activeCall?.iceCandidates.getAndClear() ?? []
|
||||
logger.debug("WebRTCClient: sending initial ice candidates: \(candidates.count)")
|
||||
return candidates
|
||||
}
|
||||
@@ -255,7 +286,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
func waitForMoreIceCandidates() {
|
||||
Task {
|
||||
await untilIceComplete(timeoutMs: 12000, stepMs: 1500) {
|
||||
let candidates = await self.activeCall.wrappedValue?.iceCandidates.getAndClear() ?? []
|
||||
let candidates = await self.activeCall?.iceCandidates.getAndClear() ?? []
|
||||
if candidates.count > 0 {
|
||||
logger.debug("WebRTCClient: sending more ice candidates: \(candidates.count)")
|
||||
await self.sendIceCandidates(candidates)
|
||||
@@ -272,25 +303,202 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
)
|
||||
}
|
||||
|
||||
func enableMedia(_ media: CallMediaType, _ enable: Bool) {
|
||||
logger.debug("WebRTCClient: enabling media \(media.rawValue) \(enable)")
|
||||
media == .video ? setVideoEnabled(enable) : setAudioEnabled(enable)
|
||||
func setupMuteUnmuteListener(_ transceiver: RTCRtpTransceiver, _ track: RTCMediaStreamTrack) {
|
||||
// logger.log("Setting up mute/unmute listener in the call without encryption for mid = \(transceiver.mid)")
|
||||
Task {
|
||||
var lastBytesReceived: Int64 = 0
|
||||
// muted initially
|
||||
var mutedSeconds = 4
|
||||
while let call = self.activeCall, transceiver.receiver.track?.readyState == .live {
|
||||
let stats: RTCStatisticsReport = await call.connection.statistics(for: transceiver.receiver)
|
||||
let stat = stats.statistics.values.first(where: { stat in stat.type == "inbound-rtp"})
|
||||
if let stat {
|
||||
//logger.debug("Stat \(stat.debugDescription)")
|
||||
let bytes = stat.values["bytesReceived"] as! Int64
|
||||
if bytes <= lastBytesReceived {
|
||||
mutedSeconds += 1
|
||||
if mutedSeconds == 3 {
|
||||
await MainActor.run {
|
||||
self.onMediaMuteUnmute(transceiver.mid, true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if mutedSeconds >= 3 {
|
||||
await MainActor.run {
|
||||
self.onMediaMuteUnmute(transceiver.mid, false)
|
||||
}
|
||||
}
|
||||
lastBytesReceived = bytes
|
||||
mutedSeconds = 0
|
||||
}
|
||||
}
|
||||
try? await Task.sleep(nanoseconds: 1000_000000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addLocalRenderer(_ activeCall: Call, _ renderer: RTCEAGLVideoView) {
|
||||
activeCall.localStream?.add(renderer)
|
||||
@MainActor
|
||||
func onMediaMuteUnmute(_ transceiverMid: String?, _ mute: Bool) {
|
||||
guard let activeCall = ChatModel.shared.activeCall else { return }
|
||||
let source = mediaSourceFromTransceiverMid(transceiverMid)
|
||||
logger.log("Mute/unmute \(source.rawValue) track = \(mute) with mid = \(transceiverMid ?? "nil")")
|
||||
if source == .mic && activeCall.peerMediaSources.mic == mute {
|
||||
activeCall.peerMediaSources.mic = !mute
|
||||
} else if (source == .camera && activeCall.peerMediaSources.camera == mute) {
|
||||
activeCall.peerMediaSources.camera = !mute
|
||||
} else if (source == .screenAudio && activeCall.peerMediaSources.screenAudio == mute) {
|
||||
activeCall.peerMediaSources.screenAudio = !mute
|
||||
} else if (source == .screenVideo && activeCall.peerMediaSources.screenVideo == mute) {
|
||||
activeCall.peerMediaSources.screenVideo = !mute
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func enableMedia(_ source: CallMediaSource, _ enable: Bool) {
|
||||
logger.debug("WebRTCClient: enabling media \(source.rawValue) \(enable)")
|
||||
source == .camera ? setCameraEnabled(enable) : setAudioEnabled(enable)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func adaptToOldVersion(_ peerHasOldVersion: Bool) {
|
||||
activeCall?.peerHasOldVersion = peerHasOldVersion
|
||||
if peerHasOldVersion {
|
||||
logger.debug("The peer has an old version. Remote audio track is nil = \(self.activeCall?.remoteAudioTrack == nil), video = \(self.activeCall?.remoteVideoTrack == nil)")
|
||||
onMediaMuteUnmute("0", false)
|
||||
if activeCall?.remoteVideoTrack != nil {
|
||||
onMediaMuteUnmute("1", false)
|
||||
}
|
||||
if ChatModel.shared.activeCall?.localMediaSources.camera == true && ChatModel.shared.activeCall?.peerMediaSources.camera == false {
|
||||
logger.debug("Stopping video track for the old version")
|
||||
activeCall?.connection.senders[1].track = nil
|
||||
ChatModel.shared.activeCall?.localMediaSources.camera = false
|
||||
(activeCall?.localCamera as? RTCCameraVideoCapturer)?.stopCapture()
|
||||
activeCall?.localCamera = nil
|
||||
activeCall?.localVideoTrack = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addLocalRenderer(_ renderer: RTCEAGLVideoView) {
|
||||
if let activeCall {
|
||||
if let track = activeCall.localVideoTrack {
|
||||
track.add(renderer)
|
||||
}
|
||||
} else if let notConnectedCall {
|
||||
if let track = notConnectedCall.localCameraAndTrack?.1 {
|
||||
track.add(renderer)
|
||||
}
|
||||
}
|
||||
// To get width and height of a frame, see videoView(videoView:, didChangeVideoSize)
|
||||
renderer.delegate = self
|
||||
}
|
||||
|
||||
func removeLocalRenderer(_ renderer: RTCEAGLVideoView) {
|
||||
if let activeCall {
|
||||
if let track = activeCall.localVideoTrack {
|
||||
track.remove(renderer)
|
||||
}
|
||||
} else if let notConnectedCall {
|
||||
if let track = notConnectedCall.localCameraAndTrack?.1 {
|
||||
track.remove(renderer)
|
||||
}
|
||||
}
|
||||
renderer.delegate = nil
|
||||
}
|
||||
|
||||
func videoView(_ videoView: RTCVideoRenderer, didChangeVideoSize size: CGSize) {
|
||||
guard size.height > 0 else { return }
|
||||
localRendererAspectRatio.wrappedValue = size.width / size.height
|
||||
}
|
||||
|
||||
func setupLocalTracks(_ incomingCall: Bool, _ call: Call) {
|
||||
let pc = call.connection
|
||||
let transceivers = call.connection.transceivers
|
||||
let audioTrack = call.localAudioTrack
|
||||
let videoTrack = call.localVideoTrack
|
||||
|
||||
if incomingCall {
|
||||
let micCameraInit = RTCRtpTransceiverInit()
|
||||
// streamIds required for old versions which adds tracks from stream, not from track property
|
||||
micCameraInit.streamIds = ["micCamera"]
|
||||
|
||||
let screenAudioVideoInit = RTCRtpTransceiverInit()
|
||||
screenAudioVideoInit.streamIds = ["screenAudioVideo"]
|
||||
|
||||
// incoming call, no transceivers yet. But they should be added in order: mic, camera, screen audio, screen video
|
||||
// mid = 0, mic
|
||||
if let audioTrack {
|
||||
pc.addTransceiver(with: audioTrack, init: micCameraInit)
|
||||
} else {
|
||||
pc.addTransceiver(of: .audio, init: micCameraInit)
|
||||
}
|
||||
// mid = 1, camera
|
||||
if let videoTrack {
|
||||
pc.addTransceiver(with: videoTrack, init: micCameraInit)
|
||||
} else {
|
||||
pc.addTransceiver(of: .video, init: micCameraInit)
|
||||
}
|
||||
// mid = 2, screenAudio
|
||||
pc.addTransceiver(of: .audio, init: screenAudioVideoInit)
|
||||
// mid = 3, screenVideo
|
||||
pc.addTransceiver(of: .video, init: screenAudioVideoInit)
|
||||
} else {
|
||||
// new version
|
||||
if transceivers.count > 2 {
|
||||
// Outgoing call. All transceivers are ready. Don't addTrack() because it will create new transceivers, replace existing (nil) tracks
|
||||
transceivers
|
||||
.first(where: { elem in mediaSourceFromTransceiverMid(elem.mid) == .mic })?
|
||||
.sender.track = audioTrack
|
||||
transceivers
|
||||
.first(where: { elem in mediaSourceFromTransceiverMid(elem.mid) == .camera })?
|
||||
.sender.track = videoTrack
|
||||
} else {
|
||||
// old version, only two transceivers
|
||||
if let audioTrack {
|
||||
pc.add(audioTrack, streamIds: ["micCamera"])
|
||||
} else {
|
||||
// it's important to have any track in order to be able to turn it on again (currently it's off)
|
||||
let sender = pc.add(createAudioTrack(), streamIds: ["micCamera"])
|
||||
sender?.track = nil
|
||||
}
|
||||
if let videoTrack {
|
||||
pc.add(videoTrack, streamIds: ["micCamera"])
|
||||
} else {
|
||||
// it's important to have any track in order to be able to turn it on again (currently it's off)
|
||||
let localVideoSource = WebRTCClient.factory.videoSource()
|
||||
let localVideoTrack = WebRTCClient.factory.videoTrack(with: localVideoSource, trackId: "video0")
|
||||
let sender = pc.add(localVideoTrack, streamIds: ["micCamera"])
|
||||
sender?.track = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mediaSourceFromTransceiverMid(_ mid: String?) -> CallMediaSource {
|
||||
switch mid {
|
||||
case "0":
|
||||
return .mic
|
||||
case "1":
|
||||
return .camera
|
||||
case "2":
|
||||
return .screenAudio
|
||||
case "3":
|
||||
return .screenVideo
|
||||
default:
|
||||
return .unknown
|
||||
}
|
||||
}
|
||||
|
||||
// Should be called after local description set
|
||||
func setupEncryptionForLocalTracks(_ call: Call) {
|
||||
if let encryptor = call.frameEncryptor {
|
||||
call.connection.senders.forEach { $0.setRtcFrameEncryptor(encryptor) }
|
||||
}
|
||||
}
|
||||
|
||||
func frameDecryptor(_ decryptor: RTCFrameDecryptor, mediaType: RTCRtpMediaType, withFrame encrypted: Data) -> Data? {
|
||||
guard encrypted.count > 0 else { return nil }
|
||||
if var key: [CChar] = activeCall.wrappedValue?.aesKey?.cString(using: .utf8),
|
||||
if var key: [CChar] = activeCall?.aesKey?.cString(using: .utf8),
|
||||
let pointer: UnsafeMutableRawPointer = malloc(encrypted.count) {
|
||||
memcpy(pointer, (encrypted as NSData).bytes, encrypted.count)
|
||||
let isKeyFrame = encrypted[0] & 1 == 0
|
||||
@@ -304,7 +512,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
|
||||
func frameEncryptor(_ encryptor: RTCFrameEncryptor, mediaType: RTCRtpMediaType, withFrame unencrypted: Data) -> Data? {
|
||||
guard unencrypted.count > 0 else { return nil }
|
||||
if var key: [CChar] = activeCall.wrappedValue?.aesKey?.cString(using: .utf8),
|
||||
if var key: [CChar] = activeCall?.aesKey?.cString(using: .utf8),
|
||||
let pointer: UnsafeMutableRawPointer = malloc(unencrypted.count + WebRTCClient.ivTagBytes) {
|
||||
memcpy(pointer, (unencrypted as NSData).bytes, unencrypted.count)
|
||||
let isKeyFrame = unencrypted[0] & 1 == 0
|
||||
@@ -327,18 +535,42 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
}
|
||||
}
|
||||
|
||||
func addRemoteRenderer(_ activeCall: Call, _ renderer: RTCVideoRenderer) {
|
||||
activeCall.remoteStream?.add(renderer)
|
||||
func addRemoteCameraRenderer(_ renderer: RTCVideoRenderer) {
|
||||
if activeCall?.remoteVideoTrack != nil {
|
||||
activeCall?.remoteVideoTrack?.add(renderer)
|
||||
} else {
|
||||
cameraRenderers.append(renderer)
|
||||
}
|
||||
}
|
||||
|
||||
func removeRemoteRenderer(_ activeCall: Call, _ renderer: RTCVideoRenderer) {
|
||||
activeCall.remoteStream?.remove(renderer)
|
||||
func removeRemoteCameraRenderer(_ renderer: RTCVideoRenderer) {
|
||||
if activeCall?.remoteVideoTrack != nil {
|
||||
activeCall?.remoteVideoTrack?.remove(renderer)
|
||||
} else {
|
||||
cameraRenderers.removeAll(where: { $0.isEqual(renderer) })
|
||||
}
|
||||
}
|
||||
|
||||
func startCaptureLocalVideo(_ activeCall: Call) {
|
||||
func addRemoteScreenRenderer(_ renderer: RTCVideoRenderer) {
|
||||
if activeCall?.remoteScreenVideoTrack != nil {
|
||||
activeCall?.remoteScreenVideoTrack?.add(renderer)
|
||||
} else {
|
||||
screenRenderers.append(renderer)
|
||||
}
|
||||
}
|
||||
|
||||
func removeRemoteScreenRenderer(_ renderer: RTCVideoRenderer) {
|
||||
if activeCall?.remoteScreenVideoTrack != nil {
|
||||
activeCall?.remoteScreenVideoTrack?.remove(renderer)
|
||||
} else {
|
||||
screenRenderers.removeAll(where: { $0.isEqual(renderer) })
|
||||
}
|
||||
}
|
||||
|
||||
func startCaptureLocalVideo(_ device: AVCaptureDevice.Position?, _ capturer: RTCVideoCapturer?) {
|
||||
#if targetEnvironment(simulator)
|
||||
guard
|
||||
let capturer = activeCall.localCamera as? RTCFileVideoCapturer
|
||||
let capturer = (activeCall?.localCamera ?? notConnectedCall?.localCameraAndTrack?.0) as? RTCFileVideoCapturer
|
||||
else {
|
||||
logger.error("Unable to work with a file capturer")
|
||||
return
|
||||
@@ -348,10 +580,10 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
capturer.startCapturing(fromFileNamed: "sounds/video.mp4")
|
||||
#else
|
||||
guard
|
||||
let capturer = activeCall.localCamera as? RTCCameraVideoCapturer,
|
||||
let camera = (RTCCameraVideoCapturer.captureDevices().first { $0.position == activeCall.device })
|
||||
let capturer = capturer as? RTCCameraVideoCapturer,
|
||||
let camera = (RTCCameraVideoCapturer.captureDevices().first { $0.position == device })
|
||||
else {
|
||||
logger.error("Unable to find a camera")
|
||||
logger.error("Unable to find a camera or local track")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -377,19 +609,6 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
#endif
|
||||
}
|
||||
|
||||
private func createAudioSender(_ connection: RTCPeerConnection) {
|
||||
let streamId = "stream"
|
||||
let audioTrack = createAudioTrack()
|
||||
connection.add(audioTrack, streamIds: [streamId])
|
||||
}
|
||||
|
||||
private func createVideoSender(_ connection: RTCPeerConnection) -> (RTCVideoTrack?, RTCVideoTrack?, RTCVideoCapturer?, RTCVideoSource?) {
|
||||
let streamId = "stream"
|
||||
let (localVideoTrack, localCamera, localVideoSource) = createVideoTrack()
|
||||
connection.add(localVideoTrack, streamIds: [streamId])
|
||||
return (localVideoTrack, connection.transceivers.first { $0.mediaType == .video }?.receiver.track as? RTCVideoTrack, localCamera, localVideoSource)
|
||||
}
|
||||
|
||||
private func createAudioTrack() -> RTCAudioTrack {
|
||||
let audioConstrains = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: nil)
|
||||
let audioSource = WebRTCClient.factory.audioSource(with: audioConstrains)
|
||||
@@ -397,7 +616,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
return audioTrack
|
||||
}
|
||||
|
||||
private func createVideoTrack() -> (RTCVideoTrack, RTCVideoCapturer, RTCVideoSource) {
|
||||
private func createVideoTrackAndStartCapture(_ device: AVCaptureDevice.Position) -> (RTCVideoCapturer, RTCVideoTrack) {
|
||||
let localVideoSource = WebRTCClient.factory.videoSource()
|
||||
|
||||
#if targetEnvironment(simulator)
|
||||
@@ -407,7 +626,8 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
#endif
|
||||
|
||||
let localVideoTrack = WebRTCClient.factory.videoTrack(with: localVideoSource, trackId: "video0")
|
||||
return (localVideoTrack, localCamera, localVideoSource)
|
||||
startCaptureLocalVideo(device, localCamera)
|
||||
return (localCamera, localVideoTrack)
|
||||
}
|
||||
|
||||
func endCall() {
|
||||
@@ -420,15 +640,16 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
}
|
||||
|
||||
private func _endCall() {
|
||||
guard let call = activeCall.wrappedValue else { return }
|
||||
(notConnectedCall?.localCameraAndTrack?.0 as? RTCCameraVideoCapturer)?.stopCapture()
|
||||
guard let call = activeCall else { return }
|
||||
logger.debug("WebRTCClient: ending the call")
|
||||
activeCall.wrappedValue = nil
|
||||
(call.localCamera as? RTCCameraVideoCapturer)?.stopCapture()
|
||||
call.connection.close()
|
||||
call.connection.delegate = nil
|
||||
call.frameEncryptor?.delegate = nil
|
||||
call.frameDecryptor?.delegate = nil
|
||||
(call.localCamera as? RTCCameraVideoCapturer)?.stopCapture()
|
||||
audioSessionToDefaults()
|
||||
activeCall = nil
|
||||
}
|
||||
|
||||
func untilIceComplete(timeoutMs: UInt64, stepMs: UInt64, action: @escaping () async -> Void) async {
|
||||
@@ -437,7 +658,7 @@ final class WebRTCClient: NSObject, RTCVideoViewDelegate, RTCFrameEncryptorDeleg
|
||||
_ = try? await Task.sleep(nanoseconds: stepMs * 1000000)
|
||||
t += stepMs
|
||||
await action()
|
||||
} while t < timeoutMs && activeCall.wrappedValue?.connection.iceGatheringState != .complete
|
||||
} while t < timeoutMs && activeCall?.connection.iceGatheringState != .complete
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,11 +719,40 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
|
||||
logger.debug("Connection should negotiate")
|
||||
}
|
||||
|
||||
func peerConnection(_ peerConnection: RTCPeerConnection, didStartReceivingOn transceiver: RTCRtpTransceiver) {
|
||||
if let track = transceiver.receiver.track {
|
||||
DispatchQueue.main.async {
|
||||
// Doesn't work for outgoing video call (audio in video call works ok still, same as incoming call)
|
||||
// if let decryptor = self.activeCall?.frameDecryptor {
|
||||
// transceiver.receiver.setRtcFrameDecryptor(decryptor)
|
||||
// }
|
||||
let source = self.mediaSourceFromTransceiverMid(transceiver.mid)
|
||||
switch source {
|
||||
case .mic: self.activeCall?.remoteAudioTrack = track as? RTCAudioTrack
|
||||
case .camera:
|
||||
self.activeCall?.remoteVideoTrack = track as? RTCVideoTrack
|
||||
self.cameraRenderers.forEach({ renderer in
|
||||
self.activeCall?.remoteVideoTrack?.add(renderer)
|
||||
})
|
||||
self.cameraRenderers.removeAll()
|
||||
case .screenAudio: self.activeCall?.remoteScreenAudioTrack = track as? RTCAudioTrack
|
||||
case .screenVideo:
|
||||
self.activeCall?.remoteScreenVideoTrack = track as? RTCVideoTrack
|
||||
self.screenRenderers.forEach({ renderer in
|
||||
self.activeCall?.remoteScreenVideoTrack?.add(renderer)
|
||||
})
|
||||
self.screenRenderers.removeAll()
|
||||
case .unknown: ()
|
||||
}
|
||||
}
|
||||
self.setupMuteUnmuteListener(transceiver, track)
|
||||
}
|
||||
}
|
||||
|
||||
func peerConnection(_ connection: RTCPeerConnection, didChange newState: RTCIceConnectionState) {
|
||||
debugPrint("Connection new connection state: \(newState.toString() ?? "" + newState.rawValue.description) \(connection.receivers)")
|
||||
|
||||
guard let call = activeCall.wrappedValue,
|
||||
let connectionStateString = newState.toString(),
|
||||
guard let connectionStateString = newState.toString(),
|
||||
let iceConnectionStateString = connection.iceConnectionState.toString(),
|
||||
let iceGatheringStateString = connection.iceGatheringState.toString(),
|
||||
let signalingStateString = connection.signalingState.toString()
|
||||
@@ -523,18 +773,14 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
|
||||
|
||||
switch newState {
|
||||
case .checking:
|
||||
if let frameDecryptor = activeCall.wrappedValue?.frameDecryptor {
|
||||
if let frameDecryptor = activeCall?.frameDecryptor {
|
||||
connection.receivers.forEach { $0.setRtcFrameDecryptor(frameDecryptor) }
|
||||
}
|
||||
let enableSpeaker: Bool
|
||||
switch call.localMedia {
|
||||
case .video: enableSpeaker = true
|
||||
default: enableSpeaker = false
|
||||
}
|
||||
let enableSpeaker: Bool = ChatModel.shared.activeCall?.localMediaSources.hasVideo == true
|
||||
setSpeakerEnabledAndConfigureSession(enableSpeaker)
|
||||
case .connected: sendConnectedEvent(connection)
|
||||
case .disconnected, .failed: endCall()
|
||||
default: do {}
|
||||
default: ()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -546,7 +792,7 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
|
||||
func peerConnection(_ connection: RTCPeerConnection, didGenerate candidate: WebRTC.RTCIceCandidate) {
|
||||
// logger.debug("Connection generated candidate \(candidate.debugDescription)")
|
||||
Task {
|
||||
await self.activeCall.wrappedValue?.iceCandidates.append(candidate.toCandidate(nil, nil))
|
||||
await self.activeCall?.iceCandidates.append(candidate.toCandidate(nil, nil))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,11 +847,42 @@ extension WebRTCClient: RTCPeerConnectionDelegate {
|
||||
}
|
||||
|
||||
extension WebRTCClient {
|
||||
func setAudioEnabled(_ enabled: Bool) {
|
||||
setTrackEnabled(RTCAudioTrack.self, enabled)
|
||||
static func isAuthorized(for type: AVMediaType) async -> Bool {
|
||||
let status = AVCaptureDevice.authorizationStatus(for: type)
|
||||
var isAuthorized = status == .authorized
|
||||
if status == .notDetermined {
|
||||
isAuthorized = await AVCaptureDevice.requestAccess(for: type)
|
||||
}
|
||||
return isAuthorized
|
||||
}
|
||||
|
||||
func setSpeakerEnabledAndConfigureSession( _ enabled: Bool) {
|
||||
static func showUnauthorizedAlert(for type: AVMediaType) {
|
||||
if type == .audio {
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("No permission to record speech"),
|
||||
message: Text("To record speech please grant permission to use Microphone."),
|
||||
primaryButton: .default(Text("Open Settings")) {
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
|
||||
}
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
))
|
||||
} else if type == .video {
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("No permission to record video"),
|
||||
message: Text("To record video please grant permission to use Camera."),
|
||||
primaryButton: .default(Text("Open Settings")) {
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
|
||||
}
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
func setSpeakerEnabledAndConfigureSession( _ enabled: Bool, skipExternalDevice: Bool = false) {
|
||||
logger.debug("WebRTCClient: configuring session with speaker enabled \(enabled)")
|
||||
audioQueue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
@@ -618,7 +895,7 @@ extension WebRTCClient {
|
||||
if enabled {
|
||||
try self.rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord.rawValue, with: [.defaultToSpeaker, .allowBluetooth, .allowAirPlay, .allowBluetoothA2DP])
|
||||
try self.rtcAudioSession.setMode(AVAudioSession.Mode.videoChat.rawValue)
|
||||
if hasExternalAudioDevice, let preferred = self.rtcAudioSession.session.preferredInputDevice() {
|
||||
if hasExternalAudioDevice && !skipExternalDevice, let preferred = self.rtcAudioSession.session.preferredInputDevice() {
|
||||
try self.rtcAudioSession.setPreferredInput(preferred)
|
||||
} else {
|
||||
try self.rtcAudioSession.overrideOutputAudioPort(.speaker)
|
||||
@@ -628,7 +905,7 @@ extension WebRTCClient {
|
||||
try self.rtcAudioSession.setMode(AVAudioSession.Mode.voiceChat.rawValue)
|
||||
try self.rtcAudioSession.overrideOutputAudioPort(.none)
|
||||
}
|
||||
if hasExternalAudioDevice {
|
||||
if hasExternalAudioDevice && !skipExternalDevice {
|
||||
logger.debug("WebRTCClient: configuring session with external device available, skip configuring speaker")
|
||||
}
|
||||
try self.rtcAudioSession.setActive(true)
|
||||
@@ -659,25 +936,59 @@ extension WebRTCClient {
|
||||
}
|
||||
}
|
||||
|
||||
func setVideoEnabled(_ enabled: Bool) {
|
||||
setTrackEnabled(RTCVideoTrack.self, enabled)
|
||||
@MainActor
|
||||
func setAudioEnabled(_ enabled: Bool) {
|
||||
if activeCall != nil {
|
||||
activeCall?.localAudioTrack = enabled ? createAudioTrack() : nil
|
||||
activeCall?.connection.transceivers.first(where: { t in mediaSourceFromTransceiverMid(t.mid) == .mic })?.sender.track = activeCall?.localAudioTrack
|
||||
} else if notConnectedCall != nil {
|
||||
notConnectedCall?.audioTrack = enabled ? createAudioTrack() : nil
|
||||
}
|
||||
ChatModel.shared.activeCall?.localMediaSources.mic = enabled
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func setCameraEnabled(_ enabled: Bool) {
|
||||
if let call = activeCall {
|
||||
if enabled {
|
||||
if call.localVideoTrack == nil {
|
||||
let device = activeCall?.device ?? notConnectedCall?.device ?? .front
|
||||
let (camera, track) = createVideoTrackAndStartCapture(device)
|
||||
activeCall?.localCamera = camera
|
||||
activeCall?.localVideoTrack = track
|
||||
}
|
||||
} else {
|
||||
(call.localCamera as? RTCCameraVideoCapturer)?.stopCapture()
|
||||
activeCall?.localCamera = nil
|
||||
activeCall?.localVideoTrack = nil
|
||||
}
|
||||
call.connection.transceivers
|
||||
.first(where: { t in mediaSourceFromTransceiverMid(t.mid) == .camera })?
|
||||
.sender.track = activeCall?.localVideoTrack
|
||||
ChatModel.shared.activeCall?.localMediaSources.camera = activeCall?.localVideoTrack != nil
|
||||
} else if let call = notConnectedCall {
|
||||
if enabled {
|
||||
let device = activeCall?.device ?? notConnectedCall?.device ?? .front
|
||||
notConnectedCall?.localCameraAndTrack = createVideoTrackAndStartCapture(device)
|
||||
} else {
|
||||
(call.localCameraAndTrack?.0 as? RTCCameraVideoCapturer)?.stopCapture()
|
||||
notConnectedCall?.localCameraAndTrack = nil
|
||||
}
|
||||
ChatModel.shared.activeCall?.localMediaSources.camera = notConnectedCall?.localCameraAndTrack != nil
|
||||
}
|
||||
}
|
||||
|
||||
func flipCamera() {
|
||||
switch activeCall.wrappedValue?.device {
|
||||
case .front: activeCall.wrappedValue?.device = .back
|
||||
case .back: activeCall.wrappedValue?.device = .front
|
||||
default: ()
|
||||
let device = activeCall?.device ?? notConnectedCall?.device
|
||||
if activeCall != nil {
|
||||
activeCall?.device = device == .front ? .back : .front
|
||||
} else {
|
||||
notConnectedCall?.device = device == .front ? .back : .front
|
||||
}
|
||||
if let call = activeCall.wrappedValue {
|
||||
startCaptureLocalVideo(call)
|
||||
}
|
||||
}
|
||||
|
||||
private func setTrackEnabled<T: RTCMediaStreamTrack>(_ type: T.Type, _ enabled: Bool) {
|
||||
activeCall.wrappedValue?.connection.transceivers
|
||||
.compactMap { $0.sender.track as? T }
|
||||
.forEach { $0.isEnabled = enabled }
|
||||
startCaptureLocalVideo(
|
||||
activeCall?.device ?? notConnectedCall?.device,
|
||||
(activeCall?.localCamera ?? notConnectedCall?.localCameraAndTrack?.0) as? RTCCameraVideoCapturer
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ struct CIRcvDecryptionError: View {
|
||||
if case let .group(groupInfo) = chat.chatInfo,
|
||||
case let .groupRcv(groupMember) = chatItem.chatDir {
|
||||
do {
|
||||
let (member, stats) = try apiGroupMemberInfo(groupInfo.apiId, groupMember.groupMemberId)
|
||||
let (member, stats) = try apiGroupMemberInfoSync(groupInfo.apiId, groupMember.groupMemberId)
|
||||
if let s = stats {
|
||||
m.updateGroupMemberConnectionStats(groupInfo, member, s)
|
||||
}
|
||||
|
||||
@@ -137,6 +137,14 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
// it should be presented on top level in order to prevent a bug in SwiftUI on iOS 16 related to .focused() modifier in AddGroupMembersView's search field
|
||||
.appSheet(isPresented: $showAddMembersSheet) {
|
||||
Group {
|
||||
if case let .group(groupInfo) = cInfo {
|
||||
AddGroupMembersView(chat: chat, groupInfo: groupInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: Binding(
|
||||
get: { !forwardedChatItems.isEmpty },
|
||||
set: { isPresented in
|
||||
@@ -304,9 +312,6 @@ struct ChatView: View {
|
||||
}
|
||||
} else {
|
||||
addMembersButton()
|
||||
.appSheet(isPresented: $showAddMembersSheet) {
|
||||
AddGroupMembersView(chat: chat, groupInfo: groupInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
@@ -1182,7 +1187,7 @@ struct ChatView: View {
|
||||
allowMenu: $allowMenu
|
||||
)
|
||||
.environment(\.showTimestamp, itemSeparation.timestamp)
|
||||
.modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap))
|
||||
.modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap && (ci.meta.itemDeleted == nil || revealed)))
|
||||
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }
|
||||
.accessibilityLabel("")
|
||||
if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 {
|
||||
|
||||
@@ -18,6 +18,7 @@ struct GroupMemberInfoView: View {
|
||||
var navigation: Bool = false
|
||||
@State private var connectionStats: ConnectionStats? = nil
|
||||
@State private var connectionCode: String? = nil
|
||||
@State private var connectionLoaded: Bool = false
|
||||
@State private var newRole: GroupMemberRole = .member
|
||||
@State private var alert: GroupMemberInfoViewAlert?
|
||||
@State private var sheet: PlanAndConnectActionSheet?
|
||||
@@ -94,129 +95,137 @@ struct GroupMemberInfoView: View {
|
||||
.listRowSeparator(.hidden)
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
|
||||
if member.memberActive {
|
||||
Section {
|
||||
if let code = connectionCode { verifyCodeButton(code) }
|
||||
if let connStats = connectionStats,
|
||||
connStats.ratchetSyncAllowed {
|
||||
synchronizeConnectionButton()
|
||||
}
|
||||
// } else if developerTools {
|
||||
// synchronizeConnectionButtonForce()
|
||||
// }
|
||||
}
|
||||
}
|
||||
if connectionLoaded {
|
||||
|
||||
if let contactLink = member.contactLink {
|
||||
Section {
|
||||
SimpleXLinkQRCode(uri: contactLink)
|
||||
Button {
|
||||
showShareSheet(items: [simplexChatLink(contactLink)])
|
||||
} label: {
|
||||
Label("Share address", systemImage: "square.and.arrow.up")
|
||||
if member.memberActive {
|
||||
Section {
|
||||
if let code = connectionCode { verifyCodeButton(code) }
|
||||
if let connStats = connectionStats,
|
||||
connStats.ratchetSyncAllowed {
|
||||
synchronizeConnectionButton()
|
||||
}
|
||||
// } else if developerTools {
|
||||
// synchronizeConnectionButtonForce()
|
||||
// }
|
||||
}
|
||||
if let contactId = member.memberContactId {
|
||||
if knownDirectChat(contactId) == nil && !groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
}
|
||||
|
||||
if let contactLink = member.contactLink {
|
||||
Section {
|
||||
SimpleXLinkQRCode(uri: contactLink)
|
||||
Button {
|
||||
showShareSheet(items: [simplexChatLink(contactLink)])
|
||||
} label: {
|
||||
Label("Share address", systemImage: "square.and.arrow.up")
|
||||
}
|
||||
if let contactId = member.memberContactId {
|
||||
if knownDirectChat(contactId) == nil && !groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
connectViaAddressButton(contactLink)
|
||||
}
|
||||
} else {
|
||||
connectViaAddressButton(contactLink)
|
||||
}
|
||||
} else {
|
||||
connectViaAddressButton(contactLink)
|
||||
} header: {
|
||||
Text("Address")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} footer: {
|
||||
Text("You can share this address with your contacts to let them connect with **\(member.displayName)**.")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
} header: {
|
||||
Text("Address")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
} footer: {
|
||||
Text("You can share this address with your contacts to let them connect with **\(member.displayName)**.")
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
Section(header: Text("Member").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Group", groupInfo.displayName)
|
||||
Section(header: Text("Member").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Group", groupInfo.displayName)
|
||||
|
||||
if let roles = member.canChangeRoleTo(groupInfo: groupInfo) {
|
||||
Picker("Change role", selection: $newRole) {
|
||||
ForEach(roles) { role in
|
||||
Text(role.text)
|
||||
if let roles = member.canChangeRoleTo(groupInfo: groupInfo) {
|
||||
Picker("Change role", selection: $newRole) {
|
||||
ForEach(roles) { role in
|
||||
Text(role.text)
|
||||
}
|
||||
}
|
||||
.frame(height: 36)
|
||||
} else {
|
||||
infoRow("Role", member.memberRole.text)
|
||||
}
|
||||
.frame(height: 36)
|
||||
} else {
|
||||
infoRow("Role", member.memberRole.text)
|
||||
}
|
||||
}
|
||||
|
||||
if let connStats = connectionStats {
|
||||
Section(header: Text("Servers").foregroundColor(theme.colors.secondary)) {
|
||||
// TODO network connection status
|
||||
Button("Change receiving address") {
|
||||
alert = .switchAddressAlert
|
||||
}
|
||||
.disabled(
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil }
|
||||
|| connStats.ratchetSyncSendProhibited
|
||||
)
|
||||
if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) {
|
||||
Button("Abort changing address") {
|
||||
alert = .abortSwitchAddressAlert
|
||||
if let connStats = connectionStats {
|
||||
Section(header: Text("Servers").foregroundColor(theme.colors.secondary)) {
|
||||
// TODO network connection status
|
||||
Button("Change receiving address") {
|
||||
alert = .switchAddressAlert
|
||||
}
|
||||
.disabled(
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch }
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil }
|
||||
|| connStats.ratchetSyncSendProhibited
|
||||
)
|
||||
if connStats.rcvQueuesInfo.contains(where: { $0.rcvSwitchStatus != nil }) {
|
||||
Button("Abort changing address") {
|
||||
alert = .abortSwitchAddressAlert
|
||||
}
|
||||
.disabled(
|
||||
connStats.rcvQueuesInfo.contains { $0.rcvSwitchStatus != nil && !$0.canAbortSwitch }
|
||||
|| connStats.ratchetSyncSendProhibited
|
||||
)
|
||||
}
|
||||
smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }, theme.colors.secondary)
|
||||
smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }, theme.colors.secondary)
|
||||
}
|
||||
smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }, theme.colors.secondary)
|
||||
smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }, theme.colors.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
if groupInfo.membership.memberRole >= .admin {
|
||||
adminDestructiveSection(member)
|
||||
} else {
|
||||
nonAdminBlockSection(member)
|
||||
}
|
||||
if groupInfo.membership.memberRole >= .admin {
|
||||
adminDestructiveSection(member)
|
||||
} else {
|
||||
nonAdminBlockSection(member)
|
||||
}
|
||||
|
||||
if developerTools {
|
||||
Section(header: Text("For console").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Local name", member.localDisplayName)
|
||||
infoRow("Database ID", "\(member.groupMemberId)")
|
||||
if let conn = member.activeConn {
|
||||
let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel)
|
||||
infoRow("Connection", connLevelDesc)
|
||||
}
|
||||
Button ("Debug delivery") {
|
||||
Task {
|
||||
do {
|
||||
let info = queueInfoText(try await apiGroupMemberQueueInfo(groupInfo.apiId, member.groupMemberId))
|
||||
await MainActor.run { alert = .queueInfo(info: info) }
|
||||
} catch let e {
|
||||
logger.error("apiContactQueueInfo error: \(responseError(e))")
|
||||
let a = getErrorAlert(e, "Error")
|
||||
await MainActor.run { alert = .error(title: a.title, error: a.message) }
|
||||
if developerTools {
|
||||
Section(header: Text("For console").foregroundColor(theme.colors.secondary)) {
|
||||
infoRow("Local name", member.localDisplayName)
|
||||
infoRow("Database ID", "\(member.groupMemberId)")
|
||||
if let conn = member.activeConn {
|
||||
let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel)
|
||||
infoRow("Connection", connLevelDesc)
|
||||
}
|
||||
Button ("Debug delivery") {
|
||||
Task {
|
||||
do {
|
||||
let info = queueInfoText(try await apiGroupMemberQueueInfo(groupInfo.apiId, member.groupMemberId))
|
||||
await MainActor.run { alert = .queueInfo(info: info) }
|
||||
} catch let e {
|
||||
logger.error("apiContactQueueInfo error: \(responseError(e))")
|
||||
let a = getErrorAlert(e, "Error")
|
||||
await MainActor.run { alert = .error(title: a.title, error: a.message) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
.onAppear {
|
||||
.task {
|
||||
if #unavailable(iOS 16) {
|
||||
// this condition prevents re-setting picker
|
||||
if !justOpened { return }
|
||||
}
|
||||
justOpened = false
|
||||
DispatchQueue.main.async {
|
||||
newRole = member.memberRole
|
||||
do {
|
||||
let (_, stats) = try apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId)
|
||||
let (mem, code) = member.memberActive ? try apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil)
|
||||
newRole = member.memberRole
|
||||
do {
|
||||
let (_, stats) = try await apiGroupMemberInfo(groupInfo.apiId, member.groupMemberId)
|
||||
let (mem, code) = member.memberActive ? try await apiGetGroupMemberCode(groupInfo.apiId, member.groupMemberId) : (member, nil)
|
||||
await MainActor.run {
|
||||
_ = chatModel.upsertGroupMember(groupInfo, mem)
|
||||
connectionStats = stats
|
||||
connectionCode = code
|
||||
} catch let error {
|
||||
logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))")
|
||||
connectionLoaded = true
|
||||
}
|
||||
} catch let error {
|
||||
await MainActor.run {
|
||||
connectionLoaded = true
|
||||
}
|
||||
logger.error("apiGroupMemberInfo or apiGetGroupMemberCode error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
.onChange(of: newRole) { newRole in
|
||||
|
||||
@@ -41,7 +41,8 @@ struct SelectedItemsBottomToolbar: View {
|
||||
|
||||
@State var forwardEnabled: Bool = false
|
||||
|
||||
@State var allButtonsDisabled = false
|
||||
@State var deleteCountProhibited = false
|
||||
@State var forwardCountProhibited = false
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
@@ -55,9 +56,9 @@ struct SelectedItemsBottomToolbar: View {
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 20, height: 20, alignment: .center)
|
||||
.foregroundColor(!deleteEnabled || allButtonsDisabled ? theme.colors.secondary: .red)
|
||||
.foregroundColor(!deleteEnabled || deleteCountProhibited ? theme.colors.secondary: .red)
|
||||
}
|
||||
.disabled(!deleteEnabled || allButtonsDisabled)
|
||||
.disabled(!deleteEnabled || deleteCountProhibited)
|
||||
|
||||
Spacer()
|
||||
Button {
|
||||
@@ -67,9 +68,9 @@ struct SelectedItemsBottomToolbar: View {
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 20, height: 20, alignment: .center)
|
||||
.foregroundColor(!moderateEnabled || allButtonsDisabled ? theme.colors.secondary : .red)
|
||||
.foregroundColor(!moderateEnabled || deleteCountProhibited ? theme.colors.secondary : .red)
|
||||
}
|
||||
.disabled(!moderateEnabled || allButtonsDisabled)
|
||||
.disabled(!moderateEnabled || deleteCountProhibited)
|
||||
.opacity(canModerate ? 1 : 0)
|
||||
|
||||
Spacer()
|
||||
@@ -80,9 +81,9 @@ struct SelectedItemsBottomToolbar: View {
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 20, height: 20, alignment: .center)
|
||||
.foregroundColor(!forwardEnabled || allButtonsDisabled ? theme.colors.secondary : theme.colors.primary)
|
||||
.foregroundColor(!forwardEnabled || forwardCountProhibited ? theme.colors.secondary : theme.colors.primary)
|
||||
}
|
||||
.disabled(!forwardEnabled || allButtonsDisabled)
|
||||
.disabled(!forwardEnabled || forwardCountProhibited)
|
||||
}
|
||||
.frame(maxHeight: .infinity)
|
||||
.padding([.leading, .trailing], 12)
|
||||
@@ -105,7 +106,8 @@ struct SelectedItemsBottomToolbar: View {
|
||||
|
||||
private func recheckItems(_ chatInfo: ChatInfo, _ chatItems: [ChatItem], _ selectedItems: Set<Int64>?) {
|
||||
let count = selectedItems?.count ?? 0
|
||||
allButtonsDisabled = count == 0 || count > 20
|
||||
deleteCountProhibited = count == 0 || count > 200
|
||||
forwardCountProhibited = count == 0 || count > 20
|
||||
canModerate = possibleToModerate(chatInfo)
|
||||
if let selected = selectedItems {
|
||||
let me: Bool
|
||||
|
||||
@@ -10,7 +10,7 @@ import SwiftUI
|
||||
|
||||
struct ChatHelp: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@Binding var showSettings: Bool
|
||||
let dismissSettingsSheet: DismissAction
|
||||
|
||||
var body: some View {
|
||||
ScrollView { chatHelp() }
|
||||
@@ -23,7 +23,7 @@ struct ChatHelp: View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text("To ask any questions and to receive updates:")
|
||||
Button("connect to SimpleX Chat developers.") {
|
||||
showSettings = false
|
||||
dismissSettingsSheet()
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.open(simplexTeamURL)
|
||||
}
|
||||
@@ -61,8 +61,9 @@ struct ChatHelp: View {
|
||||
}
|
||||
|
||||
struct ChatHelp_Previews: PreviewProvider {
|
||||
@Environment(\.dismiss) static var mockDismiss
|
||||
|
||||
static var previews: some View {
|
||||
@State var showSettings = false
|
||||
return ChatHelp(showSettings: $showSettings)
|
||||
ChatHelp(dismissSettingsSheet: mockDismiss)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,77 @@ enum UserPickerSheet: Identifiable {
|
||||
case settings
|
||||
|
||||
var id: Self { self }
|
||||
|
||||
var navigationTitle: LocalizedStringKey {
|
||||
switch self {
|
||||
case .address: "SimpleX address"
|
||||
case .chatPreferences: "Your preferences"
|
||||
case .chatProfiles: "Your chat profiles"
|
||||
case .currentProfile: "Your current profile"
|
||||
case .useFromDesktop: "Connect to desktop"
|
||||
case .settings: "Your settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct UserPickerSheetView: View {
|
||||
let sheet: UserPickerSheet
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@State private var loaded = false
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
if loaded, let currentUser = chatModel.currentUser {
|
||||
switch sheet {
|
||||
case .address:
|
||||
UserAddressView(shareViaProfile: currentUser.addressShared)
|
||||
case .chatPreferences:
|
||||
PreferencesView(
|
||||
profile: currentUser.profile,
|
||||
preferences: currentUser.fullPreferences,
|
||||
currentPreferences: currentUser.fullPreferences
|
||||
)
|
||||
case .chatProfiles:
|
||||
UserProfilesView()
|
||||
case .currentProfile:
|
||||
UserProfile()
|
||||
case .useFromDesktop:
|
||||
ConnectDesktopView()
|
||||
case .settings:
|
||||
SettingsView()
|
||||
}
|
||||
}
|
||||
Color.clear // Required for list background to be rendered during loading
|
||||
}
|
||||
.navigationTitle(sheet.navigationTitle)
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
.overlay {
|
||||
if let la = chatModel.laRequest {
|
||||
LocalAuthView(authRequest: la)
|
||||
}
|
||||
}
|
||||
.task {
|
||||
withAnimation(
|
||||
.easeOut(duration: 0.1),
|
||||
{ loaded = true }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatListView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var showSettings: Bool
|
||||
@Binding var activeUserPickerSheet: UserPickerSheet?
|
||||
@State private var searchMode = false
|
||||
@FocusState private var searchFocussed
|
||||
@State private var searchText = ""
|
||||
@State private var searchShowingSimplexLink = false
|
||||
@State private var searchChatFilteredBySimplexLink: String? = nil
|
||||
@State private var scrollToSearchBar = false
|
||||
@State private var activeUserPickerSheet: UserPickerSheet? = nil
|
||||
@State private var userPickerShown: Bool = false
|
||||
|
||||
@AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false
|
||||
@@ -58,43 +116,20 @@ struct ChatListView: View {
|
||||
destination: chatView
|
||||
) { chatListView }
|
||||
}
|
||||
.sheet(isPresented: $userPickerShown) {
|
||||
UserPicker(activeSheet: $activeUserPickerSheet)
|
||||
.sheet(item: $activeUserPickerSheet) { sheet in
|
||||
if let currentUser = chatModel.currentUser {
|
||||
switch sheet {
|
||||
case .address:
|
||||
NavigationView {
|
||||
UserAddressView(shareViaProfile: currentUser.addressShared)
|
||||
.navigationTitle("SimpleX address")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
case .chatProfiles:
|
||||
NavigationView {
|
||||
UserProfilesView()
|
||||
}
|
||||
case .currentProfile:
|
||||
NavigationView {
|
||||
UserProfile()
|
||||
.navigationTitle("Your current profile")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
case .chatPreferences:
|
||||
NavigationView {
|
||||
PreferencesView(profile: currentUser.profile, preferences: currentUser.fullPreferences, currentPreferences: currentUser.fullPreferences)
|
||||
.navigationTitle("Your preferences")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
}
|
||||
case .useFromDesktop:
|
||||
ConnectDesktopView(viaSettings: false)
|
||||
case .settings:
|
||||
SettingsView(showSettings: $showSettings)
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
}
|
||||
}
|
||||
.modifier(
|
||||
Sheet(isPresented: $userPickerShown) {
|
||||
UserPicker(userPickerShown: $userPickerShown, activeSheet: $activeUserPickerSheet)
|
||||
}
|
||||
)
|
||||
.sheet(item: $activeUserPickerSheet) {
|
||||
UserPickerSheetView(sheet: $0)
|
||||
}
|
||||
.onChange(of: activeUserPickerSheet) {
|
||||
if $0 != nil {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||
userPickerShown = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +437,7 @@ struct SubsStatusIndicator: View {
|
||||
private func startTask() {
|
||||
task = Task {
|
||||
while !Task.isCancelled {
|
||||
if AppChatState.shared.value == .active {
|
||||
if AppChatState.shared.value == .active, ChatModel.shared.chatRunning == true {
|
||||
do {
|
||||
let (subs, hasSess) = try await getAgentSubsTotal()
|
||||
await MainActor.run {
|
||||
@@ -544,6 +579,8 @@ func chatStoppedIcon() -> some View {
|
||||
}
|
||||
|
||||
struct ChatListView_Previews: PreviewProvider {
|
||||
@State static var userPickerSheet: UserPickerSheet? = .none
|
||||
|
||||
static var previews: some View {
|
||||
let chatModel = ChatModel()
|
||||
chatModel.updateChats([
|
||||
@@ -562,9 +599,9 @@ struct ChatListView_Previews: PreviewProvider {
|
||||
|
||||
])
|
||||
return Group {
|
||||
ChatListView(showSettings: Binding.constant(false))
|
||||
ChatListView(activeUserPickerSheet: $userPickerSheet)
|
||||
.environmentObject(chatModel)
|
||||
ChatListView(showSettings: Binding.constant(false))
|
||||
ChatListView(activeUserPickerSheet: $userPickerSheet)
|
||||
.environmentObject(ChatModel())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,42 +12,31 @@ struct UserPicker: View {
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
@Environment(\.scenePhase) private var scenePhase: ScenePhase
|
||||
@Environment(\.colorScheme) private var colorScheme: ColorScheme
|
||||
@Environment(\.dismiss) private var dismiss: DismissAction
|
||||
@Binding var userPickerShown: Bool
|
||||
@Binding var activeSheet: UserPickerSheet?
|
||||
@State private var currentUser: Int64?
|
||||
@State private var switchingProfile = false
|
||||
@State private var frameWidth: CGFloat = 0
|
||||
@State private var resetScroll = ResetScrollAction()
|
||||
|
||||
// Inset grouped list dimensions
|
||||
private let imageSize: CGFloat = 44
|
||||
private let rowPadding: CGFloat = 16
|
||||
private let rowVerticalPadding: CGFloat = 11
|
||||
private let sectionSpacing: CGFloat = 35
|
||||
private var sectionHorizontalPadding: CGFloat { frameWidth > 375 ? 20 : 16 }
|
||||
private let sectionShape = RoundedRectangle(cornerRadius: 10, style: .continuous)
|
||||
|
||||
var body: some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
let v = viewBody.presentationDetents([.height(400)])
|
||||
if #available(iOS 16.4, *) {
|
||||
v.scrollBounceBehavior(.basedOnSize)
|
||||
} else {
|
||||
v
|
||||
}
|
||||
} else {
|
||||
viewBody
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var viewBody: some View {
|
||||
let otherUsers: [UserInfo] = m.users
|
||||
.filter { u in !u.user.hidden && u.user.userId != m.currentUser?.userId }
|
||||
.sorted(using: KeyPathComparator<UserInfo>(\.user.activeOrder, order: .reverse))
|
||||
let sectionWidth = max(frameWidth - sectionHorizontalPadding * 2, 0)
|
||||
let currentUserWidth = max(frameWidth - sectionHorizontalPadding - rowPadding * 2 - 14 - imageSize, 0)
|
||||
VStack(spacing: 0) {
|
||||
let stopped = m.chatRunning != true
|
||||
VStack(spacing: sectionSpacing) {
|
||||
if let user = m.currentUser {
|
||||
StickyScrollView {
|
||||
StickyScrollView(resetScroll: $resetScroll) {
|
||||
HStack(spacing: rowPadding) {
|
||||
HStack {
|
||||
ProfileImage(imageStr: user.image, size: imageSize, color: Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
@@ -56,13 +45,16 @@ struct UserPicker: View {
|
||||
}
|
||||
.padding(rowPadding)
|
||||
.frame(width: otherUsers.isEmpty ? sectionWidth : currentUserWidth, alignment: .leading)
|
||||
.background(Color(.secondarySystemGroupedBackground))
|
||||
.modifier(ListRow { activeSheet = .currentProfile })
|
||||
.clipShape(sectionShape)
|
||||
.onTapGesture { activeSheet = .currentProfile }
|
||||
.disabled(stopped)
|
||||
.opacity(stopped ? 0.4 : 1)
|
||||
ForEach(otherUsers) { u in
|
||||
userView(u, size: imageSize)
|
||||
.frame(maxWidth: sectionWidth * 0.618)
|
||||
.fixedSize()
|
||||
.disabled(stopped)
|
||||
.opacity(stopped ? 0.4 : 1)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, sectionHorizontalPadding)
|
||||
@@ -72,20 +64,21 @@ struct UserPicker: View {
|
||||
.overlay(DetermineWidth())
|
||||
.onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 }
|
||||
}
|
||||
List {
|
||||
Section {
|
||||
openSheetOnTap("qrcode", title: m.userAddress == nil ? "Create SimpleX address" : "Your SimpleX address", sheet: .address)
|
||||
openSheetOnTap("switch.2", title: "Chat preferences", sheet: .chatPreferences)
|
||||
openSheetOnTap("person.crop.rectangle.stack", title: "Your chat profiles", sheet: .chatProfiles)
|
||||
openSheetOnTap("desktopcomputer", title: "Use from desktop", sheet: .useFromDesktop)
|
||||
|
||||
ZStack(alignment: .trailing) {
|
||||
openSheetOnTap("gearshape", title: "Settings", sheet: .settings)
|
||||
Image(systemName: colorScheme == .light ? "sun.max" : "moon.fill")
|
||||
VStack(spacing: 0) {
|
||||
openSheetOnTap("qrcode", title: m.userAddress == nil ? "Create SimpleX address" : "Your SimpleX address", sheet: .address, disabled: stopped)
|
||||
openSheetOnTap("switch.2", title: "Chat preferences", sheet: .chatPreferences, disabled: stopped)
|
||||
openSheetOnTap("person.crop.rectangle.stack", title: "Your chat profiles", sheet: .chatProfiles, disabled: stopped)
|
||||
openSheetOnTap("desktopcomputer", title: "Use from desktop", sheet: .useFromDesktop, disabled: stopped)
|
||||
ZStack(alignment: .trailing) {
|
||||
openSheetOnTap("gearshape", title: "Settings", sheet: .settings, showDivider: false)
|
||||
Image(systemName: colorScheme == .light ? "sun.max" : "moon.fill")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.frame(maxWidth: 20, maxHeight: 20)
|
||||
.frame(maxWidth: 20, maxHeight: .infinity)
|
||||
.padding(.horizontal, rowPadding)
|
||||
.background(Color(.systemBackground).opacity(0.01))
|
||||
.onTapGesture {
|
||||
if (colorScheme == .light) {
|
||||
ThemeManager.applyTheme(systemDarkThemeDefault.get())
|
||||
@@ -96,9 +89,11 @@ struct UserPicker: View {
|
||||
.onLongPressGesture {
|
||||
ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.clipShape(sectionShape)
|
||||
.padding(.horizontal, sectionHorizontalPadding)
|
||||
.padding(.bottom, sectionSpacing)
|
||||
}
|
||||
.onAppear {
|
||||
// This check prevents the call of listUsers after the app is suspended, and the database is closed.
|
||||
@@ -117,6 +112,9 @@ struct UserPicker: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: userPickerShown) {
|
||||
if !$0 { resetScroll() }
|
||||
}
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.disabled(switchingProfile)
|
||||
}
|
||||
@@ -133,15 +131,15 @@ struct UserPicker: View {
|
||||
Text(u.user.displayName).font(.title2).lineLimit(1)
|
||||
}
|
||||
.padding(rowPadding)
|
||||
.background(Color(.secondarySystemGroupedBackground))
|
||||
.clipShape(sectionShape)
|
||||
.onTapGesture {
|
||||
.modifier(ListRow {
|
||||
switchingProfile = true
|
||||
dismiss()
|
||||
Task {
|
||||
do {
|
||||
try await changeActiveUserAsync_(u.user.userId, viewPwd: nil)
|
||||
await MainActor.run { switchingProfile = false }
|
||||
await MainActor.run {
|
||||
switchingProfile = false
|
||||
userPickerShown = false
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
switchingProfile = false
|
||||
@@ -152,19 +150,24 @@ struct UserPicker: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.clipShape(sectionShape)
|
||||
}
|
||||
|
||||
private func openSheetOnTap(_ icon: String, title: LocalizedStringKey, sheet: UserPickerSheet) -> some View {
|
||||
Button {
|
||||
activeSheet = sheet
|
||||
} label: {
|
||||
|
||||
private func openSheetOnTap(_ icon: String, title: LocalizedStringKey, sheet: UserPickerSheet, showDivider: Bool = true, disabled: Bool = false) -> some View {
|
||||
ZStack(alignment: .bottom) {
|
||||
settingsRow(icon, color: theme.colors.secondary) {
|
||||
Text(title).foregroundColor(.primary)
|
||||
Text(title).foregroundColor(.primary).opacity(disabled ? 0.4 : 1)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.horizontal, rowPadding)
|
||||
.padding(.vertical, rowVerticalPadding)
|
||||
.modifier(ListRow { activeSheet = sheet })
|
||||
.disabled(disabled)
|
||||
if showDivider {
|
||||
Divider().padding(.leading, 52)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
|
||||
private func unreadBadge(_ u: UserInfo) -> some View {
|
||||
@@ -179,6 +182,92 @@ struct UserPicker: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct ListRow: ViewModifier {
|
||||
@Environment(\.colorScheme) private var colorScheme: ColorScheme
|
||||
@State private var touchDown = false
|
||||
let action: () -> Void
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
ZStack {
|
||||
elevatedSecondarySystemGroupedBackground
|
||||
Color(.systemGray4).opacity(touchDown ? 1 : 0)
|
||||
content
|
||||
TouchOverlay(touchDown: $touchDown, action: action)
|
||||
}
|
||||
}
|
||||
|
||||
var elevatedSecondarySystemGroupedBackground: Color {
|
||||
switch colorScheme {
|
||||
case .dark: Color(0xFF2C2C2E)
|
||||
default: Color(0xFFFFFFFF)
|
||||
}
|
||||
}
|
||||
|
||||
struct TouchOverlay: UIViewRepresentable {
|
||||
@Binding var touchDown: Bool
|
||||
let action: () -> Void
|
||||
|
||||
func makeUIView(context: Context) -> TouchView {
|
||||
let touchView = TouchView()
|
||||
let gesture = UILongPressGestureRecognizer(
|
||||
target: touchView,
|
||||
action: #selector(touchView.longPress(gesture:))
|
||||
)
|
||||
gesture.delegate = touchView
|
||||
gesture.minimumPressDuration = 0
|
||||
touchView.addGestureRecognizer(gesture)
|
||||
return touchView
|
||||
}
|
||||
|
||||
func updateUIView(_ touchView: TouchView, context: Context) {
|
||||
touchView.representer = self
|
||||
}
|
||||
|
||||
class TouchView: UIView, UIGestureRecognizerDelegate {
|
||||
var representer: TouchOverlay?
|
||||
private var startLocation: CGPoint?
|
||||
private var task: Task<Void, Never>?
|
||||
|
||||
@objc
|
||||
func longPress(gesture: UILongPressGestureRecognizer) {
|
||||
switch gesture.state {
|
||||
case .began:
|
||||
startLocation = gesture.location(in: nil)
|
||||
task = Task {
|
||||
do {
|
||||
try await Task.sleep(nanoseconds: 200_000000)
|
||||
await MainActor.run { representer?.touchDown = true }
|
||||
} catch { }
|
||||
}
|
||||
case .ended:
|
||||
if hitTest(gesture.location(in: self), with: nil) == self {
|
||||
representer?.action()
|
||||
}
|
||||
task?.cancel()
|
||||
representer?.touchDown = false
|
||||
case .changed:
|
||||
if let startLocation {
|
||||
let location = gesture.location(in: nil)
|
||||
let dx = location.x - startLocation.x
|
||||
let dy = location.y - startLocation.y
|
||||
if sqrt(pow(dx, 2) + pow(dy, 2)) > 10 { gesture.state = .failed }
|
||||
}
|
||||
case .cancelled, .failed:
|
||||
task?.cancel()
|
||||
representer?.touchDown = false
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
func gestureRecognizer(
|
||||
_: UIGestureRecognizer,
|
||||
shouldRecognizeSimultaneouslyWith: UIGestureRecognizer
|
||||
) -> Bool { true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct UserPicker_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
@State var activeSheet: UserPickerSheet?
|
||||
@@ -186,6 +275,7 @@ struct UserPicker_Previews: PreviewProvider {
|
||||
let m = ChatModel()
|
||||
m.users = [UserInfo.sampleData, UserInfo.sampleData]
|
||||
return UserPicker(
|
||||
userPickerShown: .constant(true),
|
||||
activeSheet: $activeSheet
|
||||
)
|
||||
.environmentObject(m)
|
||||
|
||||
@@ -44,7 +44,7 @@ enum DatabaseAlert: Identifiable {
|
||||
struct DatabaseView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var showSettings: Bool
|
||||
let dismissSettingsSheet: DismissAction
|
||||
@State private var runChat = false
|
||||
@State private var alert: DatabaseAlert? = nil
|
||||
@State private var showFileImporter = false
|
||||
@@ -439,7 +439,7 @@ struct DatabaseView: View {
|
||||
|
||||
private func startChat() {
|
||||
if m.chatDbChanged {
|
||||
showSettings = false
|
||||
dismissSettingsSheet()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
resetChatCtrl()
|
||||
do {
|
||||
@@ -533,7 +533,9 @@ func deleteChatAsync() async throws {
|
||||
}
|
||||
|
||||
struct DatabaseView_Previews: PreviewProvider {
|
||||
@Environment(\.dismiss) static var mockDismiss
|
||||
|
||||
static var previews: some View {
|
||||
DatabaseView(showSettings: Binding.constant(false), chatItemTTL: .none)
|
||||
DatabaseView(dismissSettingsSheet: mockDismiss, chatItemTTL: .none)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,12 +36,7 @@ struct ChatItemClipped: ViewModifier {
|
||||
.sndMsgContent,
|
||||
.rcvMsgContent,
|
||||
.rcvDecryptionError,
|
||||
.sndDeleted,
|
||||
.rcvDeleted,
|
||||
.rcvIntegrityError,
|
||||
.sndModerated,
|
||||
.rcvModerated,
|
||||
.rcvBlocked,
|
||||
.invalidJSON:
|
||||
let tail = if let mc = ci.content.msgContent, mc.isImageOrVideo && mc.text.isEmpty {
|
||||
false
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
//
|
||||
// SwiftUISheet.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by user on 23/09/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
private let sheetAnimationDuration: Double = 0.35
|
||||
|
||||
// Refrence: https://easings.net/
|
||||
private let easeOutCubic = UICubicTimingParameters(
|
||||
controlPoint1: CGPoint(x: 0.215, y: 0.61),
|
||||
controlPoint2: CGPoint(x: 0.355, y: 1)
|
||||
)
|
||||
|
||||
struct Sheet<SheetContent: View>: ViewModifier {
|
||||
@Binding var isPresented: Bool
|
||||
@ViewBuilder let sheetContent: () -> SheetContent
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
ZStack {
|
||||
content
|
||||
SheetRepresentable(isPresented: $isPresented, content: sheetContent())
|
||||
.allowsHitTesting(isPresented)
|
||||
.ignoresSafeArea()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SheetRepresentable<Content: View>: UIViewControllerRepresentable {
|
||||
@Binding var isPresented: Bool
|
||||
let content: Content
|
||||
|
||||
func makeUIViewController(context: Context) -> Controller<Content> {
|
||||
Controller(content: content, representer: self)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ sheetController: Controller<Content>, context: Context) {
|
||||
sheetController.animate(isPresented: isPresented)
|
||||
}
|
||||
|
||||
class Controller<C: View>: UIViewController {
|
||||
let hostingController: UIHostingController<C>
|
||||
private let animator = UIViewPropertyAnimator(
|
||||
duration: sheetAnimationDuration,
|
||||
timingParameters: easeOutCubic
|
||||
)
|
||||
private let representer: SheetRepresentable<C>
|
||||
private var retainedFraction: CGFloat = 0
|
||||
private var sheetHeight: Double { hostingController.view.frame.height }
|
||||
private var task: Task<Void, Never>?
|
||||
|
||||
init(content: C, representer: SheetRepresentable<C>) {
|
||||
self.representer = representer
|
||||
self.hostingController = UIHostingController(rootView: content)
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) missing") }
|
||||
|
||||
deinit {
|
||||
animator.stopAnimation(true)
|
||||
animator.finishAnimation(at: .current)
|
||||
}
|
||||
|
||||
func animate(isPresented: Bool) {
|
||||
let alreadyAnimating = animator.isRunning && isPresented != animator.isReversed
|
||||
let sheetFullyDismissed = animator.fractionComplete == (animator.isReversed ? 1 : 0)
|
||||
let sheetFullyPresented = animator.fractionComplete == (animator.isReversed ? 0 : 1)
|
||||
|
||||
if !isPresented && sheetFullyDismissed ||
|
||||
isPresented && sheetFullyPresented ||
|
||||
alreadyAnimating {
|
||||
return
|
||||
}
|
||||
|
||||
animator.pauseAnimation()
|
||||
animator.isReversed = !isPresented
|
||||
animator.continueAnimation(
|
||||
withTimingParameters: isPresented
|
||||
? easeOutCubic
|
||||
: UICubicTimingParameters(animationCurve: .easeIn),
|
||||
durationFactor: 1 - animator.fractionComplete
|
||||
)
|
||||
handleVisibility()
|
||||
}
|
||||
|
||||
func handleVisibility() {
|
||||
if animator.isReversed {
|
||||
task = Task {
|
||||
do {
|
||||
let sleepDuration = UInt64(sheetAnimationDuration * Double(NSEC_PER_SEC))
|
||||
try await Task.sleep(nanoseconds: sleepDuration)
|
||||
view.isHidden = true
|
||||
} catch { }
|
||||
}
|
||||
} else {
|
||||
task?.cancel()
|
||||
task = nil
|
||||
view.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
view.isHidden = true
|
||||
view.backgroundColor = .clear
|
||||
view.addGestureRecognizer(
|
||||
UITapGestureRecognizer(target: self, action: #selector(tap(gesture:)))
|
||||
)
|
||||
addChild(hostingController)
|
||||
hostingController.didMove(toParent: self)
|
||||
if let sheet = hostingController.view {
|
||||
sheet.isHidden = true
|
||||
sheet.clipsToBounds = true
|
||||
sheet.layer.cornerRadius = 10
|
||||
sheet.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
|
||||
sheet.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(pan(gesture:))))
|
||||
sheet.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(sheet)
|
||||
NSLayoutConstraint.activate([
|
||||
hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
// Ensures animations are only setup once
|
||||
// on some iOS version `viewDidAppear` can get called on each state change.
|
||||
if hostingController.view.isHidden {
|
||||
hostingController.view.transform = CGAffineTransform(translationX: 0, y: self.sheetHeight)
|
||||
hostingController.view.isHidden = false
|
||||
animator.pausesOnCompletion = true
|
||||
animator.addAnimations {
|
||||
self.hostingController.view.transform = .identity
|
||||
self.view.backgroundColor = UIColor {
|
||||
switch $0.userInterfaceStyle {
|
||||
case .dark: .black.withAlphaComponent(0.290)
|
||||
default: .black.withAlphaComponent(0.121)
|
||||
}
|
||||
}
|
||||
}
|
||||
animator.startAnimation()
|
||||
animator.pauseAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func pan(gesture: UIPanGestureRecognizer) {
|
||||
switch gesture.state {
|
||||
case .began:
|
||||
animator.isReversed = false
|
||||
animator.pauseAnimation()
|
||||
retainedFraction = animator.fractionComplete
|
||||
case .changed:
|
||||
animator.fractionComplete = retainedFraction - gesture.translation(in: view).y / sheetHeight
|
||||
case .ended, .cancelled:
|
||||
let velocity = gesture.velocity(in: view).y
|
||||
animator.isReversed = (velocity - (animator.fractionComplete - 0.5) * 100).sign == .plus
|
||||
let defaultVelocity = sheetHeight / sheetAnimationDuration
|
||||
let fractionRemaining = 1 - animator.fractionComplete
|
||||
let durationFactor = min(max(fractionRemaining / (abs(velocity) / defaultVelocity), 0.5), 1)
|
||||
animator.continueAnimation(withTimingParameters: nil, durationFactor: durationFactor * fractionRemaining)
|
||||
handleVisibility()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + sheetAnimationDuration) {
|
||||
self.representer.isPresented = !self.animator.isReversed
|
||||
}
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func tap(gesture: UITapGestureRecognizer) {
|
||||
switch gesture.state {
|
||||
case .ended:
|
||||
if gesture.location(in: view).y < view.frame.height - sheetHeight {
|
||||
representer.isPresented = false
|
||||
}
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
import SwiftUI
|
||||
|
||||
struct StickyScrollView<Content: View>: UIViewRepresentable {
|
||||
@Binding var resetScroll: ResetScrollAction
|
||||
@ViewBuilder let content: () -> Content
|
||||
|
||||
func makeUIView(context: Context) -> UIScrollView {
|
||||
@@ -18,6 +19,9 @@ struct StickyScrollView<Content: View>: UIViewRepresentable {
|
||||
sv.showsHorizontalScrollIndicator = false
|
||||
sv.addSubview(hc.view)
|
||||
sv.delegate = context.coordinator
|
||||
DispatchQueue.main.async {
|
||||
resetScroll = ResetScrollAction { sv.setContentOffset(.zero, animated: false) }
|
||||
}
|
||||
return sv
|
||||
}
|
||||
|
||||
@@ -50,3 +54,8 @@ struct StickyScrollView<Content: View>: UIViewRepresentable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ResetScrollAction {
|
||||
var action = { }
|
||||
func callAsFunction() { action() }
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ enum ContactType: Int {
|
||||
}
|
||||
|
||||
struct NewChatMenuButton: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
// do not use chatModel here because it prevents showing AddGroupMembersView after group creation and QR code after link creation on iOS 16
|
||||
// @EnvironmentObject var chatModel: ChatModel
|
||||
@State private var showNewChatSheet = false
|
||||
@State private var alert: SomeAlert? = nil
|
||||
@State private var pendingConnection: PendingContactConnection? = nil
|
||||
@@ -32,7 +33,7 @@ struct NewChatMenuButton: View {
|
||||
NewChatSheet(pendingConnection: $pendingConnection)
|
||||
.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)
|
||||
.onDisappear {
|
||||
alert = cleanupPendingConnection(chatModel: chatModel, contactConnection: pendingConnection)
|
||||
alert = cleanupPendingConnection(contactConnection: pendingConnection)
|
||||
pendingConnection = nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ enum NewChatOption: Identifiable {
|
||||
var id: Self { self }
|
||||
}
|
||||
|
||||
func cleanupPendingConnection(chatModel: ChatModel, contactConnection: PendingContactConnection?) -> SomeAlert? {
|
||||
func cleanupPendingConnection(contactConnection: PendingContactConnection?) -> SomeAlert? {
|
||||
var alert: SomeAlert? = nil
|
||||
|
||||
if !(chatModel.showingInvitation?.connChatUsed ?? true),
|
||||
if !(ChatModel.shared.showingInvitation?.connChatUsed ?? true),
|
||||
let conn = contactConnection {
|
||||
alert = SomeAlert(
|
||||
alert: Alert(
|
||||
@@ -68,7 +68,7 @@ func cleanupPendingConnection(chatModel: ChatModel, contactConnection: PendingCo
|
||||
)
|
||||
}
|
||||
|
||||
chatModel.showingInvitation = nil
|
||||
ChatModel.shared.showingInvitation = nil
|
||||
|
||||
return alert
|
||||
}
|
||||
@@ -97,6 +97,11 @@ struct NewChatView: View {
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
.padding()
|
||||
.onChange(of: $selection.wrappedValue) { opt in
|
||||
if opt == NewChatOption.connect {
|
||||
showQRCodeScanner = true
|
||||
}
|
||||
}
|
||||
|
||||
VStack {
|
||||
// it seems there's a bug in iOS 15 if several views in switch (or if-else) statement have different transitions
|
||||
@@ -152,7 +157,7 @@ struct NewChatView: View {
|
||||
}
|
||||
.onDisappear {
|
||||
if !choosingProfile {
|
||||
parentAlert = cleanupPendingConnection(chatModel: m, contactConnection: contactConnection)
|
||||
parentAlert = cleanupPendingConnection(contactConnection: contactConnection)
|
||||
contactConnection = nil
|
||||
}
|
||||
}
|
||||
@@ -241,7 +246,6 @@ private struct InviteView: View {
|
||||
@Binding var choosingProfile: Bool
|
||||
|
||||
@AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false
|
||||
@State private var showSettings: Bool = false
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
@@ -693,6 +697,7 @@ struct ScannerInView: View {
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.foregroundColor(Color.clear)
|
||||
switch cameraAuthorizationStatus {
|
||||
case .authorized, nil: EmptyView()
|
||||
case .restricted: Text("Camera not available")
|
||||
case .denied: Label("Enable camera access", systemImage: "camera")
|
||||
default: Label("Tap to scan", systemImage: "qrcode")
|
||||
@@ -712,21 +717,26 @@ struct ScannerInView: View {
|
||||
.disabled(cameraAuthorizationStatus == .restricted)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
.task {
|
||||
let status = AVCaptureDevice.authorizationStatus(for: .video)
|
||||
cameraAuthorizationStatus = status
|
||||
if showQRCodeScanner {
|
||||
switch status {
|
||||
case .notDetermined: askCameraAuthorization()
|
||||
case .notDetermined: await askCameraAuthorizationAsync()
|
||||
case .restricted: showQRCodeScanner = false
|
||||
case .denied: showQRCodeScanner = false
|
||||
case .authorized: ()
|
||||
@unknown default: askCameraAuthorization()
|
||||
@unknown default: await askCameraAuthorizationAsync()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func askCameraAuthorizationAsync() async {
|
||||
await AVCaptureDevice.requestAccess(for: .video)
|
||||
cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
|
||||
}
|
||||
|
||||
func askCameraAuthorization(_ cb: (() -> Void)? = nil) {
|
||||
AVCaptureDevice.requestAccess(for: .video) { allowed in
|
||||
cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
|
||||
|
||||
@@ -49,34 +49,34 @@ struct QRCode: View {
|
||||
ZStack {
|
||||
if let image = image {
|
||||
qrCodeImage(image)
|
||||
}
|
||||
GeometryReader { geo in
|
||||
ZStack {
|
||||
if withLogo {
|
||||
let w = geo.size.width
|
||||
Image("icon-light")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: w * 0.16, height: w * 0.16)
|
||||
.frame(width: w * 0.165, height: w * 0.165)
|
||||
.background(.white)
|
||||
.clipShape(Circle())
|
||||
GeometryReader { geo in
|
||||
ZStack {
|
||||
if withLogo {
|
||||
let w = geo.size.width
|
||||
Image("icon-light")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: w * 0.16, height: w * 0.16)
|
||||
.frame(width: w * 0.165, height: w * 0.165)
|
||||
.background(.white)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
makeScreenshotFunc = {
|
||||
let size = CGSizeMake(1024 / UIScreen.main.scale, 1024 / UIScreen.main.scale)
|
||||
showShareSheet(items: [makeScreenshot(geo.frame(in: .local).origin, size)])
|
||||
onShare?()
|
||||
.onAppear {
|
||||
makeScreenshotFunc = {
|
||||
let size = CGSizeMake(1024 / UIScreen.main.scale, 1024 / UIScreen.main.scale)
|
||||
showShareSheet(items: [makeScreenshot(geo.frame(in: .local).origin, size)])
|
||||
onShare?()
|
||||
}
|
||||
}
|
||||
.frame(width: geo.size.width, height: geo.size.height)
|
||||
}
|
||||
.frame(width: geo.size.width, height: geo.size.height)
|
||||
} else {
|
||||
Color.clear.aspectRatio(1, contentMode: .fit)
|
||||
}
|
||||
}
|
||||
.onTapGesture(perform: makeScreenshotFunc)
|
||||
.onAppear {
|
||||
image = image ?? generateImage(uri, tintColor: tintColor)
|
||||
}
|
||||
.task { image = await generateImage(uri, tintColor: tintColor) }
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ private func qrCodeImage(_ image: UIImage) -> some View {
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
|
||||
private func generateImage(_ uri: String, tintColor: UIColor) -> UIImage? {
|
||||
private func generateImage(_ uri: String, tintColor: UIColor) async -> UIImage? {
|
||||
let context = CIContext()
|
||||
let filter = CIFilter.qrCodeGenerator()
|
||||
filter.message = Data(uri.utf8)
|
||||
|
||||
@@ -467,6 +467,39 @@ private let versionDescriptions: [VersionDescription] = [
|
||||
)
|
||||
]
|
||||
),
|
||||
VersionDescription(
|
||||
version: "v6.1",
|
||||
post: URL(string: "https://simplex.chat/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html"),
|
||||
features: [
|
||||
FeatureDescription(
|
||||
icon: "checkmark.shield",
|
||||
title: "Better security ✅",
|
||||
description: "SimpleX protocols reviewed by Trail of Bits."
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "video",
|
||||
title: "Better calls",
|
||||
description: "Switch audio and video during the call."
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: "bolt",
|
||||
title: "Better notifications",
|
||||
description: "Improved delivery, reduced traffic usage.\nMore improvements are coming soon!"
|
||||
),
|
||||
FeatureDescription(
|
||||
icon: nil,
|
||||
title: "Better user experience",
|
||||
description: nil,
|
||||
subfeatures: [
|
||||
("link", "Switch chat profile for 1-time invitations."),
|
||||
("message", "Customizable message shape."),
|
||||
("calendar", "Better message dates."),
|
||||
("arrowshape.turn.up.right", "Forward up to 20 messages at once."),
|
||||
("flag", "Delete or moderate up to 200 messages.")
|
||||
]
|
||||
),
|
||||
]
|
||||
),
|
||||
]
|
||||
|
||||
private let lastVersion = versionDescriptions.last!.version
|
||||
|
||||
@@ -14,7 +14,6 @@ struct ConnectDesktopView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
var viaSettings = false
|
||||
@AppStorage(DEFAULT_DEVICE_NAME_FOR_REMOTE_ACCESS) private var deviceName = UIDevice.current.name
|
||||
@AppStorage(DEFAULT_CONFIRM_REMOTE_SESSIONS) private var confirmRemoteSessions = false
|
||||
@AppStorage(DEFAULT_CONNECT_REMOTE_VIA_MULTICAST) private var connectRemoteViaMulticast = true
|
||||
@@ -57,16 +56,6 @@ struct ConnectDesktopView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
if viaSettings {
|
||||
viewBody
|
||||
} else {
|
||||
NavigationView {
|
||||
viewBody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var viewBody: some View {
|
||||
Group {
|
||||
let discovery = m.remoteCtrlSession?.discovery
|
||||
if discovery == true || (discovery == nil && !showConnectScreen) {
|
||||
|
||||
@@ -196,11 +196,14 @@ struct AdvancedNetworkSettings: View {
|
||||
if developerTools {
|
||||
Section {
|
||||
Picker("Transport isolation", selection: $netCfg.sessionMode) {
|
||||
ForEach(TransportSessionMode.values, id: \.self) { Text($0.text) }
|
||||
let modes = TransportSessionMode.values.contains(netCfg.sessionMode)
|
||||
? TransportSessionMode.values
|
||||
: TransportSessionMode.values + [netCfg.sessionMode]
|
||||
ForEach(modes, id: \.self) { Text($0.text) }
|
||||
}
|
||||
.frame(height: 36)
|
||||
} footer: {
|
||||
Text(sessionModeInfo(netCfg.sessionMode))
|
||||
sessionModeInfo(netCfg.sessionMode)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
}
|
||||
@@ -353,10 +356,13 @@ struct AdvancedNetworkSettings: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func sessionModeInfo(_ mode: TransportSessionMode) -> LocalizedStringKey {
|
||||
switch mode {
|
||||
case .user: return "A separate TCP connection will be used **for each chat profile you have in the app**."
|
||||
case .entity: return "A separate TCP connection will be used **for each contact and group member**.\n**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail."
|
||||
private func sessionModeInfo(_ mode: TransportSessionMode) -> Text {
|
||||
let userMode = Text("A separate TCP connection will be used **for each chat profile you have in the app**.")
|
||||
return switch mode {
|
||||
case .user: userMode
|
||||
case .session: userMode + Text("\n") + Text("New SOCKS credentials will be used every time you start the app.")
|
||||
case .server: userMode + Text("\n") + Text("New SOCKS credentials will be used for each server.")
|
||||
case .entity: Text("A separate TCP connection will be used **for each contact and group member**.\n**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -257,23 +257,18 @@ let networkProxyDefault: CodableDefault<NetworkProxy> = CodableDefault(defaults:
|
||||
|
||||
struct SettingsView: View {
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var sceneDelegate: SceneDelegate
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var showSettings: Bool
|
||||
@State private var showProgress: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
NavigationView {
|
||||
settingsView()
|
||||
}
|
||||
settingsView()
|
||||
if showProgress {
|
||||
progressView()
|
||||
}
|
||||
if let la = chatModel.laRequest {
|
||||
LocalAuthView(authRequest: la)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +342,7 @@ struct SettingsView: View {
|
||||
Section(header: Text("Help").foregroundColor(theme.colors.secondary)) {
|
||||
if let user = user {
|
||||
NavigationLink {
|
||||
ChatHelp(showSettings: $showSettings)
|
||||
ChatHelp(dismissSettingsSheet: dismiss)
|
||||
.navigationTitle("Welcome \(user.displayName)!")
|
||||
.modifier(ThemedBackground())
|
||||
.frame(maxHeight: .infinity, alignment: .top)
|
||||
@@ -372,7 +367,7 @@ struct SettingsView: View {
|
||||
}
|
||||
settingsRow("number", color: theme.colors.secondary) {
|
||||
Button("Send questions and ideas") {
|
||||
showSettings = false
|
||||
dismiss()
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.open(simplexTeamURL)
|
||||
}
|
||||
@@ -429,7 +424,7 @@ struct SettingsView: View {
|
||||
|
||||
private func chatDatabaseRow() -> some View {
|
||||
NavigationLink {
|
||||
DatabaseView(showSettings: $showSettings, chatItemTTL: chatModel.chatItemTTL)
|
||||
DatabaseView(dismissSettingsSheet: dismiss, chatItemTTL: chatModel.chatItemTTL)
|
||||
.navigationTitle("Your chat database")
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
} label: {
|
||||
@@ -525,9 +520,7 @@ struct SettingsView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let chatModel = ChatModel()
|
||||
chatModel.currentUser = User.sampleData
|
||||
@State var showSettings = false
|
||||
|
||||
return SettingsView(showSettings: $showSettings)
|
||||
return SettingsView()
|
||||
.environmentObject(chatModel)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -925,6 +925,10 @@
|
||||
<target>Кода за достъп до приложение се заменя с код за самоунищожение.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Версия на приложението</target>
|
||||
@@ -1055,11 +1059,19 @@
|
||||
<target>Лош хеш на съобщението</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>По-добри групи</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>По-добри съобщения</target>
|
||||
@@ -1069,6 +1081,18 @@
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1342,6 +1366,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Потребителски профил</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1844,6 +1873,10 @@ This is your own one-time link!</source>
|
||||
<target>Персонализирано време</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2133,6 +2166,10 @@ This is your own one-time link!</source>
|
||||
<target>Изтрий старата база данни?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Изтрий предстоящата връзка?</target>
|
||||
@@ -3215,6 +3252,10 @@ This is your own one-time link!</source>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Препратено</target>
|
||||
@@ -3592,6 +3633,11 @@ Error: %2$@</source>
|
||||
<target>Импортиране на архив</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Подобрена доставка на съобщения</target>
|
||||
@@ -4357,6 +4403,14 @@ This is your link for group %@!</source>
|
||||
<target>Нов kод за достъп</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Нов чат</target>
|
||||
@@ -4473,6 +4527,14 @@ This is your link for group %@!</source>
|
||||
<target>Няма мрежова връзка</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Няма разрешение за запис на гласово съобщение</target>
|
||||
@@ -5876,6 +5938,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Sent via proxy</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6159,6 +6225,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Еднократна покана за SimpleX</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Опростен режим инкогнито</target>
|
||||
@@ -6323,6 +6393,14 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Подкрепете SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Системен</target>
|
||||
@@ -6676,6 +6754,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Ще бъдете подканени да извършите идентификация, преди тази функция да бъде активирана.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>За да запишете гласово съобщение, моля, дайте разрешение за използване на микрофон.</target>
|
||||
@@ -7000,11 +7086,6 @@ To connect, please ask your contact to create another connection link and check
|
||||
<source>Use the app with one hand.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Потребителски профил</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
|
||||
@@ -898,6 +898,10 @@
|
||||
<target>Přístupový kód aplikace je nahrazen sebedestrukčním přístupovým heslem.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Verze aplikace</target>
|
||||
@@ -1024,10 +1028,18 @@
|
||||
<target>Špatný hash zprávy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Lepší zprávy</target>
|
||||
@@ -1037,6 +1049,18 @@
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1298,6 +1322,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Profil uživatele</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1774,6 +1803,10 @@ This is your own one-time link!</source>
|
||||
<target>Vlastní čas</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2060,6 +2093,10 @@ This is your own one-time link!</source>
|
||||
<target>Smazat starou databázi?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Smazat čekající připojení?</target>
|
||||
@@ -3107,6 +3144,10 @@ This is your own one-time link!</source>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3473,6 +3514,11 @@ Error: %2$@</source>
|
||||
<source>Importing archive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4201,6 +4247,14 @@ This is your link for group %@!</source>
|
||||
<target>Nové heslo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4315,6 +4369,14 @@ This is your link for group %@!</source>
|
||||
<source>No network connection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Nemáte oprávnění nahrávat hlasové zprávy</target>
|
||||
@@ -5678,6 +5740,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Sent via proxy</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5954,6 +6020,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Jednorázová pozvánka SimpleX</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Zjednodušený inkognito režim</target>
|
||||
@@ -6114,6 +6184,14 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Podpořte SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Systém</target>
|
||||
@@ -6455,6 +6533,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Před zapnutím této funkce budete vyzváni k dokončení ověření.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Chcete-li nahrávat hlasové zprávy, udělte povolení k použití mikrofonu.</target>
|
||||
@@ -6765,11 +6851,6 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu
|
||||
<source>Use the app with one hand.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Profil uživatele</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
|
||||
@@ -945,6 +945,11 @@
|
||||
<target>App-Zugangscode wurde durch den Selbstzerstörungs-Zugangscode ersetzt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<target>App-Sitzung</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>App Version</target>
|
||||
@@ -1080,11 +1085,21 @@
|
||||
<target>Ungültiger Nachrichten-Hash</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<target>Verbesserte Anrufe</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Bessere Gruppen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<target>Verbesserte Nachrichten-Datumsinformation</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Verbesserungen bei Nachrichten</target>
|
||||
@@ -1095,6 +1110,21 @@
|
||||
<target>Kontrollieren Sie Ihr Netzwerk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<target>Verbesserte Benachrichtigungen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<target>Verbesserte Sicherheit ✅</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<target>Verbesserte Nutzer-Erfahrung</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Schwarz</target>
|
||||
@@ -1381,6 +1411,11 @@
|
||||
<target>Die Chat-Präferenzen wurden geändert.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Benutzerprofil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Chat-Design</target>
|
||||
@@ -1782,7 +1817,7 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<target>Ecken-Abrundung</target>
|
||||
<target>Abrundung Ecken</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
@@ -1910,6 +1945,11 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Zeit anpassen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<target>Anpassbares Format des Nachrichtenfelds</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Design anpassen</target>
|
||||
@@ -2204,6 +2244,11 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Alte Datenbank löschen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<target>Bis zu 200 Nachrichten löschen oder moderieren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Ausstehende Verbindung löschen?</target>
|
||||
@@ -3327,6 +3372,11 @@ Das ist Ihr eigener Einmal-Link!</target>
|
||||
<target>Nachrichten ohne Dateien weiterleiten?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<target>Bis zu 20 Nachrichten auf einmal weiterleiten</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Weitergeleitet</target>
|
||||
@@ -3716,6 +3766,13 @@ Fehler: %2$@</target>
|
||||
<target>Archiv wird importiert</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<target>Verbesserte Nachrichten-Auslieferung und verringerter Datenverbrauch.
|
||||
Weitere Verbesserungen sind bald verfügbar!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Verbesserte Zustellung von Nachrichten</target>
|
||||
@@ -4501,6 +4558,16 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Neuer Zugangscode</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<target>Jedes Mal wenn Sie die App starten, werden neue SOCKS-Anmeldeinformationen genutzt</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<target>Für jeden Server werden neue SOCKS-Anmeldeinformationen genutzt</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Neuer Chat</target>
|
||||
@@ -4621,6 +4688,16 @@ Das ist Ihr Link für die Gruppe %@!</target>
|
||||
<target>Keine Netzwerkverbindung</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<target>Keine Genehmigung für Sprach-Aufnahmen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<target>Keine Genehmigung für Video-Aufnahmen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Keine Berechtigung für das Aufnehmen von Sprachnachrichten</target>
|
||||
@@ -6089,6 +6166,11 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Über einen Proxy gesendet</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<target>Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Server-Adresse</target>
|
||||
@@ -6389,6 +6471,11 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>SimpleX-Einmal-Einladung</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<target>Die SimpleX-Protokolle wurden von Trail of Bits überprüft.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Vereinfachter Inkognito-Modus</target>
|
||||
@@ -6564,6 +6651,16 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen.</target>
|
||||
<target>Unterstützung von SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<target>Während des Anrufs zwischen Audio und Video wechseln</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<target>Das Chat-Profil für Einmal-Einladungen wechseln</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>System</target>
|
||||
@@ -6928,6 +7025,16 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funktion aktiviert wird.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<target>Bitte erteilen Sie für Sprach-Aufnahmen die Genehmigung das Mikrofon zu nutzen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<target>Bitte erteilen Sie für Video-Aufnahmen die Genehmigung die Kamera zu nutzen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Bitte erlauben Sie die Nutzung des Mikrofons, um Sprachnachrichten aufnehmen zu können.</target>
|
||||
@@ -7265,11 +7372,6 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s
|
||||
<target>Die App mit einer Hand bedienen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Benutzerprofil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Benutzer-Auswahl</target>
|
||||
@@ -8401,7 +8503,7 @@ Verbindungsanfrage wiederholen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="expired" xml:space="preserve">
|
||||
<source>expired</source>
|
||||
<target>abgelaufen</target>
|
||||
<target>Abgelaufen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="forwarded" xml:space="preserve">
|
||||
@@ -8633,7 +8735,7 @@ Verbindungsanfrage wiederholen?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="other" xml:space="preserve">
|
||||
<source>other</source>
|
||||
<target>andere</target>
|
||||
<target>Andere</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="other errors" xml:space="preserve">
|
||||
|
||||
@@ -4200,7 +4200,7 @@ SimpleX servers cannot see your profile.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="## In reply to" xml:space="preserve" approved="no">
|
||||
<source>## In reply to</source>
|
||||
<target state="translated">## Ως απαντηση σε</target>
|
||||
<target state="translated">## Ως απάντηση σε</target>
|
||||
<note>copied message info</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@ (current)" xml:space="preserve" approved="no">
|
||||
|
||||
@@ -945,6 +945,11 @@
|
||||
<target>App passcode is replaced with self-destruct passcode.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<target>App session</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>App version</target>
|
||||
@@ -1080,11 +1085,21 @@
|
||||
<target>Bad message hash</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<target>Better calls</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Better groups</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<target>Better message dates.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Better messages</target>
|
||||
@@ -1095,6 +1110,21 @@
|
||||
<target>Better networking</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<target>Better notifications</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<target>Better security ✅</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<target>Better user experience</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Black</target>
|
||||
@@ -1381,6 +1411,11 @@
|
||||
<target>Chat preferences were changed.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Chat profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Chat theme</target>
|
||||
@@ -1910,6 +1945,11 @@ This is your own one-time link!</target>
|
||||
<target>Custom time</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<target>Customizable message shape.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Customize theme</target>
|
||||
@@ -2204,6 +2244,11 @@ This is your own one-time link!</target>
|
||||
<target>Delete old database?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<target>Delete or moderate up to 200 messages.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Delete pending connection?</target>
|
||||
@@ -3327,6 +3372,11 @@ This is your own one-time link!</target>
|
||||
<target>Forward messages without files?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<target>Forward up to 20 messages at once.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Forwarded</target>
|
||||
@@ -3716,6 +3766,13 @@ Error: %2$@</target>
|
||||
<target>Importing archive</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<target>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Improved message delivery</target>
|
||||
@@ -4501,6 +4558,16 @@ This is your link for group %@!</target>
|
||||
<target>New Passcode</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<target>New SOCKS credentials will be used every time you start the app.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<target>New SOCKS credentials will be used for each server.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>New chat</target>
|
||||
@@ -4621,6 +4688,16 @@ This is your link for group %@!</target>
|
||||
<target>No network connection</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<target>No permission to record speech</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<target>No permission to record video</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>No permission to record voice message</target>
|
||||
@@ -6089,6 +6166,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Sent via proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<target>Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Server address</target>
|
||||
@@ -6389,6 +6471,11 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>SimpleX one-time invitation</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<target>SimpleX protocols reviewed by Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Simplified incognito mode</target>
|
||||
@@ -6564,6 +6651,16 @@ Enable in *Network & servers* settings.</target>
|
||||
<target>Support SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<target>Switch audio and video during the call.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<target>Switch chat profile for 1-time invitations.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>System</target>
|
||||
@@ -6928,6 +7025,16 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
You will be prompted to complete authentication before this feature is enabled.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<target>To record speech please grant permission to use Microphone.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<target>To record video please grant permission to use Camera.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>To record voice message please grant permission to use Microphone.</target>
|
||||
@@ -7265,11 +7372,6 @@ To connect, please ask your contact to create another connection link and check
|
||||
<target>Use the app with one hand.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>User profile</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>User selection</target>
|
||||
|
||||
@@ -945,6 +945,11 @@
|
||||
<target>El código de acceso será reemplazado por código de autodestrucción.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<target>Sesión de aplicación</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Versión de la aplicación</target>
|
||||
@@ -1080,11 +1085,21 @@
|
||||
<target>Hash de mensaje incorrecto</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<target>Llamadas mejoradas</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Grupos mejorados</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<target>Sistema de fechas mejorado.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Mensajes mejorados</target>
|
||||
@@ -1095,6 +1110,21 @@
|
||||
<target>Uso de red mejorado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<target>Notificaciones mejoradas</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<target>Seguridad mejorada ✅</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<target>Experiencia de usuario mejorada</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Negro</target>
|
||||
@@ -1381,6 +1411,11 @@
|
||||
<target>Las preferencias del chat han sido modificadas.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Perfil de usuario</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Tema de chat</target>
|
||||
@@ -1533,7 +1568,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm that you remember database passphrase to migrate it." xml:space="preserve">
|
||||
<source>Confirm that you remember database passphrase to migrate it.</source>
|
||||
<target>Para migrar confirma que recuerdas la frase de contraseña de la base de datos.</target>
|
||||
<target>Para migrar la base de datos confirma que recuerdas la frase de contraseña.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Confirm upload" xml:space="preserve">
|
||||
@@ -1910,6 +1945,11 @@ This is your own one-time link!</source>
|
||||
<target>Tiempo personalizado</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<target>Forma personalizable de los mensajes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Personalizar tema</target>
|
||||
@@ -2204,6 +2244,11 @@ This is your own one-time link!</source>
|
||||
<target>¿Eliminar base de datos antigua?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<target>Borra o modera hasta 200 mensajes a la vez.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>¿Eliminar conexión pendiente?</target>
|
||||
@@ -3327,6 +3372,11 @@ This is your own one-time link!</source>
|
||||
<target>¿Reenviar mensajes sin los archivos?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<target>Desplazamiento de hasta 20 mensajes.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Reenviado</target>
|
||||
@@ -3716,6 +3766,13 @@ Error: %2$@</target>
|
||||
<target>Importando archivo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<target>Reducción del tráfico y entrega mejorada.
|
||||
¡Pronto habrá nuevas mejoras!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Entrega de mensajes mejorada</target>
|
||||
@@ -4118,7 +4175,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Local profile data only" xml:space="preserve">
|
||||
<source>Local profile data only</source>
|
||||
<target>Sólo datos del perfil local</target>
|
||||
<target>Eliminar sólo el perfil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Lock after" xml:space="preserve">
|
||||
@@ -4501,6 +4558,16 @@ This is your link for group %@!</source>
|
||||
<target>Código Nuevo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<target>Se usarán credenciales SOCKS nuevas cada vez que inicies la aplicación.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<target>Se usarán credenciales SOCKS nuevas por cada servidor.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Nuevo chat</target>
|
||||
@@ -4621,6 +4688,16 @@ This is your link for group %@!</source>
|
||||
<target>Sin conexión de red</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<target>Sin permiso para grabación de voz</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<target>Sin permiso para grabación de vídeo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Sin permiso para grabar mensajes de voz</target>
|
||||
@@ -5072,7 +5149,7 @@ Error: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
|
||||
<source>Possibly, certificate fingerprint in server address is incorrect</source>
|
||||
<target>Posiblemente la huella digital del certificado en la dirección del servidor es incorrecta</target>
|
||||
<target>Posiblemente la huella del certificado en la dirección del servidor es incorrecta</target>
|
||||
<note>server test error</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Preserve the last message draft, with attachments." xml:space="preserve">
|
||||
@@ -5142,7 +5219,7 @@ Error: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile and server connections" xml:space="preserve">
|
||||
<source>Profile and server connections</source>
|
||||
<target>Datos del perfil y conexiones</target>
|
||||
<target>Eliminar perfil y conexiones</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Profile image" xml:space="preserve">
|
||||
@@ -6089,6 +6166,11 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<target>Mediante proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<target>Servidor</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Dirección del servidor</target>
|
||||
@@ -6116,7 +6198,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server test failed!" xml:space="preserve">
|
||||
<source>Server test failed!</source>
|
||||
<target>¡Error en prueba del servidor!</target>
|
||||
<target>¡Prueba no superada!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server type" xml:space="preserve">
|
||||
@@ -6389,6 +6471,11 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<target>Invitación SimpleX de un uso</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<target>Protocolos de SimpleX auditados por Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Modo incógnito simplificado</target>
|
||||
@@ -6564,6 +6651,16 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
<target>Soporte SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<target>Intercambia audio y video durante la llamada.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<target>Cambia el perfil de chat para invitaciones de un solo uso.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Sistema</target>
|
||||
@@ -6651,7 +6748,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Test failed at step %@." xml:space="preserve">
|
||||
<source>Test failed at step %@.</source>
|
||||
<target>La prueba ha fallado en el paso %@.</target>
|
||||
<target>Prueba no superada en el paso %@.</target>
|
||||
<note>server test failure</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Test server" xml:space="preserve">
|
||||
@@ -6666,7 +6763,7 @@ Actívalo en ajustes de *Servidores y Redes*.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tests failed!" xml:space="preserve">
|
||||
<source>Tests failed!</source>
|
||||
<target>¡Pruebas fallidas!</target>
|
||||
<target>¡Pruebas no superadas!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Thank you for installing SimpleX Chat!" xml:space="preserve">
|
||||
@@ -6928,6 +7025,16 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Se te pedirá que completes la autenticación antes de activar esta función.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<target>Para grabación de voz, por favor concede el permiso para usar el micrófono.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<target>Para grabación de vídeo, por favor concede el permiso para usar la cámara.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Para grabar el mensaje de voz concede permiso para usar el micrófono.</target>
|
||||
@@ -7265,11 +7372,6 @@ Para conectarte pide a tu contacto que cree otro enlace y comprueba la conexión
|
||||
<target>Usa la aplicación con una sola mano.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Perfil de usuario</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Selección de usuarios</target>
|
||||
@@ -8693,7 +8795,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="removed profile picture" xml:space="preserve">
|
||||
<source>removed profile picture</source>
|
||||
<target>imagen de perfil eliminada</target>
|
||||
<target>ha eliminado la imagen del perfil</target>
|
||||
<note>profile update event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="removed you" xml:space="preserve">
|
||||
@@ -8757,7 +8859,7 @@ last received msg: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="set new profile picture" xml:space="preserve">
|
||||
<source>set new profile picture</source>
|
||||
<target>nueva imagen de perfil</target>
|
||||
<target>tiene nueva imagen del perfil</target>
|
||||
<note>profile update event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="standard end-to-end encryption" xml:space="preserve">
|
||||
|
||||
@@ -892,6 +892,10 @@
|
||||
<target>Sovelluksen pääsykoodi korvataan itsetuhoutuvalla pääsykoodilla.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Sovellusversio</target>
|
||||
@@ -1018,10 +1022,18 @@
|
||||
<target>Virheellinen viestin tarkiste</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Parempia viestejä</target>
|
||||
@@ -1031,6 +1043,18 @@
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1291,6 +1315,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Käyttäjäprofiili</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1767,6 +1796,10 @@ This is your own one-time link!</source>
|
||||
<target>Mukautettu aika</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2053,6 +2086,10 @@ This is your own one-time link!</source>
|
||||
<target>Poista vanha tietokanta?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Poistetaanko odottava yhteys?</target>
|
||||
@@ -3097,6 +3134,10 @@ This is your own one-time link!</source>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3463,6 +3504,11 @@ Error: %2$@</source>
|
||||
<source>Importing archive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4191,6 +4237,14 @@ This is your link for group %@!</source>
|
||||
<target>Uusi pääsykoodi</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4304,6 +4358,14 @@ This is your link for group %@!</source>
|
||||
<source>No network connection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Ei lupaa ääniviestin tallentamiseen</target>
|
||||
@@ -5665,6 +5727,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Sent via proxy</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5941,6 +6007,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>SimpleX-kertakutsu</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6100,6 +6170,14 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>SimpleX Chat tuki</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Järjestelmä</target>
|
||||
@@ -6441,6 +6519,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Sinua kehotetaan suorittamaan todennus loppuun, ennen kuin tämä ominaisuus otetaan käyttöön.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Jos haluat nauhoittaa ääniviestin, anna lupa käyttää mikrofonia.</target>
|
||||
@@ -6750,11 +6836,6 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja
|
||||
<source>Use the app with one hand.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Käyttäjäprofiili</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
|
||||
@@ -939,6 +939,10 @@
|
||||
<target>Le code d'accès de l'application est remplacé par un code d'autodestruction.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Version de l'app</target>
|
||||
@@ -1073,11 +1077,19 @@
|
||||
<target>Mauvais hash de message</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Des groupes plus performants</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Meilleurs messages</target>
|
||||
@@ -1088,6 +1100,18 @@
|
||||
<target>Meilleure gestion de réseau</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Noir</target>
|
||||
@@ -1373,6 +1397,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Profil d'utilisateur</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Thème de chat</target>
|
||||
@@ -1901,6 +1930,10 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Délai personnalisé</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Personnaliser le thème</target>
|
||||
@@ -2195,6 +2228,10 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<target>Supprimer l'ancienne base de données ?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Supprimer la connexion en attente ?</target>
|
||||
@@ -3307,6 +3344,10 @@ Il s'agit de votre propre lien unique !</target>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Transféré</target>
|
||||
@@ -3694,6 +3735,11 @@ Erreur : %2$@</target>
|
||||
<target>Importation de l'archive</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Amélioration de la transmission des messages</target>
|
||||
@@ -4477,6 +4523,14 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Nouveau code d'accès</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Nouveau chat</target>
|
||||
@@ -4597,6 +4651,14 @@ Voici votre lien pour le groupe %@ !</target>
|
||||
<target>Pas de connexion au réseau</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Pas l'autorisation d'enregistrer un message vocal</target>
|
||||
@@ -6054,6 +6116,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Envoyé via le proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Adresse du serveur</target>
|
||||
@@ -6352,6 +6418,10 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Invitation unique SimpleX</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Mode incognito simplifié</target>
|
||||
@@ -6526,6 +6596,14 @@ Activez-le dans les paramètres *Réseau et serveurs*.</target>
|
||||
<target>Supporter SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Système</target>
|
||||
@@ -6888,6 +6966,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Vous serez invité à confirmer l'authentification avant que cette fonction ne soit activée.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Pour enregistrer un message vocal, veuillez accorder la permission d'utiliser le microphone.</target>
|
||||
@@ -7224,11 +7310,6 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien
|
||||
<target>Utiliser l'application d'une main.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Profil d'utilisateur</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Sélection de l'utilisateur</target>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -945,6 +945,11 @@
|
||||
<target>Il codice di accesso dell'app viene sostituito da un codice di autodistruzione.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<target>Sessione dell'app</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Versione dell'app</target>
|
||||
@@ -1080,11 +1085,21 @@
|
||||
<target>Hash del messaggio errato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<target>Chiamate migliorate</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Gruppi migliorati</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<target>Date dei messaggi migliorate.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Messaggi migliorati</target>
|
||||
@@ -1095,6 +1110,21 @@
|
||||
<target>Rete migliorata</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<target>Notifiche migliorate</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<target>Sicurezza migliorata ✅</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<target>Esperienza utente migliorata</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Nero</target>
|
||||
@@ -1381,6 +1411,11 @@
|
||||
<target>Le preferenze della chat sono state cambiate.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Profilo utente</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Tema della chat</target>
|
||||
@@ -1910,6 +1945,11 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Tempo personalizzato</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<target>Forma dei messaggi personalizzabile.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Personalizza il tema</target>
|
||||
@@ -2204,6 +2244,11 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Eliminare il database vecchio?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<target>Elimina o modera fino a 200 messaggi.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Eliminare la connessione in attesa?</target>
|
||||
@@ -3327,6 +3372,11 @@ Questo è il tuo link una tantum!</target>
|
||||
<target>Inoltrare i messaggi senza file?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<target>Inoltra fino a 20 messaggi alla volta.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Inoltrato</target>
|
||||
@@ -3716,6 +3766,13 @@ Errore: %2$@</target>
|
||||
<target>Importazione archivio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<target>Consegna migliorata, utilizzo di traffico ridotto.
|
||||
Altri miglioramenti sono in arrivo!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Consegna dei messaggi migliorata</target>
|
||||
@@ -4501,6 +4558,16 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Nuovo codice di accesso</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<target>Le nuove credenziali SOCKS verranno usate ogni volta che avvii l'app.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<target>Le nuove credenziali SOCKS verranno usate per ogni server.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Nuova chat</target>
|
||||
@@ -4621,6 +4688,16 @@ Questo è il tuo link per il gruppo %@!</target>
|
||||
<target>Nessuna connessione di rete</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<target>Nessuna autorizzazione per registrare l'audio</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<target>Nessuna autorizzazione per registrare il video</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Nessuna autorizzazione per registrare messaggi vocali</target>
|
||||
@@ -6089,6 +6166,11 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Inviato via proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<target>Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Indirizzo server</target>
|
||||
@@ -6389,6 +6471,11 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Invito SimpleX una tantum</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<target>Protocolli di SimpleX esaminati da Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Modalità incognito semplificata</target>
|
||||
@@ -6564,6 +6651,16 @@ Attivalo nelle impostazioni *Rete e server*.</target>
|
||||
<target>Supporta SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<target>Cambia tra audio e video durante la chiamata.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<target>Cambia profilo di chat per inviti una tantum.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Sistema</target>
|
||||
@@ -6928,6 +7025,16 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzionalità.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<target>Per registrare l'audio, concedi l'autorizzazione di usare il microfono.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<target>Per registrare il video, concedi l'autorizzazione di usare la fotocamera.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Per registrare un messaggio vocale, concedi l'autorizzazione all'uso del microfono.</target>
|
||||
@@ -7265,11 +7372,6 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e
|
||||
<target>Usa l'app con una mano sola.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Profilo utente</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Selezione utente</target>
|
||||
|
||||
@@ -915,6 +915,10 @@
|
||||
<target>アプリのパスコードは自己破壊パスコードに置き換えられます。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>アプリのバージョン</target>
|
||||
@@ -1041,10 +1045,18 @@
|
||||
<target>メッセージのハッシュ値問題</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>より良いメッセージ</target>
|
||||
@@ -1054,6 +1066,18 @@
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1315,6 +1339,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>ユーザープロフィール</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1791,6 +1820,10 @@ This is your own one-time link!</source>
|
||||
<target>カスタム時間</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2077,6 +2110,10 @@ This is your own one-time link!</source>
|
||||
<target>古いデータベースを削除しますか?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>接続待ちの接続を削除しますか?</target>
|
||||
@@ -3122,6 +3159,10 @@ This is your own one-time link!</source>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3488,6 +3529,11 @@ Error: %2$@</source>
|
||||
<source>Importing archive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4075,10 +4121,12 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
|
||||
<source>Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
|
||||
<target>メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**エンドツーエンドの暗号化**によって保護されます。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages, files and calls are protected by **quantum resistant e2e encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
|
||||
<source>Messages, files and calls are protected by **quantum resistant e2e encryption** with perfect forward secrecy, repudiation and break-in recovery.</source>
|
||||
<target>メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**耐量子E2E暗号化**によって保護されます。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Migrate device" xml:space="preserve">
|
||||
@@ -4215,6 +4263,14 @@ This is your link for group %@!</source>
|
||||
<target>新しいパスコード</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4329,6 +4385,14 @@ This is your link for group %@!</source>
|
||||
<source>No network connection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>音声メッセージを録音する権限がありません</target>
|
||||
@@ -5683,6 +5747,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Sent via proxy</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5959,6 +6027,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>SimpleX使い捨て招待リンク</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>シークレットモードの簡素化</target>
|
||||
@@ -6119,6 +6191,14 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Simplex Chatを支援</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>システム</target>
|
||||
@@ -6459,6 +6539,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
オンにするには、認証ステップが行われます。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>音声メッセージを録音する場合は、マイクの使用を許可してください。</target>
|
||||
@@ -6768,11 +6856,6 @@ To connect, please ask your contact to create another connection link and check
|
||||
<source>Use the app with one hand.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>ユーザープロフィール</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
|
||||
@@ -945,6 +945,11 @@
|
||||
<target>De app-toegangscode wordt vervangen door een zelfvernietigings wachtwoord.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<target>Appsessie</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>App versie</target>
|
||||
@@ -1080,11 +1085,21 @@
|
||||
<target>Onjuiste bericht hash</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<target>Betere gesprekken</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Betere groepen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<target>Betere datums voor berichten.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Betere berichten</target>
|
||||
@@ -1095,6 +1110,21 @@
|
||||
<target>Beter netwerk</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<target>Betere meldingen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<target>Betere beveiliging ✅</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<target>Betere gebruikerservaring</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Zwart</target>
|
||||
@@ -1381,6 +1411,11 @@
|
||||
<target>Chatvoorkeuren zijn gewijzigd.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Gebruikers profiel</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Chat thema</target>
|
||||
@@ -1910,6 +1945,11 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Aangepaste tijd</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<target>Aanpasbare berichtvorm.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Thema aanpassen</target>
|
||||
@@ -2204,6 +2244,11 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Oude database verwijderen?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<target>Maximaal 200 berichten verwijderen of modereren.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Wachtende verbinding verwijderen?</target>
|
||||
@@ -3327,6 +3372,11 @@ Dit is uw eigen eenmalige link!</target>
|
||||
<target>Berichten doorsturen zonder bestanden?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<target>Stuur maximaal 20 berichten tegelijk door.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Doorgestuurd</target>
|
||||
@@ -3716,6 +3766,13 @@ Fout: %2$@</target>
|
||||
<target>Archief importeren</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<target>Verbeterde levering, minder data gebruik.
|
||||
Binnenkort meer verbeteringen!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Verbeterde berichtbezorging</target>
|
||||
@@ -4501,6 +4558,16 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Nieuwe toegangscode</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<target>Elke keer dat u de app start, worden er nieuwe SOCKS-inloggegevens gebruikt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<target>Voor elke server worden nieuwe SOCKS-inloggegevens gebruikt.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Nieuw gesprek</target>
|
||||
@@ -4621,6 +4688,16 @@ Dit is jouw link voor groep %@!</target>
|
||||
<target>Geen netwerkverbinding</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<target>Geen toestemming om spraak op te nemen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<target>Geen toestemming om video op te nemen</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Geen toestemming om spraakbericht op te nemen</target>
|
||||
@@ -6089,6 +6166,11 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Verzonden via proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<target>Server</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Server adres</target>
|
||||
@@ -6389,6 +6471,11 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Eenmalige SimpleX uitnodiging</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<target>SimpleX-protocollen beoordeeld door Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Vereenvoudigde incognitomodus</target>
|
||||
@@ -6564,6 +6651,16 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
<target>Ondersteuning van SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<target>Wisselen tussen audio en video tijdens het gesprek.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<target>Wijzig chatprofiel voor eenmalige uitnodigingen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Systeem</target>
|
||||
@@ -6601,6 +6698,7 @@ Schakel dit in in *Netwerk en servers*-instellingen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<target>Staart</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
@@ -6927,6 +7025,16 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingeschakeld.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<target>Geef toestemming om de microfoon te gebruiken om spraak op te nemen.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<target>Om video op te nemen, dient u toestemming te geven om de camera te gebruiken.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Geef toestemming om de microfoon te gebruiken om een spraakbericht op te nemen.</target>
|
||||
@@ -7264,11 +7372,6 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak
|
||||
<target>Gebruik de app met één hand.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Gebruikers profiel</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Gebruikersselectie</target>
|
||||
@@ -8901,7 +9004,7 @@ laatst ontvangen bericht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="you are observer" xml:space="preserve">
|
||||
<source>you are observer</source>
|
||||
<target>jij bent waarnemer</target>
|
||||
<target>je bent waarnemer</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="you blocked %@" xml:space="preserve">
|
||||
@@ -8931,7 +9034,7 @@ laatst ontvangen bericht: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="you left" xml:space="preserve">
|
||||
<source>you left</source>
|
||||
<target>jij bent vertrokken</target>
|
||||
<target>je bent vertrokken</target>
|
||||
<note>snd group event chat item</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="you removed %@" xml:space="preserve">
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<target>%1$@, %2$@</target>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
@@ -163,18 +164,22 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
|
||||
<source>%d file(s) are still being downloaded.</source>
|
||||
<target>%d plik(ów) jest dalej pobieranych.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
|
||||
<source>%d file(s) failed to download.</source>
|
||||
<target>%d plik(ów) nie udało się pobrać.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
|
||||
<source>%d file(s) were deleted.</source>
|
||||
<target>%d plik(ów) zostało usuniętych.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
|
||||
<source>%d file(s) were not downloaded.</source>
|
||||
<target>%d plik(ów) nie zostało pobranych.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d hours" xml:space="preserve">
|
||||
@@ -184,6 +189,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%d messages not forwarded" xml:space="preserve">
|
||||
<source>%d messages not forwarded</source>
|
||||
<target>%d wiadomości nie przekazanych</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d min" xml:space="preserve">
|
||||
@@ -939,6 +945,11 @@
|
||||
<target>Pin aplikacji został zastąpiony pinem samozniszczenia.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<target>Sesja aplikacji</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Wersja aplikacji</target>
|
||||
@@ -1046,6 +1057,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Auto-accept settings" xml:space="preserve">
|
||||
<source>Auto-accept settings</source>
|
||||
<target>Ustawienia automatycznej akceptacji</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Back" xml:space="preserve">
|
||||
@@ -1073,11 +1085,19 @@
|
||||
<target>Zły hash wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Lepsze grupy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Lepsze wiadomości</target>
|
||||
@@ -1088,6 +1108,18 @@
|
||||
<target>Lepsze sieciowanie</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Czarny</target>
|
||||
@@ -1371,8 +1403,14 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat preferences were changed." xml:space="preserve">
|
||||
<source>Chat preferences were changed.</source>
|
||||
<target>Preferencje czatu zostały zmienione.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Profil użytkownika</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Motyw czatu</target>
|
||||
@@ -1774,6 +1812,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<target>Róg</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
@@ -1901,6 +1940,10 @@ To jest twój jednorazowy link!</target>
|
||||
<target>Niestandardowy czas</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Dostosuj motyw</target>
|
||||
@@ -2195,6 +2238,10 @@ To jest twój jednorazowy link!</target>
|
||||
<target>Usunąć starą bazę danych?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Usunąć oczekujące połączenie?</target>
|
||||
@@ -2447,6 +2494,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
|
||||
<source>Do not use credentials with proxy.</source>
|
||||
<target>Nie używaj danych logowania do proxy.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't create address" xml:space="preserve">
|
||||
@@ -2492,6 +2540,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download files" xml:space="preserve">
|
||||
<source>Download files</source>
|
||||
<target>Pobierz pliki</target>
|
||||
<note>alert action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded" xml:space="preserve">
|
||||
@@ -2771,6 +2820,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<target>Błąd zmiany połączenia profilu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
@@ -2785,6 +2835,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<target>Błąd zmiany na incognito!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
@@ -2909,6 +2960,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error migrating settings" xml:space="preserve">
|
||||
<source>Error migrating settings</source>
|
||||
<target>Błąd migracji ustawień</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error opening chat" xml:space="preserve">
|
||||
@@ -3013,6 +3065,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<target>Błąd zmiany profilu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
@@ -3153,6 +3206,8 @@ To jest twój jednorazowy link!</target>
|
||||
<trans-unit id="File errors: %@" xml:space="preserve">
|
||||
<source>File errors:
|
||||
%@</source>
|
||||
<target>Błędy pliku:
|
||||
%@</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
|
||||
@@ -3292,6 +3347,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
|
||||
<source>Forward %d message(s)?</source>
|
||||
<target>Przekazać %d wiadomość(i)?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward and save messages" xml:space="preserve">
|
||||
@@ -3301,12 +3357,18 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward messages" xml:space="preserve">
|
||||
<source>Forward messages</source>
|
||||
<target>Przekaż wiadomości</target>
|
||||
<note>alert action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward messages without files?" xml:space="preserve">
|
||||
<source>Forward messages without files?</source>
|
||||
<target>Przekazać wiadomości bez plików?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Przekazane dalej</target>
|
||||
@@ -3319,6 +3381,7 @@ To jest twój jednorazowy link!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
|
||||
<source>Forwarding %lld messages</source>
|
||||
<target>Przekazywanie %lld wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarding server %@ failed to connect to destination server %@. Please try later." xml:space="preserve">
|
||||
@@ -3617,6 +3680,7 @@ Błąd: %2$@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="IP address" xml:space="preserve">
|
||||
<source>IP address</source>
|
||||
<target>Adres IP</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
|
||||
@@ -3694,6 +3758,11 @@ Błąd: %2$@</target>
|
||||
<target>Importowanie archiwum</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Ulepszona dostawa wiadomości</target>
|
||||
@@ -4266,6 +4335,7 @@ To jest twój link do grupy %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<target>Kształt wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
@@ -4320,6 +4390,7 @@ To jest twój link do grupy %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
|
||||
<source>Messages were deleted after you selected them.</source>
|
||||
<target>Wiadomości zostały usunięte po wybraniu ich.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
|
||||
@@ -4477,6 +4548,16 @@ To jest twój link do grupy %@!</target>
|
||||
<target>Nowy Pin</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<target>Nowe poświadczenia SOCKS będą używane przy każdym uruchomieniu aplikacji.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<target>Dla każdego serwera zostaną użyte nowe poświadczenia SOCKS.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Nowy czat</target>
|
||||
@@ -4597,6 +4678,16 @@ To jest twój link do grupy %@!</target>
|
||||
<target>Brak połączenia z siecią</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<target>Brak zezwoleń do nagrania rozmowy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<target>Brak zezwoleń do nagrania wideo</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Brak uprawnień do nagrywania wiadomości głosowej</target>
|
||||
@@ -4619,6 +4710,7 @@ To jest twój link do grupy %@!</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Nothing to forward!" xml:space="preserve">
|
||||
<source>Nothing to forward!</source>
|
||||
<target>Nic do przekazania!</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Notifications" xml:space="preserve">
|
||||
@@ -4847,6 +4939,8 @@ Wymaga włączenia VPN.</target>
|
||||
<trans-unit id="Other file errors: %@" xml:space="preserve">
|
||||
<source>Other file errors:
|
||||
%@</source>
|
||||
<target>Inne błędy pliku:
|
||||
%@</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
@@ -4886,6 +4980,7 @@ Wymaga włączenia VPN.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Password" xml:space="preserve">
|
||||
<source>Password</source>
|
||||
<target>Hasło</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Password to show" xml:space="preserve">
|
||||
@@ -5039,6 +5134,7 @@ Błąd: %@</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Port" xml:space="preserve">
|
||||
<source>Port</source>
|
||||
<target>Port</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
|
||||
@@ -5230,6 +5326,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxy requires password" xml:space="preserve">
|
||||
<source>Proxy requires password</source>
|
||||
<target>Proxy wymaga hasła</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
@@ -5455,6 +5552,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove archive?" xml:space="preserve">
|
||||
<source>Remove archive?</source>
|
||||
<target>Usunąć archiwum?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove image" xml:space="preserve">
|
||||
@@ -5639,6 +5737,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="SOCKS proxy" xml:space="preserve">
|
||||
<source>SOCKS proxy</source>
|
||||
<target>Proxy SOCKS</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Safely receive files" xml:space="preserve">
|
||||
@@ -5729,6 +5828,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save your profile?" xml:space="preserve">
|
||||
<source>Save your profile?</source>
|
||||
<target>Zapisać Twój profil?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Saved" xml:space="preserve">
|
||||
@@ -5753,6 +5853,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Saving %lld messages" xml:space="preserve">
|
||||
<source>Saving %lld messages</source>
|
||||
<target>Zapisywanie %lld wiadomości</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scale" xml:space="preserve">
|
||||
@@ -5837,6 +5938,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<target>Wybierz profil czatu</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
@@ -6054,6 +6156,11 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<target>Wysłano przez proxy</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<target>Serwer</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Adres serwera</target>
|
||||
@@ -6176,6 +6283,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Settings were changed." xml:space="preserve">
|
||||
<source>Settings were changed.</source>
|
||||
<target>Ustawienia zostały zmienione.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Shape profile images" xml:space="preserve">
|
||||
@@ -6215,6 +6323,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<target>Udostępnij profil</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
@@ -6352,6 +6461,10 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<target>Zaproszenie jednorazowe SimpleX</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Uproszczony tryb incognito</target>
|
||||
@@ -6384,6 +6497,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some app settings were not migrated." xml:space="preserve">
|
||||
<source>Some app settings were not migrated.</source>
|
||||
<target>Niektóre ustawienia aplikacji nie zostały zmigrowane.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
|
||||
@@ -6526,6 +6640,14 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
<target>Wspieraj SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>System</target>
|
||||
@@ -6563,6 +6685,7 @@ Włącz w ustawianiach *Sieć i serwery* .</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<target>Ogon</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
@@ -6759,6 +6882,7 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom
|
||||
</trans-unit>
|
||||
<trans-unit id="The uploaded database archive will be permanently removed from the servers." xml:space="preserve">
|
||||
<source>The uploaded database archive will be permanently removed from the servers.</source>
|
||||
<target>Przesłane archiwum bazy danych zostanie trwale usunięte z serwerów.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Themes" xml:space="preserve">
|
||||
@@ -6888,6 +7012,16 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Przed włączeniem tej funkcji zostanie wyświetlony monit uwierzytelniania.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<target>Aby nagrać rozmowę, proszę zezwolić na użycie Mikrofonu.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<target>Aby nagrać wideo, proszę zezwolić na użycie Aparatu.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Aby nagrać wiadomość głosową należy udzielić zgody na użycie Mikrofonu.</target>
|
||||
@@ -7157,6 +7291,7 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
|
||||
</trans-unit>
|
||||
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
|
||||
<source>Use SOCKS proxy</source>
|
||||
<target>Użyj proxy SOCKS</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
|
||||
@@ -7224,11 +7359,6 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
|
||||
<target>Korzystaj z aplikacji jedną ręką.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Profil użytkownika</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Wybór użytkownika</target>
|
||||
@@ -7236,6 +7366,7 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc
|
||||
</trans-unit>
|
||||
<trans-unit id="Username" xml:space="preserve">
|
||||
<source>Username</source>
|
||||
<target>Nazwa użytkownika</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
|
||||
@@ -7849,6 +7980,7 @@ Powtórzyć prośbę połączenia?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your chat preferences" xml:space="preserve">
|
||||
<source>Your chat preferences</source>
|
||||
<target>Twoje preferencje czatu</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your chat profiles" xml:space="preserve">
|
||||
@@ -7858,6 +7990,7 @@ Powtórzyć prośbę połączenia?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<target>Twoje połączenie zostało przeniesione do %@, ale podczas przekierowywania do profilu wystąpił nieoczekiwany błąd.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
@@ -7877,6 +8010,7 @@ Powtórzyć prośbę połączenia?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
|
||||
<source>Your credentials may be sent unencrypted.</source>
|
||||
<target>Twoje poświadczenia mogą zostać wysłane niezaszyfrowane.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
@@ -7916,6 +8050,7 @@ Powtórzyć prośbę połączenia?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your profile was changed. If you save it, the updated profile will be sent to all your contacts." xml:space="preserve">
|
||||
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
|
||||
<target>Twój profil został zmieniony. Jeśli go zapiszesz, zaktualizowany profil zostanie wysłany do wszystkich kontaktów.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@" xml:space="preserve">
|
||||
<source>%1$@, %2$@</source>
|
||||
<target>%1$@, %2$@</target>
|
||||
<note>format for date separator in chat</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%@, %@ and %lld members" xml:space="preserve">
|
||||
@@ -163,18 +164,22 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) are still being downloaded." xml:space="preserve">
|
||||
<source>%d file(s) are still being downloaded.</source>
|
||||
<target>%d файл(ов) загружаются.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) failed to download." xml:space="preserve">
|
||||
<source>%d file(s) failed to download.</source>
|
||||
<target>%d файл(ов) не удалось загрузить.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) were deleted." xml:space="preserve">
|
||||
<source>%d file(s) were deleted.</source>
|
||||
<target>%d файлов было удалено.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d file(s) were not downloaded." xml:space="preserve">
|
||||
<source>%d file(s) were not downloaded.</source>
|
||||
<target>%d файлов не было загружено.</target>
|
||||
<note>forward confirmation reason</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d hours" xml:space="preserve">
|
||||
@@ -184,6 +189,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="%d messages not forwarded" xml:space="preserve">
|
||||
<source>%d messages not forwarded</source>
|
||||
<target>%d сообщений не переслано</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="%d min" xml:space="preserve">
|
||||
@@ -939,6 +945,11 @@
|
||||
<target>Код доступа в приложение будет заменен кодом самоуничтожения.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<target>Сессия приложения</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Версия приложения</target>
|
||||
@@ -1046,6 +1057,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Auto-accept settings" xml:space="preserve">
|
||||
<source>Auto-accept settings</source>
|
||||
<target>Настройки автоприема</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Back" xml:space="preserve">
|
||||
@@ -1073,11 +1085,21 @@
|
||||
<target>Ошибка хэш сообщения</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<target>Улучшенные звонки</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Улучшенные группы</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<target>Улучшенные даты сообщений.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Улучшенные сообщения</target>
|
||||
@@ -1088,6 +1110,21 @@
|
||||
<target>Улучшенные сетевые функции</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<target>Улучшенные уведомления</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<target>Улучшенная безопасность ✅</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<target>Улучшенный интерфейс</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Черная</target>
|
||||
@@ -1371,8 +1408,14 @@
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat preferences were changed." xml:space="preserve">
|
||||
<source>Chat preferences were changed.</source>
|
||||
<target>Настройки чата были изменены.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Профиль чата</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Тема чата</target>
|
||||
@@ -1774,6 +1817,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Corner" xml:space="preserve">
|
||||
<source>Corner</source>
|
||||
<target>Угол</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Correct name to %@?" xml:space="preserve">
|
||||
@@ -1901,6 +1945,11 @@ This is your own one-time link!</source>
|
||||
<target>Пользовательское время</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<target>Настраиваемая форма сообщений.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Настроить тему</target>
|
||||
@@ -2195,6 +2244,11 @@ This is your own one-time link!</source>
|
||||
<target>Удалить предыдущую версию данных?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<target>Удаляйте или модерируйте до 200 сообщений.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Удалить ожидаемое соединение?</target>
|
||||
@@ -2447,6 +2501,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Do not use credentials with proxy." xml:space="preserve">
|
||||
<source>Do not use credentials with proxy.</source>
|
||||
<target>Не использовать учетные данные с прокси.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Don't create address" xml:space="preserve">
|
||||
@@ -2492,6 +2547,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Download files" xml:space="preserve">
|
||||
<source>Download files</source>
|
||||
<target>Загрузить файлы</target>
|
||||
<note>alert action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Downloaded" xml:space="preserve">
|
||||
@@ -2771,6 +2827,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing connection profile" xml:space="preserve">
|
||||
<source>Error changing connection profile</source>
|
||||
<target>Ошибка при изменении профиля соединения</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing role" xml:space="preserve">
|
||||
@@ -2785,6 +2842,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error changing to incognito!" xml:space="preserve">
|
||||
<source>Error changing to incognito!</source>
|
||||
<target>Ошибка при смене на Инкогнито!</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error connecting to forwarding server %@. Please try later." xml:space="preserve">
|
||||
@@ -2909,6 +2967,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error migrating settings" xml:space="preserve">
|
||||
<source>Error migrating settings</source>
|
||||
<target>Ошибка миграции настроек</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error opening chat" xml:space="preserve">
|
||||
@@ -3013,6 +3072,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile" xml:space="preserve">
|
||||
<source>Error switching profile</source>
|
||||
<target>Ошибка переключения профиля</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Error switching profile!" xml:space="preserve">
|
||||
@@ -3153,6 +3213,8 @@ This is your own one-time link!</source>
|
||||
<trans-unit id="File errors: %@" xml:space="preserve">
|
||||
<source>File errors:
|
||||
%@</source>
|
||||
<target>Ошибки файлов:
|
||||
%@</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="File not found - most likely file was deleted or cancelled." xml:space="preserve">
|
||||
@@ -3292,6 +3354,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward %d message(s)?" xml:space="preserve">
|
||||
<source>Forward %d message(s)?</source>
|
||||
<target>Переслать %d сообщение(й)?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward and save messages" xml:space="preserve">
|
||||
@@ -3301,12 +3364,19 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward messages" xml:space="preserve">
|
||||
<source>Forward messages</source>
|
||||
<target>Переслать сообщения</target>
|
||||
<note>alert action</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward messages without files?" xml:space="preserve">
|
||||
<source>Forward messages without files?</source>
|
||||
<target>Переслать сообщения без файлов?</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<target>Пересылайте до 20 сообщений за раз.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Переслано</target>
|
||||
@@ -3319,6 +3389,7 @@ This is your own one-time link!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarding %lld messages" xml:space="preserve">
|
||||
<source>Forwarding %lld messages</source>
|
||||
<target>Пересылка %lld сообщений</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarding server %@ failed to connect to destination server %@. Please try later." xml:space="preserve">
|
||||
@@ -3617,6 +3688,7 @@ Error: %2$@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="IP address" xml:space="preserve">
|
||||
<source>IP address</source>
|
||||
<target>IP адрес</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="If you can't meet in person, show QR code in a video call, or share the link." xml:space="preserve">
|
||||
@@ -3694,6 +3766,12 @@ Error: %2$@</source>
|
||||
<target>Импорт архива</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<target>Улучшенная доставка, меньше трафик.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Улучшенная доставка сообщений</target>
|
||||
@@ -4266,6 +4344,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message shape" xml:space="preserve">
|
||||
<source>Message shape</source>
|
||||
<target>Форма сообщений</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Message source remains private." xml:space="preserve">
|
||||
@@ -4320,6 +4399,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages were deleted after you selected them." xml:space="preserve">
|
||||
<source>Messages were deleted after you selected them.</source>
|
||||
<target>Сообщения были удалены после того, как вы их выбрали.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." xml:space="preserve">
|
||||
@@ -4477,6 +4557,16 @@ This is your link for group %@!</source>
|
||||
<target>Новый Код</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<target>Новые учетные данные SOCKS будут использоваться при каждом запуске приложения.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<target>Новые учетные данные SOCKS будут использоваться для каждого сервера.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Новый чат</target>
|
||||
@@ -4597,6 +4687,16 @@ This is your link for group %@!</source>
|
||||
<target>Нет интернет-соединения</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<target>Нет разрешения на запись речи</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<target>Нет разрешения на запись видео</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Нет разрешения для записи голосового сообщения</target>
|
||||
@@ -4619,6 +4719,7 @@ This is your link for group %@!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Nothing to forward!" xml:space="preserve">
|
||||
<source>Nothing to forward!</source>
|
||||
<target>Нет сообщений, которые можно переслать!</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Notifications" xml:space="preserve">
|
||||
@@ -4847,6 +4948,8 @@ Requires compatible VPN.</source>
|
||||
<trans-unit id="Other file errors: %@" xml:space="preserve">
|
||||
<source>Other file errors:
|
||||
%@</source>
|
||||
<target>Другие ошибки файлов:
|
||||
%@</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PING count" xml:space="preserve">
|
||||
@@ -4886,6 +4989,7 @@ Requires compatible VPN.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Password" xml:space="preserve">
|
||||
<source>Password</source>
|
||||
<target>Пароль</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Password to show" xml:space="preserve">
|
||||
@@ -5039,6 +5143,7 @@ Error: %@</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Port" xml:space="preserve">
|
||||
<source>Port</source>
|
||||
<target>Порт</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Possibly, certificate fingerprint in server address is incorrect" xml:space="preserve">
|
||||
@@ -5230,6 +5335,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proxy requires password" xml:space="preserve">
|
||||
<source>Proxy requires password</source>
|
||||
<target>Прокси требует пароль</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Push notifications" xml:space="preserve">
|
||||
@@ -5455,6 +5561,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove archive?" xml:space="preserve">
|
||||
<source>Remove archive?</source>
|
||||
<target>Удалить архив?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remove image" xml:space="preserve">
|
||||
@@ -5639,6 +5746,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="SOCKS proxy" xml:space="preserve">
|
||||
<source>SOCKS proxy</source>
|
||||
<target>SOCKS прокси</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Safely receive files" xml:space="preserve">
|
||||
@@ -5729,6 +5837,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Save your profile?" xml:space="preserve">
|
||||
<source>Save your profile?</source>
|
||||
<target>Сохранить ваш профиль?</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Saved" xml:space="preserve">
|
||||
@@ -5753,6 +5862,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Saving %lld messages" xml:space="preserve">
|
||||
<source>Saving %lld messages</source>
|
||||
<target>Сохранение %lld сообщений</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Scale" xml:space="preserve">
|
||||
@@ -5837,6 +5947,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Select chat profile" xml:space="preserve">
|
||||
<source>Select chat profile</source>
|
||||
<target>Выберите профиль чата</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Selected %lld" xml:space="preserve">
|
||||
@@ -6054,6 +6165,11 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Отправлено через прокси</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<target>Сервер</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Адрес сервера</target>
|
||||
@@ -6176,6 +6292,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Settings were changed." xml:space="preserve">
|
||||
<source>Settings were changed.</source>
|
||||
<target>Настройки были изменены.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Shape profile images" xml:space="preserve">
|
||||
@@ -6215,6 +6332,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share profile" xml:space="preserve">
|
||||
<source>Share profile</source>
|
||||
<target>Поделиться профилем</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Share this 1-time invite link" xml:space="preserve">
|
||||
@@ -6352,6 +6470,11 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>SimpleX одноразовая ссылка</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<target>Аудит SimpleX протоколов от Trail of Bits.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Упрощенный режим Инкогнито</target>
|
||||
@@ -6384,6 +6507,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some app settings were not migrated." xml:space="preserve">
|
||||
<source>Some app settings were not migrated.</source>
|
||||
<target>Некоторые настройки приложения не были перенесены.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Some file(s) were not exported:" xml:space="preserve">
|
||||
@@ -6526,6 +6650,16 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Поддержать SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<target>Переключайте звук и видео во время звонка.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<target>Переключайте профиль чата для одноразовых приглашений.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Системная</target>
|
||||
@@ -6563,6 +6697,7 @@ Enable in *Network & servers* settings.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Tail" xml:space="preserve">
|
||||
<source>Tail</source>
|
||||
<target>Хвост</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Take picture" xml:space="preserve">
|
||||
@@ -6759,6 +6894,7 @@ It can happen because of some bug or when the connection is compromised.</source
|
||||
</trans-unit>
|
||||
<trans-unit id="The uploaded database archive will be permanently removed from the servers." xml:space="preserve">
|
||||
<source>The uploaded database archive will be permanently removed from the servers.</source>
|
||||
<target>Загруженный архив базы данных будет навсегда удален с серверов.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Themes" xml:space="preserve">
|
||||
@@ -6888,6 +7024,16 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Вам будет нужно пройти аутентификацию для включения блокировки.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<target>Для записи речи, пожалуйста, дайте разрешение на использование микрофона.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<target>Для записи видео, пожалуйста, дайте разрешение на использование камеры.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Для записи голосового сообщения, пожалуйста разрешите доступ к микрофону.</target>
|
||||
@@ -7157,6 +7303,7 @@ To connect, please ask your contact to create another connection link and check
|
||||
</trans-unit>
|
||||
<trans-unit id="Use SOCKS proxy" xml:space="preserve">
|
||||
<source>Use SOCKS proxy</source>
|
||||
<target>Использовать SOCKS прокси</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Use SimpleX Chat servers?" xml:space="preserve">
|
||||
@@ -7224,11 +7371,6 @@ To connect, please ask your contact to create another connection link and check
|
||||
<target>Используйте приложение одной рукой.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Профиль чата</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Выбор пользователя</target>
|
||||
@@ -7236,6 +7378,7 @@ To connect, please ask your contact to create another connection link and check
|
||||
</trans-unit>
|
||||
<trans-unit id="Username" xml:space="preserve">
|
||||
<source>Username</source>
|
||||
<target>Имя пользователя</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Using SimpleX Chat servers." xml:space="preserve">
|
||||
@@ -7849,6 +7992,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your chat preferences" xml:space="preserve">
|
||||
<source>Your chat preferences</source>
|
||||
<target>Ваши настройки чата</target>
|
||||
<note>alert title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your chat profiles" xml:space="preserve">
|
||||
@@ -7858,6 +8002,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." xml:space="preserve">
|
||||
<source>Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile.</source>
|
||||
<target>Соединение было перемещено на %@, но при смене профиля произошла неожиданная ошибка.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your contact sent a file that is larger than currently supported maximum size (%@)." xml:space="preserve">
|
||||
@@ -7877,6 +8022,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your credentials may be sent unencrypted." xml:space="preserve">
|
||||
<source>Your credentials may be sent unencrypted.</source>
|
||||
<target>Ваши учетные данные могут быть отправлены в незашифрованном виде.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your current chat database will be DELETED and REPLACED with the imported one." xml:space="preserve">
|
||||
@@ -7916,6 +8062,7 @@ Repeat connection request?</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your profile was changed. If you save it, the updated profile will be sent to all your contacts." xml:space="preserve">
|
||||
<source>Your profile was changed. If you save it, the updated profile will be sent to all your contacts.</source>
|
||||
<target>Ваш профиль был изменен. Если вы сохраните его, обновленный профиль будет отправлен всем вашим контактам.</target>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Your profile, contacts and delivered messages are stored on your device." xml:space="preserve">
|
||||
|
||||
@@ -884,6 +884,10 @@
|
||||
<target>รหัสผ่านแอปจะถูกแทนที่ด้วยรหัสผ่านที่ทำลายตัวเอง</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>เวอร์ชันแอป</target>
|
||||
@@ -1010,10 +1014,18 @@
|
||||
<target>แฮชข้อความไม่ดี</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>ข้อความที่ดีขึ้น</target>
|
||||
@@ -1023,6 +1035,18 @@
|
||||
<source>Better networking</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1283,6 +1307,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>โปรไฟล์ผู้ใช้</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -1756,6 +1785,10 @@ This is your own one-time link!</source>
|
||||
<target>เวลาที่กําหนดเอง</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -2042,6 +2075,10 @@ This is your own one-time link!</source>
|
||||
<target>ลบฐานข้อมูลเก่า?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>ลบการเชื่อมต่อที่รอดำเนินการหรือไม่?</target>
|
||||
@@ -3082,6 +3119,10 @@ This is your own one-time link!</source>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -3448,6 +3489,11 @@ Error: %2$@</source>
|
||||
<source>Importing archive</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4173,6 +4219,14 @@ This is your link for group %@!</source>
|
||||
<target>รหัสผ่านใหม่</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -4285,6 +4339,14 @@ This is your link for group %@!</source>
|
||||
<source>No network connection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>ไม่อนุญาตให้บันทึกข้อความเสียง</target>
|
||||
@@ -5640,6 +5702,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<source>Sent via proxy</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -5915,6 +5981,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>คำเชิญ SimpleX แบบครั้งเดียว</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
@@ -6073,6 +6143,14 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>สนับสนุน SimpleX แชท</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>ระบบ</target>
|
||||
@@ -6413,6 +6491,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
คุณจะได้รับแจ้งให้ยืนยันตัวตนให้เสร็จสมบูรณ์ก่อนที่จะเปิดใช้งานคุณลักษณะนี้</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>ในการบันทึกข้อความเสียง โปรดให้สิทธิ์ในการใช้ไมโครโฟน</target>
|
||||
@@ -6720,11 +6806,6 @@ To connect, please ask your contact to create another connection link and check
|
||||
<source>Use the app with one hand.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>โปรไฟล์ผู้ใช้</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -939,6 +939,10 @@
|
||||
<target>Пароль програми замінено на пароль самознищення.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>Версія програми</target>
|
||||
@@ -1073,11 +1077,19 @@
|
||||
<target>Поганий хеш повідомлення</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>Кращі групи</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>Кращі повідомлення</target>
|
||||
@@ -1088,6 +1100,18 @@
|
||||
<target>Краща мережа</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>Чорний</target>
|
||||
@@ -1373,6 +1397,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>Профіль користувача</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>Тема чату</target>
|
||||
@@ -1901,6 +1930,10 @@ This is your own one-time link!</source>
|
||||
<target>Індивідуальний час</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>Налаштувати тему</target>
|
||||
@@ -2195,6 +2228,10 @@ This is your own one-time link!</source>
|
||||
<target>Видалити стару базу даних?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>Видалити очікуване з'єднання?</target>
|
||||
@@ -3307,6 +3344,10 @@ This is your own one-time link!</source>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>Переслано</target>
|
||||
@@ -3694,6 +3735,11 @@ Error: %2$@</source>
|
||||
<target>Імпорт архіву</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>Покращена доставка повідомлень</target>
|
||||
@@ -4477,6 +4523,14 @@ This is your link for group %@!</source>
|
||||
<target>Новий пароль</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>Новий чат</target>
|
||||
@@ -4597,6 +4651,14 @@ This is your link for group %@!</source>
|
||||
<target>Немає підключення до мережі</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>Немає дозволу на запис голосового повідомлення</target>
|
||||
@@ -6054,6 +6116,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Відправлено через проксі</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>Адреса сервера</target>
|
||||
@@ -6352,6 +6418,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Одноразове запрошення SimpleX</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>Спрощений режим інкогніто</target>
|
||||
@@ -6526,6 +6596,14 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>Підтримка чату SimpleX</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>Система</target>
|
||||
@@ -6888,6 +6966,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
Перед увімкненням цієї функції вам буде запропоновано пройти автентифікацію.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>Щоб записати голосове повідомлення, будь ласка, надайте дозвіл на використання мікрофону.</target>
|
||||
@@ -7224,11 +7310,6 @@ To connect, please ask your contact to create another connection link and check
|
||||
<target>Використовуйте додаток однією рукою.</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>Профіль користувача</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>Вибір користувача</target>
|
||||
|
||||
@@ -939,6 +939,10 @@
|
||||
<target>应用程序密码被替换为自毁密码。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App session" xml:space="preserve">
|
||||
<source>App session</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="App version" xml:space="preserve">
|
||||
<source>App version</source>
|
||||
<target>应用程序版本</target>
|
||||
@@ -1073,11 +1077,19 @@
|
||||
<target>错误消息散列</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better calls" xml:space="preserve">
|
||||
<source>Better calls</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better groups" xml:space="preserve">
|
||||
<source>Better groups</source>
|
||||
<target>更佳的群组</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better message dates." xml:space="preserve">
|
||||
<source>Better message dates.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better messages" xml:space="preserve">
|
||||
<source>Better messages</source>
|
||||
<target>更好的消息</target>
|
||||
@@ -1088,6 +1100,18 @@
|
||||
<target>更好的网络</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better notifications" xml:space="preserve">
|
||||
<source>Better notifications</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better security ✅" xml:space="preserve">
|
||||
<source>Better security ✅</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Better user experience" xml:space="preserve">
|
||||
<source>Better user experience</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black" xml:space="preserve">
|
||||
<source>Black</source>
|
||||
<target>黑色</target>
|
||||
@@ -1373,6 +1397,11 @@
|
||||
<source>Chat preferences were changed.</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat profile" xml:space="preserve">
|
||||
<source>Chat profile</source>
|
||||
<target>用户资料</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chat theme" xml:space="preserve">
|
||||
<source>Chat theme</source>
|
||||
<target>聊天主题</target>
|
||||
@@ -1901,6 +1930,10 @@ This is your own one-time link!</source>
|
||||
<target>自定义时间</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customizable message shape." xml:space="preserve">
|
||||
<source>Customizable message shape.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Customize theme" xml:space="preserve">
|
||||
<source>Customize theme</source>
|
||||
<target>自定义主题</target>
|
||||
@@ -2195,6 +2228,10 @@ This is your own one-time link!</source>
|
||||
<target>删除旧数据库吗?</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete or moderate up to 200 messages." xml:space="preserve">
|
||||
<source>Delete or moderate up to 200 messages.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Delete pending connection?" xml:space="preserve">
|
||||
<source>Delete pending connection?</source>
|
||||
<target>删除待定连接?</target>
|
||||
@@ -3307,6 +3344,10 @@ This is your own one-time link!</source>
|
||||
<source>Forward messages without files?</source>
|
||||
<note>alert message</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forward up to 20 messages at once." xml:space="preserve">
|
||||
<source>Forward up to 20 messages at once.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Forwarded" xml:space="preserve">
|
||||
<source>Forwarded</source>
|
||||
<target>已转发</target>
|
||||
@@ -3694,6 +3735,11 @@ Error: %2$@</source>
|
||||
<target>正在导入存档</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved delivery, reduced traffic usage. More improvements are coming soon!" xml:space="preserve">
|
||||
<source>Improved delivery, reduced traffic usage.
|
||||
More improvements are coming soon!</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Improved message delivery" xml:space="preserve">
|
||||
<source>Improved message delivery</source>
|
||||
<target>改进了消息传递</target>
|
||||
@@ -4477,6 +4523,14 @@ This is your link for group %@!</source>
|
||||
<target>新密码</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used every time you start the app." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used every time you start the app.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New SOCKS credentials will be used for each server." xml:space="preserve">
|
||||
<source>New SOCKS credentials will be used for each server.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="New chat" xml:space="preserve">
|
||||
<source>New chat</source>
|
||||
<target>新聊天</target>
|
||||
@@ -4597,6 +4651,14 @@ This is your link for group %@!</source>
|
||||
<target>无网络连接</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record speech" xml:space="preserve">
|
||||
<source>No permission to record speech</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record video" xml:space="preserve">
|
||||
<source>No permission to record video</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="No permission to record voice message" xml:space="preserve">
|
||||
<source>No permission to record voice message</source>
|
||||
<target>没有录制语音消息的权限</target>
|
||||
@@ -6054,6 +6116,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>通过代理发送</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server" xml:space="preserve">
|
||||
<source>Server</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Server address" xml:space="preserve">
|
||||
<source>Server address</source>
|
||||
<target>服务器地址</target>
|
||||
@@ -6352,6 +6418,10 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>SimpleX 一次性邀请</target>
|
||||
<note>simplex link type</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SimpleX protocols reviewed by Trail of Bits." xml:space="preserve">
|
||||
<source>SimpleX protocols reviewed by Trail of Bits.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Simplified incognito mode" xml:space="preserve">
|
||||
<source>Simplified incognito mode</source>
|
||||
<target>简化的隐身模式</target>
|
||||
@@ -6526,6 +6596,14 @@ Enable in *Network & servers* settings.</source>
|
||||
<target>支持 SimpleX Chat</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch audio and video during the call." xml:space="preserve">
|
||||
<source>Switch audio and video during the call.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="Switch chat profile for 1-time invitations." xml:space="preserve">
|
||||
<source>Switch chat profile for 1-time invitations.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="System" xml:space="preserve">
|
||||
<source>System</source>
|
||||
<target>系统</target>
|
||||
@@ -6888,6 +6966,14 @@ You will be prompted to complete authentication before this feature is enabled.<
|
||||
在启用此功能之前,系统将提示您完成身份验证。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record speech please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record speech please grant permission to use Microphone.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record video please grant permission to use Camera." xml:space="preserve">
|
||||
<source>To record video please grant permission to use Camera.</source>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="To record voice message please grant permission to use Microphone." xml:space="preserve">
|
||||
<source>To record voice message please grant permission to use Microphone.</source>
|
||||
<target>请授权使用麦克风以录制语音消息。</target>
|
||||
@@ -7224,11 +7310,6 @@ To connect, please ask your contact to create another connection link and check
|
||||
<target>用一只手使用应用程序。</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User profile" xml:space="preserve">
|
||||
<source>User profile</source>
|
||||
<target>用户资料</target>
|
||||
<note>No comment provided by engineer.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="User selection" xml:space="preserve">
|
||||
<source>User selection</source>
|
||||
<target>用户选择</target>
|
||||
|
||||
@@ -26,7 +26,7 @@ enum NSENotification {
|
||||
case nse(UNMutableNotificationContent)
|
||||
case callkit(RcvCallInvitation)
|
||||
case empty
|
||||
case msgInfo(NtfMsgInfo)
|
||||
case msgInfo(NtfMsgAckInfo)
|
||||
|
||||
var isCallInvitation: Bool {
|
||||
switch self {
|
||||
@@ -119,7 +119,9 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
var threadId: UUID? = NSEThreads.shared.newThread()
|
||||
var notificationInfo: NtfMessages?
|
||||
var receiveEntityId: String?
|
||||
var receiveConnId: String?
|
||||
var expectedMessage: String?
|
||||
var allowedGetNextAttempts: Int = 3
|
||||
// return true if the message is taken - it prevents sending it to another NotificationService instance for processing
|
||||
var shouldProcessNtf = false
|
||||
var appSubscriber: AppSubscriber?
|
||||
@@ -191,17 +193,21 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
let dbStatus = startChat()
|
||||
if case .ok = dbStatus,
|
||||
let ntfInfo = apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo) {
|
||||
logger.debug("NotificationService: receiveNtfMessages: apiGetNtfMessage \(String(describing: ntfInfo.ntfMessage_ == nil ? 0 : 1))")
|
||||
logger.debug("NotificationService: receiveNtfMessages: apiGetNtfMessage \(String(describing: ntfInfo.receivedMsg_ == nil ? 0 : 1))")
|
||||
if let connEntity = ntfInfo.connEntity_ {
|
||||
setBestAttemptNtf(
|
||||
ntfInfo.ntfsEnabled
|
||||
? .nse(createConnectionEventNtf(ntfInfo.user, connEntity))
|
||||
: .empty
|
||||
)
|
||||
if let id = connEntity.id, ntfInfo.msgTs != nil {
|
||||
if let id = connEntity.id, ntfInfo.expectedMsg_ != nil {
|
||||
notificationInfo = ntfInfo
|
||||
receiveEntityId = id
|
||||
expectedMessage = ntfInfo.ntfMessage_.flatMap { $0.msgId }
|
||||
receiveConnId = connEntity.conn.agentConnId
|
||||
let expectedMsgId = ntfInfo.expectedMsg_?.msgId
|
||||
let receivedMsgId = ntfInfo.receivedMsg_?.msgId
|
||||
logger.debug("NotificationService: receiveNtfMessages: expectedMsgId = \(expectedMsgId ?? "nil", privacy: .private), receivedMsgId = \(receivedMsgId ?? "nil", privacy: .private)")
|
||||
expectedMessage = expectedMsgId
|
||||
shouldProcessNtf = true
|
||||
return
|
||||
}
|
||||
@@ -219,22 +225,34 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
}
|
||||
|
||||
func processReceivedNtf(_ ntf: NSENotification) -> Bool {
|
||||
guard let ntfInfo = notificationInfo, let msgTs = ntfInfo.msgTs else { return false }
|
||||
guard let ntfInfo = notificationInfo, let expectedMsgTs = ntfInfo.expectedMsg_?.msgTs else { return false }
|
||||
if !ntfInfo.user.showNotifications {
|
||||
self.setBestAttemptNtf(.empty)
|
||||
}
|
||||
if case let .msgInfo(info) = ntf {
|
||||
if info.msgId == expectedMessage {
|
||||
expectedMessage = nil
|
||||
logger.debug("NotificationService processNtf: msgInfo")
|
||||
logger.debug("NotificationService processNtf: msgInfo msgId = \(info.msgId, privacy: .private): expected")
|
||||
self.deliverBestAttemptNtf()
|
||||
return true
|
||||
} else if info.msgTs > msgTs {
|
||||
logger.debug("NotificationService processNtf: unexpected msgInfo, let other instance to process it, stopping this one")
|
||||
} else if let msgTs = info.msgTs_, msgTs > expectedMsgTs {
|
||||
logger.debug("NotificationService processNtf: msgInfo msgId = \(info.msgId, privacy: .private): unexpected msgInfo, let other instance to process it, stopping this one")
|
||||
self.deliverBestAttemptNtf()
|
||||
return false
|
||||
} else if allowedGetNextAttempts > 0, let receiveConnId = receiveConnId {
|
||||
logger.debug("NotificationService processNtf: msgInfo msgId = \(info.msgId, privacy: .private): unexpected msgInfo, get next message")
|
||||
allowedGetNextAttempts -= 1
|
||||
if let receivedMsg = apiGetConnNtfMessage(connId: receiveConnId) {
|
||||
logger.debug("NotificationService processNtf, on apiGetConnNtfMessage: msgInfo msgId = \(info.msgId, privacy: .private), receivedMsg msgId = \(receivedMsg.msgId, privacy: .private)")
|
||||
return true
|
||||
} else {
|
||||
logger.debug("NotificationService processNtf, on apiGetConnNtfMessage: msgInfo msgId = \(info.msgId, privacy: .private): no next message, deliver best attempt")
|
||||
self.deliverBestAttemptNtf()
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
logger.debug("NotificationService processNtf: unknown message, let other instance to process it")
|
||||
logger.debug("NotificationService processNtf: msgInfo msgId = \(info.msgId, privacy: .private): unknown message, let other instance to process it")
|
||||
self.deliverBestAttemptNtf()
|
||||
return false
|
||||
}
|
||||
} else if ntfInfo.user.showNotifications {
|
||||
@@ -692,9 +710,9 @@ func apiGetNtfMessage(nonce: String, encNtfInfo: String) -> NtfMessages? {
|
||||
return nil
|
||||
}
|
||||
let r = sendSimpleXCmd(.apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo))
|
||||
if case let .ntfMessages(user, connEntity_, msgTs, ntfMessage_) = r, let user = user {
|
||||
logger.debug("apiGetNtfMessage response ntfMessages: \(ntfMessage_ == nil ? 0 : 1)")
|
||||
return NtfMessages(user: user, connEntity_: connEntity_, msgTs: msgTs, ntfMessage_: ntfMessage_)
|
||||
if case let .ntfMessages(user, connEntity_, expectedMsg_, receivedMsg_) = r, let user = user {
|
||||
logger.debug("apiGetNtfMessage response ntfMessages: \(receivedMsg_ == nil ? 0 : 1)")
|
||||
return NtfMessages(user: user, connEntity_: connEntity_, expectedMsg_: expectedMsg_, receivedMsg_: receivedMsg_)
|
||||
} else if case let .chatCmdError(_, error) = r {
|
||||
logger.debug("apiGetNtfMessage error response: \(String.init(describing: error))")
|
||||
} else {
|
||||
@@ -703,6 +721,20 @@ func apiGetNtfMessage(nonce: String, encNtfInfo: String) -> NtfMessages? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func apiGetConnNtfMessage(connId: String) -> NtfMsgInfo? {
|
||||
guard apiGetActiveUser() != nil else {
|
||||
logger.debug("no active user")
|
||||
return nil
|
||||
}
|
||||
let r = sendSimpleXCmd(.apiGetConnNtfMessage(connId: connId))
|
||||
if case let .connNtfMessage(receivedMsg_) = r {
|
||||
logger.debug("apiGetConnNtfMessage response receivedMsg_: \(receivedMsg_ == nil ? 0 : 1)")
|
||||
return receivedMsg_
|
||||
}
|
||||
logger.debug("apiGetConnNtfMessage error: \(responseError(r))")
|
||||
return nil
|
||||
}
|
||||
|
||||
func apiReceiveFile(fileId: Int64, encrypted: Bool, inline: Bool? = nil) -> AChatItem? {
|
||||
let userApprovedRelays = !privacyAskToApproveRelaysGroupDefault.get()
|
||||
let r = sendSimpleXCmd(.receiveFile(fileId: fileId, userApprovedRelays: userApprovedRelays, encrypted: encrypted, inline: inline))
|
||||
@@ -740,8 +772,8 @@ func setNetworkConfig(_ cfg: NetCfg) throws {
|
||||
struct NtfMessages {
|
||||
var user: User
|
||||
var connEntity_: ConnectionEntity?
|
||||
var msgTs: Date?
|
||||
var ntfMessage_: NtfMsgInfo?
|
||||
var expectedMsg_: NtfMsgInfo?
|
||||
var receivedMsg_: NtfMsgInfo?
|
||||
|
||||
var ntfsEnabled: Bool {
|
||||
user.showNotifications && (connEntity_?.ntfsEnabled ?? false)
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
"Invalid migration confirmation" = "Érvénytelen átköltöztetési visszaigazolás";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Keychain error" = "Kulcstartó hiba";
|
||||
"Keychain error" = "Kulcstartóhiba";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Large file!" = "Nagy fájl!";
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
SimpleX
|
||||
/* Bundle display name */
|
||||
"CFBundleDisplayName" = "SimpleX SE";
|
||||
|
||||
/* Bundle name */
|
||||
"CFBundleName" = "SimpleX SE";
|
||||
|
||||
/* Copyright (human-readable) */
|
||||
"NSHumanReadableCopyright" = "Telif Hakkı © 2024 SimpleX Chat. Tüm hakları saklıdır.";
|
||||
|
||||
Created by EP on 30/07/2024.
|
||||
Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,111 @@
|
||||
/*
|
||||
Localizable.strings
|
||||
SimpleX
|
||||
/* No comment provided by engineer. */
|
||||
"%@" = "%@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App is locked!" = "Uygulama kilitlendi!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cancel" = "İptal et";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot access keychain to save database password" = "Veritabanı şifresini kaydetmek için Anahtar Zinciri'ne erişilemiyor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Cannot forward message" = "Mesaj iletilemiyor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Comment" = "Yorum";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Currently maximum supported file size is %@." = "Şu anki maksimum desteklenen dosya boyutu %@ kadardır.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database downgrade required" = "Veritabanı sürüm düşürme gerekli";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database encrypted!" = "Veritabanı şifrelendi!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database error" = "Veritabanı hatası";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database passphrase is different from saved in the keychain." = "Veritabanı parolası Anahtar Zinciri'nde kayıtlı olandan farklıdır.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database passphrase is required to open chat." = "Konuşmayı açmak için veri tabanı parolası gerekli.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Database upgrade required" = "Veritabanı yükseltmesi gerekli";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error preparing file" = "Dosya hazırlanırken hata oluştu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error preparing message" = "Mesaj hazırlanırken hata oluştu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error: %@" = "Hata: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"File error" = "Dosya hatası";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Incompatible database version" = "Uyumsuz veritabanı sürümü";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Invalid migration confirmation" = "Geçerli olmayan taşıma onayı";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Keychain error" = "Anahtarlık hatası";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Large file!" = "Büyük dosya!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No active profile" = "Aktif profil yok";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Ok" = "Tamam";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open the app to downgrade the database." = "Veritabanının sürümünü düşürmek için uygulamayı açın.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Open the app to upgrade the database." = "Veritabanını güncellemek için uygulamayı açın.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Passphrase" = "Parola";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Please create a profile in the SimpleX app" = "Lütfen SimpleX uygulamasında bir profil oluşturun";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Selected chat preferences prohibit this message." = "Seçilen sohbet tercihleri bu mesajı yasakladı.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sending a message takes longer than expected." = "Mesaj göndermek beklenenden daha uzun sürüyor.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Sending message…" = "Mesaj gönderiliyor…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share" = "Paylaş";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Slow network?" = "Ağ yavaş mı?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Unknown database error: %@" = "Bilinmeyen veritabanı hatası: %@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Unsupported format" = "Desteklenmeyen format";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wait" = "Bekleyin";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Wrong database passphrase" = "Yanlış veritabanı parolası";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You can allow sharing in Privacy & Security / SimpleX Lock settings." = "Gizlilik ve Güvenlik / SimpleX Lock ayarlarından paylaşıma izin verebilirsiniz.";
|
||||
|
||||
Created by EP on 30/07/2024.
|
||||
Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -211,22 +211,23 @@
|
||||
CEE723F02C3D25C70009AE93 /* ShareView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE723EF2C3D25C70009AE93 /* ShareView.swift */; };
|
||||
CEE723F22C3D25ED0009AE93 /* ShareModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE723F12C3D25ED0009AE93 /* ShareModel.swift */; };
|
||||
CEEA861D2C2ABCB50084E1EA /* ReverseList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */; };
|
||||
CEFB2EDF2CA1BCC7004B1ECE /* SheetRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFB2EDE2CA1BCC7004B1ECE /* SheetRepresentable.swift */; };
|
||||
D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; };
|
||||
D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A9087294BD7A70047C86D /* NativeTextEditor.swift */; };
|
||||
D741547829AF89AF0022400A /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547729AF89AF0022400A /* StoreKit.framework */; };
|
||||
D741547A29AF90B00022400A /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547929AF90B00022400A /* PushKit.framework */; };
|
||||
D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; };
|
||||
D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; };
|
||||
E51B923B2CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51B92362CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU.a */; };
|
||||
E51B923C2CAB2B8800C212F2 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51B92372CAB2B8800C212F2 /* libgmp.a */; };
|
||||
E51B923D2CAB2B8800C212F2 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51B92382CAB2B8800C212F2 /* libffi.a */; };
|
||||
E51B923E2CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51B92392CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU-ghc9.6.3.a */; };
|
||||
E51B923F2CAB2B8800C212F2 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E51B923A2CAB2B8800C212F2 /* libgmpxx.a */; };
|
||||
E51CC1E62C62085600DB91FE /* OneHandUICard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51CC1E52C62085600DB91FE /* OneHandUICard.swift */; };
|
||||
E5DCF8DB2C56FAC1007928CC /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; };
|
||||
E5DCF9712C590272007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF96F2C590272007928CC /* Localizable.strings */; };
|
||||
E5DCF9842C5902CE007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9822C5902CE007928CC /* Localizable.strings */; };
|
||||
E5DCF9982C5906FF007928CC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9962C5906FF007928CC /* InfoPlist.strings */; };
|
||||
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C42CBA891A00D7A2FA /* libgmpxx.a */; };
|
||||
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C52CBA891A00D7A2FA /* libgmp.a */; };
|
||||
E5E997CB2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */; };
|
||||
E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C72CBA891A00D7A2FA /* libffi.a */; };
|
||||
E5E997CD2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -553,15 +554,11 @@
|
||||
CEE723EF2C3D25C70009AE93 /* ShareView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareView.swift; sourceTree = "<group>"; };
|
||||
CEE723F12C3D25ED0009AE93 /* ShareModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareModel.swift; sourceTree = "<group>"; };
|
||||
CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseList.swift; sourceTree = "<group>"; };
|
||||
CEFB2EDE2CA1BCC7004B1ECE /* SheetRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetRepresentable.swift; sourceTree = "<group>"; };
|
||||
D72A9087294BD7A70047C86D /* NativeTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTextEditor.swift; sourceTree = "<group>"; };
|
||||
D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
D7AA2C3429A936B400737B40 /* MediaEncryption.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = MediaEncryption.playground; path = Shared/MediaEncryption.playground; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
E51B92362CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU.a"; sourceTree = "<group>"; };
|
||||
E51B92372CAB2B8800C212F2 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
E51B92382CAB2B8800C212F2 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
E51B92392CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E51B923A2CAB2B8800C212F2 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
E51CC1E52C62085600DB91FE /* OneHandUICard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneHandUICard.swift; sourceTree = "<group>"; };
|
||||
E5DCF9702C590272007928CC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
E5DCF9722C590274007928CC /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
@@ -615,6 +612,11 @@
|
||||
E5DCF9A62C590731007928CC /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
E5DCF9A72C590732007928CC /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
E5DCF9A82C590732007928CC /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
E5E997C42CBA891A00D7A2FA /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
E5E997C52CBA891A00D7A2FA /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E5E997C72CBA891A00D7A2FA /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -653,14 +655,14 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E51B923B2CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU.a in Frameworks */,
|
||||
E51B923D2CAB2B8800C212F2 /* libffi.a in Frameworks */,
|
||||
E51B923C2CAB2B8800C212F2 /* libgmp.a in Frameworks */,
|
||||
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */,
|
||||
E5E997CB2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a in Frameworks */,
|
||||
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */,
|
||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||
E51B923F2CAB2B8800C212F2 /* libgmpxx.a in Frameworks */,
|
||||
E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */,
|
||||
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
E51B923E2CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU-ghc9.6.3.a in Frameworks */,
|
||||
E5E997CD2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -737,11 +739,11 @@
|
||||
5C764E5C279C70B7000C6508 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E51B92382CAB2B8800C212F2 /* libffi.a */,
|
||||
E51B92372CAB2B8800C212F2 /* libgmp.a */,
|
||||
E51B923A2CAB2B8800C212F2 /* libgmpxx.a */,
|
||||
E51B92392CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU-ghc9.6.3.a */,
|
||||
E51B92362CAB2B8800C212F2 /* libHSsimplex-chat-6.1.0.5-HWShuJBYoppEOt1hLB8GPU.a */,
|
||||
E5E997C72CBA891A00D7A2FA /* libffi.a */,
|
||||
E5E997C52CBA891A00D7A2FA /* libgmp.a */,
|
||||
E5E997C42CBA891A00D7A2FA /* libgmpxx.a */,
|
||||
E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */,
|
||||
E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -799,6 +801,7 @@
|
||||
CE7548092C622630009579B7 /* SwipeLabel.swift */,
|
||||
CE176F1F2C87014C00145DBC /* InvertedForegroundStyle.swift */,
|
||||
CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */,
|
||||
CEFB2EDE2CA1BCC7004B1ECE /* SheetRepresentable.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1449,6 +1452,7 @@
|
||||
5CB634B129E5EFEA0066AD6B /* PasscodeView.swift in Sources */,
|
||||
8C69FE7D2B8C7D2700267E38 /* AppSettings.swift in Sources */,
|
||||
5C2E260F27A30FDC00F70299 /* ChatView.swift in Sources */,
|
||||
CEFB2EDF2CA1BCC7004B1ECE /* SheetRepresentable.swift in Sources */,
|
||||
5C2E260B27A30CFA00F70299 /* ChatListView.swift in Sources */,
|
||||
6442E0BA287F169300CEC0F9 /* AddGroupView.swift in Sources */,
|
||||
5CF937232B2503D000E1D781 /* NSESubscriber.swift in Sources */,
|
||||
@@ -1895,7 +1899,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -1944,7 +1948,7 @@
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -1985,7 +1989,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
@@ -2005,7 +2009,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
@@ -2030,7 +2034,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
@@ -2067,7 +2071,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_CODE_COVERAGE = NO;
|
||||
@@ -2104,7 +2108,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -2155,7 +2159,7 @@
|
||||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -2206,7 +2210,7 @@
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
@@ -2240,7 +2244,7 @@
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 241;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
|
||||
@@ -56,6 +56,7 @@ public enum ChatCommand {
|
||||
case apiVerifyToken(token: DeviceToken, nonce: String, code: String)
|
||||
case apiDeleteToken(token: DeviceToken)
|
||||
case apiGetNtfMessage(nonce: String, encNtfInfo: String)
|
||||
case apiGetConnNtfMessage(connId: String)
|
||||
case apiNewGroup(userId: Int64, incognito: Bool, groupProfile: GroupProfile)
|
||||
case apiAddMember(groupId: Int64, contactId: Int64, memberRole: GroupMemberRole)
|
||||
case apiJoinGroup(groupId: Int64)
|
||||
@@ -214,6 +215,7 @@ public enum ChatCommand {
|
||||
case let .apiVerifyToken(token, nonce, code): return "/_ntf verify \(token.cmdString) \(nonce) \(code)"
|
||||
case let .apiDeleteToken(token): return "/_ntf delete \(token.cmdString)"
|
||||
case let .apiGetNtfMessage(nonce, encNtfInfo): return "/_ntf message \(nonce) \(encNtfInfo)"
|
||||
case let .apiGetConnNtfMessage(connId): return "/_ntf conn message \(connId)"
|
||||
case let .apiNewGroup(userId, incognito, groupProfile): return "/_group \(userId) incognito=\(onOff(incognito)) \(encodeJSON(groupProfile))"
|
||||
case let .apiAddMember(groupId, contactId, memberRole): return "/_add #\(groupId) \(contactId) \(memberRole)"
|
||||
case let .apiJoinGroup(groupId): return "/_join #\(groupId)"
|
||||
@@ -368,6 +370,7 @@ public enum ChatCommand {
|
||||
case .apiVerifyToken: return "apiVerifyToken"
|
||||
case .apiDeleteToken: return "apiDeleteToken"
|
||||
case .apiGetNtfMessage: return "apiGetNtfMessage"
|
||||
case .apiGetConnNtfMessage: return "apiGetConnNtfMessage"
|
||||
case .apiNewGroup: return "apiNewGroup"
|
||||
case .apiAddMember: return "apiAddMember"
|
||||
case .apiJoinGroup: return "apiJoinGroup"
|
||||
@@ -679,8 +682,9 @@ public enum ChatResponse: Decodable, Error {
|
||||
case callInvitations(callInvitations: [RcvCallInvitation])
|
||||
case ntfTokenStatus(status: NtfTknStatus)
|
||||
case ntfToken(token: DeviceToken, status: NtfTknStatus, ntfMode: NotificationsMode, ntfServer: String)
|
||||
case ntfMessages(user_: User?, connEntity_: ConnectionEntity?, msgTs: Date?, ntfMessage_: NtfMsgInfo?)
|
||||
case ntfMessage(user: UserRef, connEntity: ConnectionEntity, ntfMessage: NtfMsgInfo)
|
||||
case ntfMessages(user_: User?, connEntity_: ConnectionEntity?, expectedMsg_: NtfMsgInfo?, receivedMsg_: NtfMsgInfo?)
|
||||
case connNtfMessage(receivedMsg_: NtfMsgInfo?)
|
||||
case ntfMessage(user: UserRef, connEntity: ConnectionEntity, ntfMessage: NtfMsgAckInfo)
|
||||
case contactConnectionDeleted(user: UserRef, connection: PendingContactConnection)
|
||||
case contactDisabled(user: UserRef, contact: Contact)
|
||||
// remote desktop responses/events
|
||||
@@ -848,6 +852,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .ntfTokenStatus: return "ntfTokenStatus"
|
||||
case .ntfToken: return "ntfToken"
|
||||
case .ntfMessages: return "ntfMessages"
|
||||
case .connNtfMessage: return "connNtfMessage"
|
||||
case .ntfMessage: return "ntfMessage"
|
||||
case .contactConnectionDeleted: return "contactConnectionDeleted"
|
||||
case .contactDisabled: return "contactDisabled"
|
||||
@@ -1024,7 +1029,8 @@ public enum ChatResponse: Decodable, Error {
|
||||
case let .callInvitations(invs): return String(describing: invs)
|
||||
case let .ntfTokenStatus(status): return String(describing: status)
|
||||
case let .ntfToken(token, status, ntfMode, ntfServer): return "token: \(token)\nstatus: \(status.rawValue)\nntfMode: \(ntfMode.rawValue)\nntfServer: \(ntfServer)"
|
||||
case let .ntfMessages(u, connEntity, msgTs, ntfMessages): return withUser(u, "connEntity: \(String(describing: connEntity))\nmsgTs: \(String(describing: msgTs))\nntfMessages: \(String(describing: ntfMessages))")
|
||||
case let .ntfMessages(u, connEntity, expectedMsg_, receivedMsg_): return withUser(u, "connEntity: \(String(describing: connEntity))\nexpectedMsg_: \(String(describing: expectedMsg_))\nreceivedMsg_: \(String(describing: receivedMsg_))")
|
||||
case let .connNtfMessage(receivedMsg_): return "receivedMsg_: \(String(describing: receivedMsg_))"
|
||||
case let .ntfMessage(u, connEntity, ntfMessage): return withUser(u, "connEntity: \(String(describing: connEntity))\nntfMessage: \(String(describing: ntfMessage))")
|
||||
case let .contactConnectionDeleted(u, connection): return withUser(u, String(describing: connection))
|
||||
case let .contactDisabled(u, contact): return withUser(u, String(describing: contact))
|
||||
@@ -1353,7 +1359,7 @@ public struct NetCfg: Codable, Equatable {
|
||||
public var sessionMode = TransportSessionMode.user
|
||||
public var smpProxyMode: SMPProxyMode = .unknown
|
||||
public var smpProxyFallback: SMPProxyFallback = .allowProtected
|
||||
var smpWebPort = false
|
||||
public var smpWebPort = false
|
||||
public var tcpConnectTimeout: Int // microseconds
|
||||
public var tcpTimeout: Int // microseconds
|
||||
public var tcpTimeoutPerKb: Int // microseconds
|
||||
@@ -1485,18 +1491,22 @@ public enum OnionHosts: String, Identifiable {
|
||||
|
||||
public enum TransportSessionMode: String, Codable, Identifiable {
|
||||
case user
|
||||
case session
|
||||
case server
|
||||
case entity
|
||||
|
||||
public var text: LocalizedStringKey {
|
||||
switch self {
|
||||
case .user: return "User profile"
|
||||
case .user: return "Chat profile"
|
||||
case .session: return "App session"
|
||||
case .server: return "Server"
|
||||
case .entity: return "Connection"
|
||||
}
|
||||
}
|
||||
|
||||
public var id: TransportSessionMode { self }
|
||||
|
||||
public static let values: [TransportSessionMode] = [.user, .entity]
|
||||
public static let values: [TransportSessionMode] = [.user, .session, .server, .entity]
|
||||
}
|
||||
|
||||
public struct KeepAliveOpts: Codable, Equatable {
|
||||
@@ -2031,7 +2041,7 @@ public enum SQLiteError: Decodable, Hashable {
|
||||
}
|
||||
|
||||
public enum AgentErrorType: Decodable, Hashable {
|
||||
case CMD(cmdErr: CommandErrorType)
|
||||
case CMD(cmdErr: CommandErrorType, errContext: String)
|
||||
case CONN(connErr: ConnectionErrorType)
|
||||
case SMP(serverAddress: String, smpErr: ProtocolErrorType)
|
||||
case NTF(ntfErr: ProtocolErrorType)
|
||||
|
||||
@@ -67,7 +67,7 @@ public func registerGroupDefaults() {
|
||||
GROUP_DEFAULT_NTF_ENABLE_LOCAL: false,
|
||||
GROUP_DEFAULT_NTF_ENABLE_PERIODIC: false,
|
||||
GROUP_DEFAULT_NETWORK_USE_ONION_HOSTS: OnionHosts.no.rawValue,
|
||||
GROUP_DEFAULT_NETWORK_SESSION_MODE: TransportSessionMode.user.rawValue,
|
||||
GROUP_DEFAULT_NETWORK_SESSION_MODE: TransportSessionMode.session.rawValue,
|
||||
GROUP_DEFAULT_NETWORK_SMP_PROXY_MODE: SMPProxyMode.unknown.rawValue,
|
||||
GROUP_DEFAULT_NETWORK_SMP_PROXY_FALLBACK: SMPProxyFallback.allowProtected.rawValue,
|
||||
GROUP_DEFAULT_NETWORK_TCP_CONNECT_TIMEOUT: NetCfg.defaults.tcpConnectTimeout,
|
||||
@@ -85,7 +85,7 @@ public func registerGroupDefaults() {
|
||||
GROUP_DEFAULT_INITIAL_RANDOM_DB_PASSPHRASE: false,
|
||||
GROUP_DEFAULT_APP_LOCAL_AUTH_ENABLED: true,
|
||||
GROUP_DEFAULT_ALLOW_SHARE_EXTENSION: false,
|
||||
GROUP_DEFAULT_PRIVACY_LINK_PREVIEWS: false,
|
||||
GROUP_DEFAULT_PRIVACY_LINK_PREVIEWS: true,
|
||||
GROUP_DEFAULT_PRIVACY_ACCEPT_IMAGES: true,
|
||||
GROUP_DEFAULT_PRIVACY_TRANSFER_IMAGES_INLINE: false,
|
||||
GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES: true,
|
||||
@@ -232,7 +232,7 @@ public let networkUseOnionHostsGroupDefault = EnumDefault<OnionHosts>(
|
||||
public let networkSessionModeGroupDefault = EnumDefault<TransportSessionMode>(
|
||||
defaults: groupDefaults,
|
||||
forKey: GROUP_DEFAULT_NETWORK_SESSION_MODE,
|
||||
withDefault: .user
|
||||
withDefault: .session
|
||||
)
|
||||
|
||||
public let networkSMPProxyModeGroupDefault = EnumDefault<SMPProxyMode>(
|
||||
@@ -357,6 +357,7 @@ public func getNetCfg() -> NetCfg {
|
||||
sessionMode: sessionMode,
|
||||
smpProxyMode: smpProxyMode,
|
||||
smpProxyFallback: smpProxyFallback,
|
||||
smpWebPort: false,
|
||||
tcpConnectTimeout: tcpConnectTimeout,
|
||||
tcpTimeout: tcpTimeout,
|
||||
tcpTimeoutPerKb: tcpTimeoutPerKb,
|
||||
|
||||
@@ -80,6 +80,14 @@ public enum CallMediaType: String, Codable, Equatable {
|
||||
case audio = "audio"
|
||||
}
|
||||
|
||||
public enum CallMediaSource: String, Codable, Equatable {
|
||||
case mic = "mic"
|
||||
case camera = "camera"
|
||||
case screenAudio = "screenAudio"
|
||||
case screenVideo = "screenVideo"
|
||||
case unknown = "unknown"
|
||||
}
|
||||
|
||||
public enum VideoCamera: String, Codable, Equatable {
|
||||
case user = "user"
|
||||
case environment = "environment"
|
||||
|
||||
@@ -1852,6 +1852,7 @@ public struct PendingContactConnection: Decodable, NamedChat, Hashable {
|
||||
|
||||
public enum ConnStatus: String, Decodable, Hashable {
|
||||
case new = "new"
|
||||
case prepared = "prepared"
|
||||
case joined = "joined"
|
||||
case requested = "requested"
|
||||
case accepted = "accepted"
|
||||
@@ -1863,6 +1864,7 @@ public enum ConnStatus: String, Decodable, Hashable {
|
||||
get {
|
||||
switch self {
|
||||
case .new: return true
|
||||
case .prepared: return false
|
||||
case .joined: return false
|
||||
case .requested: return true
|
||||
case .accepted: return true
|
||||
@@ -2240,32 +2242,42 @@ public struct MemberSubError: Decodable, Hashable {
|
||||
}
|
||||
|
||||
public enum ConnectionEntity: Decodable, Hashable {
|
||||
case rcvDirectMsgConnection(contact: Contact?)
|
||||
case rcvGroupMsgConnection(groupInfo: GroupInfo, groupMember: GroupMember)
|
||||
case sndFileConnection(sndFileTransfer: SndFileTransfer)
|
||||
case rcvFileConnection(rcvFileTransfer: RcvFileTransfer)
|
||||
case userContactConnection(userContact: UserContact)
|
||||
case rcvDirectMsgConnection(entityConnection: Connection, contact: Contact?)
|
||||
case rcvGroupMsgConnection(entityConnection: Connection, groupInfo: GroupInfo, groupMember: GroupMember)
|
||||
case sndFileConnection(entityConnection: Connection, sndFileTransfer: SndFileTransfer)
|
||||
case rcvFileConnection(entityConnection: Connection, rcvFileTransfer: RcvFileTransfer)
|
||||
case userContactConnection(entityConnection: Connection, userContact: UserContact)
|
||||
|
||||
public var id: String? {
|
||||
switch self {
|
||||
case let .rcvDirectMsgConnection(contact):
|
||||
case let .rcvDirectMsgConnection(_, contact):
|
||||
return contact?.id
|
||||
case let .rcvGroupMsgConnection(_, groupMember):
|
||||
case let .rcvGroupMsgConnection(_, _, groupMember):
|
||||
return groupMember.id
|
||||
case let .userContactConnection(userContact):
|
||||
case let .userContactConnection(_, userContact):
|
||||
return userContact.id
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public var conn: Connection {
|
||||
switch self {
|
||||
case let .rcvDirectMsgConnection(entityConnection, _): entityConnection
|
||||
case let .rcvGroupMsgConnection(entityConnection, _, _): entityConnection
|
||||
case let .sndFileConnection(entityConnection, _): entityConnection
|
||||
case let .rcvFileConnection(entityConnection, _): entityConnection
|
||||
case let .userContactConnection(entityConnection, _): entityConnection
|
||||
}
|
||||
}
|
||||
|
||||
public var ntfsEnabled: Bool {
|
||||
switch self {
|
||||
case let .rcvDirectMsgConnection(contact): return contact?.chatSettings.enableNtfs == .all
|
||||
case let .rcvGroupMsgConnection(groupInfo, _): return groupInfo.chatSettings.enableNtfs == .all
|
||||
case let .rcvDirectMsgConnection(_, contact): return contact?.chatSettings.enableNtfs == .all
|
||||
case let .rcvGroupMsgConnection(_, groupInfo, _): return groupInfo.chatSettings.enableNtfs == .all
|
||||
case .sndFileConnection: return false
|
||||
case .rcvFileConnection: return false
|
||||
case let .userContactConnection(userContact): return userContact.groupId == nil
|
||||
case let .userContactConnection(_, userContact): return userContact.groupId == nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2275,6 +2287,11 @@ public struct NtfMsgInfo: Decodable, Hashable {
|
||||
public var msgTs: Date
|
||||
}
|
||||
|
||||
public struct NtfMsgAckInfo: Decodable, Hashable {
|
||||
public var msgId: String
|
||||
public var msgTs_: Date?
|
||||
}
|
||||
|
||||
public struct ChatItemDeletion: Decodable, Hashable {
|
||||
public var deletedChatItem: AChatItem
|
||||
public var toChatItem: AChatItem? = nil
|
||||
|
||||
@@ -94,7 +94,7 @@ public func createConnectionEventNtf(_ user: User, _ connEntity: ConnectionEntit
|
||||
var body: String? = nil
|
||||
var targetContentIdentifier: String? = nil
|
||||
switch connEntity {
|
||||
case let .rcvDirectMsgConnection(contact):
|
||||
case let .rcvDirectMsgConnection(_, contact):
|
||||
if let contact = contact {
|
||||
title = hideContent ? contactHidden : "\(contact.chatViewName):"
|
||||
targetContentIdentifier = contact.id
|
||||
@@ -102,7 +102,7 @@ public func createConnectionEventNtf(_ user: User, _ connEntity: ConnectionEntit
|
||||
title = NSLocalizedString("New contact:", comment: "notification")
|
||||
}
|
||||
body = NSLocalizedString("message received", comment: "notification")
|
||||
case let .rcvGroupMsgConnection(groupInfo, groupMember):
|
||||
case let .rcvGroupMsgConnection(_, groupInfo, groupMember):
|
||||
title = groupMsgNtfTitle(groupInfo, groupMember, hideContent: hideContent)
|
||||
body = NSLocalizedString("message received", comment: "notification")
|
||||
targetContentIdentifier = groupInfo.id
|
||||
|
||||
@@ -791,6 +791,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Чат настройки";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Потребителски профил";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chats" = "Чатове";
|
||||
|
||||
@@ -3989,9 +3992,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app while in the call." = "Използвайте приложението по време на разговора.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Потребителски профил";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using SimpleX Chat servers." = "Използват се сървърите на SimpleX Chat.";
|
||||
|
||||
|
||||
@@ -644,6 +644,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Předvolby chatu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Profil uživatele";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chats" = "Chaty";
|
||||
|
||||
@@ -3229,9 +3232,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use SimpleX Chat servers?" = "Používat servery SimpleX Chat?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Profil uživatele";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using SimpleX Chat servers." = "Používat servery SimpleX Chat.";
|
||||
|
||||
|
||||
@@ -595,6 +595,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"App passcode is replaced with self-destruct passcode." = "App-Zugangscode wurde durch den Selbstzerstörungs-Zugangscode ersetzt.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App session" = "App-Sitzung";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App version" = "App Version";
|
||||
|
||||
@@ -691,15 +694,30 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Bad message ID" = "Falsche Nachrichten-ID";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better calls" = "Verbesserte Anrufe";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better groups" = "Bessere Gruppen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better message dates." = "Verbesserte Nachrichten-Datumsinformation";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better messages" = "Verbesserungen bei Nachrichten";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better networking" = "Kontrollieren Sie Ihr Netzwerk";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better notifications" = "Verbesserte Benachrichtigungen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better security ✅" = "Verbesserte Sicherheit ✅";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better user experience" = "Verbesserte Nutzer-Erfahrung";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Black" = "Schwarz";
|
||||
|
||||
@@ -914,6 +932,9 @@
|
||||
/* alert message */
|
||||
"Chat preferences were changed." = "Die Chat-Präferenzen wurden geändert.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Benutzerprofil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Chat-Design";
|
||||
|
||||
@@ -1203,7 +1224,7 @@
|
||||
"Core version: v%@" = "Core Version: v%@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Corner" = "Ecken-Abrundung";
|
||||
"Corner" = "Abrundung Ecken";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Correct name to %@?" = "Richtiger Name für %@?";
|
||||
@@ -1286,6 +1307,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Custom time" = "Zeit anpassen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customizable message shape." = "Anpassbares Format des Nachrichtenfelds";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customize theme" = "Design anpassen";
|
||||
|
||||
@@ -1476,6 +1500,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Delete old database?" = "Alte Datenbank löschen?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete or moderate up to 200 messages." = "Bis zu 200 Nachrichten löschen oder moderieren";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete pending connection?" = "Ausstehende Verbindung löschen?";
|
||||
|
||||
@@ -2093,7 +2120,7 @@
|
||||
"Expand" = "Erweitern";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"expired" = "abgelaufen";
|
||||
"expired" = "Abgelaufen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Export database" = "Datenbank exportieren";
|
||||
@@ -2224,6 +2251,9 @@
|
||||
/* alert message */
|
||||
"Forward messages without files?" = "Nachrichten ohne Dateien weiterleiten?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forward up to 20 messages at once." = "Bis zu 20 Nachrichten auf einmal weiterleiten";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"forwarded" = "weitergeleitet";
|
||||
|
||||
@@ -2464,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Importing archive" = "Archiv wird importiert";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Verbesserte Nachrichten-Auslieferung und verringerter Datenverbrauch.\nWeitere Verbesserungen sind bald verfügbar!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved message delivery" = "Verbesserte Zustellung von Nachrichten";
|
||||
|
||||
@@ -3067,6 +3100,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"New passphrase…" = "Neues Passwort…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used every time you start the app." = "Jedes Mal wenn Sie die App starten, werden neue SOCKS-Anmeldeinformationen genutzt";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used for each server." = "Für jeden Server werden neue SOCKS-Anmeldeinformationen genutzt";
|
||||
|
||||
/* pref value */
|
||||
"no" = "Nein";
|
||||
|
||||
@@ -3109,6 +3148,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Keine Netzwerkverbindung";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record speech" = "Keine Genehmigung für Sprach-Aufnahmen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record video" = "Keine Genehmigung für Video-Aufnahmen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record voice message" = "Keine Berechtigung für das Aufnehmen von Sprachnachrichten";
|
||||
|
||||
@@ -3268,7 +3313,7 @@
|
||||
"Or show this code" = "Oder diesen QR-Code anzeigen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"other" = "andere";
|
||||
"other" = "Andere";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Other" = "Andere";
|
||||
@@ -4061,6 +4106,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Über einen Proxy gesendet";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server" = "Server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Server-Adresse";
|
||||
|
||||
@@ -4250,6 +4298,9 @@
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "SimpleX-Einmal-Einladung";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Die SimpleX-Protokolle wurden von Trail of Bits überprüft.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Simplified incognito mode" = "Vereinfachter Inkognito-Modus";
|
||||
|
||||
@@ -4370,6 +4421,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Support SimpleX Chat" = "Unterstützung von SimpleX Chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch audio and video during the call." = "Während des Anrufs zwischen Audio und Video wechseln";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch chat profile for 1-time invitations." = "Das Chat-Profil für Einmal-Einladungen wechseln";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"System" = "System";
|
||||
|
||||
@@ -4589,6 +4646,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Zum Schutz Ihrer IP-Adresse, wird für die Nachrichten-Auslieferung privates Routing über Ihre konfigurierten SMP-Server genutzt.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record speech please grant permission to use Microphone." = "Bitte erteilen Sie für Sprach-Aufnahmen die Genehmigung das Mikrofon zu nutzen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record video please grant permission to use Camera." = "Bitte erteilen Sie für Video-Aufnahmen die Genehmigung die Kamera zu nutzen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Bitte erlauben Sie die Nutzung des Mikrofons, um Sprachnachrichten aufnehmen zu können.";
|
||||
|
||||
@@ -4814,9 +4877,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app with one hand." = "Die App mit einer Hand bedienen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Benutzerprofil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Benutzer-Auswahl";
|
||||
|
||||
|
||||
@@ -595,6 +595,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"App passcode is replaced with self-destruct passcode." = "El código de acceso será reemplazado por código de autodestrucción.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App session" = "Sesión de aplicación";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App version" = "Versión de la aplicación";
|
||||
|
||||
@@ -691,15 +694,30 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Bad message ID" = "ID de mensaje incorrecto";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better calls" = "Llamadas mejoradas";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better groups" = "Grupos mejorados";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better message dates." = "Sistema de fechas mejorado.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better messages" = "Mensajes mejorados";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better networking" = "Uso de red mejorado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better notifications" = "Notificaciones mejoradas";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better security ✅" = "Seguridad mejorada ✅";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better user experience" = "Experiencia de usuario mejorada";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Black" = "Negro";
|
||||
|
||||
@@ -914,6 +932,9 @@
|
||||
/* alert message */
|
||||
"Chat preferences were changed." = "Las preferencias del chat han sido modificadas.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Perfil de usuario";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Tema de chat";
|
||||
|
||||
@@ -1011,7 +1032,7 @@
|
||||
"Confirm password" = "Confirmar contraseña";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Confirm that you remember database passphrase to migrate it." = "Para migrar confirma que recuerdas la frase de contraseña de la base de datos.";
|
||||
"Confirm that you remember database passphrase to migrate it." = "Para migrar la base de datos confirma que recuerdas la frase de contraseña.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Confirm upload" = "Confirmar subida";
|
||||
@@ -1286,6 +1307,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Custom time" = "Tiempo personalizado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customizable message shape." = "Forma personalizable de los mensajes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customize theme" = "Personalizar tema";
|
||||
|
||||
@@ -1476,6 +1500,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Delete old database?" = "¿Eliminar base de datos antigua?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete or moderate up to 200 messages." = "Borra o modera hasta 200 mensajes a la vez.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete pending connection?" = "¿Eliminar conexión pendiente?";
|
||||
|
||||
@@ -2224,6 +2251,9 @@
|
||||
/* alert message */
|
||||
"Forward messages without files?" = "¿Reenviar mensajes sin los archivos?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forward up to 20 messages at once." = "Desplazamiento de hasta 20 mensajes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"forwarded" = "reenviado";
|
||||
|
||||
@@ -2464,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Importing archive" = "Importando archivo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Reducción del tráfico y entrega mejorada.\n¡Pronto habrá nuevas mejoras!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved message delivery" = "Entrega de mensajes mejorada";
|
||||
|
||||
@@ -2759,7 +2792,7 @@
|
||||
"Local name" = "Nombre local";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Local profile data only" = "Sólo datos del perfil local";
|
||||
"Local profile data only" = "Eliminar sólo el perfil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Lock after" = "Bloquear en";
|
||||
@@ -3067,6 +3100,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"New passphrase…" = "Contraseña nueva…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used every time you start the app." = "Se usarán credenciales SOCKS nuevas cada vez que inicies la aplicación.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used for each server." = "Se usarán credenciales SOCKS nuevas por cada servidor.";
|
||||
|
||||
/* pref value */
|
||||
"no" = "no";
|
||||
|
||||
@@ -3109,6 +3148,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Sin conexión de red";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record speech" = "Sin permiso para grabación de voz";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record video" = "Sin permiso para grabación de vídeo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record voice message" = "Sin permiso para grabar mensajes de voz";
|
||||
|
||||
@@ -3406,7 +3451,7 @@
|
||||
"Port" = "Puerto";
|
||||
|
||||
/* server test error */
|
||||
"Possibly, certificate fingerprint in server address is incorrect" = "Posiblemente la huella digital del certificado en la dirección del servidor es incorrecta";
|
||||
"Possibly, certificate fingerprint in server address is incorrect" = "Posiblemente la huella del certificado en la dirección del servidor es incorrecta";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Preserve the last message draft, with attachments." = "Conserva el último borrador del mensaje con los datos adjuntos.";
|
||||
@@ -3448,7 +3493,7 @@
|
||||
"Private routing error" = "Error de enrutamiento privado";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Profile and server connections" = "Datos del perfil y conexiones";
|
||||
"Profile and server connections" = "Eliminar perfil y conexiones";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Profile image" = "Imagen del perfil";
|
||||
@@ -3689,7 +3734,7 @@
|
||||
"removed contact address" = "dirección de contacto eliminada";
|
||||
|
||||
/* profile update event chat item */
|
||||
"removed profile picture" = "imagen de perfil eliminada";
|
||||
"removed profile picture" = "ha eliminado la imagen del perfil";
|
||||
|
||||
/* rcv group event chat item */
|
||||
"removed you" = "te ha expulsado";
|
||||
@@ -4061,6 +4106,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Mediante proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server" = "Servidor";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Dirección del servidor";
|
||||
|
||||
@@ -4080,7 +4128,7 @@
|
||||
"Server requires authorization to upload, check password" = "El servidor requiere autorización para subir, comprueba la contraseña";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server test failed!" = "¡Error en prueba del servidor!";
|
||||
"Server test failed!" = "¡Prueba no superada!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server type" = "Tipo de servidor";
|
||||
@@ -4122,7 +4170,7 @@
|
||||
"set new contact address" = "nueva dirección de contacto";
|
||||
|
||||
/* profile update event chat item */
|
||||
"set new profile picture" = "nueva imagen de perfil";
|
||||
"set new profile picture" = "tiene nueva imagen del perfil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Set passcode" = "Código autodestrucción";
|
||||
@@ -4250,6 +4298,9 @@
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "Invitación SimpleX de un uso";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Protocolos de SimpleX auditados por Trail of Bits.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Simplified incognito mode" = "Modo incógnito simplificado";
|
||||
|
||||
@@ -4370,6 +4421,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Support SimpleX Chat" = "Soporte SimpleX Chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch audio and video during the call." = "Intercambia audio y video durante la llamada.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch chat profile for 1-time invitations." = "Cambia el perfil de chat para invitaciones de un solo uso.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"System" = "Sistema";
|
||||
|
||||
@@ -4422,7 +4479,7 @@
|
||||
"Temporary file error" = "Error en archivo temporal";
|
||||
|
||||
/* server test failure */
|
||||
"Test failed at step %@." = "La prueba ha fallado en el paso %@.";
|
||||
"Test failed at step %@." = "Prueba no superada en el paso %@.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Test server" = "Probar servidor";
|
||||
@@ -4431,7 +4488,7 @@
|
||||
"Test servers" = "Probar servidores";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Tests failed!" = "¡Pruebas fallidas!";
|
||||
"Tests failed!" = "¡Pruebas no superadas!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Thank you for installing SimpleX Chat!" = "¡Gracias por instalar SimpleX Chat!";
|
||||
@@ -4589,6 +4646,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Para proteger tu dirección IP, el enrutamiento privado usa tu lista de servidores SMP para enviar mensajes.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record speech please grant permission to use Microphone." = "Para grabación de voz, por favor concede el permiso para usar el micrófono.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record video please grant permission to use Camera." = "Para grabación de vídeo, por favor concede el permiso para usar la cámara.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Para grabar el mensaje de voz concede permiso para usar el micrófono.";
|
||||
|
||||
@@ -4814,9 +4877,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app with one hand." = "Usa la aplicación con una sola mano.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Perfil de usuario";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Selección de usuarios";
|
||||
|
||||
|
||||
@@ -629,6 +629,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Chat-asetukset";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Käyttäjäprofiili";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chats" = "Keskustelut";
|
||||
|
||||
@@ -3187,9 +3190,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use SimpleX Chat servers?" = "Käytä SimpleX Chat palvelimia?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Käyttäjäprofiili";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using SimpleX Chat servers." = "Käyttää SimpleX Chat -palvelimia.";
|
||||
|
||||
|
||||
@@ -890,6 +890,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Préférences de chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Profil d'utilisateur";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Thème de chat";
|
||||
|
||||
@@ -4697,9 +4700,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app with one hand." = "Utiliser l'application d'une main.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Profil d'utilisateur";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Sélection de l'utilisateur";
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
"CFBundleName" = "SimpleX";
|
||||
|
||||
/* Privacy - Camera Usage Description */
|
||||
"NSCameraUsageDescription" = "A SimpleX-nek kamera-hozzáférésre van szüksége a QR-kódok beolvasásához, hogy kapcsolódhasson más felhasználókhoz és videohívásokhoz.";
|
||||
"NSCameraUsageDescription" = "A SimpleXnek kamera-hozzáférésre van szüksége a QR-kódok beolvasásához, hogy kapcsolódhasson más felhasználókhoz és videohívásokhoz.";
|
||||
|
||||
/* Privacy - Face ID Usage Description */
|
||||
"NSFaceIDUsageDescription" = "A SimpleX Face ID-t használ a helyi hitelesítéshez";
|
||||
@@ -11,8 +11,8 @@
|
||||
"NSLocalNetworkUsageDescription" = "A SimpleX helyi hálózati hozzáférést használ, hogy lehetővé tegye a felhasználói csevegőprofil használatát számítógépen keresztül ugyanazon a hálózaton.";
|
||||
|
||||
/* Privacy - Microphone Usage Description */
|
||||
"NSMicrophoneUsageDescription" = "A SimpleX-nek mikrofon-hozzáférésre van szüksége hang- és videohívásokhoz, valamint hangüzenetek rögzítéséhez.";
|
||||
"NSMicrophoneUsageDescription" = "A SimpleXnek mikrofon-hozzáférésre van szüksége hang- és videohívásokhoz, valamint hangüzenetek rögzítéséhez.";
|
||||
|
||||
/* Privacy - Photo Library Additions Usage Description */
|
||||
"NSPhotoLibraryAddUsageDescription" = "A SimpleX-nek hozzáférésre van szüksége a Galériához a rögzített és fogadott média mentéséhez";
|
||||
"NSPhotoLibraryAddUsageDescription" = "A SimpleXnek galéria-hozzáférésre van szüksége a rögzített és fogadott média mentéséhez";
|
||||
|
||||
|
||||
@@ -595,6 +595,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"App passcode is replaced with self-destruct passcode." = "Il codice di accesso dell'app viene sostituito da un codice di autodistruzione.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App session" = "Sessione dell'app";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App version" = "Versione dell'app";
|
||||
|
||||
@@ -691,15 +694,30 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Bad message ID" = "ID del messaggio errato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better calls" = "Chiamate migliorate";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better groups" = "Gruppi migliorati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better message dates." = "Date dei messaggi migliorate.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better messages" = "Messaggi migliorati";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better networking" = "Rete migliorata";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better notifications" = "Notifiche migliorate";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better security ✅" = "Sicurezza migliorata ✅";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better user experience" = "Esperienza utente migliorata";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Black" = "Nero";
|
||||
|
||||
@@ -914,6 +932,9 @@
|
||||
/* alert message */
|
||||
"Chat preferences were changed." = "Le preferenze della chat sono state cambiate.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Profilo utente";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Tema della chat";
|
||||
|
||||
@@ -1286,6 +1307,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Custom time" = "Tempo personalizzato";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customizable message shape." = "Forma dei messaggi personalizzabile.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customize theme" = "Personalizza il tema";
|
||||
|
||||
@@ -1476,6 +1500,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Delete old database?" = "Eliminare il database vecchio?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete or moderate up to 200 messages." = "Elimina o modera fino a 200 messaggi.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete pending connection?" = "Eliminare la connessione in attesa?";
|
||||
|
||||
@@ -2224,6 +2251,9 @@
|
||||
/* alert message */
|
||||
"Forward messages without files?" = "Inoltrare i messaggi senza file?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forward up to 20 messages at once." = "Inoltra fino a 20 messaggi alla volta.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"forwarded" = "inoltrato";
|
||||
|
||||
@@ -2464,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Importing archive" = "Importazione archivio";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Consegna migliorata, utilizzo di traffico ridotto.\nAltri miglioramenti sono in arrivo!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved message delivery" = "Consegna dei messaggi migliorata";
|
||||
|
||||
@@ -3067,6 +3100,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"New passphrase…" = "Nuova password…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used every time you start the app." = "Le nuove credenziali SOCKS verranno usate ogni volta che avvii l'app.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used for each server." = "Le nuove credenziali SOCKS verranno usate per ogni server.";
|
||||
|
||||
/* pref value */
|
||||
"no" = "no";
|
||||
|
||||
@@ -3109,6 +3148,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Nessuna connessione di rete";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record speech" = "Nessuna autorizzazione per registrare l'audio";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record video" = "Nessuna autorizzazione per registrare il video";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record voice message" = "Nessuna autorizzazione per registrare messaggi vocali";
|
||||
|
||||
@@ -4061,6 +4106,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Inviato via proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server" = "Server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Indirizzo server";
|
||||
|
||||
@@ -4250,6 +4298,9 @@
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "Invito SimpleX una tantum";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Protocolli di SimpleX esaminati da Trail of Bits.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Simplified incognito mode" = "Modalità incognito semplificata";
|
||||
|
||||
@@ -4370,6 +4421,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Support SimpleX Chat" = "Supporta SimpleX Chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch audio and video during the call." = "Cambia tra audio e video durante la chiamata.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch chat profile for 1-time invitations." = "Cambia profilo di chat per inviti una tantum.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"System" = "Sistema";
|
||||
|
||||
@@ -4589,6 +4646,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Per proteggere il tuo indirizzo IP, l'instradamento privato usa i tuoi server SMP per consegnare i messaggi.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record speech please grant permission to use Microphone." = "Per registrare l'audio, concedi l'autorizzazione di usare il microfono.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record video please grant permission to use Camera." = "Per registrare il video, concedi l'autorizzazione di usare la fotocamera.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Per registrare un messaggio vocale, concedi l'autorizzazione all'uso del microfono.";
|
||||
|
||||
@@ -4814,9 +4877,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app with one hand." = "Usa l'app con una mano sola.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Profilo utente";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Selezione utente";
|
||||
|
||||
|
||||
@@ -701,6 +701,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "チャット設定";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "ユーザープロフィール";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chats" = "チャット";
|
||||
|
||||
@@ -2064,6 +2067,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Messages & files" = "メッセージ & ファイル";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." = "メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**エンドツーエンドの暗号化**によって保護されます。";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages, files and calls are protected by **quantum resistant e2e encryption** with perfect forward secrecy, repudiation and break-in recovery." = "メッセージ、ファイル、通話は、前方秘匿性、否認可能性および侵入復元性を備えた**耐量子E2E暗号化**によって保護されます。";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Migrating database archive…" = "データベースのアーカイブを移行しています…";
|
||||
|
||||
@@ -3241,9 +3250,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use SimpleX Chat servers?" = "SimpleX チャット サーバーを使用しますか?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "ユーザープロフィール";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using SimpleX Chat servers." = "SimpleX チャット サーバーを使用する。";
|
||||
|
||||
|
||||
@@ -595,6 +595,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"App passcode is replaced with self-destruct passcode." = "De app-toegangscode wordt vervangen door een zelfvernietigings wachtwoord.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App session" = "Appsessie";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App version" = "App versie";
|
||||
|
||||
@@ -691,15 +694,30 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Bad message ID" = "Onjuiste bericht-ID";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better calls" = "Betere gesprekken";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better groups" = "Betere groepen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better message dates." = "Betere datums voor berichten.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better messages" = "Betere berichten";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better networking" = "Beter netwerk";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better notifications" = "Betere meldingen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better security ✅" = "Betere beveiliging ✅";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better user experience" = "Betere gebruikerservaring";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Black" = "Zwart";
|
||||
|
||||
@@ -914,6 +932,9 @@
|
||||
/* alert message */
|
||||
"Chat preferences were changed." = "Chatvoorkeuren zijn gewijzigd.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Gebruikers profiel";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Chat thema";
|
||||
|
||||
@@ -1286,6 +1307,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Custom time" = "Aangepaste tijd";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customizable message shape." = "Aanpasbare berichtvorm.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customize theme" = "Thema aanpassen";
|
||||
|
||||
@@ -1476,6 +1500,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Delete old database?" = "Oude database verwijderen?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete or moderate up to 200 messages." = "Maximaal 200 berichten verwijderen of modereren.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete pending connection?" = "Wachtende verbinding verwijderen?";
|
||||
|
||||
@@ -2224,6 +2251,9 @@
|
||||
/* alert message */
|
||||
"Forward messages without files?" = "Berichten doorsturen zonder bestanden?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forward up to 20 messages at once." = "Stuur maximaal 20 berichten tegelijk door.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"forwarded" = "doorgestuurd";
|
||||
|
||||
@@ -2464,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Importing archive" = "Archief importeren";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Verbeterde levering, minder data gebruik.\nBinnenkort meer verbeteringen!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved message delivery" = "Verbeterde berichtbezorging";
|
||||
|
||||
@@ -3067,6 +3100,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"New passphrase…" = "Nieuw wachtwoord…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used every time you start the app." = "Elke keer dat u de app start, worden er nieuwe SOCKS-inloggegevens gebruikt.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used for each server." = "Voor elke server worden nieuwe SOCKS-inloggegevens gebruikt.";
|
||||
|
||||
/* pref value */
|
||||
"no" = "Nee";
|
||||
|
||||
@@ -3109,6 +3148,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Geen netwerkverbinding";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record speech" = "Geen toestemming om spraak op te nemen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record video" = "Geen toestemming om video op te nemen";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record voice message" = "Geen toestemming om spraakbericht op te nemen";
|
||||
|
||||
@@ -4061,6 +4106,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Verzonden via proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server" = "Server";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Server adres";
|
||||
|
||||
@@ -4250,6 +4298,9 @@
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "Eenmalige SimpleX uitnodiging";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "SimpleX-protocollen beoordeeld door Trail of Bits.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Simplified incognito mode" = "Vereenvoudigde incognitomodus";
|
||||
|
||||
@@ -4370,12 +4421,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Support SimpleX Chat" = "Ondersteuning van SimpleX Chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch audio and video during the call." = "Wisselen tussen audio en video tijdens het gesprek.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch chat profile for 1-time invitations." = "Wijzig chatprofiel voor eenmalige uitnodigingen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"System" = "Systeem";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"System authentication" = "Systeem authenticatie";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Tail" = "Staart";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Take picture" = "Foto nemen";
|
||||
|
||||
@@ -4586,6 +4646,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Om uw IP-adres te beschermen, gebruikt privéroutering uw SMP-servers om berichten te bezorgen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record speech please grant permission to use Microphone." = "Geef toestemming om de microfoon te gebruiken om spraak op te nemen.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record video please grant permission to use Camera." = "Om video op te nemen, dient u toestemming te geven om de camera te gebruiken.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Geef toestemming om de microfoon te gebruiken om een spraakbericht op te nemen.";
|
||||
|
||||
@@ -4811,9 +4877,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app with one hand." = "Gebruik de app met één hand.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Gebruikers profiel";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Gebruikersselectie";
|
||||
|
||||
@@ -5070,7 +5133,7 @@
|
||||
"You are not connected to these servers. Private routing is used to deliver messages to them." = "U bent niet verbonden met deze servers. Privéroutering wordt gebruikt om berichten bij hen af te leveren.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"you are observer" = "jij bent waarnemer";
|
||||
"you are observer" = "je bent waarnemer";
|
||||
|
||||
/* snd group event chat item */
|
||||
"you blocked %@" = "je hebt %@ geblokkeerd";
|
||||
@@ -5172,7 +5235,7 @@
|
||||
"You joined this group. Connecting to inviting group member." = "Je bent lid geworden van deze groep. Verbinding maken met uitnodigend groepslid.";
|
||||
|
||||
/* snd group event chat item */
|
||||
"you left" = "jij bent vertrokken";
|
||||
"you left" = "je bent vertrokken";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"You may migrate the exported database." = "U kunt de geëxporteerde database migreren.";
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
/* notification title */
|
||||
"%@ wants to connect!" = "%@ chce się połączyć!";
|
||||
|
||||
/* format for date separator in chat */
|
||||
"%@, %@" = "%1$@, %2$@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@, %@ and %lld members" = "%@, %@ i %lld członków";
|
||||
|
||||
@@ -172,9 +175,24 @@
|
||||
/* time interval */
|
||||
"%d days" = "%d dni";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) are still being downloaded." = "%d plik(ów) jest dalej pobieranych.";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) failed to download." = "%d plik(ów) nie udało się pobrać.";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) were deleted." = "%d plik(ów) zostało usuniętych.";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) were not downloaded." = "%d plik(ów) nie zostało pobranych.";
|
||||
|
||||
/* time interval */
|
||||
"%d hours" = "%d godzin";
|
||||
|
||||
/* alert title */
|
||||
"%d messages not forwarded" = "%d wiadomości nie przekazanych";
|
||||
|
||||
/* time interval */
|
||||
"%d min" = "%d min";
|
||||
|
||||
@@ -577,6 +595,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"App passcode is replaced with self-destruct passcode." = "Pin aplikacji został zastąpiony pinem samozniszczenia.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App session" = "Sesja aplikacji";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App version" = "Wersja aplikacji";
|
||||
|
||||
@@ -649,6 +670,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Auto-accept images" = "Automatyczne akceptowanie obrazów";
|
||||
|
||||
/* alert title */
|
||||
"Auto-accept settings" = "Ustawienia automatycznej akceptacji";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Back" = "Wstecz";
|
||||
|
||||
@@ -890,6 +914,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Preferencje czatu";
|
||||
|
||||
/* alert message */
|
||||
"Chat preferences were changed." = "Preferencje czatu zostały zmienione.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Profil użytkownika";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Motyw czatu";
|
||||
|
||||
@@ -1178,6 +1208,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Core version: v%@" = "Wersja rdzenia: v%@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Corner" = "Róg";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Correct name to %@?" = "Poprawić imię na %@?";
|
||||
|
||||
@@ -1611,6 +1644,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Do NOT send messages directly, even if your or destination server does not support private routing." = "NIE wysyłaj wiadomości bezpośrednio, nawet jeśli serwer docelowy nie obsługuje prywatnego trasowania.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do not use credentials with proxy." = "Nie używaj danych logowania do proxy.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do NOT use private routing." = "NIE używaj prywatnego trasowania.";
|
||||
|
||||
@@ -1642,6 +1678,9 @@
|
||||
/* server test step */
|
||||
"Download file" = "Pobierz plik";
|
||||
|
||||
/* alert action */
|
||||
"Download files" = "Pobierz pliki";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloaded" = "Pobrane";
|
||||
|
||||
@@ -1858,12 +1897,18 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing address" = "Błąd zmiany adresu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing connection profile" = "Błąd zmiany połączenia profilu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing role" = "Błąd zmiany roli";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing setting" = "Błąd zmiany ustawienia";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing to incognito!" = "Błąd zmiany na incognito!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error connecting to forwarding server %@. Please try later." = "Błąd połączenia z serwerem przekierowania %@. Spróbuj ponownie później.";
|
||||
|
||||
@@ -1936,6 +1981,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error loading %@ servers" = "Błąd ładowania %@ serwerów";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error migrating settings" = "Błąd migracji ustawień";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error opening chat" = "Błąd otwierania czatu";
|
||||
|
||||
@@ -1996,6 +2044,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error stopping chat" = "Błąd zatrzymania czatu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error switching profile" = "Błąd zmiany profilu";
|
||||
|
||||
/* alertTitle */
|
||||
"Error switching profile!" = "Błąd przełączania profilu!";
|
||||
|
||||
@@ -2083,6 +2134,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"File error" = "Błąd pliku";
|
||||
|
||||
/* alert message */
|
||||
"File errors:\n%@" = "Błędy pliku:\n%@";
|
||||
|
||||
/* file error text */
|
||||
"File not found - most likely file was deleted or cancelled." = "Nie odnaleziono pliku - najprawdopodobniej plik został usunięty lub anulowany.";
|
||||
|
||||
@@ -2164,9 +2218,18 @@
|
||||
/* chat item action */
|
||||
"Forward" = "Przekaż dalej";
|
||||
|
||||
/* alert title */
|
||||
"Forward %d message(s)?" = "Przekazać %d wiadomość(i)?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forward and save messages" = "Przesyłaj dalej i zapisuj wiadomości";
|
||||
|
||||
/* alert action */
|
||||
"Forward messages" = "Przekaż wiadomości";
|
||||
|
||||
/* alert message */
|
||||
"Forward messages without files?" = "Przekazać wiadomości bez plików?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"forwarded" = "przekazane dalej";
|
||||
|
||||
@@ -2176,6 +2239,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Forwarded from" = "Przekazane dalej od";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forwarding %lld messages" = "Przekazywanie %lld wiadomości";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forwarding server %@ failed to connect to destination server %@. Please try later." = "Serwer przekazujący %@ nie mógł połączyć się z serwerem docelowym %@. Spróbuj ponownie później.";
|
||||
|
||||
@@ -2563,6 +2629,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications." = "iOS Keychain będzie używany do bezpiecznego przechowywania hasła po ponownym uruchomieniu aplikacji lub zmianie hasła - pozwoli to na otrzymywanie powiadomień push.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"IP address" = "Adres IP";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Irreversible message deletion" = "Nieodwracalne usuwanie wiadomości";
|
||||
|
||||
@@ -2815,6 +2884,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message servers" = "Serwery wiadomości";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message shape" = "Kształt wiadomości";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message source remains private." = "Źródło wiadomości pozostaje prywatne.";
|
||||
|
||||
@@ -2845,6 +2917,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Messages sent" = "Wysłane wiadomości";
|
||||
|
||||
/* alert message */
|
||||
"Messages were deleted after you selected them." = "Wiadomości zostały usunięte po wybraniu ich.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." = "Wiadomości, pliki i połączenia są chronione przez **szyfrowanie end-to-end** z doskonałym utajnianiem z wyprzedzeniem i odzyskiem po złamaniu.";
|
||||
|
||||
@@ -2998,6 +3073,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"New passphrase…" = "Nowe hasło…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used every time you start the app." = "Nowe poświadczenia SOCKS będą używane przy każdym uruchomieniu aplikacji.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used for each server." = "Dla każdego serwera zostaną użyte nowe poświadczenia SOCKS.";
|
||||
|
||||
/* pref value */
|
||||
"no" = "nie";
|
||||
|
||||
@@ -3040,6 +3121,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Brak połączenia z siecią";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record speech" = "Brak zezwoleń do nagrania rozmowy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record video" = "Brak zezwoleń do nagrania wideo";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record voice message" = "Brak uprawnień do nagrywania wiadomości głosowej";
|
||||
|
||||
@@ -3055,6 +3142,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Nothing selected" = "Nic nie jest zaznaczone";
|
||||
|
||||
/* alert title */
|
||||
"Nothing to forward!" = "Nic do przekazania!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Notifications" = "Powiadomienia";
|
||||
|
||||
@@ -3207,6 +3297,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"other errors" = "inne błędy";
|
||||
|
||||
/* alert message */
|
||||
"Other file errors:\n%@" = "Inne błędy pliku:\n%@";
|
||||
|
||||
/* member role */
|
||||
"owner" = "właściciel";
|
||||
|
||||
@@ -3228,6 +3321,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Passcode set!" = "Pin ustawiony!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Password" = "Hasło";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Password to show" = "Hasło do wyświetlenia";
|
||||
|
||||
@@ -3324,6 +3420,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Polish interface" = "Polski interfejs";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Port" = "Port";
|
||||
|
||||
/* server test error */
|
||||
"Possibly, certificate fingerprint in server address is incorrect" = "Możliwe, że odcisk palca certyfikatu w adresie serwera jest nieprawidłowy";
|
||||
|
||||
@@ -3435,6 +3534,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Proxied servers" = "Serwery trasowane przez proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Proxy requires password" = "Proxy wymaga hasła";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Powiadomienia push";
|
||||
|
||||
@@ -3580,6 +3682,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Remove" = "Usuń";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove archive?" = "Usunąć archiwum?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove image" = "Usuń obraz";
|
||||
|
||||
@@ -3752,6 +3857,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Save welcome message?" = "Zapisać wiadomość powitalną?";
|
||||
|
||||
/* alert title */
|
||||
"Save your profile?" = "Zapisać Twój profil?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"saved" = "zapisane";
|
||||
|
||||
@@ -3770,6 +3878,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Saved WebRTC ICE servers will be removed" = "Zapisane serwery WebRTC ICE zostaną usunięte";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Saving %lld messages" = "Zapisywanie %lld wiadomości";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scale" = "Skaluj";
|
||||
|
||||
@@ -3833,6 +3944,9 @@
|
||||
/* chat item action */
|
||||
"Select" = "Wybierz";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Select chat profile" = "Wybierz profil czatu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Selected %lld" = "Zaznaczono %lld";
|
||||
|
||||
@@ -3965,6 +4079,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Wysłano przez proxy";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server" = "Serwer";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Adres serwera";
|
||||
|
||||
@@ -4046,6 +4163,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Settings" = "Ustawienia";
|
||||
|
||||
/* alert message */
|
||||
"Settings were changed." = "Ustawienia zostały zmienione.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Shape profile images" = "Kształtuj obrazy profilowe";
|
||||
|
||||
@@ -4067,6 +4187,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Share link" = "Udostępnij link";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share profile" = "Udostępnij profil";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share this 1-time invite link" = "Udostępnij ten jednorazowy link";
|
||||
|
||||
@@ -4166,9 +4289,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"SMP server" = "Serwer SMP";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SOCKS proxy" = "Proxy SOCKS";
|
||||
|
||||
/* blur media */
|
||||
"Soft" = "Łagodny";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Some app settings were not migrated." = "Niektóre ustawienia aplikacji nie zostały zmigrowane.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Some file(s) were not exported:" = "Niektóre plik(i) nie zostały wyeksportowane:";
|
||||
|
||||
@@ -4268,6 +4397,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"System authentication" = "Uwierzytelnianie systemu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Tail" = "Ogon";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Take picture" = "Zrób zdjęcie";
|
||||
|
||||
@@ -4397,6 +4529,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Tekst, który wkleiłeś nie jest linkiem SimpleX.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The uploaded database archive will be permanently removed from the servers." = "Przesłane archiwum bazy danych zostanie trwale usunięte z serwerów.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Themes" = "Motywy";
|
||||
|
||||
@@ -4475,6 +4610,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Aby chronić Twój adres IP, prywatne trasowanie używa Twoich serwerów SMP, aby dostarczyć wiadomości.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record speech please grant permission to use Microphone." = "Aby nagrać rozmowę, proszę zezwolić na użycie Mikrofonu.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record video please grant permission to use Camera." = "Aby nagrać wideo, proszę zezwolić na użycie Aparatu.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Aby nagrać wiadomość głosową należy udzielić zgody na użycie Mikrofonu.";
|
||||
|
||||
@@ -4691,6 +4832,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use SimpleX Chat servers?" = "Użyć serwerów SimpleX Chat?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Use SOCKS proxy" = "Użyj proxy SOCKS";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app while in the call." = "Używaj aplikacji podczas połączenia.";
|
||||
|
||||
@@ -4698,10 +4842,10 @@
|
||||
"Use the app with one hand." = "Korzystaj z aplikacji jedną ręką.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Profil użytkownika";
|
||||
"User selection" = "Wybór użytkownika";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Wybór użytkownika";
|
||||
"Username" = "Nazwa użytkownika";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using SimpleX Chat servers." = "Używanie serwerów SimpleX Chat.";
|
||||
@@ -5138,9 +5282,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Your chat database is not encrypted - set passphrase to encrypt it." = "Baza danych czatu nie jest szyfrowana - ustaw hasło, aby ją zaszyfrować.";
|
||||
|
||||
/* alert title */
|
||||
"Your chat preferences" = "Twoje preferencje czatu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your chat profiles" = "Twoje profile czatu";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." = "Twoje połączenie zostało przeniesione do %@, ale podczas przekierowywania do profilu wystąpił nieoczekiwany błąd.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Twój kontakt wysłał plik, który jest większy niż obecnie obsługiwany maksymalny rozmiar (%@).";
|
||||
|
||||
@@ -5150,6 +5300,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Your contacts will remain connected." = "Twoje kontakty pozostaną połączone.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your credentials may be sent unencrypted." = "Twoje poświadczenia mogą zostać wysłane niezaszyfrowane.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your current chat database will be DELETED and REPLACED with the imported one." = "Twoja obecna baza danych czatu zostanie usunięta i zastąpiona zaimportowaną.";
|
||||
|
||||
@@ -5174,6 +5327,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." = "Twój profil jest przechowywany na urządzeniu i udostępniany tylko Twoim kontaktom. Serwery SimpleX nie mogą zobaczyć Twojego profilu.";
|
||||
|
||||
/* alert message */
|
||||
"Your profile was changed. If you save it, the updated profile will be sent to all your contacts." = "Twój profil został zmieniony. Jeśli go zapiszesz, zaktualizowany profil zostanie wysłany do wszystkich kontaktów.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your profile, contacts and delivered messages are stored on your device." = "Twój profil, kontakty i dostarczone wiadomości są przechowywane na Twoim urządzeniu.";
|
||||
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
/* notification title */
|
||||
"%@ wants to connect!" = "%@ хочет соединиться!";
|
||||
|
||||
/* format for date separator in chat */
|
||||
"%@, %@" = "%1$@, %2$@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"%@, %@ and %lld members" = "%@, %@ и %lld членов группы";
|
||||
|
||||
@@ -172,9 +175,24 @@
|
||||
/* time interval */
|
||||
"%d days" = "%d дней";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) are still being downloaded." = "%d файл(ов) загружаются.";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) failed to download." = "%d файл(ов) не удалось загрузить.";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) were deleted." = "%d файлов было удалено.";
|
||||
|
||||
/* forward confirmation reason */
|
||||
"%d file(s) were not downloaded." = "%d файлов не было загружено.";
|
||||
|
||||
/* time interval */
|
||||
"%d hours" = "%d ч.";
|
||||
|
||||
/* alert title */
|
||||
"%d messages not forwarded" = "%d сообщений не переслано";
|
||||
|
||||
/* time interval */
|
||||
"%d min" = "%d мин";
|
||||
|
||||
@@ -577,6 +595,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"App passcode is replaced with self-destruct passcode." = "Код доступа в приложение будет заменен кодом самоуничтожения.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App session" = "Сессия приложения";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"App version" = "Версия приложения";
|
||||
|
||||
@@ -649,6 +670,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Auto-accept images" = "Автоприем изображений";
|
||||
|
||||
/* alert title */
|
||||
"Auto-accept settings" = "Настройки автоприема";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Back" = "Назад";
|
||||
|
||||
@@ -670,15 +694,30 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Bad message ID" = "Ошибка ID сообщения";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better calls" = "Улучшенные звонки";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better groups" = "Улучшенные группы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better message dates." = "Улучшенные даты сообщений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better messages" = "Улучшенные сообщения";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better networking" = "Улучшенные сетевые функции";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better notifications" = "Улучшенные уведомления";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better security ✅" = "Улучшенная безопасность ✅";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Better user experience" = "Улучшенный интерфейс";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Black" = "Черная";
|
||||
|
||||
@@ -890,6 +929,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Предпочтения";
|
||||
|
||||
/* alert message */
|
||||
"Chat preferences were changed." = "Настройки чата были изменены.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Профиль чата";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Тема чата";
|
||||
|
||||
@@ -1178,6 +1223,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Core version: v%@" = "Версия ядра: v%@";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Corner" = "Угол";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Correct name to %@?" = "Исправить имя на %@?";
|
||||
|
||||
@@ -1259,6 +1307,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Custom time" = "Пользовательское время";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customizable message shape." = "Настраиваемая форма сообщений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Customize theme" = "Настроить тему";
|
||||
|
||||
@@ -1449,6 +1500,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Delete old database?" = "Удалить предыдущую версию данных?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete or moderate up to 200 messages." = "Удаляйте или модерируйте до 200 сообщений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Delete pending connection?" = "Удалить ожидаемое соединение?";
|
||||
|
||||
@@ -1611,6 +1665,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Do NOT send messages directly, even if your or destination server does not support private routing." = "Не отправлять сообщения напрямую, даже если сервер получателя не поддерживает конфиденциальную доставку.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do not use credentials with proxy." = "Не использовать учетные данные с прокси.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do NOT use private routing." = "Не использовать конфиденциальную доставку.";
|
||||
|
||||
@@ -1642,6 +1699,9 @@
|
||||
/* server test step */
|
||||
"Download file" = "Загрузка файла";
|
||||
|
||||
/* alert action */
|
||||
"Download files" = "Загрузить файлы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Downloaded" = "Принято";
|
||||
|
||||
@@ -1858,12 +1918,18 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing address" = "Ошибка при изменении адреса";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing connection profile" = "Ошибка при изменении профиля соединения";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing role" = "Ошибка при изменении роли";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing setting" = "Ошибка при изменении настройки";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error changing to incognito!" = "Ошибка при смене на Инкогнито!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error connecting to forwarding server %@. Please try later." = "Ошибка подключения к пересылающему серверу %@. Попробуйте позже.";
|
||||
|
||||
@@ -1936,6 +2002,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error loading %@ servers" = "Ошибка загрузки %@ серверов";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error migrating settings" = "Ошибка миграции настроек";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error opening chat" = "Ошибка доступа к чату";
|
||||
|
||||
@@ -1996,6 +2065,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Error stopping chat" = "Ошибка при остановке чата";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Error switching profile" = "Ошибка переключения профиля";
|
||||
|
||||
/* alertTitle */
|
||||
"Error switching profile!" = "Ошибка выбора профиля!";
|
||||
|
||||
@@ -2083,6 +2155,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"File error" = "Ошибка файла";
|
||||
|
||||
/* alert message */
|
||||
"File errors:\n%@" = "Ошибки файлов:\n%@";
|
||||
|
||||
/* file error text */
|
||||
"File not found - most likely file was deleted or cancelled." = "Файл не найден - скорее всего, файл был удален или отменен.";
|
||||
|
||||
@@ -2164,9 +2239,21 @@
|
||||
/* chat item action */
|
||||
"Forward" = "Переслать";
|
||||
|
||||
/* alert title */
|
||||
"Forward %d message(s)?" = "Переслать %d сообщение(й)?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forward and save messages" = "Переслать и сохранить сообщение";
|
||||
|
||||
/* alert action */
|
||||
"Forward messages" = "Переслать сообщения";
|
||||
|
||||
/* alert message */
|
||||
"Forward messages without files?" = "Переслать сообщения без файлов?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forward up to 20 messages at once." = "Пересылайте до 20 сообщений за раз.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"forwarded" = "переслано";
|
||||
|
||||
@@ -2176,6 +2263,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Forwarded from" = "Переслано из";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forwarding %lld messages" = "Пересылка %lld сообщений";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Forwarding server %@ failed to connect to destination server %@. Please try later." = "Пересылающий сервер %@ не смог подключиться к серверу назначения %@. Попробуйте позже.";
|
||||
|
||||
@@ -2404,6 +2494,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Importing archive" = "Импорт архива";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved delivery, reduced traffic usage.\nMore improvements are coming soon!" = "Улучшенная доставка, меньше трафик.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Improved message delivery" = "Улучшенная доставка сообщений";
|
||||
|
||||
@@ -2563,6 +2656,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications." = "Пароль базы данных будет безопасно сохранен в iOS Keychain после запуска чата или изменения пароля - это позволит получать мгновенные уведомления.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"IP address" = "IP адрес";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Irreversible message deletion" = "Окончательное удаление сообщений";
|
||||
|
||||
@@ -2815,6 +2911,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Message servers" = "Серверы сообщений";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message shape" = "Форма сообщений";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Message source remains private." = "Источник сообщения остаётся конфиденциальным.";
|
||||
|
||||
@@ -2845,6 +2944,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Messages sent" = "Сообщений отправлено";
|
||||
|
||||
/* alert message */
|
||||
"Messages were deleted after you selected them." = "Сообщения были удалены после того, как вы их выбрали.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery." = "Сообщения, файлы и звонки защищены **end-to-end шифрованием** с прямой секретностью (PFS), правдоподобным отрицанием и восстановлением от взлома.";
|
||||
|
||||
@@ -2998,6 +3100,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"New passphrase…" = "Новый пароль…";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used every time you start the app." = "Новые учетные данные SOCKS будут использоваться при каждом запуске приложения.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"New SOCKS credentials will be used for each server." = "Новые учетные данные SOCKS будут использоваться для каждого сервера.";
|
||||
|
||||
/* pref value */
|
||||
"no" = "нет";
|
||||
|
||||
@@ -3040,6 +3148,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"No network connection" = "Нет интернет-соединения";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record speech" = "Нет разрешения на запись речи";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record video" = "Нет разрешения на запись видео";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"No permission to record voice message" = "Нет разрешения для записи голосового сообщения";
|
||||
|
||||
@@ -3055,6 +3169,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Nothing selected" = "Ничего не выбрано";
|
||||
|
||||
/* alert title */
|
||||
"Nothing to forward!" = "Нет сообщений, которые можно переслать!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Notifications" = "Уведомления";
|
||||
|
||||
@@ -3207,6 +3324,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"other errors" = "другие ошибки";
|
||||
|
||||
/* alert message */
|
||||
"Other file errors:\n%@" = "Другие ошибки файлов:\n%@";
|
||||
|
||||
/* member role */
|
||||
"owner" = "владелец";
|
||||
|
||||
@@ -3228,6 +3348,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Passcode set!" = "Код доступа установлен!";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Password" = "Пароль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Password to show" = "Пароль чтобы раскрыть";
|
||||
|
||||
@@ -3324,6 +3447,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Polish interface" = "Польский интерфейс";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Port" = "Порт";
|
||||
|
||||
/* server test error */
|
||||
"Possibly, certificate fingerprint in server address is incorrect" = "Возможно, хэш сертификата в адресе сервера неверный";
|
||||
|
||||
@@ -3435,6 +3561,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Proxied servers" = "Проксированные серверы";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Proxy requires password" = "Прокси требует пароль";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Push notifications" = "Доставка уведомлений";
|
||||
|
||||
@@ -3580,6 +3709,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Remove" = "Удалить";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove archive?" = "Удалить архив?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Remove image" = "Удалить изображение";
|
||||
|
||||
@@ -3752,6 +3884,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Save welcome message?" = "Сохранить приветственное сообщение?";
|
||||
|
||||
/* alert title */
|
||||
"Save your profile?" = "Сохранить ваш профиль?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"saved" = "сохранено";
|
||||
|
||||
@@ -3770,6 +3905,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Saved WebRTC ICE servers will be removed" = "Сохраненные WebRTC ICE серверы будут удалены";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Saving %lld messages" = "Сохранение %lld сообщений";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Scale" = "Масштаб";
|
||||
|
||||
@@ -3833,6 +3971,9 @@
|
||||
/* chat item action */
|
||||
"Select" = "Выбрать";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Select chat profile" = "Выберите профиль чата";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Selected %lld" = "Выбрано %lld";
|
||||
|
||||
@@ -3965,6 +4106,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Sent via proxy" = "Отправлено через прокси";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server" = "Сервер";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Server address" = "Адрес сервера";
|
||||
|
||||
@@ -4046,6 +4190,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Settings" = "Настройки";
|
||||
|
||||
/* alert message */
|
||||
"Settings were changed." = "Настройки были изменены.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Shape profile images" = "Форма картинок профилей";
|
||||
|
||||
@@ -4067,6 +4214,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Share link" = "Поделиться ссылкой";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share profile" = "Поделиться профилем";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Share this 1-time invite link" = "Поделиться одноразовой ссылкой-приглашением";
|
||||
|
||||
@@ -4148,6 +4298,9 @@
|
||||
/* simplex link type */
|
||||
"SimpleX one-time invitation" = "SimpleX одноразовая ссылка";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SimpleX protocols reviewed by Trail of Bits." = "Аудит SimpleX протоколов от Trail of Bits.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Simplified incognito mode" = "Упрощенный режим Инкогнито";
|
||||
|
||||
@@ -4166,9 +4319,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"SMP server" = "SMP сервер";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"SOCKS proxy" = "SOCKS прокси";
|
||||
|
||||
/* blur media */
|
||||
"Soft" = "Слабое";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Some app settings were not migrated." = "Некоторые настройки приложения не были перенесены.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Some file(s) were not exported:" = "Некоторые файл(ы) не были экспортированы:";
|
||||
|
||||
@@ -4262,12 +4421,21 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Support SimpleX Chat" = "Поддержать SimpleX Chat";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch audio and video during the call." = "Переключайте звук и видео во время звонка.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Switch chat profile for 1-time invitations." = "Переключайте профиль чата для одноразовых приглашений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"System" = "Системная";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"System authentication" = "Системная аутентификация";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Tail" = "Хвост";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Take picture" = "Сделать фото";
|
||||
|
||||
@@ -4397,6 +4565,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"The text you pasted is not a SimpleX link." = "Вставленный текст не является SimpleX-ссылкой.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"The uploaded database archive will be permanently removed from the servers." = "Загруженный архив базы данных будет навсегда удален с серверов.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Themes" = "Темы";
|
||||
|
||||
@@ -4475,6 +4646,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"To protect your IP address, private routing uses your SMP servers to deliver messages." = "Чтобы защитить ваш IP адрес, приложение использует Ваши SMP серверы для конфиденциальной доставки сообщений.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record speech please grant permission to use Microphone." = "Для записи речи, пожалуйста, дайте разрешение на использование микрофона.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record video please grant permission to use Camera." = "Для записи видео, пожалуйста, дайте разрешение на использование камеры.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"To record voice message please grant permission to use Microphone." = "Для записи голосового сообщения, пожалуйста разрешите доступ к микрофону.";
|
||||
|
||||
@@ -4691,6 +4868,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use SimpleX Chat servers?" = "Использовать серверы предосталенные SimpleX Chat?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Use SOCKS proxy" = "Использовать SOCKS прокси";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app while in the call." = "Используйте приложение во время звонка.";
|
||||
|
||||
@@ -4698,10 +4878,10 @@
|
||||
"Use the app with one hand." = "Используйте приложение одной рукой.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Профиль чата";
|
||||
"User selection" = "Выбор пользователя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Выбор пользователя";
|
||||
"Username" = "Имя пользователя";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using SimpleX Chat servers." = "Используются серверы, предоставленные SimpleX Chat.";
|
||||
@@ -5138,9 +5318,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Your chat database is not encrypted - set passphrase to encrypt it." = "База данных НЕ зашифрована. Установите пароль, чтобы защитить Ваши данные.";
|
||||
|
||||
/* alert title */
|
||||
"Your chat preferences" = "Ваши настройки чата";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your chat profiles" = "Ваши профили чата";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your connection was moved to %@ but an unexpected error occurred while redirecting you to the profile." = "Соединение было перемещено на %@, но при смене профиля произошла неожиданная ошибка.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your contact sent a file that is larger than currently supported maximum size (%@)." = "Ваш контакт отправил файл, размер которого превышает максимальный размер (%@).";
|
||||
|
||||
@@ -5150,6 +5336,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Your contacts will remain connected." = "Ваши контакты сохранятся.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your credentials may be sent unencrypted." = "Ваши учетные данные могут быть отправлены в незашифрованном виде.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your current chat database will be DELETED and REPLACED with the imported one." = "Текущие данные Вашего чата будет УДАЛЕНЫ и ЗАМЕНЕНЫ импортированными.";
|
||||
|
||||
@@ -5174,6 +5363,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Your profile is stored on your device and shared only with your contacts. SimpleX servers cannot see your profile." = "Ваш профиль хранится на Вашем устройстве и отправляется только Вашим контактам. SimpleX серверы не могут получить доступ к Вашему профилю.";
|
||||
|
||||
/* alert message */
|
||||
"Your profile was changed. If you save it, the updated profile will be sent to all your contacts." = "Ваш профиль был изменен. Если вы сохраните его, обновленный профиль будет отправлен всем вашим контактам.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Your profile, contacts and delivered messages are stored on your device." = "Ваш профиль, контакты и доставленные сообщения хранятся на Вашем устройстве.";
|
||||
|
||||
|
||||
@@ -605,6 +605,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "ค่ากําหนดในการแชท";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "โปรไฟล์ผู้ใช้";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chats" = "แชท";
|
||||
|
||||
@@ -3094,9 +3097,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use SimpleX Chat servers?" = "ใช้เซิร์ฟเวอร์ SimpleX Chat ไหม?";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "โปรไฟล์ผู้ใช้";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Using SimpleX Chat servers." = "กำลังใช้เซิร์ฟเวอร์ SimpleX Chat อยู่";
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -890,6 +890,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "Налаштування чату";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "Профіль користувача";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "Тема чату";
|
||||
|
||||
@@ -4697,9 +4700,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app with one hand." = "Використовуйте додаток однією рукою.";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "Профіль користувача";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "Вибір користувача";
|
||||
|
||||
|
||||
@@ -890,6 +890,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Chat preferences" = "聊天偏好设置";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat profile" = "用户资料";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Chat theme" = "聊天主题";
|
||||
|
||||
@@ -4697,9 +4700,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Use the app with one hand." = "用一只手使用应用程序。";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User profile" = "用户资料";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"User selection" = "用户选择";
|
||||
|
||||
|
||||
+7
-3
@@ -24,8 +24,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.platform.*
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -37,7 +36,9 @@ import chat.simplex.app.R
|
||||
import chat.simplex.app.TAG
|
||||
import chat.simplex.app.model.NtfManager
|
||||
import chat.simplex.app.model.NtfManager.AcceptCallAction
|
||||
import chat.simplex.common.helpers.applyAppLocale
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.platform.chatModel
|
||||
import chat.simplex.common.ui.theme.*
|
||||
@@ -49,6 +50,7 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.datetime.Clock
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
import chat.simplex.common.platform.chatModel as m
|
||||
|
||||
class CallActivity: ComponentActivity(), ServiceConnection {
|
||||
@@ -56,6 +58,7 @@ class CallActivity: ComponentActivity(), ServiceConnection {
|
||||
var boundService: CallService? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
applyAppLocale(appPrefs.appLanguage)
|
||||
super.onCreate(savedInstanceState)
|
||||
callActivity = WeakReference(this)
|
||||
when (intent?.action) {
|
||||
@@ -80,6 +83,7 @@ class CallActivity: ComponentActivity(), ServiceConnection {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
(mainActivity.get() ?: this).applyAppLocale(appPrefs.appLanguage)
|
||||
if (isOnLockScreenNow()) {
|
||||
lockAfterIncomingCall()
|
||||
}
|
||||
@@ -233,7 +237,7 @@ fun CallActivityView() {
|
||||
}
|
||||
SimpleXTheme {
|
||||
var prevCall by remember { mutableStateOf(call) }
|
||||
KeyChangeEffect(m.activeCall.value) {
|
||||
KeyChangeEffect(m.activeCall.value, remember { appPrefs.appLanguage.state }.value) {
|
||||
if (m.activeCall.value != null) {
|
||||
prevCall = m.activeCall.value
|
||||
activity.boundService?.updateNotification()
|
||||
|
||||
+1
-2
@@ -31,8 +31,7 @@ private fun Activity.applyLocale(locale: Locale) {
|
||||
Locale.setDefault(locale)
|
||||
val appConf = Configuration(androidAppContext.resources.configuration).apply { setLocale(locale) }
|
||||
val activityConf = Configuration(resources.configuration).apply { setLocale(locale) }
|
||||
@Suppress("DEPRECATION")
|
||||
androidAppContext.resources.updateConfiguration(appConf, resources.displayMetrics)
|
||||
androidAppContext = androidAppContext.createConfigurationContext(appConf)
|
||||
@Suppress("DEPRECATION")
|
||||
resources.updateConfiguration(activityConf, resources.displayMetrics)
|
||||
}
|
||||
|
||||
+22
-4
@@ -41,8 +41,10 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.*
|
||||
import androidx.webkit.WebViewAssetLoader
|
||||
import androidx.webkit.WebViewClientCompat
|
||||
import chat.simplex.common.helpers.applyAppLocale
|
||||
import chat.simplex.common.helpers.showAllowPermissionInSettingsAlert
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -192,7 +194,11 @@ actual fun ActiveCallView() {
|
||||
updateActiveCall(call) {
|
||||
val sources = it.localMediaSources
|
||||
when (cmd.source) {
|
||||
CallMediaSource.Mic -> it.copy(localMediaSources = sources.copy(mic = cmd.enable))
|
||||
CallMediaSource.Mic -> {
|
||||
val am = androidAppContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
am.isMicrophoneMute = !cmd.enable
|
||||
it.copy(localMediaSources = sources.copy(mic = cmd.enable))
|
||||
}
|
||||
CallMediaSource.Camera -> it.copy(localMediaSources = sources.copy(camera = cmd.enable))
|
||||
CallMediaSource.ScreenAudio -> it.copy(localMediaSources = sources.copy(screenAudio = cmd.enable))
|
||||
CallMediaSource.ScreenVideo -> it.copy(localMediaSources = sources.copy(screenVideo = cmd.enable))
|
||||
@@ -226,8 +232,9 @@ actual fun ActiveCallView() {
|
||||
ActiveCallOverlay(call, chatModel, callAudioDeviceManager)
|
||||
}
|
||||
}
|
||||
KeyChangeEffect(call?.hasVideo) {
|
||||
if (call != null) {
|
||||
KeyChangeEffect(call?.localMediaSources?.hasVideo) {
|
||||
if (call != null && call.hasVideo && callAudioDeviceManager.currentDevice.value?.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) {
|
||||
// enabling speaker on user action (peer action ignored) and not disabling it again
|
||||
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.hasVideo, true)
|
||||
}
|
||||
}
|
||||
@@ -701,9 +708,10 @@ fun WebRTCView(callCommand: SnapshotStateList<WCallCommand>, onResponse: (WVAPIM
|
||||
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
AndroidView(
|
||||
factory = { AndroidViewContext ->
|
||||
factory = {
|
||||
try {
|
||||
(staticWebView ?: WebView(androidAppContext)).apply {
|
||||
reapplyLocale()
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
@@ -774,6 +782,16 @@ private fun updateActiveCall(initial: Call, transform: (Call) -> Call) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creating WebView automatically drops user's custom app locale to default system locale.
|
||||
* Preventing it by re-applying custom locale
|
||||
* https://issuetracker.google.com/issues/109833940
|
||||
* */
|
||||
private fun reapplyLocale() {
|
||||
mainActivity.get()?.applyAppLocale(appPrefs.appLanguage)
|
||||
callActivity.get()?.applyAppLocale(appPrefs.appLanguage)
|
||||
}
|
||||
|
||||
private class LocalContentWebViewClient(val webView: MutableState<WebView?>, private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() {
|
||||
override fun shouldInterceptRequest(
|
||||
view: WebView,
|
||||
|
||||
+15
@@ -71,6 +71,9 @@ object ChatModel {
|
||||
val groupMembers = mutableStateListOf<GroupMember>()
|
||||
val groupMembersIndexes = mutableStateMapOf<Long, Int>()
|
||||
|
||||
// false: default placement, true: floating window.
|
||||
// Used for deciding to add terminal items on main thread or not. Floating means appPrefs.terminalAlwaysVisible
|
||||
var terminalsVisible = setOf<Boolean>()
|
||||
val terminalItems = mutableStateOf<List<TerminalItem>>(listOf())
|
||||
val userAddress = mutableStateOf<UserContactLinkRec?>(null)
|
||||
val chatItemTTL = mutableStateOf<ChatItemTTL>(ChatItemTTL.None)
|
||||
@@ -772,6 +775,16 @@ object ChatModel {
|
||||
|
||||
fun addTerminalItem(item: TerminalItem) {
|
||||
val maxItems = if (appPreferences.developerTools.get()) 500 else 200
|
||||
if (terminalsVisible.isNotEmpty()) {
|
||||
withApi {
|
||||
addTerminalItem(item, maxItems)
|
||||
}
|
||||
} else {
|
||||
addTerminalItem(item, maxItems)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addTerminalItem(item: TerminalItem, maxItems: Int) {
|
||||
if (terminalItems.value.size >= maxItems) {
|
||||
terminalItems.value = terminalItems.value.subList(1, terminalItems.value.size)
|
||||
}
|
||||
@@ -1876,6 +1889,7 @@ class PendingContactConnection(
|
||||
@Serializable
|
||||
enum class ConnStatus {
|
||||
@SerialName("new") New,
|
||||
@SerialName("prepared") Prepared,
|
||||
@SerialName("joined") Joined,
|
||||
@SerialName("requested") Requested,
|
||||
@SerialName("accepted") Accepted,
|
||||
@@ -1885,6 +1899,7 @@ enum class ConnStatus {
|
||||
|
||||
val initiated: Boolean? get() = when (this) {
|
||||
New -> true
|
||||
Prepared -> false
|
||||
Joined -> false
|
||||
Requested -> true
|
||||
Accepted -> true
|
||||
|
||||
+5
-2
@@ -3654,7 +3654,7 @@ data class NetCfg(
|
||||
val socksMode: SocksMode = SocksMode.Always,
|
||||
val hostMode: HostMode = HostMode.OnionViaSocks,
|
||||
val requiredHostMode: Boolean = false,
|
||||
val sessionMode: TransportSessionMode = TransportSessionMode.User,
|
||||
val sessionMode: TransportSessionMode = TransportSessionMode.default,
|
||||
val smpProxyMode: SMPProxyMode = SMPProxyMode.Unknown,
|
||||
val smpProxyFallback: SMPProxyFallback = SMPProxyFallback.AllowProtected,
|
||||
val smpWebPort: Boolean = false,
|
||||
@@ -3781,10 +3781,13 @@ enum class SMPProxyFallback {
|
||||
@Serializable
|
||||
enum class TransportSessionMode {
|
||||
@SerialName("user") User,
|
||||
@SerialName("session") Session,
|
||||
@SerialName("server") Server,
|
||||
@SerialName("entity") Entity;
|
||||
|
||||
companion object {
|
||||
val default = User
|
||||
val default = Session
|
||||
val safeValues = arrayOf(User, Session, Server)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+47
-7
@@ -20,11 +20,12 @@ import chat.simplex.common.views.chat.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun TerminalView(chatModel: ChatModel, close: () -> Unit) {
|
||||
fun TerminalView(floating: Boolean = false, close: () -> Unit) {
|
||||
val composeState = remember { mutableStateOf(ComposeState(useLinkPreviews = false)) }
|
||||
val close = {
|
||||
close()
|
||||
@@ -37,6 +38,7 @@ fun TerminalView(chatModel: ChatModel, close: () -> Unit) {
|
||||
})
|
||||
TerminalLayout(
|
||||
composeState,
|
||||
floating,
|
||||
sendCommand = { sendCommand(chatModel, composeState) },
|
||||
close
|
||||
)
|
||||
@@ -65,6 +67,7 @@ private fun sendCommand(chatModel: ChatModel, composeState: MutableState<Compose
|
||||
@Composable
|
||||
fun TerminalLayout(
|
||||
composeState: MutableState<ComposeState>,
|
||||
floating: Boolean,
|
||||
sendCommand: () -> Unit,
|
||||
close: () -> Unit
|
||||
) {
|
||||
@@ -118,19 +121,40 @@ fun TerminalLayout(
|
||||
color = MaterialTheme.colors.background,
|
||||
contentColor = LocalContentColor.current
|
||||
) {
|
||||
TerminalLog()
|
||||
TerminalLog(floating)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TerminalLog() {
|
||||
fun TerminalLog(floating: Boolean) {
|
||||
val reversedTerminalItems by remember {
|
||||
derivedStateOf { chatModel.terminalItems.value.asReversed() }
|
||||
}
|
||||
val clipboard = LocalClipboardManager.current
|
||||
LazyColumnWithScrollBar(reverseLayout = true) {
|
||||
val listState = LocalAppBarHandler.current?.listState ?: rememberLazyListState()
|
||||
LaunchedEffect(Unit) {
|
||||
var autoScrollToBottom = true
|
||||
launch {
|
||||
snapshotFlow { listState.layoutInfo.totalItemsCount }
|
||||
.filter { autoScrollToBottom }
|
||||
.collect {
|
||||
try {
|
||||
listState.scrollToItem(0)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.stackTraceToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
launch {
|
||||
snapshotFlow { listState.firstVisibleItemIndex }
|
||||
.collect {
|
||||
autoScrollToBottom = listState.firstVisibleItemIndex == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
LazyColumnWithScrollBar(reverseLayout = true, state = listState) {
|
||||
items(reversedTerminalItems, key = { item -> item.id to item.createdAtNanos }) { item ->
|
||||
val rhId = item.remoteHostId
|
||||
val rhIdStr = if (rhId == null) "" else "$rhId "
|
||||
@@ -142,7 +166,12 @@ fun TerminalLog() {
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
ModalManager.start.showModal(endButtons = { ShareButton { clipboard.shareText(item.details) } }) {
|
||||
val modalPlace = if (floating) {
|
||||
ModalManager.floatingTerminal
|
||||
} else {
|
||||
ModalManager.start
|
||||
}
|
||||
modalPlace.showModal(endButtons = { ShareButton { clipboard.shareText(item.details) } }) {
|
||||
SelectionContainer(modifier = Modifier.verticalScroll(rememberScrollState())) {
|
||||
val details = item.details
|
||||
.let {
|
||||
@@ -156,6 +185,16 @@ fun TerminalLog() {
|
||||
)
|
||||
}
|
||||
}
|
||||
DisposableEffect(Unit) {
|
||||
val terminals = chatModel.terminalsVisible.toMutableSet()
|
||||
terminals += floating
|
||||
chatModel.terminalsVisible = terminals
|
||||
onDispose {
|
||||
val terminals = chatModel.terminalsVisible.toMutableSet()
|
||||
terminals -= floating
|
||||
chatModel.terminalsVisible = terminals
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview/*(
|
||||
@@ -169,6 +208,7 @@ fun PreviewTerminalLayout() {
|
||||
TerminalLayout(
|
||||
composeState = remember { mutableStateOf(ComposeState(useLinkPreviews = false)) },
|
||||
sendCommand = {},
|
||||
floating = false,
|
||||
close = {}
|
||||
)
|
||||
}
|
||||
|
||||
+1
@@ -83,6 +83,7 @@ enum class CallState {
|
||||
@Serializable
|
||||
sealed class WCallCommand {
|
||||
@Serializable @SerialName("capabilities") data class Capabilities(val media: CallMediaType): WCallCommand()
|
||||
@Serializable @SerialName("permission") data class Permission(val title: String, val chrome: String, val safari: String): WCallCommand()
|
||||
@Serializable @SerialName("start") data class Start(val media: CallMediaType, val aesKey: String? = null, val iceServers: List<RTCIceServer>? = null, val relay: Boolean? = null): WCallCommand()
|
||||
@Serializable @SerialName("offer") data class Offer(val offer: String, val iceCandidates: String, val media: CallMediaType, val aesKey: String? = null, val iceServers: List<RTCIceServer>? = null, val relay: Boolean? = null): WCallCommand()
|
||||
@Serializable @SerialName("answer") data class Answer (val answer: String, val iceCandidates: String): WCallCommand()
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package chat.simplex.common.views.chat
|
||||
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import chat.simplex.common.model.*
|
||||
|
||||
data class SectionItems (
|
||||
val mergeCategory: CIMergeCategory?,
|
||||
val items: SnapshotStateList<ChatItem>,
|
||||
val revealed: Boolean,
|
||||
val showAvatar: MutableSet<Long>,
|
||||
)
|
||||
|
||||
fun List<ChatItem>.putIntoGroups(revealedItems: Set<Long>): List<SectionItems> {
|
||||
println("LALAL LENGTH ${size}")
|
||||
val start = System.currentTimeMillis()
|
||||
val groups = ArrayList<SectionItems>()
|
||||
var recent: SectionItems = if (isNotEmpty()) {
|
||||
val first = this[0]
|
||||
SectionItems(
|
||||
mergeCategory = first.mergeCategory,
|
||||
items = SnapshotStateList<ChatItem>().also { it.add(first) },
|
||||
revealed = first.mergeCategory == null || revealedItems.contains(first.id),
|
||||
showAvatar = mutableSetOf<Long>().also { if (first.chatDir is CIDirection.GroupRcv) it.add(first.id) })
|
||||
} else {
|
||||
return emptyList()
|
||||
}
|
||||
groups.add(recent)
|
||||
var prev = this[0]
|
||||
var index = 0
|
||||
while (index < size) {
|
||||
if (index == 0) {
|
||||
index++
|
||||
continue
|
||||
}
|
||||
val item = this[index]
|
||||
val category = item.mergeCategory
|
||||
if (recent.mergeCategory == category) {
|
||||
recent.items.add(item)
|
||||
if (item.chatDir is CIDirection.GroupRcv && prev.chatDir is CIDirection.GroupRcv && item.chatDir.groupMember == (prev.chatDir as CIDirection.GroupRcv).groupMember) {
|
||||
recent.showAvatar.add(item.id)
|
||||
}
|
||||
} else {
|
||||
recent = SectionItems(
|
||||
mergeCategory = item.mergeCategory,
|
||||
items = SnapshotStateList<ChatItem>().also { it.add(item) },
|
||||
revealed = item.mergeCategory == null || revealedItems.contains(item.id),
|
||||
showAvatar = mutableSetOf<Long>().also {
|
||||
if (item.chatDir is CIDirection.GroupRcv && (prev.chatDir !is CIDirection.GroupRcv || (prev.chatDir as CIDirection.GroupRcv).groupMember != item.chatDir.groupMember)) {
|
||||
it.add(item.id)
|
||||
}
|
||||
}
|
||||
)
|
||||
groups.add(recent)
|
||||
}
|
||||
prev = item
|
||||
index++
|
||||
}
|
||||
println("LALAL RES ${System.currentTimeMillis() - start}, groups: ${groups.size}")
|
||||
return groups
|
||||
}
|
||||
+29
-34
@@ -11,6 +11,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.drawWithCache
|
||||
@@ -988,6 +989,8 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
||||
|
||||
Spacer(Modifier.size(8.dp))
|
||||
val reversedChatItems by remember { derivedStateOf { chatModel.chatItems.asReversed() } }
|
||||
val revealedItems = rememberSaveable { mutableStateOf(setOf<Long>()) }
|
||||
val groups by remember { derivedStateOf { (reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems + reversedChatItems).putIntoGroups(revealedItems.value) } }
|
||||
val maxHeightRounded = with(LocalDensity.current) { maxHeight.roundToPx() }
|
||||
val scrollToItem: (Long) -> Unit = { itemId: Long ->
|
||||
val index = reversedChatItems.indexOfFirst { it.id == itemId }
|
||||
@@ -1011,8 +1014,8 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
||||
VideoPlayerHolder.releaseAll()
|
||||
}
|
||||
)
|
||||
LazyColumnWithScrollBar(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) {
|
||||
itemsIndexed(reversedChatItems, key = { _, item -> item.id to item.meta.createdAt.toEpochMilliseconds() }) { i, cItem ->
|
||||
@Composable
|
||||
fun ChatViewListItem(i: Int, showAvatar: Boolean, cItem: ChatItem) {
|
||||
CompositionLocalProvider(
|
||||
// Makes horizontal and vertical scrolling to coexist nicely.
|
||||
// With default touchSlop when you scroll LazyColumn, you can unintentionally open reply view
|
||||
@@ -1104,7 +1107,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
||||
} else {
|
||||
null to 1
|
||||
}
|
||||
if (prevItem == null || showMemberImage(member, prevItem) || prevMember != null) {
|
||||
if (showMemberImage(member, prevItem) || showAvatar) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(top = 8.dp)
|
||||
@@ -1225,37 +1228,6 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val (currIndex, nextItem) = chatModel.getNextChatItem(cItem)
|
||||
val ciCategory = cItem.mergeCategory
|
||||
if (ciCategory != null && ciCategory == nextItem?.mergeCategory) {
|
||||
// memberConnected events and deleted items are aggregated at the last chat item in a row, see ChatItemView
|
||||
} else {
|
||||
val (prevHidden, prevItem) = chatModel.getPrevShownChatItem(currIndex, ciCategory)
|
||||
|
||||
val itemSeparation = getItemSeparation(cItem, nextItem)
|
||||
val previousItemSeparation = if (prevItem != null) getItemSeparation(prevItem, cItem) else null
|
||||
|
||||
if (itemSeparation.date != null) {
|
||||
DateSeparator(itemSeparation.date)
|
||||
}
|
||||
|
||||
val range = chatViewItemsRange(currIndex, prevHidden)
|
||||
if (revealed.value && range != null) {
|
||||
reversedChatItems.subList(range.first, range.last + 1).forEachIndexed { index, ci ->
|
||||
val prev = if (index + range.first == prevHidden) prevItem else reversedChatItems[index + range.first + 1]
|
||||
ChatItemView(ci, null, prev, itemSeparation, previousItemSeparation)
|
||||
}
|
||||
} else {
|
||||
ChatItemView(cItem, range, prevItem, itemSeparation, previousItemSeparation)
|
||||
}
|
||||
|
||||
if (i == reversedChatItems.lastIndex) {
|
||||
DateSeparator(cItem.meta.itemTs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cItem.isRcvNew && chatInfo.id == ChatModel.chatId.value) {
|
||||
LaunchedEffect(cItem.id) {
|
||||
scope.launch {
|
||||
@@ -1264,6 +1236,29 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
||||
}
|
||||
}
|
||||
}
|
||||
val itemSeparation = getItemSeparation(cItem, null)
|
||||
ChatItemView(cItem, null, null, itemSeparation, null)
|
||||
}
|
||||
}
|
||||
LazyColumnWithScrollBar(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) {
|
||||
for (group in groups) {
|
||||
if (group.revealed) {
|
||||
itemsIndexed(group.items, key = { _, item -> (item.id to item.meta.createdAt.toEpochMilliseconds()).toString() }) { i, cItem ->
|
||||
// index here is just temporary, should be removed at all or put in the section items
|
||||
ChatViewListItem(reversedChatItems.indexOf(cItem), showAvatar = group.showAvatar.contains(cItem.id), cItem)
|
||||
}
|
||||
} else {
|
||||
val item = group.items.last()
|
||||
item(key = { (item.id to item.meta.createdAt.toEpochMilliseconds()).toString() }) {
|
||||
// here you make one collapsed item from multiple items (should be already in section items)
|
||||
ChatViewListItem(reversedChatItems.indexOf(item), showAvatar = group.showAvatar.contains(item.id), item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reversedChatItems.isNotEmpty()) {
|
||||
item {
|
||||
DateSeparator(reversedChatItems.last().meta.itemTs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-10
@@ -59,7 +59,8 @@ fun SelectedItemsBottomToolbar(
|
||||
val canModerate = remember { mutableStateOf(false) }
|
||||
val moderateEnabled = remember { mutableStateOf(false) }
|
||||
val forwardEnabled = remember { mutableStateOf(false) }
|
||||
val allButtonsDisabled = remember { mutableStateOf(false) }
|
||||
val deleteCountProhibited = remember { mutableStateOf(false) }
|
||||
val forwardCountProhibited = remember { mutableStateOf(false) }
|
||||
Box {
|
||||
// It's hard to measure exact height of ComposeView with different fontSizes. Better to depend on actual ComposeView, even empty
|
||||
ComposeView(chatModel = chatModel, Chat.sampleData, remember { mutableStateOf(ComposeState(useLinkPreviews = false)) }, remember { mutableStateOf(null) }, {})
|
||||
@@ -75,36 +76,36 @@ fun SelectedItemsBottomToolbar(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
IconButton({ deleteItems(deleteForEveryoneEnabled.value) }, enabled = deleteEnabled.value && !allButtonsDisabled.value) {
|
||||
IconButton({ deleteItems(deleteForEveryoneEnabled.value) }, enabled = deleteEnabled.value && !deleteCountProhibited.value) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_delete),
|
||||
null,
|
||||
Modifier.size(22.dp),
|
||||
tint = if (!deleteEnabled.value || allButtonsDisabled.value) MaterialTheme.colors.secondary else MaterialTheme.colors.error
|
||||
tint = if (!deleteEnabled.value || deleteCountProhibited.value) MaterialTheme.colors.secondary else MaterialTheme.colors.error
|
||||
)
|
||||
}
|
||||
|
||||
IconButton({ moderateItems() }, Modifier.alpha(if (canModerate.value) 1f else 0f), enabled = moderateEnabled.value && !allButtonsDisabled.value) {
|
||||
IconButton({ moderateItems() }, Modifier.alpha(if (canModerate.value) 1f else 0f), enabled = moderateEnabled.value && !deleteCountProhibited.value) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_flag),
|
||||
null,
|
||||
Modifier.size(22.dp),
|
||||
tint = if (!moderateEnabled.value || allButtonsDisabled.value) MaterialTheme.colors.secondary else MaterialTheme.colors.error
|
||||
tint = if (!moderateEnabled.value || deleteCountProhibited.value) MaterialTheme.colors.secondary else MaterialTheme.colors.error
|
||||
)
|
||||
}
|
||||
|
||||
IconButton({ forwardItems() }, enabled = forwardEnabled.value && !allButtonsDisabled.value) {
|
||||
IconButton({ forwardItems() }, enabled = forwardEnabled.value && !forwardCountProhibited.value) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_forward),
|
||||
null,
|
||||
Modifier.size(22.dp),
|
||||
tint = if (!forwardEnabled.value || allButtonsDisabled.value) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
|
||||
tint = if (!forwardEnabled.value || forwardCountProhibited.value) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(chatInfo, chatItems, selectedChatItems.value) {
|
||||
recheckItems(chatInfo, chatItems, selectedChatItems, deleteEnabled, deleteForEveryoneEnabled, canModerate, moderateEnabled, forwardEnabled, allButtonsDisabled)
|
||||
recheckItems(chatInfo, chatItems, selectedChatItems, deleteEnabled, deleteForEveryoneEnabled, canModerate, moderateEnabled, forwardEnabled, deleteCountProhibited, forwardCountProhibited)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,10 +117,12 @@ private fun recheckItems(chatInfo: ChatInfo,
|
||||
canModerate: MutableState<Boolean>,
|
||||
moderateEnabled: MutableState<Boolean>,
|
||||
forwardEnabled: MutableState<Boolean>,
|
||||
allButtonsDisabled: MutableState<Boolean>
|
||||
deleteCountProhibited: MutableState<Boolean>,
|
||||
forwardCountProhibited: MutableState<Boolean>
|
||||
) {
|
||||
val count = selectedChatItems.value?.size ?: 0
|
||||
allButtonsDisabled.value = count == 0 || count > 20
|
||||
deleteCountProhibited.value = count == 0 || count > 200
|
||||
forwardCountProhibited.value = count == 0 || count > 20
|
||||
canModerate.value = possibleToModerate(chatInfo)
|
||||
val selected = selectedChatItems.value ?: return
|
||||
var rDeleteEnabled = true
|
||||
|
||||
+2
-1
@@ -341,7 +341,8 @@ private fun GlobalSettingsSection(
|
||||
ModalManager.start.showCustomModal { close ->
|
||||
ConnectDesktopView(close)
|
||||
}
|
||||
}
|
||||
},
|
||||
disabled = stopped
|
||||
)
|
||||
} else {
|
||||
UserPickerOptionRow(
|
||||
|
||||
+3
-2
@@ -2,10 +2,8 @@ package chat.simplex.common.views.helpers
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -209,11 +207,14 @@ class ModalManager(private val placement: ModalPlacement? = null) {
|
||||
val end = if (appPlatform.isAndroid) shared else ModalManager(ModalPlacement.END)
|
||||
val fullscreen = if (appPlatform.isAndroid) shared else ModalManager(ModalPlacement.FULLSCREEN)
|
||||
|
||||
val floatingTerminal = if (appPlatform.isAndroid) shared else ModalManager(ModalPlacement.START)
|
||||
|
||||
fun closeAllModalsEverywhere() {
|
||||
start.closeModals()
|
||||
center.closeModals()
|
||||
end.closeModals()
|
||||
fullscreen.closeModals()
|
||||
floatingTerminal.closeModals()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
|
||||
+12
-10
@@ -321,17 +321,19 @@ fun ActiveProfilePicker(
|
||||
}
|
||||
}
|
||||
|
||||
controller.changeActiveUser_(
|
||||
rhId = user.remoteHostId,
|
||||
toUserId = user.userId,
|
||||
viewPwd = if (user.hidden) searchTextOrPassword.value else null
|
||||
)
|
||||
|
||||
if (chatModel.currentUser.value?.userId != user.userId) {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(
|
||||
MR.strings.switching_profile_error_title),
|
||||
String.format(generalGetString(MR.strings.switching_profile_error_message), user.chatViewName)
|
||||
if ((contactConnection != null && updatedConn != null) || contactConnection == null) {
|
||||
controller.changeActiveUser_(
|
||||
rhId = user.remoteHostId,
|
||||
toUserId = user.userId,
|
||||
viewPwd = if (user.hidden) searchTextOrPassword.value else null
|
||||
)
|
||||
|
||||
if (chatModel.currentUser.value?.userId != user.userId) {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(
|
||||
MR.strings.switching_profile_error_title),
|
||||
String.format(generalGetString(MR.strings.switching_profile_error_message), user.chatViewName)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedConn != null) {
|
||||
|
||||
+33
-3
@@ -53,7 +53,8 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) {
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.h4,
|
||||
fontWeight = FontWeight.Medium
|
||||
fontWeight = FontWeight.Medium,
|
||||
modifier = Modifier.padding(bottom = 6.dp)
|
||||
)
|
||||
if (link != null) {
|
||||
linkButton(link)
|
||||
@@ -64,7 +65,7 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = Modifier.padding(bottom = 4.dp)
|
||||
modifier = Modifier.padding(bottom = 6.dp)
|
||||
) {
|
||||
Icon(painterResource(si), stringResource(sd), tint = MaterialTheme.colors.secondary)
|
||||
Text(generalGetString(sd), fontSize = 15.sp)
|
||||
@@ -648,7 +649,36 @@ private val versionDescriptions: List<VersionDescription> = listOf(
|
||||
show = appPlatform.isDesktop
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
VersionDescription(
|
||||
version = "v6.1",
|
||||
post = "https://simplex.chat/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html",
|
||||
features = listOf(
|
||||
FeatureDescription(
|
||||
icon = MR.images.ic_verified_user,
|
||||
titleId = MR.strings.v6_1_better_security,
|
||||
descrId = MR.strings.v6_1_better_security_descr,
|
||||
link = "https://simplex.chat/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html"
|
||||
),
|
||||
FeatureDescription(
|
||||
icon = MR.images.ic_videocam,
|
||||
titleId = MR.strings.v6_1_better_calls,
|
||||
descrId = MR.strings.v6_1_better_calls_descr
|
||||
),
|
||||
FeatureDescription(
|
||||
icon = null,
|
||||
titleId = MR.strings.v6_1_better_user_experience,
|
||||
descrId = null,
|
||||
subfeatures = listOf(
|
||||
MR.images.ic_link to MR.strings.v6_1_switch_chat_profile_descr,
|
||||
MR.images.ic_chat to MR.strings.v6_1_customizable_message_descr,
|
||||
MR.images.ic_calendar to MR.strings.v6_1_message_dates_descr,
|
||||
MR.images.ic_forward to MR.strings.v6_1_forward_many_messages_descr,
|
||||
MR.images.ic_delete to MR.strings.v6_1_delete_many_messages_descr
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private val lastVersion = versionDescriptions.last().version
|
||||
|
||||
+1
-1
@@ -218,7 +218,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U
|
||||
SectionDividerSpaced(maxTopPadding = true)
|
||||
}
|
||||
|
||||
if (currentRemoteHost == null && developerTools) {
|
||||
if (currentRemoteHost == null) {
|
||||
SectionView(stringResource(MR.strings.network_session_mode_transport_isolation).uppercase()) {
|
||||
SessionModePicker(sessionMode, showModal, updateSessionMode)
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ fun DeveloperView(
|
||||
val unchangedHints = mutableStateOf(unchangedHintPreferences())
|
||||
SectionView {
|
||||
InstallTerminalAppItem(uriHandler)
|
||||
ChatConsoleItem { withAuth(generalGetString(MR.strings.auth_open_chat_console), generalGetString(MR.strings.auth_log_in_using_credential), showCustomModal { it, close -> TerminalView(it, close) }) }
|
||||
ChatConsoleItem { withAuth(generalGetString(MR.strings.auth_open_chat_console), generalGetString(MR.strings.auth_log_in_using_credential), showCustomModal { it, close -> TerminalView(false, close) }) }
|
||||
ResetHintsItem(unchangedHints)
|
||||
SettingsPreferenceItem(painterResource(MR.images.ic_code), stringResource(MR.strings.show_developer_options), developerTools)
|
||||
SectionTextFooter(
|
||||
|
||||
+11
-5
@@ -164,9 +164,7 @@ fun NetworkAndServersView() {
|
||||
val showCustomModal = { it: @Composable (close: () -> Unit) -> Unit -> ModalManager.fullscreen.showCustomModal { close -> it(close) }}
|
||||
UseSocksProxySwitch(networkUseSocksProxy, toggleSocksProxy)
|
||||
SettingsActionItem(painterResource(MR.images.ic_settings_ethernet), stringResource(MR.strings.network_socks_proxy_settings), { showCustomModal { SocksProxySettings(networkUseSocksProxy.value, networkProxy, onionHosts, sessionMode.value, true, it) } })
|
||||
if (developerTools) {
|
||||
SessionModePicker(sessionMode, showModal, updateSessionMode)
|
||||
}
|
||||
SessionModePicker(sessionMode, showModal, updateSessionMode)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -458,9 +456,17 @@ fun SessionModePicker(
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val values = remember {
|
||||
TransportSessionMode.values().map {
|
||||
val safeModes = TransportSessionMode.safeValues
|
||||
val modes: Array<TransportSessionMode> =
|
||||
if (appPrefs.developerTools.get()) TransportSessionMode.values()
|
||||
else if (safeModes.contains(sessionMode.value)) safeModes
|
||||
else safeModes + sessionMode.value
|
||||
modes.map {
|
||||
val userModeDescr: AnnotatedString = escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_user_description), density)
|
||||
when (it) {
|
||||
TransportSessionMode.User -> ValueTitleDesc(TransportSessionMode.User, generalGetString(MR.strings.network_session_mode_user), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_user_description), density))
|
||||
TransportSessionMode.User -> ValueTitleDesc(TransportSessionMode.User, generalGetString(MR.strings.network_session_mode_user), userModeDescr)
|
||||
TransportSessionMode.Session -> ValueTitleDesc(TransportSessionMode.Session, generalGetString(MR.strings.network_session_mode_session), userModeDescr + AnnotatedString("\n") + escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_session_description), density))
|
||||
TransportSessionMode.Server -> ValueTitleDesc(TransportSessionMode.Server, generalGetString(MR.strings.network_session_mode_server), userModeDescr + AnnotatedString("\n") + escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_server_description), density))
|
||||
TransportSessionMode.Entity -> ValueTitleDesc(TransportSessionMode.Entity, generalGetString(MR.strings.network_session_mode_entity), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_session_mode_entity_description), density))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2104,4 +2104,25 @@
|
||||
<string name="network_proxy_auth">استيثاق الوكيل</string>
|
||||
<string name="delete_messages_cannot_be_undone_warning">سيتم حذف الرسائل - لا يمكن التراجع عن هذا!</string>
|
||||
<string name="icon_descr_sound_muted">الصوت مكتوم</string>
|
||||
<string name="error_initializing_web_view_wrong_arch">حدث خطأ أثناء تهيئة WebView. تأكد من تثبيت WebView وأن بنيته المدعومة هي arm64.\nالخطأ: %s</string>
|
||||
<string name="settings_section_title_message_shape">شكل الرسالة</string>
|
||||
<string name="settings_message_shape_tail">ذيل</string>
|
||||
<string name="settings_message_shape_corner">ركن</string>
|
||||
<string name="network_session_mode_session">جلسة التطبيق</string>
|
||||
<string name="network_session_mode_server">الخادم</string>
|
||||
<string name="network_session_mode_session_description">سيتم استخدام بيانات اعتماد SOCKS الجديدة في كل مرة تبدأ فيها تشغيل التطبيق.</string>
|
||||
<string name="network_session_mode_server_description">سيتم استخدام بيانات اعتماد SOCKS الجديدة لكل خادم.</string>
|
||||
<string name="call_desktop_permission_denied_chrome">انقر فوق زر المعلومات الموجود بالقرب من حقل العنوان للسماح باستخدام الميكروفون.</string>
|
||||
<string name="call_desktop_permission_denied_safari">افتح إعدادات Safari / مواقع الويب / الميكروفون، ثم اختر السماح لـ localhost.</string>
|
||||
<string name="call_desktop_permission_denied_title">لإجراء مكالمات، اسمح باستخدام الميكروفون. أنهِ المكالمة وحاول الاتصال مرة أخرى.</string>
|
||||
<string name="v6_1_better_user_experience">تجربة مستخدم أفضل</string>
|
||||
<string name="v6_1_customizable_message_descr">شكل الرسالة قابل للتخصيص.</string>
|
||||
<string name="v6_1_better_calls_descr">تبديل الصوت والفيديو أثناء المكالمة.</string>
|
||||
<string name="v6_1_delete_many_messages_descr">حذف أو إشراف ما يصل إلى 200 رسالة.</string>
|
||||
<string name="v6_1_forward_many_messages_descr">حوّل ما يصل إلى 20 رسالة آن واحد.</string>
|
||||
<string name="v6_1_better_calls">مكالمات أفضل</string>
|
||||
<string name="v6_1_message_dates_descr">تواريخ أفضل للرسائل.</string>
|
||||
<string name="v6_1_better_security">أمان أفضل ✅</string>
|
||||
<string name="v6_1_better_security_descr">بروتوكولات SimpleX تمت مراجعتها بواسطة Trail of Bits.</string>
|
||||
<string name="v6_1_switch_chat_profile_descr">تبديل ملف تعريف الدردشة لدعوات لمرة واحدة.</string>
|
||||
</resources>
|
||||
@@ -811,8 +811,12 @@
|
||||
<string name="network_use_onion_hosts_required_desc">Onion hosts will be required for connection.\nPlease note: you will not be able to connect to the servers without .onion address.</string>
|
||||
<string name="network_session_mode_transport_isolation">Transport isolation</string>
|
||||
<string name="network_session_mode_user">Chat profile</string>
|
||||
<string name="network_session_mode_session">App session</string>
|
||||
<string name="network_session_mode_server">Server</string>
|
||||
<string name="network_session_mode_entity">Connection</string>
|
||||
<string name="network_session_mode_user_description"><![CDATA[A separate TCP connection (and SOCKS credential) will be used <b>for each chat profile you have in the app</b>.]]></string>
|
||||
<string name="network_session_mode_session_description">New SOCKS credentials will be used every time you start the app.</string>
|
||||
<string name="network_session_mode_server_description">New SOCKS credentials will be used for each server.</string>
|
||||
<string name="network_session_mode_entity_description"><![CDATA[A separate TCP connection (and SOCKS credential) will be used <b>for each contact and group member</b>.\n<b>Please note</b>: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail.]]></string>
|
||||
<string name="update_network_session_mode_question">Update transport isolation mode?</string>
|
||||
<string name="disable_onion_hosts_when_not_supported"><![CDATA[Set <i>Use .onion hosts</i> to No if SOCKS proxy does not support them.]]></string>
|
||||
@@ -1043,6 +1047,9 @@
|
||||
<string name="call_already_ended">Call already ended!</string>
|
||||
<string name="icon_descr_video_call">video call</string>
|
||||
<string name="icon_descr_audio_call">audio call</string>
|
||||
<string name="call_desktop_permission_denied_title">To make calls, allow to use your microphone. End the call and try to call again.</string>
|
||||
<string name="call_desktop_permission_denied_chrome">Click info button near address field to allow using microphone.</string>
|
||||
<string name="call_desktop_permission_denied_safari">Open Safari Settings / Websites / Microphone, then choose Allow for localhost.</string>
|
||||
|
||||
<!-- Call settings -->
|
||||
<string name="settings_audio_video_calls">Audio & video calls</string>
|
||||
@@ -2034,6 +2041,16 @@
|
||||
<string name="v6_0_upgrade_app_descr">Download new versions from GitHub.</string>
|
||||
<string name="v6_0_connection_servers_status">Control your network</string>
|
||||
<string name="v6_0_connection_servers_status_descr">Connection and servers status.</string>
|
||||
<string name="v6_1_better_security">Better security ✅</string>
|
||||
<string name="v6_1_better_security_descr">SimpleX protocols reviewed by Trail of Bits.</string>
|
||||
<string name="v6_1_better_calls">Better calls</string>
|
||||
<string name="v6_1_better_calls_descr">Switch audio and video during the call.</string>
|
||||
<string name="v6_1_better_user_experience">Better user experience</string>
|
||||
<string name="v6_1_switch_chat_profile_descr">Switch chat profile for 1-time invitations.</string>
|
||||
<string name="v6_1_customizable_message_descr">Customizable message shape.</string>
|
||||
<string name="v6_1_message_dates_descr">Better message dates.</string>
|
||||
<string name="v6_1_forward_many_messages_descr">Forward up to 20 messages at once.</string>
|
||||
<string name="v6_1_delete_many_messages_descr">Delete or moderate up to 200 messages.</string>
|
||||
|
||||
<!-- CustomTimePicker -->
|
||||
<string name="custom_time_unit_seconds">seconds</string>
|
||||
|
||||
@@ -667,8 +667,8 @@
|
||||
<string name="callstate_received_confirmation">obdržel potvrzení…</string>
|
||||
<string name="callstate_connecting">připojování…</string>
|
||||
<string name="privacy_redefined">Nové vymezení soukromí</string>
|
||||
<string name="first_platform_without_user_ids">1. platforma bez jakýchkoliv uživatelských identifikátorů – soukromá již od návrhu.</string>
|
||||
<string name="immune_to_spam_and_abuse">Odolná vůči spamu a zneužití</string>
|
||||
<string name="first_platform_without_user_ids">Bez uživatelských identifikátorů</string>
|
||||
<string name="immune_to_spam_and_abuse">Odolná vůči spamu</string>
|
||||
<string name="to_protect_privacy_simplex_has_ids_for_queues">K ochraně soukromí, místo uživatelských ID užívaných všemi ostatními platformami, SimpleX používá identifikátory pro fronty zpráv, zvlášť pro každý z vašich kontaktů.</string>
|
||||
<string name="many_people_asked_how_can_it_deliver"><![CDATA[Mnoho lidí se ptá: <i>když SimpleX nemá žádný identifikátor uživatelů, jak může doručovat zprávy\?</i>]]></string>
|
||||
<string name="you_control_servers_to_receive_your_contacts_to_send"><![CDATA[Vy určujete, přes které servery <b>přijímat</b> zprávy, vaše kontakty – servery, které používáte k zasílání zpráv.]]></string>
|
||||
@@ -679,8 +679,8 @@
|
||||
<string name="onboarding_notifications_mode_off">Když aplikace běží</string>
|
||||
<string name="onboarding_notifications_mode_service">Okamžité</string>
|
||||
<string name="onboarding_notifications_mode_off_desc"><![CDATA[<b>Nejlepší pro baterii</b>. Budete přijímat oznámení pouze když aplikace běží (žádná služba na pozadí).]]></string>
|
||||
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Dobré pro baterii</b>. Služba na pozadí bude kontrolovat každých 10 minut. Můžete zmeškat hovory nebo naléhavé zprávy.]]></string>
|
||||
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Využívá více baterie</b>! Služba na pozadí je spuštěna vždy - oznámení se zobrazí, jakmile jsou zprávy k dispozici.]]></string>
|
||||
<string name="onboarding_notifications_mode_periodic_desc"><![CDATA[<b>Dobré pro baterii</b>. Apka bude kontrolovat zprávy každých 10 minut. Můžete zmeškat volání nebo naléhavé zprávy.]]></string>
|
||||
<string name="onboarding_notifications_mode_service_desc"><![CDATA[<b>Využívá více baterie</b>! Apka stále běží na pozadí - oznámení se zobrazí okamžitě.]]></string>
|
||||
<string name="paste_the_link_you_received">Vložte přijatý odkaz</string>
|
||||
<string name="incoming_video_call">Příchozí videohovor</string>
|
||||
<string name="incoming_audio_call">Příchozí zvukový hovor</string>
|
||||
@@ -1582,7 +1582,7 @@
|
||||
<string name="profile_update_event_member_name_changed">člen %1$s změněn na %2$s</string>
|
||||
<string name="member_info_member_blocked">blokováno</string>
|
||||
<string name="member_blocked_by_admin">Blokováno adminem</string>
|
||||
<string name="share_text_created_at">Vytvořeno v: %s</string>
|
||||
<string name="share_text_created_at">Vytvořen v: %s</string>
|
||||
<string name="message_too_large">Zpráva příliš velká</string>
|
||||
<string name="remote_host_disconnected_from"><![CDATA[Odpojeno z mobilu <b>%s</b> z důvodu: %s]]></string>
|
||||
<string name="remote_host_was_disconnected_title">Spojení zastaveno</string>
|
||||
@@ -1817,8 +1817,7 @@
|
||||
<string name="v5_8_safe_files">Bezpečné přijímání souborů</string>
|
||||
<string name="v5_8_chat_themes">Nové motivy chatu</string>
|
||||
<string name="v5_8_private_routing">Soukromé směrování zpráv 🚀</string>
|
||||
<string name="v5_8_private_routing_descr">Chraňte vaši IP adresu před relé zpráv, které jste si vybrali.
|
||||
\nPovolit v nastavení *Síť & servery*.</string>
|
||||
<string name="v5_8_private_routing_descr">Chraňte vaši IP adresu před relé zpráv vašich kontaktů.\nPovolte v nastavení *Síť & servery*.</string>
|
||||
<string name="v5_8_message_delivery">Vylepšené doručování zpráv</string>
|
||||
<string name="v5_8_persian_ui">Perské UI</string>
|
||||
<string name="remote_ctrl_connection_stopped_desc">Prosím zkontrolujte, že mobil a desktop jsou připojeny ke stejné místní síti, a že stolní firewall umožňuje připojení.
|
||||
@@ -1862,4 +1861,193 @@
|
||||
<string name="cant_call_member_alert_title">Nelze zavolat člena skupiny</string>
|
||||
<string name="deleted_chats">Archivované kontakty</string>
|
||||
<string name="v6_0_your_contacts_descr">Archivujte kontakty pro pozdější chatování.</string>
|
||||
<string name="smp_proxy_error_broker_host">Adresa předávacího serveru je nekompatibilní s nastavením sítě: %1$s.</string>
|
||||
<string name="smp_proxy_error_broker_version">Verze předávacího serveru je nekompatibilní s nastavením sítě: %1$s.</string>
|
||||
<string name="proxy_destination_error_broker_host">Cílová adresa serveru %1$s je nekompatibilní s nastavením přeposílajícího serveru %2$s.</string>
|
||||
<string name="smp_proxy_error_connecting">Chyba připojení k přeposílajícímu serveru %1$s. Prosím, zkuste to později.</string>
|
||||
<string name="proxy_destination_error_failed_to_connect">Předávacímu serveru %1$s se nepodařilo připojit k cílovému serveru %2$s. Prosím, zkuste to později.</string>
|
||||
<string name="cannot_share_message_alert_text">Vybrané nastavení chatu zakazuje tuto zprávu.</string>
|
||||
<string name="smp_servers_other">Jiné SMP servery</string>
|
||||
<string name="smp_servers_configured">Nastavené SMP servery</string>
|
||||
<string name="servers_info_subscriptions_connections_pending">Probíhá</string>
|
||||
<string name="chunks_uploaded">Části nahrány</string>
|
||||
<string name="n_file_errors">%1$d chuba souboru(ů):\n%2$s</string>
|
||||
<string name="n_other_file_errors">%1$d jiná chyba souboru(ů).</string>
|
||||
<string name="error_forwarding_messages">Chyba přeposílaní zpráv</string>
|
||||
<string name="srv_error_host">Adresa serveru není kompatibilní s nastavením sítě.</string>
|
||||
<string name="forward_alert_title_messages_to_forward">Předat %1$s zpráv(u)?</string>
|
||||
<string name="forward_alert_title_nothing_to_forward">Nic k předání!</string>
|
||||
<string name="forward_alert_forward_messages_without_files">Předat zprávy bez souborů?</string>
|
||||
<string name="forward_files_failed_to_receive_desc">%1$d soubor(y) se nepodařilo stáhnout.</string>
|
||||
<string name="forward_files_not_accepted_desc">%1$d soubor(y) nestažen(y).</string>
|
||||
<string name="forward_files_missing_desc">%1$d soubor(y) smazán(y).</string>
|
||||
<string name="forward_files_messages_deleted_after_selection_title">%1$s zprávy nepředány</string>
|
||||
<string name="forward_files_not_accepted_receive_files">Stáhnout</string>
|
||||
<string name="compose_forward_messages_n">Předávám %1$s zpráv</string>
|
||||
<string name="forward_multiple">Předat zprávy…</string>
|
||||
<string name="compose_save_messages_n">Uložit %1$s zpráv</string>
|
||||
<string name="network_proxy_auth_mode_no_auth">Nepoužívat autorizaci s proxy.</string>
|
||||
<string name="network_proxy_incorrect_config_title">Chyba ukládání proxy</string>
|
||||
<string name="network_proxy_incorrect_config_desc">Ujistěte se, že nastavení proxy je správné.</string>
|
||||
<string name="network_proxy_password">Heslo</string>
|
||||
<string name="network_proxy_auth">Proxy autentizace</string>
|
||||
<string name="app_check_for_updates_button_install">Instalovat aktualizace</string>
|
||||
<string name="app_check_for_updates_button_open">Otevřít umístění souboru</string>
|
||||
<string name="app_check_for_updates_download_started">Stahování aktualizace, nezavírejte aplikaci</string>
|
||||
<string name="app_check_for_updates_installed_successfully_desc">Prosím restartujte aplikaci.</string>
|
||||
<string name="app_check_for_updates_installed_successfully_title">Instalovány úspěšně</string>
|
||||
<string name="app_check_for_updates_button_remind_later">Připomenout později</string>
|
||||
<string name="app_check_for_updates_notice_title">Zkontrolovat aktualizace</string>
|
||||
<string name="privacy_media_blur_radius_off">Vypnuto</string>
|
||||
<string name="settings_section_title_chat_database">CHAT DATABÁZE</string>
|
||||
<string name="member_info_member_disabled">vypnut</string>
|
||||
<string name="message_queue_info_server_info">info fronty serveru: %1$s\n\nposlední obdržená zpráva: %2$s</string>
|
||||
<string name="network_options_save_and_reconnect">Uložit a připojit znovu</string>
|
||||
<string name="v6_0_chat_list_media">Hrajte ze seznamu chatů.</string>
|
||||
<string name="servers_info_messages_received">Přijatých zprávy</string>
|
||||
<string name="servers_info_reconnect_servers_title">Znovu připojit servery?</string>
|
||||
<string name="completed">Kompletní</string>
|
||||
<string name="secured">Zabezpečeno</string>
|
||||
<string name="error_parsing_uri_desc">Prosím zkontrolujte, že SimpleX odkaz je správný.</string>
|
||||
<string name="error_parsing_uri_title">Chybný odkaz</string>
|
||||
<string name="proxy_destination_error_broker_version">Verze cílového serveru %1$s je nekompatibilní s nastavením přeposílajícího serveru %2$s.</string>
|
||||
<string name="message_forwarded_title">Zpráva předána</string>
|
||||
<string name="keep_conversation">Udržujte konverzaci</string>
|
||||
<string name="only_delete_conversation">Jen smazat konverzaci</string>
|
||||
<string name="confirm_delete_contact_question">Potvrdit smazání kontaktu?</string>
|
||||
<string name="delete_contact_cannot_undo_warning">Kontakt bude smazán - nelze vrátit!</string>
|
||||
<string name="conversation_deleted">Konverzace odstraněna!</string>
|
||||
<string name="paste_link">Vložit odkaz</string>
|
||||
<string name="chat_database_exported_title">Chat databáze exportována</string>
|
||||
<string name="cant_send_message_to_member_alert_title">Členu skupiny nelze odeslat zprávu</string>
|
||||
<string name="calls_prohibited_ask_to_enable_calls_alert_text">Požádejte váš kontakt ať povolí volání.</string>
|
||||
<string name="color_sent_quote">Odeslaných odpovědí</string>
|
||||
<string name="wallpaper_scale">Škálovat</string>
|
||||
<string name="wallpaper_scale_fit">Přizpůsobit</string>
|
||||
<string name="v6_0_privacy_blur">Rozmazání pro lepší soukromí.</string>
|
||||
<string name="v6_0_connect_faster_descr">Připojte se k vašim přátelům rychleji.</string>
|
||||
<string name="v6_0_delete_many_messages_descr">Smazat až 20 zpráv najednou.</string>
|
||||
<string name="v6_0_increase_font_size">Zvětšit velikost písma.</string>
|
||||
<string name="v6_0_connection_servers_status_descr">Stav připojení a serverů.</string>
|
||||
<string name="v6_0_connection_servers_status">Kontrolujte svou síť</string>
|
||||
<string name="servers_info_sessions_errors">Chyby</string>
|
||||
<string name="servers_info_sessions_connected">Připojen</string>
|
||||
<string name="servers_info_sessions_connecting">Připojování</string>
|
||||
<string name="servers_info_connected_servers_section_header">Připojené servery</string>
|
||||
<string name="servers_info_previously_connected_servers_section_header">Dříve připojené servery</string>
|
||||
<string name="acknowledged">Potvrzeno</string>
|
||||
<string name="duplicates_label">duplikáty</string>
|
||||
<string name="deleted">Smazán</string>
|
||||
<string name="open_server_settings_button">Otevřít nastavení serveru</string>
|
||||
<string name="v6_0_new_chat_experience">Nový zážitek z chatu 🎉</string>
|
||||
<string name="v6_0_new_media_options">Nové možnosti médií</string>
|
||||
<string name="new_message">Nová zpráva</string>
|
||||
<string name="scan_paste_link">Skenovat / Vložit odkaz</string>
|
||||
<string name="no_filtered_contacts">Žádné filtrované kontakty</string>
|
||||
<string name="error_initializing_web_view_wrong_arch">Chyba inicializace WebView. Ujistěte se, že máte nainstalován WebView podporující architekturu arm64.\nChyba: %s</string>
|
||||
<string name="v6_0_private_routing_descr">Chrání vaši IP adresu a připojení.</string>
|
||||
<string name="forward_files_messages_deleted_after_selection_desc">Zprávy byly odstraněny poté, co jste je vybrali.</string>
|
||||
<string name="network_session_mode_session_description">Nové přihlašovací údaje SOCKS budou použity pokaždé, když zapnete aplikaci.</string>
|
||||
<string name="network_session_mode_server_description">Nové přihlašovací údaje SOCKS budou použity pro každý server.</string>
|
||||
<string name="servers_info_reconnect_servers_message">Znovu připojte všechny připojené servery pro vynucení doručení. Využívá další provoz.</string>
|
||||
<string name="reset_all_hints">Resetovat všechny tipy</string>
|
||||
<string name="forward_files_in_progress_desc">%1$d soubor(y) stále stahuji.</string>
|
||||
<string name="v6_1_message_dates_descr">Lepší datování zpráv.</string>
|
||||
<string name="v6_1_better_security">Lepší zabezpečení ✅</string>
|
||||
<string name="chunks_deleted">Části odstraněny</string>
|
||||
<string name="info_view_connect_button">připojení</string>
|
||||
<string name="current_user">Aktuální profil</string>
|
||||
<string name="servers_info_reconnect_server_error">Chyba znovu připojení serveru</string>
|
||||
<string name="servers_info_reconnect_servers_error">Chyba při opětovném připojování serverů</string>
|
||||
<string name="servers_info_reconnect_server_message">Znovu připojte server pro vynucení doručení. Využívá další provoz.</string>
|
||||
<string name="servers_info_modal_error_title">Chyba</string>
|
||||
<string name="delete_messages_cannot_be_undone_warning">Zprávy budou smazány - nelze vrátit!</string>
|
||||
<string name="delete_without_notification">Smazat bez upozornění</string>
|
||||
<string name="info_view_search_button">hledat</string>
|
||||
<string name="switching_profile_error_title">Chyba přepínání profilu</string>
|
||||
<string name="select_chat_profile">Vyberte chat profil</string>
|
||||
<string name="info_view_message_button">zpráva</string>
|
||||
<string name="info_view_open_button">otevřít</string>
|
||||
<string name="contact_deleted">Kontakt smazán!</string>
|
||||
<string name="member_info_member_inactive">neaktivní</string>
|
||||
<string name="servers_info_details">Detaily</string>
|
||||
<string name="servers_info_reset_stats">Resetovat všechny statistiky</string>
|
||||
<string name="please_try_later">Prosím zkuste později.</string>
|
||||
<string name="private_routing_error">Chyba soukromého směrování</string>
|
||||
<string name="network_error_broker_host_desc">Adresa serveru není kompatibilní s nastavením sítě: %1$s.</string>
|
||||
<string name="member_inactive_title">Člen neaktivní</string>
|
||||
<string name="member_inactive_desc">Zpráva může být doručena později až bude člen aktivní.</string>
|
||||
<string name="message_forwarded_desc">Zatím bez přímého spojení, zpráva je předána adminem.</string>
|
||||
<string name="cant_call_contact_connecting_wait_alert_text">Připojování ke kontaktu, počkejte nebo se podívejte později!</string>
|
||||
<string name="cant_call_contact_deleted_alert_text">Kontakt odstraněn.</string>
|
||||
<string name="deletion_errors">Chyby mazání</string>
|
||||
<string name="servers_info_detailed_statistics">Podrobné statistiky</string>
|
||||
<string name="chunks_downloaded">Části staženy</string>
|
||||
<string name="network_session_mode_server">Server</string>
|
||||
<string name="network_smp_proxy_fallback_allow_protected_description">Odesílat zprávy přímo, když je IP adresa chráněna a váš nebo cílový server nepodporuje soukromé směrování.</string>
|
||||
<string name="network_smp_proxy_fallback_allow_description">Odeslat zprávy přímo, když váš nebo cílový server nepodporuje soukromé směrování.</string>
|
||||
<string name="app_check_for_updates">Zkontrolovat aktualizace</string>
|
||||
<string name="app_check_for_updates_notice_disable">Vypnout</string>
|
||||
<string name="app_check_for_updates_disabled">Vypnut</string>
|
||||
<string name="app_check_for_updates_button_download">Stáhnout %s (%s)</string>
|
||||
<string name="invite_friends_short">Pozvat</string>
|
||||
<string name="create_address_button">Vytvořit</string>
|
||||
<string name="settings_message_shape_corner">Roh</string>
|
||||
<string name="settings_section_title_message_shape">Tvar zpráv</string>
|
||||
<string name="chat_database_exported_continue">Pokračovat</string>
|
||||
<string name="call_desktop_permission_denied_chrome">Klikněte na info tlačítko blízko pole adresy, pro použití mikrofonu.</string>
|
||||
<string name="call_desktop_permission_denied_safari">Otevřete nastavení Safari / Webové stránky / mikrofon, vyberte možnost Povolit pro localhost.</string>
|
||||
<string name="appearance_font_size">Velikost písma</string>
|
||||
<string name="v6_0_upgrade_app_descr">Stáhnout nové verze z GitHubu.</string>
|
||||
<string name="v6_0_reachable_chat_toolbar">Dosažitelný panel nástrojů chatu</string>
|
||||
<string name="migrate_from_device_remove_archive_question">Odebrat archiv?</string>
|
||||
<string name="servers_info_files_tab">Soubory</string>
|
||||
<string name="servers_info_messages_sent">Odeslaných zpráv</string>
|
||||
<string name="servers_info_downloaded">Staženo</string>
|
||||
<string name="servers_info_reconnect_server_title">Znovu připojit server?</string>
|
||||
<string name="decryption_errors">chyba dešifrování</string>
|
||||
<string name="v6_1_better_calls">Lepší volání</string>
|
||||
<string name="v6_1_better_user_experience">Větší přívětivost</string>
|
||||
<string name="v6_1_customizable_message_descr">Přizpůsobitelný tvar zpráv.</string>
|
||||
<string name="v6_1_delete_many_messages_descr">Smazat nebo moderovat až 200 zpráv.</string>
|
||||
<string name="v6_1_forward_many_messages_descr">Předat až 20 zpráv najednou.</string>
|
||||
<string name="servers_info_missing">Žádné info, zkuste načíst znovu</string>
|
||||
<string name="servers_info">Informace o serverech</string>
|
||||
<string name="downloaded_files">Stažené soubory</string>
|
||||
<string name="download_errors">Chyby stahování</string>
|
||||
<string name="servers_info_reset_stats_alert_error_title">Chyba resetování statistik</string>
|
||||
<string name="servers_info_detailed_statistics_received_messages_header">Přijaté zprávy</string>
|
||||
<string name="servers_info_detailed_statistics_received_total">Přijato celkem</string>
|
||||
<string name="servers_info_detailed_statistics_receive_errors">Chyb přijmutí</string>
|
||||
<string name="servers_info_reconnect_all_servers_button">Připojte znovu všechny servery</string>
|
||||
<string name="servers_info_reset_stats_alert_confirm">Reset</string>
|
||||
<string name="servers_info_reset_stats_alert_title">Resetovat všechny statistiky?</string>
|
||||
<string name="servers_info_detailed_statistics_sent_messages_header">Odeslané zprávy</string>
|
||||
<string name="servers_info_detailed_statistics_sent_messages_total">Odeslaných celkem</string>
|
||||
<string name="server_address">Adresa serveru</string>
|
||||
<string name="one_hand_ui">Dosažitelný panel nástrojů chatu</string>
|
||||
<string name="acknowledgement_errors">Chyba potvrzení</string>
|
||||
<string name="connections">Připojení</string>
|
||||
<string name="created">Vytvořen</string>
|
||||
<string name="expired_label">prošlý</string>
|
||||
<string name="other_label">jiné</string>
|
||||
<string name="other_errors">jiné chyby</string>
|
||||
<string name="reconnect">Znovu připojit</string>
|
||||
<string name="send_errors">Chyby odesílání</string>
|
||||
<string name="sent_directly">Odesláno přímo</string>
|
||||
<string name="sent_via_proxy">Odeslaných přes proxy</string>
|
||||
<string name="delete_members_messages__question">Odstranit %d zpráv členů?</string>
|
||||
<string name="delete_messages_mark_deleted_warning">Zprávy budou označeny pro smazání. Příjemci budou moci tyto zprávy odhalit.</string>
|
||||
<string name="select_verb">Vybrat</string>
|
||||
<string name="compose_message_placeholder">Zpráva</string>
|
||||
<string name="selected_chat_items_nothing_selected">Nic nevybráno</string>
|
||||
<string name="selected_chat_items_selected_n">Vybrány %d</string>
|
||||
<string name="privacy_media_blur_radius_medium">Střední</string>
|
||||
<string name="servers_info_subscriptions_section_header">Příjem zpráv</string>
|
||||
<string name="xftp_servers_configured">Nastavené XFTP servery</string>
|
||||
<string name="media_and_file_servers">Servery médií a souborů</string>
|
||||
<string name="message_servers">Servery zpráv</string>
|
||||
<string name="xftp_servers_other">Jiné FXTP servery</string>
|
||||
<string name="action_button_add_members">Pozvat</string>
|
||||
<string name="cant_call_member_send_message_alert_text">Pošlete zprávu pro povolení volání.</string>
|
||||
</resources>
|
||||
@@ -1990,7 +1990,7 @@
|
||||
<string name="downloaded_files">Heruntergeladene Dateien</string>
|
||||
<string name="download_errors">Fehler beim Herunterladen</string>
|
||||
<string name="duplicates_label">Duplikate</string>
|
||||
<string name="expired_label">abgelaufen</string>
|
||||
<string name="expired_label">Abgelaufen</string>
|
||||
<string name="open_server_settings_button">Server-Einstellungen öffnen</string>
|
||||
<string name="other_errors">Andere Fehler</string>
|
||||
<string name="proxied">Proxy</string>
|
||||
@@ -2188,4 +2188,25 @@
|
||||
<string name="forward_multiple">Nachrichten werden weitergeleitet…</string>
|
||||
<string name="compose_save_messages_n">Es wird/werden %1$s Nachricht(en) gesichert</string>
|
||||
<string name="icon_descr_sound_muted">Ton stummgeschaltet</string>
|
||||
<string name="error_initializing_web_view_wrong_arch">Fehler bei der Initialisierung von WebView. Stellen Sie sicher, dass Sie WebView installiert haben, und es die ARM64-Architektur unterstützt.\nFehler: %s</string>
|
||||
<string name="settings_section_title_message_shape">Form der Nachricht</string>
|
||||
<string name="settings_message_shape_tail">Sprechblase</string>
|
||||
<string name="settings_message_shape_corner">Abrundung Ecken</string>
|
||||
<string name="network_session_mode_session">App-Sitzung</string>
|
||||
<string name="network_session_mode_server_description">Für jeden Server werden neue SOCKS-Anmeldeinformationen genutzt</string>
|
||||
<string name="network_session_mode_server">Server</string>
|
||||
<string name="call_desktop_permission_denied_chrome">Klicken Sie auf die Info-Schaltfläche neben dem Adressfeld, um die Verwendung des Mikrofons zu erlauben.</string>
|
||||
<string name="call_desktop_permission_denied_title">Um Anrufe durchzuführen, erlauben Sie die Nutzung Ihres Mikrofons. Beenden Sie den Anruf und versuchen Sie es erneut.</string>
|
||||
<string name="call_desktop_permission_denied_safari">Öffnen Sie die Safari-Einstellungen / Webseiten / Mikrofon und wählen Sie dann \"Für Localhost erlauben\".</string>
|
||||
<string name="v6_1_better_calls">Verbesserte Anrufe</string>
|
||||
<string name="v6_1_customizable_message_descr">Anpassbares Format des Nachrichtenfelds</string>
|
||||
<string name="v6_1_delete_many_messages_descr">Bis zu 200 Nachrichten löschen oder moderieren</string>
|
||||
<string name="v6_1_forward_many_messages_descr">Bis zu 20 Nachrichten auf einmal weiterleiten</string>
|
||||
<string name="v6_1_better_security_descr">Die SimpleX-Protokolle wurden von Trail of Bits überprüft.</string>
|
||||
<string name="v6_1_better_calls_descr">Während des Anrufs zwischen Audio und Video wechseln</string>
|
||||
<string name="v6_1_switch_chat_profile_descr">Das Chat-Profil für Einmal-Einladungen wechseln</string>
|
||||
<string name="network_session_mode_session_description">Jedes Mal wenn Sie die App starten, werden neue SOCKS-Anmeldeinformationen genutzt</string>
|
||||
<string name="v6_1_better_security">Verbesserte Sicherheit ✅</string>
|
||||
<string name="v6_1_message_dates_descr">Verbesserte Nachrichten-Datumsinformation</string>
|
||||
<string name="v6_1_better_user_experience">Verbesserte Nutzer-Erfahrung</string>
|
||||
</resources>
|
||||
@@ -227,4 +227,20 @@
|
||||
<string name="deleted_description">διαγράφτηκε</string>
|
||||
<string name="moderated_item_description">με συντονιστή %s</string>
|
||||
<string name="blocked_item_description">φραγμένος</string>
|
||||
<string name="learn_more_about_address">Σχετικά με τη διεύθυνση SimpleX</string>
|
||||
<string name="conn_event_ratchet_sync_started">συμφωνία κρυπτογράφησης…</string>
|
||||
<string name="chat_theme_apply_to_all_modes">Όλες οι χρωματικές λειτουργίες</string>
|
||||
<string name="abort_switch_receiving_address_desc">Η αλλαγή διεύθυνσης θα ακυρωθεί. Θα χρησιμοποιηθεί η παλιά διεύθυνση παραλαβής.</string>
|
||||
<string name="servers_info_subscriptions_connections_subscribed">Ενεργές συνδέσεις</string>
|
||||
<string name="network_settings_title">Προχωρημένες ρυθμίσεις</string>
|
||||
<string name="color_primary_variant">Πρόσθετη προφορά</string>
|
||||
<string name="add_contact_tab">Προσθήκη επαφής</string>
|
||||
<string name="abort_switch_receiving_address">Διακοπή αλλαγής διεύθυνσης</string>
|
||||
<string name="wallpaper_advanced_settings">Προχωρημένες ρυθμίσεις</string>
|
||||
<string name="v5_6_safer_groups_descr">Οι διαχειριστές μπορούν να αποκλείσουν ένα μέλος για όλους.</string>
|
||||
<string name="acknowledged">Αναγνωρισμένο</string>
|
||||
<string name="above_then_preposition_continuation">παραπάνω, λοιπόν:</string>
|
||||
<string name="add_address_to_your_profile">Προσθέστε τη διεύθυνση στο προφίλ σας, έτσι ώστε οι επαφές σας να μπορούν να τη μοιραστούν με άλλα άτομα. Το ενημέρωμένο προφίλ θα σταλεί στις επαφές σας.</string>
|
||||
<string name="feature_roles_admins">διαχειριστές</string>
|
||||
<string name="acknowledgement_errors">Λάθη αναγνώρισης</string>
|
||||
</resources>
|
||||
@@ -366,7 +366,7 @@
|
||||
<string name="description_via_contact_address_link_incognito">en modo incógnito mediante enlace de dirección del contacto</string>
|
||||
<string name="failed_to_create_user_title">¡Error al crear perfil!</string>
|
||||
<string name="failed_to_parse_chat_title">No se pudo cargar el chat</string>
|
||||
<string name="failed_to_parse_chats_title">No se pudieron cargar los chats</string>
|
||||
<string name="failed_to_parse_chats_title">Fallo en la carga de chats</string>
|
||||
<string name="simplex_link_mode_full">Enlace completo</string>
|
||||
<string name="error_deleting_contact">Error al eliminar contacto</string>
|
||||
<string name="error_joining_group">Error al unirte al grupo</string>
|
||||
@@ -562,7 +562,7 @@
|
||||
<string name="rcv_group_event_member_left">ha salido</string>
|
||||
<string name="button_leave_group">Salir del grupo</string>
|
||||
<string name="only_group_owners_can_change_prefs">Sólo los propietarios pueden modificar las preferencias del grupo.</string>
|
||||
<string name="users_delete_data_only">Sólo datos del perfil</string>
|
||||
<string name="users_delete_data_only">Eliminar sólo el perfil</string>
|
||||
<string name="chat_preferences_no">no</string>
|
||||
<string name="thousand_abbreviation">k</string>
|
||||
<string name="marked_deleted_description">marcado eliminado</string>
|
||||
@@ -579,7 +579,7 @@
|
||||
<string name="make_private_connection">Establecer una conexión privada</string>
|
||||
<string name="network_error_desc">Comprueba tu conexión de red con %1$s e inténtalo de nuevo.</string>
|
||||
<string name="sender_may_have_deleted_the_connection_request">El remitente puede haber eliminado la solicitud de conexión.</string>
|
||||
<string name="error_smp_test_certificate">Posiblemente la huella digital del certificado en la dirección del servidor es incorrecta</string>
|
||||
<string name="error_smp_test_certificate">Posiblemente la huella del certificado en la dirección del servidor es incorrecta</string>
|
||||
<string name="reply_verb">Responder</string>
|
||||
<string name="save_passphrase_in_keychain">Guardar contraseña en Keystore</string>
|
||||
<string name="database_restore_error">Error al restaurar base de datos</string>
|
||||
@@ -668,7 +668,7 @@
|
||||
<string name="receiving_via">Recibiendo vía</string>
|
||||
<string name="network_option_protocol_timeout">Timeout protocolo</string>
|
||||
<string name="network_option_seconds_label">seg</string>
|
||||
<string name="users_delete_with_connections">Datos del perfil y conexiones</string>
|
||||
<string name="users_delete_with_connections">Eliminar perfil y conexiones</string>
|
||||
<string name="prohibit_sending_disappearing_messages">No se permiten mensajes temporales.</string>
|
||||
<string name="only_you_can_send_voice">Sólo tú puedes enviar mensajes de voz.</string>
|
||||
<string name="only_your_contact_can_send_voice">Sólo tu contacto puede enviar mensajes de voz.</string>
|
||||
@@ -820,7 +820,7 @@
|
||||
<string name="trying_to_connect_to_server_to_receive_messages">Intentando conectar con el servidor para recibir mensajes de este contacto.</string>
|
||||
<string name="unknown_message_format">formato de mensaje desconocido</string>
|
||||
<string name="trying_to_connect_to_server_to_receive_messages_with_error">Intentando conectar con el servidor para recibir mensajes de este contacto (error: %1$s).</string>
|
||||
<string name="error_smp_test_failed_at_step">Prueba fallida en el paso %s.</string>
|
||||
<string name="error_smp_test_failed_at_step">Prueba no superada en el paso %s.</string>
|
||||
<string name="tap_to_start_new_chat">Pulsa para iniciar chat nuevo</string>
|
||||
<string name="share_message">Compartir mensaje…</string>
|
||||
<string name="share_image">Compartir medios…</string>
|
||||
@@ -832,8 +832,8 @@
|
||||
<string name="switch_receiving_address">Cambiar servidor de recepción</string>
|
||||
<string name="group_is_decentralized">Totalmente descentralizado. Visible sólo para los miembros.</string>
|
||||
<string name="to_connect_via_link_title">Para conectarte mediante enlace</string>
|
||||
<string name="smp_servers_test_failed">¡Error en prueba del servidor!</string>
|
||||
<string name="smp_servers_test_some_failed">Algunos servidores no superaron la prueba:</string>
|
||||
<string name="smp_servers_test_failed">¡Prueba no superada!</string>
|
||||
<string name="smp_servers_test_some_failed">Algunos servidores no han superado la prueba:</string>
|
||||
<string name="smp_servers_use_server">Usar servidor</string>
|
||||
<string name="smp_servers_use_server_for_new_conn">Usar para conexiones nuevas</string>
|
||||
<string name="theme_system">Sistema</string>
|
||||
@@ -1627,9 +1627,9 @@
|
||||
<string name="past_member_vName">Miembro pasado %1$s</string>
|
||||
<string name="profile_update_event_member_name_changed">el miembro %1$s ha cambiado a %2$s</string>
|
||||
<string name="profile_update_event_removed_address">dirección de contacto eliminada</string>
|
||||
<string name="profile_update_event_removed_picture">imagen de perfil eliminada</string>
|
||||
<string name="profile_update_event_removed_picture">ha eliminado la imagen del perfil</string>
|
||||
<string name="profile_update_event_set_new_address">nueva dirección de contacto</string>
|
||||
<string name="profile_update_event_set_new_picture">nueva imagen de perfil</string>
|
||||
<string name="profile_update_event_set_new_picture">tiene nueva imagen del perfil</string>
|
||||
<string name="call_service_notification_audio_call">Llamada</string>
|
||||
<string name="call_service_notification_end_call">Llamada finalizada</string>
|
||||
<string name="call_service_notification_video_call">Videollamada</string>
|
||||
@@ -1686,7 +1686,7 @@
|
||||
<string name="migrate_from_device_finalize_migration">Finalizar migración</string>
|
||||
<string name="migrate_from_device_archive_will_be_deleted"><![CDATA[<b>Atención</b>: el archivo será eliminado.]]></string>
|
||||
<string name="migrate_from_device_check_connection_and_try_again">Comprueba tu conexión a internet y vuelve a intentarlo</string>
|
||||
<string name="migrate_from_device_confirm_you_remember_passphrase">Para migrar confirma que recuerdas la frase de contraseña de la base de datos.</string>
|
||||
<string name="migrate_from_device_confirm_you_remember_passphrase">Para migrar la base de datos confirma que recuerdas la frase de contraseña.</string>
|
||||
<string name="migrate_from_device_error_verifying_passphrase">Error al verificar la frase de contraseña:</string>
|
||||
<string name="migrate_from_device_using_on_two_device_breaks_encryption"><![CDATA[<b>Recuerda</b>: usar la misma base de datos en dos dispositivos hará que falle el descifrado de mensajes como protección de seguridad.]]></string>
|
||||
<string name="migrate_from_device_choose_migrate_from_another_device"><![CDATA[En el nuevo dispositivo selecciona <i>Migrar desde otro dispositivo</i> y escanea el código QR.]]></string>
|
||||
@@ -2107,4 +2107,25 @@
|
||||
<string name="new_chat_share_profile">Comparte perfil</string>
|
||||
<string name="switching_profile_error_message">Tu conexión ha sido trasladada a %s pero ha ocurrido un error inesperado al redirigirte al perfil.</string>
|
||||
<string name="icon_descr_sound_muted">Sonido silenciado</string>
|
||||
<string name="error_initializing_web_view_wrong_arch">Error al iniciar WebView. Asegúrate de tener WebView instalado y que sea compatible con la arquitectura amr64.\nError: %s</string>
|
||||
<string name="settings_section_title_message_shape">Forma del mensaje</string>
|
||||
<string name="settings_message_shape_corner">Esquinas</string>
|
||||
<string name="settings_message_shape_tail">Cola</string>
|
||||
<string name="network_session_mode_session_description">Se usarán credenciales SOCKS nuevas cada vez que inicies la aplicación.</string>
|
||||
<string name="network_session_mode_session">Sesión de aplicación</string>
|
||||
<string name="call_desktop_permission_denied_safari">Abre la configuración de Safari / Sitios Web / Micrófono y a continuación selecciona Permitir para localhost.</string>
|
||||
<string name="call_desktop_permission_denied_chrome">Pulsa el botón info del campo dirección para permitir el uso del micrófono.</string>
|
||||
<string name="call_desktop_permission_denied_title">Para hacer llamadas, permite el uso del micrófono. Cuelga e intenta llamar de nuevo.</string>
|
||||
<string name="network_session_mode_server_description">Se usarán credenciales SOCKS nuevas por cada servidor.</string>
|
||||
<string name="network_session_mode_server">Servidor</string>
|
||||
<string name="v6_1_better_calls">Llamadas mejoradas</string>
|
||||
<string name="v6_1_message_dates_descr">Sistema de fechas mejorado.</string>
|
||||
<string name="v6_1_better_user_experience">Experiencia de usuario mejorada</string>
|
||||
<string name="v6_1_customizable_message_descr">Forma personalizable de los mensajes.</string>
|
||||
<string name="v6_1_forward_many_messages_descr">Desplazamiento de hasta 20 mensajes.</string>
|
||||
<string name="v6_1_better_security_descr">Protocolos de SimpleX auditados por Trail of Bits.</string>
|
||||
<string name="v6_1_better_calls_descr">Intercambia audio y video durante la llamada.</string>
|
||||
<string name="v6_1_better_security">Seguridad mejorada ✅</string>
|
||||
<string name="v6_1_delete_many_messages_descr">Borra o modera hasta 200 mensajes a la vez.</string>
|
||||
<string name="v6_1_switch_chat_profile_descr">Cambia el perfil de chat para invitaciones de un solo uso.</string>
|
||||
</resources>
|
||||
@@ -14,7 +14,7 @@
|
||||
<string name="abort_switch_receiving_address_confirm">Megszakítás</string>
|
||||
<string name="send_disappearing_message_30_seconds">30 másodperc</string>
|
||||
<string name="one_time_link_short">Egyszer használható hivatkozás</string>
|
||||
<string name="contact_wants_to_connect_via_call">%1$s szeretne kapcsolatba lépni önnel ezen keresztül:</string>
|
||||
<string name="contact_wants_to_connect_via_call">%1$s szeretne kapcsolatba lépni Önnel ezen keresztül:</string>
|
||||
<string name="about_simplex_chat">A SimpleX Chatről</string>
|
||||
<string name="chat_item_ttl_day">1 nap</string>
|
||||
<string name="abort_switch_receiving_address">Címváltoztatás megszakítása</string>
|
||||
@@ -25,7 +25,7 @@
|
||||
<string name="accept_feature">Elfogadás</string>
|
||||
<string name="accept_call_on_lock_screen">Elfogadás</string>
|
||||
<string name="above_then_preposition_continuation">gombra fent, majd:</string>
|
||||
<string name="accept_contact_incognito_button">Elfogadás inkognítóban</string>
|
||||
<string name="accept_contact_incognito_button">Elfogadás inkognitóban</string>
|
||||
<string name="accept_connection_request__question">Kapcsolatkérés elfogadása?</string>
|
||||
<string name="accept_contact_button">Elfogadás</string>
|
||||
<string name="accept">Elfogadás</string>
|
||||
@@ -49,7 +49,7 @@
|
||||
<string name="socks_proxy_setting_limitations"><![CDATA[<b>Megjegyzés:</b> az üzenet- és fájlközvetítő-kiszolgálók SOCKS proxyn keresztül kapcsolódnak. A hívások és a hivatkozások előnézetének elküldése közvetlen kapcsolatot használnak.]]></string>
|
||||
<string name="full_backup">Alkalmazásadatok biztonsági mentése</string>
|
||||
<string name="database_initialization_error_title">Az adatbázis előkészítése sikertelen</string>
|
||||
<string name="all_your_contacts_will_remain_connected_update_sent">Az ismerőseivel kapcsolatban marad. A profil változtatások frissítésre kerülnek az ismerősöknél.</string>
|
||||
<string name="all_your_contacts_will_remain_connected_update_sent">Az ismerőseivel kapcsolatban marad. A profil-változtatások frissítésre kerülnek az ismerősöknél.</string>
|
||||
<string name="v4_5_transport_isolation_descr">A csevegési profillal (alapértelmezett), vagy a kapcsolattal (BÉTA).</string>
|
||||
<string name="connect__a_new_random_profile_will_be_shared">Egy új véletlenszerű profil lesz megosztva.</string>
|
||||
<string name="allow_voice_messages_only_if">A hangüzenetek küldése csak abban az esetben van engedélyezve, ha az ismerőse is engedélyezi.</string>
|
||||
@@ -70,8 +70,8 @@
|
||||
<string name="available_in_v51">"
|
||||
\nElérhető a v5.1-ben"</string>
|
||||
<string name="both_you_and_your_contacts_can_delete">Mindkét fél véglegesen törölheti az elküldött üzeneteket. (24 óra)</string>
|
||||
<string name="v5_4_better_groups">Javított csoportok</string>
|
||||
<string name="clear_chat_warning">Minden üzenet törlésre kerül - ez a művelet nem vonható vissza! Az üzenetek CSAK az ön számára törlődnek.</string>
|
||||
<string name="v5_4_better_groups">Továbbfejlesztett csoportok</string>
|
||||
<string name="clear_chat_warning">Minden üzenet törlésre kerül - ez a művelet nem vonható vissza! Az üzenetek CSAK az Ön számára törlődnek.</string>
|
||||
<string name="icon_descr_call_ended">Hívás befejeződött</string>
|
||||
<string name="settings_section_title_calls">HÍVÁSOK</string>
|
||||
<string name="rcv_group_and_other_events">és további %d esemény</string>
|
||||
@@ -138,7 +138,7 @@
|
||||
<string name="allow_your_contacts_irreversibly_delete">Az elküldött üzenetek végleges törlése engedélyezve van az ismerősei számára. (24 óra)</string>
|
||||
<string name="cancel_verb">Mégse</string>
|
||||
<string name="notifications_mode_off_desc">Az alkalmazás csak akkor tud értesítéseket fogadni, amikor meg van nyitva. A háttérszolgáltatás nem indul el</string>
|
||||
<string name="v5_1_better_messages">Jobb üzenetek</string>
|
||||
<string name="v5_1_better_messages">Továbbfejlesztett üzenetek</string>
|
||||
<string name="abort_switch_receiving_address_desc">A cím módosítása megszakad. A régi fogadási cím kerül felhasználásra.</string>
|
||||
<string name="allow_verb">Engedélyezés</string>
|
||||
<string name="bad_desktop_address">Hibás számítógép cím</string>
|
||||
@@ -191,20 +191,20 @@
|
||||
<string name="switch_receiving_address_question">Megváltoztatja a fogadó címet?</string>
|
||||
<string name="rcv_conn_event_switch_queue_phase_completed">cím megváltoztatva</string>
|
||||
<string name="change_self_destruct_mode">Önmegsemmisítő mód megváltoztatása</string>
|
||||
<string name="rcv_group_event_changed_your_role">megváltoztatta az ön szerepkörét erre: %s</string>
|
||||
<string name="rcv_group_event_changed_your_role">megváltoztatta az Ön szerepkörét erre: %s</string>
|
||||
<string name="connect_button">Kapcsolódás</string>
|
||||
<string name="connect_via_member_address_alert_title">Közvetlen kapcsolódás?</string>
|
||||
<string name="smp_server_test_connect">Kapcsolódás</string>
|
||||
<string name="rcv_group_event_member_created_contact">közvetlenül kapcsolódva</string>
|
||||
<string name="rcv_group_event_member_created_contact">közvetlenül kapcsolódott</string>
|
||||
<string name="connection_local_display_name">kapcsolat %1$d</string>
|
||||
<string name="status_contact_has_e2e_encryption">az ismerős e2e titkosítással rendelkezik</string>
|
||||
<string name="v5_4_incognito_groups_descr">Csoport létrehozása véletlenszerű profillal.</string>
|
||||
<string name="delete_contact_all_messages_deleted_cannot_undo_warning">Az ismerős és az összes üzenet törlésre kerül - ez a művelet nem vonható vissza!</string>
|
||||
<string name="contacts_can_mark_messages_for_deletion">Az ismerősei törlésre jelölhetnek üzeneteket; ön majd meg tudja nézni azokat.</string>
|
||||
<string name="contacts_can_mark_messages_for_deletion">Az ismerősei törlésre jelölhetnek üzeneteket; Ön majd meg tudja nézni azokat.</string>
|
||||
<string name="connect_via_invitation_link">Kapcsolódás egyszer használható hivatkozással?</string>
|
||||
<string name="connect_via_link_or_qr">Kapcsolódás egy hivatkozáson vagy QR-kódon keresztül</string>
|
||||
<string name="connection_error_auth">Kapcsolódási hiba (AUTH)</string>
|
||||
<string name="notification_preview_mode_contact">Ismerős neve</string>
|
||||
<string name="notification_preview_mode_contact">Csak név</string>
|
||||
<string name="connect_via_contact_link">Kapcsolódik a kapcsolattartási címen keresztül?</string>
|
||||
<string name="create_address">Cím létrehozása</string>
|
||||
<string name="copy_verb">Másolás</string>
|
||||
@@ -219,7 +219,7 @@
|
||||
<string name="connecting_to_desktop">Kapcsolódás a számítógéphez</string>
|
||||
<string name="network_session_mode_entity">Kapcsolat</string>
|
||||
<string name="correct_name_to">Név helyesbítése erre: %s?</string>
|
||||
<string name="connection_timeout">Kapcsolat időtúllépés</string>
|
||||
<string name="connection_timeout">Időtúllépés kapcsolódáskor</string>
|
||||
<string name="connect_with_contact_name_question">Kapcsolódás %1$s által?</string>
|
||||
<string name="create_profile_button">Létrehozás</string>
|
||||
<string name="contact_preferences">Ismerős beállításai</string>
|
||||
@@ -338,10 +338,10 @@
|
||||
<string name="delete_image">Kép törlése</string>
|
||||
<string name="smp_server_test_create_file">Fájl létrehozása</string>
|
||||
<string name="create_secret_group_title">Tikos csoport létrehozása</string>
|
||||
<string name="clear_contacts_selection_button">Kiürítés</string>
|
||||
<string name="clear_contacts_selection_button">Elvetés</string>
|
||||
<string name="delete_contact_question">Ismerős törlése?</string>
|
||||
<string name="clear_verb">Kiürítés</string>
|
||||
<string name="create_address_and_let_people_connect">Cím létrehozása, hogy az emberek kapcsolatba léphessenek önnel.</string>
|
||||
<string name="create_address_and_let_people_connect">Cím létrehozása, hogy az emberek kapcsolatba léphessenek Önnel.</string>
|
||||
<string name="v4_4_verify_connection_security_desc">Biztonsági kódok összehasonlítása az ismerősökével.</string>
|
||||
<string name="smp_server_test_compare_file">Fájl-összehasonlítás</string>
|
||||
<string name="your_chats">Csevegések</string>
|
||||
@@ -357,7 +357,7 @@
|
||||
<string name="database_encryption_will_be_updated_in_settings">Adatbázis titkosítási jelmondat frissül és eltárolásra kerül a beállításokban.</string>
|
||||
<string name="info_row_database_id">Adatbázis-azonosító</string>
|
||||
<string name="share_text_database_id">Adatbázis-azonosító: %d</string>
|
||||
<string name="developer_options">Adatbázis-azonosítók és átviteli izolációs beállítások.</string>
|
||||
<string name="developer_options">Adatbázis-azonosítók és átvitel-izolációs beállítások.</string>
|
||||
<string name="database_encryption_will_be_updated">Az adatbázis-titkosítási jelmondat megváltoztatásra és mentésre kerül a Keystore-ban.</string>
|
||||
<string name="database_will_be_encrypted_and_passphrase_stored_in_settings">Az adatbázis titkosításra kerül és a jelmondat eltárolásra a beállításokban.</string>
|
||||
<string name="smp_servers_delete_server">Kiszolgáló törlése</string>
|
||||
@@ -421,7 +421,7 @@
|
||||
<string name="blocked_items_description">%d üzenet letiltva</string>
|
||||
<string name="info_row_disappears_at">Eltűnik ekkor:</string>
|
||||
<string name="ttl_weeks">%d hét</string>
|
||||
<string name="feature_enabled_for_you">engedélyezve az ön számára</string>
|
||||
<string name="feature_enabled_for_you">engedélyezve az Ön számára</string>
|
||||
<string name="timed_messages">Eltűnő üzenetek</string>
|
||||
<string name="delete_group_menu_action">Törlés</string>
|
||||
<string name="delete_and_notify_contact">Törlés, és az ismerős értesítése</string>
|
||||
@@ -495,7 +495,7 @@
|
||||
<string name="marked_deleted_items_description">%d üzenet megjelölve törlésre</string>
|
||||
<string name="conn_event_ratchet_sync_allowed">titkosítás újra egyeztetése engedélyezve</string>
|
||||
<string name="enable_self_destruct">Önmegsemmisítés engedélyezése</string>
|
||||
<string name="v5_2_favourites_filter_descr">Olvasatlan és csillagozott csevegésekre való szűrés.</string>
|
||||
<string name="v5_2_favourites_filter_descr">Olvasatlan és kedvenc csevegésekre való szűrés.</string>
|
||||
<string name="failed_to_parse_chats_title">A csevegések betöltése sikertelen</string>
|
||||
<string name="connect_plan_group_already_exists">A csoport már létezik!</string>
|
||||
<string name="v4_4_french_interface">Francia kezelőfelület</string>
|
||||
@@ -504,7 +504,7 @@
|
||||
<string name="error_starting_chat">Hiba a csevegés elindításakor</string>
|
||||
<string name="group_profile_is_stored_on_members_devices">A csoport profilja a tagok eszközein tárolódik, nem a kiszolgálókon.</string>
|
||||
<string name="enter_passphrase">Jelmondat megadása…</string>
|
||||
<string name="error_updating_user_privacy">Hiba a felhasználói beállítások frissítésekor</string>
|
||||
<string name="error_updating_user_privacy">Hiba a felhasználói adatvédelem frissítésekor</string>
|
||||
<string name="encrypt_database">Titkosít</string>
|
||||
<string name="alert_title_no_group">Csoport nem található!</string>
|
||||
<string name="error_saving_smp_servers">Hiba az SMP-kiszolgálók mentésekor</string>
|
||||
@@ -512,16 +512,16 @@
|
||||
<string name="icon_descr_group_inactive">A csoport inaktív</string>
|
||||
<string name="v5_0_large_files_support_descr">Gyors és nem kell várni, amíg a feladó online lesz!</string>
|
||||
<string name="error_joining_group">Hiba a csoporthoz való csatlakozáskor</string>
|
||||
<string name="favorite_chat">Csillag</string>
|
||||
<string name="favorite_chat">Kedvenc</string>
|
||||
<string name="v4_6_group_moderation">Csoport moderáció</string>
|
||||
<string name="choose_file">Fájl</string>
|
||||
<string name="group_link">Csoporthivatkozás</string>
|
||||
<string name="snd_conn_event_ratchet_sync_required">titkosítás-újraegyeztetés szükséges ehhez: %s</string>
|
||||
<string name="failed_to_active_user_title">Hiba a profil váltásakor!</string>
|
||||
<string name="failed_to_active_user_title">Hiba a profilváltáskor!</string>
|
||||
<string name="settings_experimental_features">Kísérleti funkciók</string>
|
||||
<string name="receipts_contacts_enable_keep_overrides">Engedélyezés (felülírások megtartásával)</string>
|
||||
<string name="enter_correct_passphrase">Adja meg a helyes jelmondatot.</string>
|
||||
<string name="delete_group_for_self_cannot_undo_warning">A csoport törlésre kerül az ön számára - ez a művelet nem vonható vissza!</string>
|
||||
<string name="delete_group_for_self_cannot_undo_warning">A csoport törlésre kerül az Ön számára - ez a művelet nem vonható vissza!</string>
|
||||
<string name="encrypt_database_question">Adatbázis titkosítása?</string>
|
||||
<string name="allow_accepting_calls_from_lock_screen">A zárolási képernyőn megjelenő hívások engedélyezése a Beállításokban.</string>
|
||||
<string name="conn_event_ratchet_sync_agreed">titkosítás elfogadva</string>
|
||||
@@ -542,7 +542,7 @@
|
||||
<string name="files_and_media">Fájlok és médiatartalmak</string>
|
||||
<string name="section_title_for_console">KONZOLHOZ</string>
|
||||
<string name="alert_text_encryption_renegotiation_failed">Sikertelen titkosítás-újraegyeztetés.</string>
|
||||
<string name="error_deleting_user">Hiba a felhasználói profil törlésekor</string>
|
||||
<string name="error_deleting_user">Hiba a felhasználó-profil törlésekor</string>
|
||||
<string name="fix_connection_not_supported_by_group_member">Csoporttag általi javítás nem támogatott</string>
|
||||
<string name="enter_welcome_message">Üdvözlőüzenet megadása…</string>
|
||||
<string name="encrypted_database">Titkosított adatbázis</string>
|
||||
@@ -624,7 +624,7 @@
|
||||
<string name="v4_6_hidden_chat_profiles">Rejtett csevegési profilok</string>
|
||||
<string name="files_and_media_section">Fájlok és médiatartalmak</string>
|
||||
<string name="image_saved">A kép mentve a „Galériába”</string>
|
||||
<string name="hide_notification">Elrejt</string>
|
||||
<string name="hide_notification">Elrejtés</string>
|
||||
<string name="la_immediately">Azonnal</string>
|
||||
<string name="files_and_media_prohibited">A fájlok- és a médiatartalmak küldése le van tiltva!</string>
|
||||
<string name="hide_profile">Profil elrejtése</string>
|
||||
@@ -636,18 +636,18 @@
|
||||
<string name="incompatible_database_version">Nem kompatibilis adatbázis-verzió</string>
|
||||
<string name="how_simplex_works">Hogyan működik a SimpleX</string>
|
||||
<string name="desktop_incompatible_version">Nem kompatibilis verzió</string>
|
||||
<string name="user_hide">Elrejt</string>
|
||||
<string name="user_hide">Elrejtés</string>
|
||||
<string name="incoming_video_call">Bejövő videóhívás</string>
|
||||
<string name="incorrect_passcode">Téves jelkód</string>
|
||||
<string name="onboarding_notifications_mode_service">Azonnali</string>
|
||||
<string name="v5_4_incognito_groups">Inkognitó csoportok</string>
|
||||
<string name="v5_4_incognito_groups">Inkognitócsoportok</string>
|
||||
<string name="how_to">Hogyan</string>
|
||||
<string name="hide_verb">Elrejt</string>
|
||||
<string name="hide_verb">Összecsukás</string>
|
||||
<string name="gallery_image_button">Kép</string>
|
||||
<string name="v4_3_improved_privacy_and_security">Fejlesztett adatvédelem és biztonság</string>
|
||||
<string name="ignore">Mellőzés</string>
|
||||
<string name="icon_descr_image_snd_complete">Kép elküldve</string>
|
||||
<string name="notification_preview_mode_hidden">Rejtett</string>
|
||||
<string name="notification_preview_mode_hidden">Se név, se üzenet</string>
|
||||
<string name="host_verb">Kiszolgáló</string>
|
||||
<string name="initial_member_role">Kezdeti szerepkör</string>
|
||||
<string name="invalid_chat">érvénytelen csevegés</string>
|
||||
@@ -657,7 +657,7 @@
|
||||
<string name="v4_3_improved_privacy_and_security_desc">Alkalmazás képernyőjének elrejtése a gyakran használt alkalmazások között.</string>
|
||||
<string name="v4_3_improved_server_configuration">Javított kiszolgáló konfiguráció</string>
|
||||
<string name="edit_history">Előzmények</string>
|
||||
<string name="hidden_profile_password">Rejtett profil jelszó</string>
|
||||
<string name="hidden_profile_password">Rejtett profiljelszó</string>
|
||||
<string name="import_database">Adatbázis importálása</string>
|
||||
<string name="import_database_confirmation">Importálás</string>
|
||||
<string name="icon_descr_instant_notifications">Azonnali értesítések</string>
|
||||
@@ -668,7 +668,7 @@
|
||||
<string name="image_descr">Kép</string>
|
||||
<string name="files_are_prohibited_in_group">A fájlok- és a médiatartalmak le vannak tiltva ebben a csoportban.</string>
|
||||
<string name="how_it_works">Hogyan működik</string>
|
||||
<string name="hide_dev_options">Elrejt:</string>
|
||||
<string name="hide_dev_options">Elrejtés:</string>
|
||||
<string name="error_creating_member_contact">Hiba az ismerőssel történő kapcsolat létrehozásában</string>
|
||||
<string name="enter_one_ICE_server_per_line">ICE-kiszolgálók (soronként egy)</string>
|
||||
<string name="if_you_cannot_meet_in_person_scan_QR_in_video_call_or_ask_for_invitation_link"><![CDATA[Ha nem tud személyesen találkozni, <b>beolvashatja a QR-kódot a videohívásban</b>, vagy az ismerőse megoszthat egy meghívó-hivatkozást.]]></string>
|
||||
@@ -677,7 +677,7 @@
|
||||
<string name="if_you_cannot_meet_in_person_show_QR_in_video_call_or_via_another_channel"><![CDATA[Ha nem tud személyesen találkozni, <b>mutassa meg a QR-kódot a videohívásban</b>, vagy ossza meg a hivatkozást.]]></string>
|
||||
<string name="network_disable_socks_info">Megerősítés esetén az üzenetküldő-kiszolgálók látni fogják az IP-címét és a szolgáltatóját – azt, hogy mely kiszolgálókhoz kapcsolódik.</string>
|
||||
<string name="image_will_be_received_when_contact_completes_uploading">A kép akkor érkezik meg, amikor a küldője befejezte annak feltöltését.</string>
|
||||
<string name="desktop_scan_QR_code_from_app_via_scan_QR_code"><![CDATA[💻 számítógép: a megjelenített QR-kód beolvasása az alkalmazásból, a <b>QR kód beolvasásával</b>.]]></string>
|
||||
<string name="desktop_scan_QR_code_from_app_via_scan_QR_code"><![CDATA[💻 számítógép: a megjelenített QR-kód beolvasása az alkalmazásból, a <b>QR-kód beolvasásával</b>.]]></string>
|
||||
<string name="if_you_received_simplex_invitation_link_you_can_open_in_browser">A kapott SimpleX Chat-meghívó-hivatkozását megnyithatja a böngészőjében:</string>
|
||||
<string name="if_you_enter_self_destruct_code">Ha az alkalmazás megnyitásakor megadja az önmegsemmisítő jelkódot:</string>
|
||||
<string name="found_desktop">Megtalált számítógép</string>
|
||||
@@ -686,7 +686,7 @@
|
||||
<string name="create_chat_profile">Csevegési profil létrehozása</string>
|
||||
<string name="immune_to_spam_and_abuse">Levélszemét elleni védelem</string>
|
||||
<string name="disconnect_remote_hosts">Hordozható eszközök leválasztása</string>
|
||||
<string name="v4_5_multiple_chat_profiles_descr">Különböző nevek, avatarok és átviteli izoláció.</string>
|
||||
<string name="v4_5_multiple_chat_profiles_descr">Különböző nevek, profilképek és átvitel-izoláció.</string>
|
||||
<string name="if_you_choose_to_reject_the_sender_will_not_be_notified">Elutasítás esetén a feladó NEM kap értesítést.</string>
|
||||
<string name="icon_descr_expand_role">Szerepkörválasztás bővítése</string>
|
||||
<string name="image_will_be_received_when_contact_is_online">A kép akkor érkezik meg, amikor a küldője elérhető lesz, várjon, vagy ellenőrizze később!</string>
|
||||
@@ -698,7 +698,7 @@
|
||||
<string name="theme_light">Világos</string>
|
||||
<string name="delete_message_cannot_be_undone_warning">Az üzenet törlésre kerül - ez a művelet nem vonható vissza!</string>
|
||||
<string name="markdown_help">Markdown segítség</string>
|
||||
<string name="notification_preview_new_message">új üzenet</string>
|
||||
<string name="notification_preview_new_message">Rejtett üzenet</string>
|
||||
<string name="old_database_archive">Régi adatbázis-archívum</string>
|
||||
<string name="network_settings_title">Speciális beállítások</string>
|
||||
<string name="no_info_on_delivery">Nincs kézbesítési információ</string>
|
||||
@@ -715,7 +715,7 @@
|
||||
<string name="v5_2_fix_encryption">Kapcsolatok megtartása</string>
|
||||
<string name="button_add_members">Tagok meghívása</string>
|
||||
<string name="message_reactions">Üzenetreakciók</string>
|
||||
<string name="only_one_device_can_work_at_the_same_time">Egyszerre csak egy eszköz működhet</string>
|
||||
<string name="only_one_device_can_work_at_the_same_time">Egyszerre csak 1 eszköz működhet</string>
|
||||
<string name="connect_plan_join_your_group">Csatlakozik a csoportjához?</string>
|
||||
<string name="large_file">Nagy fájl!</string>
|
||||
<string name="info_row_local_name">Helyi név</string>
|
||||
@@ -726,7 +726,7 @@
|
||||
<string name="v4_6_reduced_battery_usage_descr">Hamarosan további fejlesztések érkeznek!</string>
|
||||
<string name="message_reactions_prohibited_in_this_chat">Az üzenetreakciók küldése le van tiltva ebben a csevegésben.</string>
|
||||
<string name="incorrect_code">Helytelen biztonsági kód!</string>
|
||||
<string name="alert_text_fragment_encryption_out_of_sync_old_database">Ez akkor fordulhat elő, ha ön vagy az ismerőse régi adatbázis biztonsági mentést használt.</string>
|
||||
<string name="alert_text_fragment_encryption_out_of_sync_old_database">Ez akkor fordulhat elő, ha Ön vagy az ismerőse régi adatbázis biztonsági mentést használt.</string>
|
||||
<string name="v5_3_new_desktop_app">Új számítógép-alkalmazás!</string>
|
||||
<string name="v4_6_group_moderation_descr">Most már az adminok is:
|
||||
\n- törölhetik a tagok üzeneteit.
|
||||
@@ -752,7 +752,7 @@
|
||||
<string name="notification_new_contact_request">Új kapcsolatkérés</string>
|
||||
<string name="joining_group">Csatlakozás a csoporthoz</string>
|
||||
<string name="linked_desktop_options">Társított számítógép beállítások</string>
|
||||
<string name="rcv_group_event_invited_via_your_group_link">meghíva az ön csoporthivatkozásán keresztül</string>
|
||||
<string name="rcv_group_event_invited_via_your_group_link">meghíva az Ön csoporthivatkozásán keresztül</string>
|
||||
<string name="rcv_group_event_member_left">elhagyta a csoportot</string>
|
||||
<string name="linked_desktops">Társított számítógépek</string>
|
||||
<string name="la_no_app_password">Nincs alkalmazás jelkód</string>
|
||||
@@ -769,13 +769,12 @@
|
||||
<string name="v5_2_disappear_one_message">Egy üzenet eltüntetése</string>
|
||||
<string name="v4_3_irreversible_message_deletion">Végleges üzenettörlés</string>
|
||||
<string name="videos_limit_desc">Egyszerre csak 10 videó küldhető el</string>
|
||||
<string name="only_you_can_add_message_reactions">Csak ön adhat hozzá üzenetreakciókat.</string>
|
||||
<string name="only_you_can_add_message_reactions">Csak Ön adhat hozzá üzenetreakciókat.</string>
|
||||
<string name="group_member_status_left">elhagyta a csoportot</string>
|
||||
<string name="message_deletion_prohibited">Az üzenetek végleges törlése le van tiltva ebben a csevegésben.</string>
|
||||
<string name="v4_3_voice_messages_desc">Max 40 másodperc, azonnal fogadható.</string>
|
||||
<string name="description_via_contact_address_link_incognito">inkognitó a kapcsolattartási cím-hivatkozáson keresztül</string>
|
||||
<string name="network_use_onion_hosts_required_desc">Az onion-kiszolgálók szükségesek a kapcsolódáshoz.
|
||||
\nMegjegyzés: .onion cím nélkül nem fog tudni kapcsolódni a kiszolgálókhoz.</string>
|
||||
<string name="description_via_contact_address_link_incognito">inkognitó a kapcsolattartási címhivatkozáson keresztül</string>
|
||||
<string name="network_use_onion_hosts_required_desc">Onion-kiszolgálók szükségesek a kapcsolódáshoz.\nMegjegyzés: .onion cím nélkül nem fog tudni kapcsolódni a kiszolgálókhoz.</string>
|
||||
<string name="v4_5_italian_interface">Olasz kezelőfelület</string>
|
||||
<string name="system_restricted_background_in_call_title">Nincsenek háttérhívások</string>
|
||||
<string name="messages_section_title">Üzenetek</string>
|
||||
@@ -802,10 +801,10 @@
|
||||
<string name="v4_5_multiple_chat_profiles">Több csevegőprofil</string>
|
||||
<string name="marked_deleted_description">törlésre jelölve</string>
|
||||
<string name="user_mute">Némítás</string>
|
||||
<string name="link_a_mobile">Egy hordozható eszköz társítása</string>
|
||||
<string name="link_a_mobile">Hordozható eszköz társítása</string>
|
||||
<string name="settings_notifications_mode_title">Értesítési szolgáltatás</string>
|
||||
<string name="only_group_owners_can_enable_voice">Csak a csoporttulajdonosok engedélyezhetik a hangüzenetek küldését.</string>
|
||||
<string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages"><![CDATA[Csak az alkalmazások tárolják a felhasználói profilokat, ismerősöket, csoportokat és a <b>2 rétegű végpontok közötti titkosítással</b> küldött üzeneteket.]]></string>
|
||||
<string name="only_client_devices_store_contacts_groups_e2e_encrypted_messages"><![CDATA[Csak az alkalmazások tárolják a felhasználó-profilokat, ismerősöket, csoportokat és a <b>2 rétegű végpontok közötti titkosítással</b> küldött üzeneteket.]]></string>
|
||||
<string name="invalid_migration_confirmation">Érvénytelen átköltöztetési visszaigazolás</string>
|
||||
<string name="only_group_owners_can_change_prefs">Csak a csoporttulajdonosok módosíthatják a csoportbeállításokat.</string>
|
||||
<string name="no_history">Nincsenek előzmények</string>
|
||||
@@ -823,11 +822,8 @@
|
||||
<string name="feature_offered_item">ajánlott %s</string>
|
||||
<string name="button_leave_group">Csoport elhagyása</string>
|
||||
<string name="unblock_member_desc">Minden %s által írt üzenet megjelenik!</string>
|
||||
<string name="many_people_asked_how_can_it_deliver"><![CDATA[Sokan kérdezték: <i>Ha a SimpleX Chatnek nincs felhasználói azonosítója, hogyan lehet mégis üzeneteket küldeni?</i>]]></string>
|
||||
<string name="alert_text_skipped_messages_it_can_happen_when">Ez akkor fordulhat elő, ha:
|
||||
\n1. Az üzenetek 2 nap után, vagy a kiszolgálón 30 nap után lejártak.
|
||||
\n2. Az üzenet visszafejtése sikertelen volt, mert ön, vagy az ismerőse régebbi adatbázis biztonsági mentést használt.
|
||||
\n3. A kapcsolat sérült.</string>
|
||||
<string name="many_people_asked_how_can_it_deliver"><![CDATA[Sokan kérdezték: <i>Ha a SimpleX Chatnek nincs felhasználó-azonosítója, hogyan lehet mégis üzeneteket küldeni?</i>]]></string>
|
||||
<string name="alert_text_skipped_messages_it_can_happen_when">Ez akkor fordulhat elő, ha:\n1. Az üzenetek 2 nap után, vagy a kiszolgálón 30 nap után lejártak.\n2. Az üzenet visszafejtése sikertelen volt, mert Ön, vagy az ismerőse régebbi adatbázis biztonsági mentést használt.\n3. A kapcsolat sérült.</string>
|
||||
<string name="group_member_role_observer">megfigyelő</string>
|
||||
<string name="description_via_group_link_incognito">inkognitó a csoporthivatkozáson keresztül</string>
|
||||
<string name="network_use_onion_hosts_prefer_desc">Onion-kiszolgálók használata, ha azok rendelkezésre állnak.</string>
|
||||
@@ -857,7 +853,7 @@
|
||||
<string name="callstatus_missed">nem fogadott hívás</string>
|
||||
<string name="database_migrations">Átköltöztetés: %s</string>
|
||||
<string name="in_reply_to">Válaszul erre:</string>
|
||||
<string name="notification_preview_mode_message">Üzenet szövege</string>
|
||||
<string name="notification_preview_mode_message">Név és üzenet</string>
|
||||
<string name="notifications_will_be_hidden">Az értesítések csak az alkalmazás bezárásáig érkeznek!</string>
|
||||
<string name="info_menu">Információ</string>
|
||||
<string name="settings_section_title_messages">ÜZENETEK ÉS FÁJLOK</string>
|
||||
@@ -874,24 +870,22 @@
|
||||
<string name="invite_to_group_button">Meghívás a csoportba</string>
|
||||
<string name="lock_after">Zárolás miután</string>
|
||||
<string name="incoming_audio_call">Bejövő hanghívás</string>
|
||||
<string name="keychain_error">Kulcstartó hiba</string>
|
||||
<string name="keychain_error">Kulcstartóhiba</string>
|
||||
<string name="join_group_question">Csatlakozik a csoporthoz?</string>
|
||||
<string name="incognito_info_protects">Az inkognitómód védi személyes adatait azáltal, hogy minden ismerőshöz új véletlenszerű profilt használ.</string>
|
||||
<string name="v5_2_more_things_descr">- stabilabb üzenetkézbesítés.
|
||||
\n- valamivel jobb csoportok.
|
||||
\n- és még sok más!</string>
|
||||
<string name="v5_2_more_things_descr">- stabilabb üzenetkézbesítés.\n- picit továbbfejlesztett csoportok.\n- és még sok más!</string>
|
||||
<string name="v5_1_message_reactions">Üzenetreakciók</string>
|
||||
<string name="no_connected_mobile">Nincs társított hordozható eszköz</string>
|
||||
<string name="network_status">Hálózat állapota</string>
|
||||
<string name="new_passcode">Új jelkód</string>
|
||||
<string name="message_delivery_error_desc">Valószínűleg ez az ismerős törölte önnel a kapcsolatot.</string>
|
||||
<string name="message_delivery_error_desc">Valószínűleg ez az ismerős törölte Önnel a kapcsolatot.</string>
|
||||
<string name="join_group_incognito_button">Csatlakozás inkognitóban</string>
|
||||
<string name="open_chat">Csevegés megnyitása</string>
|
||||
<string name="callstatus_rejected">elutasított hívás</string>
|
||||
<string name="onboarding_notifications_mode_periodic">Rendszeres</string>
|
||||
<string name="feature_received_prohibited">fogadott, tiltott</string>
|
||||
<string name="connect_plan_repeat_connection_request">Kapcsolatkérés megismétlése?</string>
|
||||
<string name="only_you_can_delete_messages">Véglegesen csak ön törölhet üzeneteket (ismerőse csak törlésre jelölheti őket ). (24 óra)</string>
|
||||
<string name="only_you_can_delete_messages">Véglegesen csak Ön törölhet üzeneteket (ismerőse csak törlésre jelölheti őket ). (24 óra)</string>
|
||||
<string name="role_in_group">Szerepkör</string>
|
||||
<string name="simplex_link_contact">SimpleX-kapcsolattartási-cím</string>
|
||||
<string name="stop_file__confirm">Megállítás</string>
|
||||
@@ -899,13 +893,13 @@
|
||||
<string name="add_contact_or_create_group">Új csevegés kezdése</string>
|
||||
<string name="opensource_protocol_and_code_anybody_can_run_servers">Bárki üzemeltethet kiszolgálókat.</string>
|
||||
<string name="rcv_group_event_open_chat">Megnyitás</string>
|
||||
<string name="network_option_protocol_timeout">Protokoll időtúllépés</string>
|
||||
<string name="network_option_protocol_timeout">Protokoll időtúllépése</string>
|
||||
<string name="secret_text">titkos</string>
|
||||
<string name="settings_notification_preview_mode_title">Üzenetek előnézetének megjelenítése</string>
|
||||
<string name="settings_notification_preview_mode_title">Értesítés előnézete</string>
|
||||
<string name="callstate_waiting_for_confirmation">várakozás a visszaigazolásra…</string>
|
||||
<string name="stop_file__action">Fájl megállítása</string>
|
||||
<string name="description_via_group_link">a csoporthivatkozáson keresztül</string>
|
||||
<string name="network_option_ping_interval">PING időköze</string>
|
||||
<string name="network_option_ping_interval">Időtartam a PING-ek között</string>
|
||||
<string name="send_disappearing_message">Eltűnő üzenet küldése</string>
|
||||
<string name="self_destruct_passcode">Önmegsemmisítési jelkód</string>
|
||||
<string name="save_and_update_group_profile">Mentés és a csoportprofil frissítése</string>
|
||||
@@ -914,7 +908,7 @@
|
||||
<string name="alert_text_fragment_please_report_to_developers">Jelentse a fejlesztőknek.</string>
|
||||
<string name="people_can_connect_only_via_links_you_share">Ön dönti el, hogy kivel beszélget.</string>
|
||||
<string name="prohibit_sending_disappearing">Az eltűnő üzenetek küldése le van tiltva.</string>
|
||||
<string name="only_you_can_send_voice">Csak ön tud hangüzeneteket küldeni.</string>
|
||||
<string name="only_you_can_send_voice">Csak Ön tud hangüzeneteket küldeni.</string>
|
||||
<string name="update_network_settings_confirmation">Frissítés</string>
|
||||
<string name="icon_descr_video_snd_complete">Videó elküldve</string>
|
||||
<string name="update_database_passphrase">Adatbázis-jelmondat megváltoztatása</string>
|
||||
@@ -922,7 +916,7 @@
|
||||
<string name="passcode_not_changed">A jelkód nem változott!</string>
|
||||
<string name="refresh_qr_code">Frissítés</string>
|
||||
<string name="custom_time_picker_select">Kiválasztás</string>
|
||||
<string name="only_you_can_make_calls">Csak ön tud hívásokat indítani.</string>
|
||||
<string name="only_you_can_make_calls">Csak Ön tud hívásokat indítani.</string>
|
||||
<string name="smp_server_test_secure_queue">Biztonságos sorbaállítás</string>
|
||||
<string name="rate_the_app">Értékelje az alkalmazást</string>
|
||||
<string name="share_invitation_link">Egyszer használható hivatkozás megosztása</string>
|
||||
@@ -946,9 +940,9 @@
|
||||
<string name="connect_via_link_or_qr_from_clipboard_or_in_person">(beolvasás, vagy beillesztés a vágólapról)</string>
|
||||
<string name="waiting_for_video">Várakozás a videóra</string>
|
||||
<string name="reply_verb">Válasz</string>
|
||||
<string name="connect_plan_this_is_your_own_one_time_link">Ez az ön egyszer használható hivatkozása!</string>
|
||||
<string name="connect_plan_this_is_your_own_one_time_link">Ez az Ön egyszer használható hivatkozása!</string>
|
||||
<string name="ntf_channel_calls">SimpleX Chat hívások</string>
|
||||
<string name="connect_use_new_incognito_profile">Új inkognító profil használata</string>
|
||||
<string name="connect_use_new_incognito_profile">Új inkognitóprofil használata</string>
|
||||
<string name="contact_developers">Frissítse az alkalmazást, és lépjen kapcsolatba a fejlesztőkkel.</string>
|
||||
<string name="theme_simplex">SimpleX</string>
|
||||
<string name="send_link_previews">Hivatkozás előnézete</string>
|
||||
@@ -985,12 +979,12 @@
|
||||
<string name="reject_contact_button">Elutasítás</string>
|
||||
<string name="notification_preview_mode_message_desc">Ismerős nevének és az üzenet tartalmának megjelenítése</string>
|
||||
<string name="settings_section_title_settings">BEÁLLÍTÁSOK</string>
|
||||
<string name="save_profile_password">Felhasználói fiók jelszavának mentése</string>
|
||||
<string name="save_profile_password">Profiljelszó mentése</string>
|
||||
<string name="stop_snd_file__title">Fájlküldés megállítása?</string>
|
||||
<string name="unlink_desktop_question">Számítógép leválasztása?</string>
|
||||
<string name="voice_messages_prohibited">A hangüzenetek le vannak tilva!</string>
|
||||
<string name="compose_send_direct_message_to_connect">Közvetlen üzenet küldése a kapcsolódáshoz</string>
|
||||
<string name="network_option_ping_count">PING számláló</string>
|
||||
<string name="network_option_ping_count">PING-ek száma</string>
|
||||
<string name="show_developer_options">Fejlesztői beállítások megjelenítése</string>
|
||||
<string name="rcv_group_event_1_member_connected">%s kapcsolódott</string>
|
||||
<string name="theme_system">Rendszer</string>
|
||||
@@ -1000,7 +994,7 @@
|
||||
<string name="smp_servers_your_server">Saját SMP-kiszolgáló</string>
|
||||
<string name="random_port">Véletlen</string>
|
||||
<string name="share_with_contacts">Megosztás az ismerősökkel</string>
|
||||
<string name="sender_you_pronoun">ön</string>
|
||||
<string name="sender_you_pronoun">Ön</string>
|
||||
<string name="you_have_no_chats">Nincsenek csevegései</string>
|
||||
<string name="send_disappearing_message_send">Küldés</string>
|
||||
<string name="chat_item_ttl_seconds">%s másodperc</string>
|
||||
@@ -1048,7 +1042,7 @@
|
||||
<string name="settings_section_title_support">SIMPLEX CHAT TÁMOGATÁSA</string>
|
||||
<string name="simplex_service_notification_title">SimpleX Chat szolgáltatás</string>
|
||||
<string name="observer_cant_send_message_title">Nem lehet üzeneteket küldeni!</string>
|
||||
<string name="is_verified">%s ellenőrzött</string>
|
||||
<string name="is_verified">%s hitelesítve</string>
|
||||
<string name="password_to_show">Jelszó megjelenítése</string>
|
||||
<string name="privacy_and_security">Adatvédelem és biztonság</string>
|
||||
<string name="button_remove_member">Eltávolítás</string>
|
||||
@@ -1060,7 +1054,7 @@
|
||||
<string name="group_welcome_title">Üdvözlőüzenet</string>
|
||||
<string name="network_option_seconds_label">mp</string>
|
||||
<string name="profile_update_will_be_sent_to_contacts">A profilfrissítés elküldésre került az ismerősök számára.</string>
|
||||
<string name="v5_3_simpler_incognito_mode">Egyszerűsített inkognító mód</string>
|
||||
<string name="v5_3_simpler_incognito_mode">Egyszerűsített inkognitómód</string>
|
||||
<string name="save_welcome_message_question">Üdvözlőüzenet mentése?</string>
|
||||
<string name="restart_the_app_to_create_a_new_chat_profile">Új csevegési fiók létrehozásához indítsa újra az alkalmazást.</string>
|
||||
<string name="toast_permission_denied">Engedély megtagadva!</string>
|
||||
@@ -1070,8 +1064,8 @@
|
||||
<string name="enter_passphrase_notification_title">Jelmondat szükséges</string>
|
||||
<string name="onboarding_notifications_mode_title">Privát értesítések</string>
|
||||
<string name="you_invited_a_contact">Meghívta egy ismerősét</string>
|
||||
<string name="is_not_verified">%s nincs ellenőrizve</string>
|
||||
<string name="contact_tap_to_connect">Koppintson a kapcsolódáshoz</string>
|
||||
<string name="is_not_verified">%s nincs hitelesítve</string>
|
||||
<string name="contact_tap_to_connect">Koppintson ide a kapcsolódáshoz</string>
|
||||
<string name="this_device_name">Ennek az eszköznek a neve</string>
|
||||
<string name="your_current_profile">Jelenlegi profil</string>
|
||||
<string name="smp_server_test_upload_file">Fájl feltöltése</string>
|
||||
@@ -1080,9 +1074,9 @@
|
||||
<string name="ntf_channel_messages">SimpleX Chat üzenetek</string>
|
||||
<string name="restore_database_alert_confirm">Visszaállítás</string>
|
||||
<string name="setup_database_passphrase">Adatbázis-jelmondat beállítása</string>
|
||||
<string name="color_sent_message">Elküldött üzenet</string>
|
||||
<string name="color_sent_message">Üzenetbuborék színe</string>
|
||||
<string name="notifications_mode_periodic">Időszakosan indul</string>
|
||||
<string name="connect_plan_this_is_your_own_simplex_address">Ez az ön SimpleX-címe!</string>
|
||||
<string name="connect_plan_this_is_your_own_simplex_address">Ez az Ön SimpleX-címe!</string>
|
||||
<string name="group_member_status_removed">eltávolítva</string>
|
||||
<string name="share_link">Megosztás</string>
|
||||
<string name="icon_descr_simplex_team">SimpleX csapat</string>
|
||||
@@ -1130,7 +1124,7 @@
|
||||
<string name="settings_section_title_use_from_desktop">Társítás számítógéppel</string>
|
||||
<string name="settings_section_title_you">PROFIL</string>
|
||||
<string name="network_proxy_port">port %d</string>
|
||||
<string name="to_connect_via_link_title">Kapcsolódás hivatkozáson keresztül</string>
|
||||
<string name="to_connect_via_link_title">Kapcsolódás egy hivatkozáson keresztül</string>
|
||||
<string name="share_address">Cím megosztása</string>
|
||||
<string name="smp_servers_scan_qr">A kiszolgáló QR-kódjának beolvasása</string>
|
||||
<string name="stop_chat_confirmation">Megállítás</string>
|
||||
@@ -1140,8 +1134,8 @@
|
||||
<string name="waiting_for_image">Várakozás a képre</string>
|
||||
<string name="v4_3_voice_messages">Hangüzenetek</string>
|
||||
<string name="button_remove_member_question">Biztosan eltávolítja?</string>
|
||||
<string name="verify_security_code">Biztonsági kód ellenőrzése</string>
|
||||
<string name="rcv_group_event_user_deleted">eltávolította önt</string>
|
||||
<string name="verify_security_code">Biztonsági kód hitelesítése</string>
|
||||
<string name="rcv_group_event_user_deleted">eltávolította Önt</string>
|
||||
<string name="simplex_address">SimpleX-cím</string>
|
||||
<string name="show_dev_options">Megjelenítés:</string>
|
||||
<string name="callstate_received_answer">válasz fogadása…</string>
|
||||
@@ -1155,7 +1149,7 @@
|
||||
<string name="connect_plan_open_group">Csoport megnyitása</string>
|
||||
<string name="info_row_sent_at">Elküldve ekkor:</string>
|
||||
<string name="prohibit_sending_voice">A hangüzenetek küldése le van tiltva.</string>
|
||||
<string name="privacy_show_last_messages">Utolsó üzenetek megjelenítése</string>
|
||||
<string name="privacy_show_last_messages">Szobák utolsó üzeneteinek megjelenítése a listanézetben</string>
|
||||
<string name="smp_servers_preset_address">Az előre beállított kiszolgáló címe</string>
|
||||
<string name="periodic_notifications_disabled">Rendszeres értesítések letiltva!</string>
|
||||
<string name="passcode_changed">A jelkód megváltozott!</string>
|
||||
@@ -1181,9 +1175,9 @@
|
||||
<string name="alert_title_skipped_messages">Kihagyott üzenetek</string>
|
||||
<string name="prohibit_sending_voice_messages">A hangüzenetek küldése le van tiltva.</string>
|
||||
<string name="set_contact_name">Ismerős nevének beállítása</string>
|
||||
<string name="only_you_can_send_disappearing">Csak ön tud eltűnő üzeneteket küldeni.</string>
|
||||
<string name="only_you_can_send_disappearing">Csak Ön tud eltűnő üzeneteket küldeni.</string>
|
||||
<string name="share_image">Média megosztása…</string>
|
||||
<string name="group_info_member_you">ön: %1$s</string>
|
||||
<string name="group_info_member_you">Ön: %1$s</string>
|
||||
<string name="your_preferences">Beállítások</string>
|
||||
<string name="reset_color">Színek visszaállítása</string>
|
||||
<string name="network_options_save">Mentés</string>
|
||||
@@ -1201,7 +1195,7 @@
|
||||
<string name="protect_app_screen">Alkalmazás képernyőjének védelme</string>
|
||||
<string name="show_QR_code">QR-kód megjelenítése</string>
|
||||
<string name="icon_descr_video_call">videóhívás</string>
|
||||
<string name="unfavorite_chat">Csillagozás megszüntetése</string>
|
||||
<string name="unfavorite_chat">Kedvenc megszüntetése</string>
|
||||
<string name="send_receipts">Kézbesítési jelentések küldése</string>
|
||||
<string name="icon_descr_address">SimpleX-cím</string>
|
||||
<string name="chat_help_tap_button">Koppintson a</string>
|
||||
@@ -1221,10 +1215,10 @@
|
||||
<string name="save_verb">Mentés</string>
|
||||
<string name="call_connection_via_relay">közvetítő-kiszolgálón keresztül</string>
|
||||
<string name="stop_sharing">Megosztás megállítása</string>
|
||||
<string name="snd_group_event_member_deleted">eltávolította őt: %1$s</string>
|
||||
<string name="snd_group_event_member_deleted">Ön eltávolította őt: %1$s</string>
|
||||
<string name="save_passphrase_and_open_chat">Jelmondat mentése és a csevegés megnyitása</string>
|
||||
<string name="save_preferences_question">Beállítások mentése?</string>
|
||||
<string name="first_platform_without_user_ids">Nincsenek felhasználói azonosítók.</string>
|
||||
<string name="first_platform_without_user_ids">Nincsenek felhasználó-azonosítók.</string>
|
||||
<string name="prohibit_direct_messages">A közvetlen üzenetek küldése a tagok között le van tiltva.</string>
|
||||
<string name="network_enable_socks">SOCKS proxy használata?</string>
|
||||
<string name="icon_descr_speaker_off">Hangszóró kikapcsolva</string>
|
||||
@@ -1257,12 +1251,12 @@
|
||||
<string name="reset_verb">Visszaállítás</string>
|
||||
<string name="only_your_contact_can_add_message_reactions">Csak az ismerőse tud üzenetreakciókat küldeni.</string>
|
||||
<string name="voice_messages">Hangüzenetek</string>
|
||||
<string name="snd_group_event_user_left">elhagyta a csoportot</string>
|
||||
<string name="snd_group_event_user_left">Ön elhagyta a csoportot</string>
|
||||
<string name="icon_descr_record_voice_message">Hangüzenet rögzítése</string>
|
||||
<string name="auth_simplex_lock_turned_on">SimpleX-zár bekapcsolva</string>
|
||||
<string name="member_contact_send_direct_message">közvetlen üzenet küldése</string>
|
||||
<string name="scan_from_mobile">Beolvasás hordozható eszközről</string>
|
||||
<string name="verify_connections">Kapcsolatok ellenőrzése</string>
|
||||
<string name="verify_connections">Kapcsolatok hitelesítése</string>
|
||||
<string name="share_message">Üzenet megosztása…</string>
|
||||
<string name="custom_time_unit_seconds">másodperc</string>
|
||||
<string name="lock_not_enabled">A SimpleX-zár nincs bekapcsolva!</string>
|
||||
@@ -1271,34 +1265,34 @@
|
||||
<string name="your_chat_database">Csevegési adatbázis</string>
|
||||
<string name="rcv_group_event_member_deleted">eltávolította őt: %1$s</string>
|
||||
<string name="smp_servers_test_failed">Sikertelen kiszolgáló teszt!</string>
|
||||
<string name="verify_connection">Kapcsolat ellenőrzése</string>
|
||||
<string name="verify_connection">Kapcsolat hitelesítése</string>
|
||||
<string name="whats_new_read_more">Tudjon meg többet</string>
|
||||
<string name="sender_cancelled_file_transfer">A fájl küldője visszavonta az átvitelt.</string>
|
||||
<string name="stop_chat_question">Csevegési szolgáltatás megállítása?</string>
|
||||
<string name="info_row_received_at">Fogadva ekkor:</string>
|
||||
<string name="accept_feature_set_1_day">Beállítva 1 nap</string>
|
||||
<string name="user_unhide">Felfedés</string>
|
||||
<string name="color_received_message">Fogadott üzenet</string>
|
||||
<string name="only_your_contact_can_delete">Csak az ismerőse tudja az üzeneteket véglegesen törölni (ön csak törlésre jelölheti meg azokat). (24 óra)</string>
|
||||
<string name="color_received_message">Fogadott üzenetbuborék színe</string>
|
||||
<string name="only_your_contact_can_delete">Csak az ismerőse tudja az üzeneteket véglegesen törölni (Ön csak törlésre jelölheti meg azokat). (24 óra)</string>
|
||||
<string name="self_destruct_passcode_changed">Az önmegsemmisítési jelkód megváltozott!</string>
|
||||
<string name="using_simplex_chat_servers">SimpleX Chat-kiszolgálók használatban.</string>
|
||||
<string name="use_simplex_chat_servers__question">SimpleX Chat-kiszolgálók használata?</string>
|
||||
<string name="unhide_chat_profile">Csevegési profil felfedése</string>
|
||||
<string name="v5_0_large_files_support">Videók és fájlok 1Gb méretig</string>
|
||||
<string name="network_option_tcp_connection_timeout">TCP kapcsolat időtúllépés</string>
|
||||
<string name="network_option_tcp_connection_timeout">TCP kapcsolat időtúllépése</string>
|
||||
<string name="connect__your_profile_will_be_shared">A(z) %1$s nevű profiljának SimpleX-címe megosztásra fog kerülni.</string>
|
||||
<string name="you_are_already_connected_to_vName_via_this_link">Ön már kapcsolódva van ehhez: %1$s.</string>
|
||||
<string name="your_current_chat_database_will_be_deleted_and_replaced_with_the_imported_one">Jelenlegi csevegési adatbázis TÖRLÉSRE és FELCSERÉLÉSRE kerül az importált által!
|
||||
\nEz a művelet nem vonható vissza - profiljai, ismerősei, csevegési üzenetei és fájljai véglegesen törölve lesznek.</string>
|
||||
<string name="chat_with_the_founder">Ötletek és javaslatok</string>
|
||||
<string name="database_downgrade_warning">Figyelmeztetés: néhány adat elveszhet!</string>
|
||||
<string name="tap_to_start_new_chat">Koppintson az új csevegés indításához</string>
|
||||
<string name="tap_to_start_new_chat">Koppintson ide az új csevegés indításához</string>
|
||||
<string name="waiting_for_desktop">Várakozás a számítógépre…</string>
|
||||
<string name="next_generation_of_private_messaging">A privát üzenetküldés
|
||||
\nkövetkező generációja</string>
|
||||
<string name="update_network_settings_question">Hálózati beállítások megváltoztatása?</string>
|
||||
<string name="waiting_for_mobile_to_connect">Várakozás a hordozható eszköz társítására:</string>
|
||||
<string name="v4_4_verify_connection_security">Kapcsolat biztonságának ellenőrzése</string>
|
||||
<string name="v4_4_verify_connection_security">Biztonságos kapcsolat hitelesítése</string>
|
||||
<string name="sending_files_not_yet_supported">fájlok küldése egyelőre még nem támogatott</string>
|
||||
<string name="snd_conn_event_switch_queue_phase_completed_for_member">cím megváltoztatva nála: %s</string>
|
||||
<string name="receiving_files_not_yet_supported">fájlok fogadása egyelőre még nem támogatott</string>
|
||||
@@ -1317,10 +1311,10 @@
|
||||
<string name="restore_passphrase_not_found_desc">A jelszó nem található a Keystore-ban, ezért kézzel szükséges megadni. Ez akkor történhetett meg, ha visszaállította az alkalmazás adatait egy biztonságimentési eszközzel. Ha nem így történt, akkor lépjen kapcsolatba a fejlesztőkkel.</string>
|
||||
<string name="your_contacts_will_remain_connected">Az ismerősei továbbra is kapcsolódva maradnak.</string>
|
||||
<string name="error_xftp_test_server_auth">A kiszolgálónak engedélyre van szüksége a várólisták létrehozásához, ellenőrizze jelszavát</string>
|
||||
<string name="database_initialization_error_desc">Az adatbázis nem működik megfelelően. Koppintson további információért</string>
|
||||
<string name="database_initialization_error_desc">Az adatbázis nem működik megfelelően. Koppintson ide a további információkért</string>
|
||||
<string name="stop_snd_file__message">A fájl küldése leállt.</string>
|
||||
<string name="trying_to_connect_to_server_to_receive_messages">Kapcsolódási kísérlet ahhoz a kiszolgálóhoz, amely az adott ismerősétől érkező üzenetek fogadására szolgál.</string>
|
||||
<string name="la_could_not_be_verified">Nem sikerült ellenőrizni; próbálja meg újra.</string>
|
||||
<string name="la_could_not_be_verified">Nem sikerült hitelesíteni; próbálja meg újra.</string>
|
||||
<string name="moderate_message_will_be_marked_warning">Az üzenet minden tag számára moderáltként lesz megjelölve.</string>
|
||||
<string name="enter_passphrase_notification_desc">Értesítések fogadásához adja meg az adatbázis jelmondatát</string>
|
||||
<string name="error_smp_test_failed_at_step">A teszt a(z) %s lépésnél sikertelen volt.</string>
|
||||
@@ -1351,13 +1345,13 @@
|
||||
<string name="video_will_be_received_when_contact_completes_uploading">A videó akkor érkezik meg, amikor a küldője befejezte annak feltöltését.</string>
|
||||
<string name="description_you_shared_one_time_link_incognito">egyszer használható hivatkozást osztott meg inkognitóban</string>
|
||||
<string name="connected_to_server_to_receive_messages_from_contact">Már kapcsolódott ahhoz a kiszolgálóhoz, amely az adott ismerősétől érkező üzenetek fogadására szolgál.</string>
|
||||
<string name="you_can_enable_delivery_receipts_later">Később engedélyezheti a Beállításokban</string>
|
||||
<string name="you_can_enable_delivery_receipts_later">Később engedélyezheti a „Beállításokban”</string>
|
||||
<string name="you_will_be_connected_when_group_host_device_is_online">Akkor lesz kapcsolódva a csoporthoz, amikor a csoport tulajdonosának eszköze online lesz, várjon, vagy ellenőrizze később!</string>
|
||||
<string name="mtr_error_different">különböző átköltöztetés az alkalmazásban/adatbázisban: %s / %s</string>
|
||||
<string name="connect_plan_you_are_already_connecting_to_vName"><![CDATA[A kapcsolódás már folyamatban van ehhez: <b>%1$s</b>.]]></string>
|
||||
<string name="unhide_profile">Profil felfedése</string>
|
||||
<string name="this_link_is_not_a_valid_connection_link">Ez nem egy érvényes kapcsolattartási hivatkozás!</string>
|
||||
<string name="to_verify_compare">A végpontok közötti titkosítás ellenőrzéséhez hasonlítsa össze (vagy olvassa be a QR-kódot) az ismerőse eszközén lévő kóddal.</string>
|
||||
<string name="to_verify_compare">A végpontok közötti titkosítás hitelesítéséhez hasonlítsa össze (vagy olvassa be a QR-kódot) az ismerőse eszközén lévő kóddal.</string>
|
||||
<string name="you_must_use_the_most_recent_version_of_database">A csevegési adatbázis legfrissebb verzióját CSAK egy eszközön kell használnia, ellenkező esetben előfordulhat, hogy az üzeneteket nem fogja megkapni valamennyi ismerősétől.</string>
|
||||
<string name="messages_section_description">Ez a beállítás a jelenlegi csevegési profilban lévő üzenetekre érvényes</string>
|
||||
<string name="you_are_invited_to_group_join_to_connect_with_group_members">Meghívást kapott a csoportba. Csatlakozzon, hogy kapcsolatba léphessen a csoport tagjaival.</string>
|
||||
@@ -1373,8 +1367,8 @@
|
||||
<string name="invite_prohibited_description">Egy olyan ismerősét próbálja meghívni, akivel inkognitó-profilt osztott meg abban a csoportban, amelyben a saját fő profilja van használatban</string>
|
||||
<string name="connect_plan_you_are_already_joining_the_group_vName"><![CDATA[A csatlakozás már folyamatban van a(z) <b>%1$s</b> nevű csoporthoz.]]></string>
|
||||
<string name="onboarding_notifications_mode_off">Amikor az alkalmazás fut</string>
|
||||
<string name="alert_title_cant_invite_contacts_descr">Inkognító profilt használ ehhez a csoporthoz - fő profilja megosztásának elkerülése érdekében a meghívók küldése le van tiltva</string>
|
||||
<string name="v4_5_transport_isolation">Kapcsolat izolációs mód</string>
|
||||
<string name="alert_title_cant_invite_contacts_descr">Inkognitóprofilt használ ehhez a csoporthoz - fő profilja megosztásának elkerülése érdekében a meghívók küldése le van tiltva</string>
|
||||
<string name="v4_5_transport_isolation">Átvitel-izoláció</string>
|
||||
<string name="you_will_be_connected_when_your_connection_request_is_accepted">Akkor lesz kapcsolódva, ha a kapcsolatkérése elfogadásra kerül, várjon, vagy ellenőrizze később!</string>
|
||||
<string name="voice_messages_are_prohibited">A hangüzenetek küldése le van tiltva ebben a csoportban.</string>
|
||||
<string name="system_restricted_background_in_call_warn"><![CDATA[A háttérben való hívásokhoz válassza ki az <b>Alkalmazás akkumulátor-használata</b> / <b>Korlátlan</b> módot az alkalmazás beállításaiban.]]></string>
|
||||
@@ -1387,16 +1381,16 @@
|
||||
<string name="you_will_be_connected_when_your_contacts_device_is_online">Akkor lesz kapcsolódva, amikor az ismerősének eszköze online lesz, várjon, vagy ellenőrizze később!</string>
|
||||
<string name="v5_4_block_group_members_descr">Kéretlen üzenetek elrejtése.</string>
|
||||
<string name="disable_onion_hosts_when_not_supported"><![CDATA[Állítsa az <i>Onion kiszolgálók használata</i> opciót „Nemre”, ha a SOCKS proxy nem támogatja őket.]]></string>
|
||||
<string name="you_can_share_your_address">Megoszthatja a címét egy hivatkozásként vagy egy QR-kódként – így bárki kapcsolódhat önhöz.</string>
|
||||
<string name="you_can_share_your_address">Megoszthatja a címét egy hivatkozásként vagy egy QR-kódként – így bárki kapcsolódhat Önhöz.</string>
|
||||
<string name="you_can_create_it_later">Létrehozás később</string>
|
||||
<string name="your_profile_is_stored_on_device_and_shared_only_with_contacts_simplex_cannot_see_it">A profilja az eszközén van tárolva és csak az ismerőseivel kerül megosztásra. A SimpleX-kiszolgálók nem láthatják a profilját.</string>
|
||||
<string name="snd_group_event_changed_member_role">%s szerepkörét megváltoztatta erre: %s</string>
|
||||
<string name="snd_group_event_changed_member_role">Ön megváltoztatta %s szerepkörét erre: %s</string>
|
||||
<string name="you_rejected_group_invitation">Csoportmeghívó elutasítva</string>
|
||||
<string name="to_protect_privacy_simplex_has_ids_for_queues">Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználói azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.</string>
|
||||
<string name="to_protect_privacy_simplex_has_ids_for_queues">Az adatvédelem érdekében, a más csevegési platformokon megszokott felhasználó-azonosítók helyett, a SimpleX csak az üzenetek sorbaállításához használ azonosítókat, minden egyes ismerőshöz egy-egy különbözőt.</string>
|
||||
<string name="to_share_with_your_contact">(a megosztáshoz az ismerősével)</string>
|
||||
<string name="you_sent_group_invitation">Csoportmeghívó elküldve</string>
|
||||
<string name="update_network_session_mode_question">Kapcsolat izolációs mód frissítése?</string>
|
||||
<string name="network_session_mode_transport_isolation">Kapcsolat izolációs mód</string>
|
||||
<string name="update_network_session_mode_question">Átvitel-izoláció módjának frissítése?</string>
|
||||
<string name="network_session_mode_transport_isolation">Átvitel-izoláció</string>
|
||||
<string name="you_will_stop_receiving_messages_from_this_group_chat_history_will_be_preserved">Ettől a csoporttól nem fog értesítéseket kapni. A csevegési előzmények megmaradnak.</string>
|
||||
<string name="database_is_not_encrypted">A csevegési adatbázis nem titkosított - állítson be egy jelmondatot annak védelméhez.</string>
|
||||
<string name="network_disable_socks">Közvetlen internet kapcsolat használata?</string>
|
||||
@@ -1419,37 +1413,37 @@
|
||||
<string name="connect_plan_you_are_already_connecting_via_this_one_time_link">A kapcsolódás már folyamatban van ezen az egyszer használható hivatkozáson keresztül!</string>
|
||||
<string name="you_wont_lose_your_contacts_if_delete_address">Nem veszíti el az ismerőseit, ha később törli a címét.</string>
|
||||
<string name="updating_settings_will_reconnect_client_to_all_servers">A beállítások frissítése a kiszolgálókhoz való újra kapcsolódással jár.</string>
|
||||
<string name="contact_wants_to_connect_with_you">kapcsolatba akar lépni önnel!</string>
|
||||
<string name="snd_group_event_changed_role_for_yourself">saját szerepköre erre változott: %s</string>
|
||||
<string name="contact_wants_to_connect_with_you">kapcsolatba akar lépni Önnel!</string>
|
||||
<string name="snd_group_event_changed_role_for_yourself">saját szerepköre megváltozott erre: %s</string>
|
||||
<string name="you_can_start_chat_via_setting_or_by_restarting_the_app">A csevegési szolgáltatás elindítható a „Beállítások / Adatbázis” menüben vagy az alkalmazás újraindításával.</string>
|
||||
<string name="verify_code_on_mobile">Kód ellenőrzése a hordozható eszközön</string>
|
||||
<string name="verify_code_on_mobile">Kód hitelesítése a hordozható eszközön</string>
|
||||
<string name="youve_accepted_group_invitation_connecting_to_inviting_group_member">Csatlakozott ehhez a csoporthoz. Kapcsolódás a meghívó csoporttaghoz.</string>
|
||||
<string name="you_can_connect_to_simplex_chat_founder"><![CDATA[Kapcsolatba léphet <font color="#0088ff">a SimpleX Chat fejlesztőivel, ahol bármiről kérdezhet és értesülhet az újdonságokról</font>.]]></string>
|
||||
<string name="v4_2_auto_accept_contact_requests_desc">Nem kötelező üdvözlőüzenettel.</string>
|
||||
<string name="unknown_database_error_with_info">Ismeretlen adatbázishiba: %s</string>
|
||||
<string name="you_can_hide_or_mute_user_profile">Elrejtheti vagy lenémíthatja a felhasználó profiljait - koppintson (vagy számítógép-alkalmazásban kattintson) hosszan a profilra a felugró menühöz.</string>
|
||||
<string name="v5_3_simpler_incognito_mode_descr">Inkognító mód kapcsolódáskor.</string>
|
||||
<string name="you_can_hide_or_mute_user_profile">Elrejtheti vagy lenémíthatja a felhasználó-profiljait - koppintson (vagy számítógép-alkalmazásban kattintson) hosszan a profilra a felugró menühöz.</string>
|
||||
<string name="v5_3_simpler_incognito_mode_descr">Inkognitómód használata kapcsolódáskor.</string>
|
||||
<string name="you_can_share_group_link_anybody_will_be_able_to_connect">Megoszthat egy hivatkozást vagy QR-kódot - így bárki csatlakozhat a csoporthoz. Ha a csoport később törlésre kerül, akkor nem fogja elveszíteni annak tagjait.</string>
|
||||
<string name="you_joined_this_group">Csatlakozott ehhez a csoporthoz</string>
|
||||
<string name="connect_plan_this_is_your_link_for_group_vName"><![CDATA[Ez az ön hivatkozása a(z) <b>%1$s</b> csoporthoz!]]></string>
|
||||
<string name="connect_plan_this_is_your_link_for_group_vName"><![CDATA[Ez az Ön hivatkozása a(z) <b>%1$s</b> csoporthoz!]]></string>
|
||||
<string name="voice_prohibited_in_this_chat">A hangüzenetek küldése le van tiltva ebben a csevegésben.</string>
|
||||
<string name="you_control_your_chat">Ön irányítja csevegését!</string>
|
||||
<string name="verify_code_with_desktop">Kód ellenőrzése a számítógépen</string>
|
||||
<string name="verify_code_with_desktop">Kód hitelesítése a számítógépen</string>
|
||||
<string name="v4_5_private_filenames_descr">Az időzóna védelme érdekében a kép-/hangfájlok UTC-t használnak.</string>
|
||||
<string name="connect_via_member_address_alert_desc">A kapcsolatkérés elküldésre kerül ezen csoporttag számára.</string>
|
||||
<string name="incognito_info_share">Inkognitó-profil megosztása esetén a rendszer azt a profilt fogja használni azokhoz a csoportokhoz, amelyekbe meghívást kapott.</string>
|
||||
<string name="connect_plan_you_have_already_requested_connection_via_this_address">Már küldött egy kapcsolatkérést ezen a címen keresztül!</string>
|
||||
<string name="you_can_share_this_address_with_your_contacts">Megoszthatja ezt a SimpleX-címet az ismerőseivel, hogy kapcsolatba léphessenek vele: %s.</string>
|
||||
<string name="you_can_accept_or_reject_connection">Amikor az emberek kapcsolatot kérnek, ön elfogadhatja vagy elutasíthatja azokat.</string>
|
||||
<string name="you_can_accept_or_reject_connection">Amikor az emberek kapcsolatot kérnek, Ön elfogadhatja vagy elutasíthatja azokat.</string>
|
||||
<string name="v4_6_group_welcome_message_descr">Megjelenítendő üzenet beállítása az új tagok számára!</string>
|
||||
<string name="whats_new_thanks_to_users_contribute_weblate">Köszönet a felhasználóknak - hozzájárulás a Weblate-en!</string>
|
||||
<string name="sending_delivery_receipts_will_be_enabled">A kézbesítési jelentés küldése minden ismerőse számára engedélyezésre kerül.</string>
|
||||
<string name="network_option_protocol_timeout_per_kb">Protokoll időkorlát KB-onként</string>
|
||||
<string name="network_option_protocol_timeout_per_kb">Protokoll időtúllépése KB-onként</string>
|
||||
<string name="database_backup_can_be_restored">Az adatbázis-jelmondat megváltoztatására tett kísérlet nem fejeződött be.</string>
|
||||
<string name="enable_automatic_deletion_message">Ez a művelet nem vonható vissza - a kiválasztottnál korábban küldött és fogadott üzenetek törlésre kerülnek. Ez több percet is igénybe vehet.</string>
|
||||
<string name="profile_is_only_shared_with_your_contacts">A profilja csak az ismerőseivel kerül megosztásra.</string>
|
||||
<string name="smp_servers_test_some_failed">Néhány kiszolgáló megbukott a teszten:</string>
|
||||
<string name="group_invitation_tap_to_join">Koppintson a csatlakozáshoz</string>
|
||||
<string name="group_invitation_tap_to_join">Koppintson ide a csatlakozáshoz</string>
|
||||
<string name="delete_files_and_media_desc">Ez a művelet nem vonható vissza - az összes fogadott és küldött fájl a médiatartalmakkal együtt törlésre kerülnek. Az alacsony felbontású képek viszont megmaradnak.</string>
|
||||
<string name="receipts_contacts_override_enabled">A kézbesítési jelentések engedélyezve vannak %d ismerősnél</string>
|
||||
<string name="sending_via">Küldés ezen keresztül:</string>
|
||||
@@ -1463,7 +1457,7 @@
|
||||
<string name="contact_you_shared_link_with_wont_be_able_to_connect">Az ismerőse, akivel megosztotta ezt a hivatkozást, NEM fog tudni kapcsolódni!</string>
|
||||
<string name="you_can_change_it_later">A véletlenszerű jelmondat egyszerű szövegként van tárolva a beállításokban.
|
||||
\nEz később megváltoztatható.</string>
|
||||
<string name="group_invitation_tap_to_join_incognito">Koppintson az inkognitóban való kapcsolódáshoz</string>
|
||||
<string name="group_invitation_tap_to_join_incognito">Koppintson ide az inkognitóban való kapcsolódáshoz</string>
|
||||
<string name="set_password_to_export">Jelmondat beállítása az exportáláshoz</string>
|
||||
<string name="receipts_groups_override_disabled">A kézbesítési jelentések le vannak tiltva %d csoportban</string>
|
||||
<string name="non_fatal_errors_occured_during_import">Néhány nem végzetes hiba történt az importáláskor:</string>
|
||||
@@ -1490,7 +1484,7 @@
|
||||
<string name="session_code">Munkamenet kód</string>
|
||||
<string name="v4_4_french_interface_descr">Köszönet a felhasználóknak - hozzájárulás a Weblate-en!</string>
|
||||
<string name="receipts_section_groups">Kis csoportok (max. 20 tag)</string>
|
||||
<string name="connection_you_accepted_will_be_cancelled">Az ön által elfogadott kérelem vissza lesz vonva!</string>
|
||||
<string name="connection_you_accepted_will_be_cancelled">Az Ön által elfogadott kérelem vissza lesz vonva!</string>
|
||||
<string name="send_live_message_desc">Élő üzenet küldése - a címzett(ek) számára frissül, ahogy beírja</string>
|
||||
<string name="settings_section_title_delivery_receipts">A KÉZBESÍTÉSI JELENTÉSEKET A KÖVETKEZŐ CÍMRE KELL KÜLDENI</string>
|
||||
<string name="alert_text_msg_bad_id">A következő üzenet azonosítója hibás (kisebb vagy egyenlő az előzővel).
|
||||
@@ -1525,8 +1519,8 @@
|
||||
<string name="recent_history">Látható előzmények</string>
|
||||
<string name="la_app_passcode">Alkalmazás jelkód</string>
|
||||
<string name="add_contact_tab">Ismerős hozzáadása</string>
|
||||
<string name="tap_to_scan">Koppintson a beolvasáshoz</string>
|
||||
<string name="tap_to_paste_link">Koppintson a hivatkozás beillesztéséhez</string>
|
||||
<string name="tap_to_scan">Koppintson ide a QR-kód beolvasásához</string>
|
||||
<string name="tap_to_paste_link">Koppintson ide a hivatkozás beillesztéséhez</string>
|
||||
<string name="add_contact_button_to_create_link_or_connect_via_link"><![CDATA[<b>Ismerős hozzáadása</b>: új meghívó-hivatkozás létrehozásához, vagy egy kapott hivatkozáson keresztül történő kapcsolódáshoz.]]></string>
|
||||
<string name="create_group_button_to_create_new_group"><![CDATA[<b>Csoport létrehozása</b>: új csoport létrehozásához.]]></string>
|
||||
<string name="chat_is_stopped_you_should_transfer_database">A csevegés leállt. Ha már használta ezt az adatbázist egy másik eszközön, úgy visszaállítás szükséges a csevegés megkezdése előtt.</string>
|
||||
@@ -1581,7 +1575,7 @@
|
||||
<string name="developer_options_section">Fejlesztői beállítások</string>
|
||||
<string name="possible_slow_function_desc">A funkció végrehajtása túl sokáig tart: %1$d másodperc: %2$s</string>
|
||||
<string name="remote_host_error_busy"><![CDATA[A(z) <b>%s</b> hordozható eszköz elfoglalt]]></string>
|
||||
<string name="past_member_vName">%1$s (már nem tag)</string>
|
||||
<string name="past_member_vName">Már nem tag %1$s</string>
|
||||
<string name="group_member_status_unknown">ismeretlen állapot</string>
|
||||
<string name="profile_update_event_member_name_changed">%1$s megváltoztatta a nevét erre: %2$s</string>
|
||||
<string name="profile_update_event_removed_address">eltávolította a kapcsolattartási címet</string>
|
||||
@@ -1608,7 +1602,7 @@
|
||||
<string name="v5_5_new_interface_languages">Magyar és török felhasználói felület</string>
|
||||
<string name="v5_5_join_group_conversation_descr">A közelmúlt eseményei és továbbfejlesztett könyvtárbot.</string>
|
||||
<string name="rcv_group_event_member_unblocked">feloldotta %s letiltását</string>
|
||||
<string name="snd_group_event_member_unblocked">ön feloldotta %s letiltását</string>
|
||||
<string name="snd_group_event_member_unblocked">Ön feloldotta %s letiltását</string>
|
||||
<string name="member_info_member_blocked">letiltva</string>
|
||||
<string name="blocked_by_admin_item_description">letiltva az admin által</string>
|
||||
<string name="member_blocked_by_admin">Letiltva az admin által</string>
|
||||
@@ -1618,7 +1612,7 @@
|
||||
<string name="blocked_by_admin_items_description">%d üzenetet letiltott az admin</string>
|
||||
<string name="unblock_for_all">Letiltás feloldása mindenki számára</string>
|
||||
<string name="unblock_for_all_question">Mindenki számára feloldja a tag letiltását?</string>
|
||||
<string name="snd_group_event_member_blocked">ön letiltotta őt: %s</string>
|
||||
<string name="snd_group_event_member_blocked">Ön letiltotta őt: %s</string>
|
||||
<string name="error_blocking_member_for_all">Hiba a tag mindenki számára való letiltásakor</string>
|
||||
<string name="message_too_large">Az üzenet túl nagy</string>
|
||||
<string name="welcome_message_is_too_long">Az üdvözlőüzenet túl hosszú</string>
|
||||
@@ -1652,14 +1646,14 @@
|
||||
<string name="migrate_from_device_error_saving_settings">Hiba a beállítások mentésekor</string>
|
||||
<string name="migrate_to_device_error_downloading_archive">Hiba az archívum letöltésekor</string>
|
||||
<string name="migrate_from_device_error_uploading_archive">Hiba az archívum feltöltésekor</string>
|
||||
<string name="migrate_from_device_error_verifying_passphrase">Hiba a jelmondat ellenőrzésekor:</string>
|
||||
<string name="migrate_from_device_error_verifying_passphrase">Hiba a jelmondat hitelesítésekor:</string>
|
||||
<string name="migrate_from_device_exported_file_doesnt_exist">Az exportált fájl nem létezik</string>
|
||||
<string name="migrate_to_device_file_delete_or_link_invalid">A fájl törlésre került, vagy érvénytelen hivatkozás</string>
|
||||
<string name="migrate_to_device_bytes_downloaded">%s letöltve</string>
|
||||
<string name="migrate_to_device_importing_archive">Archívum importálása</string>
|
||||
<string name="migrate_from_device_database_init">Feltöltés előkészítése</string>
|
||||
<string name="migrate_from_device_verify_database_passphrase">Az adatbázis jelmondatának ellenőrzése</string>
|
||||
<string name="migrate_from_device_verify_passphrase">Jelmondat ellenőrzése</string>
|
||||
<string name="migrate_from_device_verify_database_passphrase">Az adatbázis jelmondatának hitelesítése</string>
|
||||
<string name="migrate_from_device_verify_passphrase">Jelmondat hitelesítése</string>
|
||||
<string name="set_passphrase">Jelmondat beállítása</string>
|
||||
<string name="v5_6_picture_in_picture_calls">Kép a képben hívások</string>
|
||||
<string name="v5_6_safer_groups">Biztonságosabb csoportok</string>
|
||||
@@ -1759,7 +1753,7 @@
|
||||
<string name="settings_section_title_profile_images">Profilképek</string>
|
||||
<string name="v5_7_shape_profile_images">Profilkép alakzat</string>
|
||||
<string name="v5_7_shape_profile_images_descr">Négyzet, kör vagy bármi a kettő között.</string>
|
||||
<string name="snd_error_relay">Célkiszolgáló hiba: %1$s</string>
|
||||
<string name="snd_error_relay">Célkiszolgáló-hiba: %1$s</string>
|
||||
<string name="snd_error_proxy">Továbbító kiszolgáló: %1$s
|
||||
\nHiba: %2$s</string>
|
||||
<string name="snd_error_expired">Hálózati problémák - az üzenet többszöri elküldési kísérlet után lejárt.</string>
|
||||
@@ -1774,7 +1768,7 @@
|
||||
<string name="network_smp_proxy_mode_never">Soha</string>
|
||||
<string name="network_smp_proxy_mode_unknown">Ismeretlen kiszolgálók</string>
|
||||
<string name="network_smp_proxy_fallback_allow_protected">Ha az IP-cím rejtett</string>
|
||||
<string name="private_routing_show_message_status">Üzenet állapot megjelenítése</string>
|
||||
<string name="private_routing_show_message_status">Üzenetállapot megjelenítése</string>
|
||||
<string name="network_smp_proxy_fallback_allow_downgrade">Visszafejlesztés engedélyezése</string>
|
||||
<string name="network_smp_proxy_mode_always">Mindig</string>
|
||||
<string name="network_smp_proxy_fallback_prohibit">Nem</string>
|
||||
@@ -1784,14 +1778,14 @@
|
||||
<string name="network_smp_proxy_mode_private_routing">Privát útválasztás</string>
|
||||
<string name="network_smp_proxy_mode_unknown_description">Használjon privát útválasztást ismeretlen kiszolgálókkal.</string>
|
||||
<string name="network_smp_proxy_mode_always_description">Mindig használjon privát útválasztást.</string>
|
||||
<string name="update_network_smp_proxy_mode_question">Üzenet útválasztási mód</string>
|
||||
<string name="network_smp_proxy_fallback_allow_protected_description">Közvetlen üzenetküldés, ha az IP-cím védett és az ön kiszolgálója vagy a célkiszolgáló nem támogatja a privát útválasztást.</string>
|
||||
<string name="network_smp_proxy_fallback_allow_description">Közvetlen üzenetküldés, ha az ön kiszolgálója vagy a célkiszolgáló nem támogatja a privát útválasztást.</string>
|
||||
<string name="update_network_smp_proxy_mode_question">Üzenet-útválasztási mód</string>
|
||||
<string name="network_smp_proxy_fallback_allow_protected_description">Közvetlen üzenetküldés, ha az IP-cím védett és az Ön kiszolgálója vagy a célkiszolgáló nem támogatja a privát útválasztást.</string>
|
||||
<string name="network_smp_proxy_fallback_allow_description">Közvetlen üzenetküldés, ha az Ön kiszolgálója vagy a célkiszolgáló nem támogatja a privát útválasztást.</string>
|
||||
<string name="private_routing_explanation">Az IP-cím védelmének érdekében a privát útválasztás az SMP-kiszolgálókat használja az üzenetek kézbesítéséhez.</string>
|
||||
<string name="update_network_smp_proxy_fallback_question">Üzenet útválasztási tartalék</string>
|
||||
<string name="settings_section_title_private_message_routing">PRIVÁT ÜZENET ÚTVÁLASZTÁS</string>
|
||||
<string name="network_smp_proxy_mode_unprotected_description">Privát útválasztás használata ismeretlen kiszolgálókkal, ha az IP-cím nem védett.</string>
|
||||
<string name="network_smp_proxy_fallback_prohibit_description">Ne küldjön üzeneteket közvetlenül, még akkor sem, ha az ön kiszolgálója vagy a célkiszolgáló nem támogatja a privát útválasztást.</string>
|
||||
<string name="update_network_smp_proxy_fallback_question">Üzenet-útválasztási tartalék</string>
|
||||
<string name="settings_section_title_private_message_routing">PRIVÁT ÜZENET-ÚTVÁLASZTÁS</string>
|
||||
<string name="network_smp_proxy_mode_unprotected_description">Használjon privát útválasztást ismeretlen kiszolgálókkal, ha az IP-cím nem védett.</string>
|
||||
<string name="network_smp_proxy_fallback_prohibit_description">Ne küldjön üzeneteket közvetlenül, még akkor sem, ha az Ön kiszolgálója vagy a célkiszolgáló nem támogatja a privát útválasztást.</string>
|
||||
<string name="without_tor_or_vpn_ip_address_will_be_visible_to_file_servers">Tor vagy VPN nélkül az IP-címe látható lesz a fájlkiszolgálók számára.</string>
|
||||
<string name="settings_section_title_files">FÁJLOK</string>
|
||||
<string name="protect_ip_address">IP-cím védelem</string>
|
||||
@@ -1817,12 +1811,12 @@
|
||||
<string name="chat_list_always_visible">Csevegőlista megjelenítése új ablakban</string>
|
||||
<string name="color_mode_light">Világos</string>
|
||||
<string name="chat_theme_apply_to_light_mode">Világos mód</string>
|
||||
<string name="color_received_quote">Fogadott válasz</string>
|
||||
<string name="color_received_quote">Fogadott válaszüzenet-buborék színe</string>
|
||||
<string name="theme_remove_image">Kép eltávolítása</string>
|
||||
<string name="wallpaper_scale_repeat">Mozaik</string>
|
||||
<string name="reset_single_color">Szín visszaállítása</string>
|
||||
<string name="wallpaper_scale">Méretezés</string>
|
||||
<string name="color_sent_quote">Elküldött válasz</string>
|
||||
<string name="color_sent_quote">Válaszüzenet-buborék színe</string>
|
||||
<string name="chat_theme_set_default_theme">Alapértelmezett téma beállítása</string>
|
||||
<string name="color_mode_system">Rendszer</string>
|
||||
<string name="color_wallpaper_tint">Háttérkép kiemelés</string>
|
||||
@@ -1837,7 +1831,7 @@
|
||||
<string name="chat_theme_reset_to_app_theme">Alkalmazás témájának visszaállítása</string>
|
||||
<string name="v5_8_chat_themes_descr">Tegye egyedivé a csevegéseit!</string>
|
||||
<string name="v5_8_chat_themes">Új csevegési témák</string>
|
||||
<string name="v5_8_private_routing">Privát üzenet útválasztás 🚀</string>
|
||||
<string name="v5_8_private_routing">Privát üzenet-útválasztás 🚀</string>
|
||||
<string name="v5_8_safe_files">Fájlok biztonságos fogadása</string>
|
||||
<string name="v5_8_message_delivery_descr">Csökkentett akkumulátor-használattal.</string>
|
||||
<string name="error_initializing_web_view">Hiba a WebView előkészítésekor. Frissítse rendszerét az új verzióra. Lépjen kapcsolatba a fejlesztőkkel.
|
||||
@@ -1880,8 +1874,7 @@
|
||||
<string name="servers_info_sessions_connecting">Kapcsolódás</string>
|
||||
<string name="servers_info_sessions_errors">Hibák</string>
|
||||
<string name="servers_info_subscriptions_connections_pending">Függőben</string>
|
||||
<string name="servers_info_private_data_disclaimer">Ekkortól kezdve: %s.
|
||||
\nMinden adat biztonságban van az eszközén.</string>
|
||||
<string name="servers_info_private_data_disclaimer">Statisztikagyűjtés kezdete: %s.\nMinden adat biztonságban van az eszközén.</string>
|
||||
<string name="servers_info_messages_sent">Elküldött üzenetek</string>
|
||||
<string name="servers_info_proxied_servers_section_header">Proxyzott kiszolgálók</string>
|
||||
<string name="servers_info_reconnect_servers_title">Újrakapcsolódás a kiszolgálókhoz?</string>
|
||||
@@ -1897,15 +1890,15 @@
|
||||
<string name="servers_info_downloaded">Letöltve</string>
|
||||
<string name="expired_label">lejárt</string>
|
||||
<string name="other_label">egyéb</string>
|
||||
<string name="servers_info_detailed_statistics_received_total">Összes fogadott</string>
|
||||
<string name="servers_info_detailed_statistics_received_total">Összes fogadott üzenet</string>
|
||||
<string name="servers_info_detailed_statistics_receive_errors">Üzenetfogadási hibák</string>
|
||||
<string name="reconnect">Újrakapcsolás</string>
|
||||
<string name="send_errors">Üzenetküldési hibák</string>
|
||||
<string name="sent_directly">Közvetlenül küldött</string>
|
||||
<string name="servers_info_detailed_statistics_sent_messages_total">Összes elküldött</string>
|
||||
<string name="servers_info_detailed_statistics_sent_messages_total">Összes elküldött üzenet</string>
|
||||
<string name="sent_via_proxy">Proxyn keresztül küldve</string>
|
||||
<string name="smp_server">SMP-kiszolgáló</string>
|
||||
<string name="servers_info_starting_from">Ekkortól kezdve: %s.</string>
|
||||
<string name="servers_info_starting_from">Statisztikagyűjtés kezdete: %s.</string>
|
||||
<string name="servers_info_uploaded">Feltöltve</string>
|
||||
<string name="xftp_server">XFTP-kiszolgáló</string>
|
||||
<string name="proxied">Proxyzott</string>
|
||||
@@ -1933,7 +1926,7 @@
|
||||
<string name="xftp_servers_configured">Konfigurált XFTP-kiszolgálók</string>
|
||||
<string name="servers_info_sessions_connected">Kapcsolódva</string>
|
||||
<string name="current_user">Jelenlegi profil</string>
|
||||
<string name="servers_info_details">Részletek</string>
|
||||
<string name="servers_info_details">További részletek</string>
|
||||
<string name="decryption_errors">visszafejtési hibák</string>
|
||||
<string name="deleted">Törölve</string>
|
||||
<string name="servers_info_messages_received">Fogadott üzenetek</string>
|
||||
@@ -1950,7 +1943,7 @@
|
||||
<string name="servers_info_reconnect_server_message">A kiszolgálóhoz való újrakapcsolódás az üzenetkézbesítési jelentések kikényszerítéséhez. Ez további adatforgalmat használ.</string>
|
||||
<string name="servers_info_detailed_statistics_sent_messages_header">Elküldött üzenetek</string>
|
||||
<string name="servers_info_transport_sessions_section_header">Munkamenetek átvitele</string>
|
||||
<string name="servers_info_subscriptions_total">Összesen</string>
|
||||
<string name="servers_info_subscriptions_total">Összes kapcsolat</string>
|
||||
<string name="servers_info_statistics_section_header">Statisztikák</string>
|
||||
<string name="servers_info_target">Információk megjelenítése ehhez:</string>
|
||||
<string name="network_error_broker_version_desc">A kiszolgáló verziója nem kompatibilis az alkalmazással: %1$s.</string>
|
||||
@@ -2036,7 +2029,7 @@
|
||||
<string name="chat_database_exported_continue">Folytatás</string>
|
||||
<string name="v6_0_connection_servers_status">Ellenőrízze a hálózatát</string>
|
||||
<string name="media_and_file_servers">Média- és fájlkiszolgálók</string>
|
||||
<string name="v6_0_delete_many_messages_descr">Legfeljebb 20 üzenet törlése egyszerre.</string>
|
||||
<string name="v6_0_delete_many_messages_descr">Legfeljebb 20 üzenet egyszerre való törlése.</string>
|
||||
<string name="v6_0_private_routing_descr">Védi az IP-címét és a kapcsolatait.</string>
|
||||
<string name="v6_0_reachable_chat_toolbar">Könnyen elérhető eszköztár</string>
|
||||
<string name="message_servers">Üzenetkiszolgálók</string>
|
||||
@@ -2102,4 +2095,24 @@
|
||||
<string name="icon_descr_sound_muted">Hang elnémítva</string>
|
||||
<string name="error_initializing_web_view_wrong_arch">Hiba a WebView előkészítésekor. Győződjön meg arról, hogy a WebView telepítve van-e, és támogatja-e az arm64 architektúrát.
|
||||
\nHiba: %s</string>
|
||||
<string name="settings_message_shape_corner">Sarok</string>
|
||||
<string name="settings_section_title_message_shape">Üzenetbuborék alakja</string>
|
||||
<string name="settings_message_shape_tail">Farok</string>
|
||||
<string name="network_session_mode_server">Kiszolgáló</string>
|
||||
<string name="network_session_mode_session_description">Minden alkalommal, amikor elindítja az alkalmazást, új SOCKS-hitelesítő-adatokat fog használni.</string>
|
||||
<string name="network_session_mode_session">Alkalmazás munkamenete</string>
|
||||
<string name="network_session_mode_server_description">Minden egyes kiszolgálóhoz új SOCKS-hitelesítő-adatok legyenek használva.</string>
|
||||
<string name="call_desktop_permission_denied_chrome">Kattintson a címmező melletti info gombra a mikrofon használatának engedélyezéséhez.</string>
|
||||
<string name="call_desktop_permission_denied_safari">Nyissa meg a Safari Beállítások / Weboldalak / Mikrofon menüt, majd válassza a helyi kiszolgálók engedélyezése lehetőséget.</string>
|
||||
<string name="call_desktop_permission_denied_title">Hívások kezdeményezéséhez engedélyezze a mikrofon használatát. Fejezze be a hívást, és próbálja meg a hívást újra.</string>
|
||||
<string name="v6_1_better_calls">Továbbfejlesztett hívásélmény</string>
|
||||
<string name="v6_1_message_dates_descr">Továbbfejlesztett üzenetdátumok.</string>
|
||||
<string name="v6_1_better_user_experience">Továbbfejlesztett felhasználói élmény</string>
|
||||
<string name="v6_1_customizable_message_descr">Testreszabható üzenetbuborékok.</string>
|
||||
<string name="v6_1_delete_many_messages_descr">Legfeljebb 200 üzenet egyszerre való törlése, vagy moderálása.</string>
|
||||
<string name="v6_1_forward_many_messages_descr">Legfeljebb 20 üzenet egyszerre való továbbítása.</string>
|
||||
<string name="v6_1_better_calls_descr">Hang/Videó váltása hívás közben.</string>
|
||||
<string name="v6_1_switch_chat_profile_descr">Csevegési profilváltás az egyszer használható meghívókhoz.</string>
|
||||
<string name="v6_1_better_security">Továbbfejlesztett biztonság ✅</string>
|
||||
<string name="v6_1_better_security_descr">A SimpleX Chat biztonsága a Trail of Bits által lett újraauditálva.</string>
|
||||
</resources>
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M182-85q-22.97 0-40.23-17.27-17.27-17.26-17.27-40.23v-616q0-22.97 17.27-40.23Q159.03-816 182-816h67.5v-60H312v60h336v-60h62.5v60H778q22.97 0 40.23 17.27 17.27 17.26 17.27 40.23v616q0 22.97-17.27 40.23Q800.97-85 778-85H182Zm0-57.5h596V-569H182v426.5Zm0-484h596v-132H182v132Zm0 0v-132 132Zm298.05 226q-16.76 0-28.16-11.34-11.39-11.34-11.39-28.11 0-16.76 11.34-28.16 11.34-11.39 28.11-11.39 16.76 0 28.16 11.34 11.39 11.34 11.39 28.11 0 16.76-11.34 28.16-11.34 11.39-28.11 11.39Zm-160 0q-16.76 0-28.16-11.34-11.39-11.34-11.39-28.11 0-16.76 11.34-28.16 11.34-11.39 28.11-11.39 16.76 0 28.16 11.34 11.39 11.34 11.39 28.11 0 16.76-11.34 28.16-11.34 11.39-28.11 11.39Zm320 0q-16.76 0-28.16-11.34-11.39-11.34-11.39-28.11 0-16.76 11.34-28.16 11.34-11.39 28.11-11.39 16.76 0 28.16 11.34 11.39 11.34 11.39 28.11 0 16.76-11.34 28.16-11.34 11.39-28.11 11.39Zm-160 160q-16.76 0-28.16-11.34-11.39-11.34-11.39-28.11 0-16.76 11.34-28.16 11.34-11.39 28.11-11.39 16.76 0 28.16 11.34 11.39 11.34 11.39 28.11 0 16.76-11.34 28.16-11.34 11.39-28.11 11.39Zm-160 0q-16.76 0-28.16-11.34-11.39-11.34-11.39-28.11 0-16.76 11.34-28.16 11.34-11.39 28.11-11.39 16.76 0 28.16 11.34 11.39 11.34 11.39 28.11 0 16.76-11.34 28.16-11.34 11.39-28.11 11.39Zm320 0q-16.76 0-28.16-11.34-11.39-11.34-11.39-28.11 0-16.76 11.34-28.16 11.34-11.39 28.11-11.39 16.76 0 28.16 11.34 11.39 11.34 11.39 28.11 0 16.76-11.34 28.16-11.34 11.39-28.11 11.39Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -262,4 +262,5 @@
|
||||
<string name="only_your_contact_can_make_calls">Hanya kontak kamu yang dapat melakukan panggilan.</string>
|
||||
<string name="allow_to_send_files">Izinkan untuk mengirim file dan media.</string>
|
||||
<string name="all_your_contacts_will_remain_connected">Semua kontak kamu akan tetap terhubung.</string>
|
||||
<string name="forward_files_missing_desc">%1$d berkas telah dihapus.</string>
|
||||
</resources>
|
||||
@@ -2108,4 +2108,24 @@
|
||||
<string name="icon_descr_sound_muted">Audio silenziato</string>
|
||||
<string name="error_initializing_web_view_wrong_arch">Errore di inizializzazione di WebView. Assicurati di avere WebView installato e che la sua architettura supportata sia arm64.
|
||||
\nErrore: %s</string>
|
||||
<string name="settings_message_shape_corner">Angolo</string>
|
||||
<string name="settings_section_title_message_shape">Forma del messaggio</string>
|
||||
<string name="settings_message_shape_tail">Coda</string>
|
||||
<string name="network_session_mode_session">Sessione dell\'app</string>
|
||||
<string name="network_session_mode_session_description">Le nuove credenziali SOCKS verranno usate ogni volta che avvii l\'app.</string>
|
||||
<string name="network_session_mode_server_description">Le nuove credenziali SOCKS verranno usate per ogni server.</string>
|
||||
<string name="network_session_mode_server">Server</string>
|
||||
<string name="call_desktop_permission_denied_safari">Apri le impostazioni di Safari / Siti web / Microfono, quindi scegli Consenti per localhost.</string>
|
||||
<string name="call_desktop_permission_denied_chrome">Clicca il pulsante info vicino al campo indirizzo per consentire l\'uso del microfono.</string>
|
||||
<string name="call_desktop_permission_denied_title">Per effettuare chiamate, consenti di usare il microfono. Termina la chiamata e cerca di richiamare.</string>
|
||||
<string name="v6_1_better_calls">Chiamate migliorate</string>
|
||||
<string name="v6_1_message_dates_descr">Date dei messaggi migliorate.</string>
|
||||
<string name="v6_1_better_security">Sicurezza migliorata ✅</string>
|
||||
<string name="v6_1_better_user_experience">Esperienza utente migliorata</string>
|
||||
<string name="v6_1_customizable_message_descr">Forma dei messaggi personalizzabile.</string>
|
||||
<string name="v6_1_better_security_descr">Protocolli di SimpleX esaminati da Trail of Bits.</string>
|
||||
<string name="v6_1_better_calls_descr">Cambia tra audio e video durante la chiamata.</string>
|
||||
<string name="v6_1_switch_chat_profile_descr">Cambia profilo di chat per inviti una tantum.</string>
|
||||
<string name="v6_1_delete_many_messages_descr">Elimina o modera fino a 200 messaggi.</string>
|
||||
<string name="v6_1_forward_many_messages_descr">Inoltra fino a 20 messaggi alla volta.</string>
|
||||
</resources>
|
||||
@@ -791,7 +791,7 @@
|
||||
<string name="group_invitation_tap_to_join_incognito">Tik hier om incognito lid te worden</string>
|
||||
<string name="youve_accepted_group_invitation_connecting_to_inviting_group_member">Je bent lid geworden van deze groep. Verbinding maken met uitnodigend lid.</string>
|
||||
<string name="you_sent_group_invitation">Je hebt een groep uitnodiging verzonden</string>
|
||||
<string name="snd_group_event_user_left">jij bent vertrokken</string>
|
||||
<string name="snd_group_event_user_left">je bent vertrokken</string>
|
||||
<string name="snd_conn_event_switch_queue_phase_completed">je bent van adres veranderd</string>
|
||||
<string name="select_contacts">Selecteer contacten</string>
|
||||
<string name="skip_inviting_button">Sla het uitnodigen van leden over</string>
|
||||
@@ -950,7 +950,7 @@
|
||||
<string name="initial_member_role">Initiële rol</string>
|
||||
<string name="group_member_role_observer">Waarnemer</string>
|
||||
<string name="observer_cant_send_message_title">Je kunt geen berichten versturen!</string>
|
||||
<string name="you_are_observer">jij bent waarnemer</string>
|
||||
<string name="you_are_observer">je bent waarnemer</string>
|
||||
<string name="language_system">Systeem</string>
|
||||
<string name="v4_6_audio_video_calls">Audio en video oproepen</string>
|
||||
<string name="confirm_password">Bevestig wachtwoord</string>
|
||||
@@ -2104,4 +2104,25 @@
|
||||
<string name="network_proxy_incorrect_config_desc">Zorg ervoor dat de proxyconfiguratie correct is.</string>
|
||||
<string name="network_proxy_password">Wachtwoord</string>
|
||||
<string name="icon_descr_sound_muted">Geluid gedempt</string>
|
||||
<string name="error_initializing_web_view_wrong_arch">Fout bij initialiseren van WebView. Zorg ervoor dat WebView geïnstalleerd is en de ondersteunde architectuur is arm64.\nFout: %s</string>
|
||||
<string name="settings_message_shape_corner">Hoek</string>
|
||||
<string name="settings_section_title_message_shape">Berichtvorm</string>
|
||||
<string name="network_session_mode_session">Appsessie</string>
|
||||
<string name="network_session_mode_session_description">Elke keer dat u de app start, worden er nieuwe SOCKS-inloggegevens gebruikt.</string>
|
||||
<string name="network_session_mode_server_description">Voor elke server worden nieuwe SOCKS-inloggegevens gebruikt.</string>
|
||||
<string name="network_session_mode_server">Server</string>
|
||||
<string name="settings_message_shape_tail">Staart</string>
|
||||
<string name="call_desktop_permission_denied_chrome">Klik op de infoknop naast het adresveld om het gebruik van de microfoon toe te staan.</string>
|
||||
<string name="call_desktop_permission_denied_safari">Open Safari Instellingen / Websites / Microfoon en kies Toestaan voor localhost.</string>
|
||||
<string name="call_desktop_permission_denied_title">Als u wilt bellen, geeft u toestemming om uw microfoon te gebruiken. Beëindig het gesprek en probeer opnieuw te bellen.</string>
|
||||
<string name="v6_1_better_security">Betere beveiliging ✅</string>
|
||||
<string name="v6_1_better_security_descr">SimpleX-protocollen beoordeeld door Trail of Bits.</string>
|
||||
<string name="v6_1_message_dates_descr">Betere datums voor berichten.</string>
|
||||
<string name="v6_1_better_user_experience">Betere gebruikerservaring</string>
|
||||
<string name="v6_1_customizable_message_descr">Aanpasbare berichtvorm.</string>
|
||||
<string name="v6_1_better_calls_descr">Wisselen tussen audio en video tijdens het gesprek.</string>
|
||||
<string name="v6_1_switch_chat_profile_descr">Wijzig chatprofiel voor eenmalige uitnodigingen.</string>
|
||||
<string name="v6_1_delete_many_messages_descr">Maximaal 200 berichten verwijderen of modereren.</string>
|
||||
<string name="v6_1_forward_many_messages_descr">Stuur maximaal 20 berichten tegelijk door.</string>
|
||||
<string name="v6_1_better_calls">Betere gesprekken</string>
|
||||
</resources>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user